diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 0000000..2d3d6c4 --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -0,0 +1,28 @@ +name: Run Tests + +on: + pull_request: + branches: [ master ] + workflow_dispatch: + +jobs: + test: + name: Run Unit Tests + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 7.0.x + + - name: Restore dependencies + run: dotnet restore src/mpath-source/Migs.MPath.sln + + - name: Build + run: dotnet build src/mpath-source/Migs.MPath.sln --no-restore + + - name: Test + run: dotnet test src/mpath-source/Migs.MPath.Tests/Migs.MPath.Tests.csproj --no-build --verbosity normal \ No newline at end of file diff --git a/.gitignore b/.gitignore index e43b0f9..f3e5977 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .DS_Store +[Bb]uilds/* +*.log diff --git a/benchmarks.md b/benchmarks.md deleted file mode 100644 index cbd9b27..0000000 --- a/benchmarks.md +++ /dev/null @@ -1,82 +0,0 @@ -# MPath Benchmarks - -This document contains detailed information about MPath's performance benchmarks and how to run them yourself. - -## Complex Maze Pathfinding - -![Benchmark Maze](src/mpath-source/Migs.MPath.Benchmarks/cavern.png) - -*The complex maze used for benchmarking* - -The following benchmark was run on a complex maze to test pathfinding performance. The test involved finding a path from coordinates (10, 10) to (502, 374) through a maze with narrow passages and dead ends. All benchmarks were implemented using [BenchmarkDotNet](https://benchmarkdotnet.org/). - -### Implementation Comparison - -| Method | Mean | Allocated | -|---------- |----------:|------------:| -| MPath | 5.092 ms | 24.06 KB | -| [AStarLite](https://github.com/valantonini/AStar) | 8.118 ms | 8959.94 KB | -| [RoyTAStar](https://github.com/roy-t/AStar) | 59.028 ms | 12592.34 KB | -| [LinqToAStar](https://arc.net/l/quote/iqcsmlgc) | 5,532.7 ms | 108.13 MB | - -These results highlight MPath's optimization for both speed and memory efficiency. Memory allocation in MPath is required only for the initial pathfinder creation and for the final path result creation, with no GC pressure during the pathfinding algorithm execution. - -### Path Smoothing Comparison - -The following benchmark compares different path smoothing options using the same maze and coordinates: - -| Method | Mean | Error | StdDev | Ratio | Allocated | Alloc Ratio | -|----------------------- |---------:|----------:|----------:|------:|----------:|------------:| -| NoSmoothing | 5.066 ms | 0.0175 ms | 0.0155 ms | 1.00 | 24.06 KB | 1.00 | -| SimpleSmoothing | 5.070 ms | 0.0167 ms | 0.0139 ms | 1.00 | 24.06 KB | 1.00 | -| StringPullingSmoothing | 6.471 ms | 0.0275 ms | 0.0230 ms | 1.28 | 24.06 KB | 1.00 | - -The results show that: -- Simple smoothing adds negligible overhead compared to no smoothing -- String pulling smoothing adds about 28% overhead, but still maintains the same memory efficiency - -## Benchmark Environment Specs - -``` -BenchmarkDotNet v0.14.0, macOS Sequoia 15.3.2 (24D81) [Darwin 24.3.0] -Apple M1 Max, 1 CPU, 10 logical and 10 physical cores -.NET SDK 7.0.100 - [Host] : .NET 7.0.0 (7.0.22.61201), Arm64 RyuJIT AdvSIMD - DefaultJob : .NET 7.0.0 (7.0.22.61201), Arm64 RyuJIT AdvSIMD -``` - -## Measurement Legend - -``` -Mean : Arithmetic mean of all measurements -Error : Half of 99.9% confidence interval -StdDev : Standard deviation of all measurements -Ratio : Mean of the ratio distribution ([Current]/[Baseline]) -Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B) -1 ms : 1 Millisecond (0.001 sec) -``` - -## Running Benchmarks - -### .NET Benchmarks - -To run the benchmarks on your own machine: - -1. Clone the repository -2. Navigate to the benchmark project folder: - ``` - cd src/mpath-source/Migs.MPath.Benchmarks - ``` -3. Run the benchmarks: - ``` - dotnet run -c Release - ``` - -### Unity Benchmarks - -Unity benchmark scenes are available in the Unity project: - -1. Open the Unity project at `src/mpath-unity-project` -2. Open the benchmark scene at `Assets/MPath/Samples/Benchmarks` -3. Press play to run the benchmark scene -4. Results will be displayed in the Unity console \ No newline at end of file diff --git a/ci/process-unity-package.sh b/ci/process-unity-package.sh new file mode 100755 index 0000000..11d874f --- /dev/null +++ b/ci/process-unity-package.sh @@ -0,0 +1,250 @@ +#!/bin/bash + +# Script to run Unity to export a package, then modify its contents to change asset paths + +# Check if debug mode is enabled +DEBUG_MODE=false +if [ "$1" == "debug" ]; then + DEBUG_MODE=true + echo "Debug mode enabled - verbose logging will be shown" +fi + +# ANSI color codes +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Function to print colored messages +print_step() { + echo -e "${YELLOW}STEP: $1${NC}" +} + +# Function to print success messages +print_success() { + echo -e "${GREEN}SUCCESS: $1${NC}" +} + +# Function to print error messages and exit +print_error() { + echo -e "${RED}ERROR: $1${NC}" + exit 1 +} + +# Function to print debug info only if debug mode is enabled +print_debug() { + if [ "$DEBUG_MODE" = true ]; then + echo -e "${BLUE}DEBUG: $1${NC}" + fi +} + +# Paths +BUILDS_DIR="builds" +UNITY_PROJECT_PATH="$(pwd)/src/mpath-unity-project" +TEMP_DIR="$(pwd)/tmp_package" +UNITY_LOG="$(pwd)/unity_build.log" + +# Create builds directory if it doesn't exist +mkdir -p "$BUILDS_DIR" +print_debug "Created builds directory: $BUILDS_DIR" + +# Step 1: Run Unity to create the package +print_step "Running Unity to create UnityPackage" + +# Find Unity on macOS +UNITY_PATH="/Applications/Unity/Hub/Editor" +print_debug "Looking for Unity in: $UNITY_PATH" + +# List all Unity versions found +if [ "$DEBUG_MODE" = true ]; then + echo "Unity versions found:" + find "$UNITY_PATH" -maxdepth 1 -type d | sort -V | while read unity_ver; do + echo " - $(basename "$unity_ver")" + done +fi + +LATEST_UNITY=$(find "$UNITY_PATH" -maxdepth 1 -type d | sort -V | tail -n1) + +if [ -z "$LATEST_UNITY" ]; then + print_error "Unity installation not found in $UNITY_PATH" +fi + +print_debug "Using Unity at: $LATEST_UNITY" +UNITY_EXECUTABLE="$LATEST_UNITY/Unity.app/Contents/MacOS/Unity" + +if [ ! -f "$UNITY_EXECUTABLE" ]; then + print_error "Unity executable not found at $UNITY_EXECUTABLE" +fi + +# Check if project path exists +if [ ! -d "$UNITY_PROJECT_PATH" ]; then + print_error "Unity project path does not exist: $UNITY_PROJECT_PATH" +fi +print_debug "Unity project path: $UNITY_PROJECT_PATH" + +# Check if Editor script exists +EDITOR_SCRIPT_PATH="$UNITY_PROJECT_PATH/Assets/Editor/PackageExporter.cs" +if [ ! -f "$EDITOR_SCRIPT_PATH" ]; then + print_error "Editor script not found at $EDITOR_SCRIPT_PATH" +fi +print_debug "Editor script exists at: $EDITOR_SCRIPT_PATH" + +# Clean up any previous logs +rm -f "$UNITY_LOG" 2>/dev/null + +# Run Unity in batch mode to create the package +print_step "Running Unity in batch mode..." +print_debug "Command: $UNITY_EXECUTABLE -batchmode -projectPath $UNITY_PROJECT_PATH -executeMethod Migs.MPath.Editor.PackageExporter.ExportPackageFromBatchMode -logFile $UNITY_LOG -quit" + +"$UNITY_EXECUTABLE" -batchmode -projectPath "$UNITY_PROJECT_PATH" -executeMethod Migs.MPath.Editor.PackageExporter.ExportPackageFromBatchMode -logFile "$UNITY_LOG" -quit + +UNITY_EXIT_CODE=$? +print_debug "Unity exit code: $UNITY_EXIT_CODE" + +# Always show the log if in debug mode or if there was an error +if [ "$DEBUG_MODE" = true ] || [ $UNITY_EXIT_CODE -ne 0 ]; then + if [ -f "$UNITY_LOG" ]; then + echo "=== Unity Log ===" + cat "$UNITY_LOG" + echo "=== End Unity Log ===" + else + print_debug "No Unity log file was created!" + fi +fi + +# Check log for common errors even if exit code is 0 +if [ -f "$UNITY_LOG" ]; then + if grep -q "ExecuteMethod method Migs.MPath.Editor.PackageExporter.ExportPackageFromBatchMode not found" "$UNITY_LOG"; then + print_error "Method not found: Migs.MPath.Editor.PackageExporter.ExportPackageFromBatchMode" + fi + + if grep -q "Assembly 'Assembly-CSharp-Editor' will not be loaded due to errors:" "$UNITY_LOG"; then + print_error "Editor script has compilation errors" + fi +fi + +if [ $UNITY_EXIT_CODE -ne 0 ]; then + print_error "Unity batch mode execution failed with exit code $UNITY_EXIT_CODE" +fi + +print_success "Unity batch execution completed" + +# Check if any packages were created +print_debug "Checking for created packages in $BUILDS_DIR" +if [ "$DEBUG_MODE" = true ]; then + find "$BUILDS_DIR" -name "*.unitypackage" -type f -print +fi + +# Find the generated package +UNITY_PACKAGE=$(find "$BUILDS_DIR" -name "migs-mpath-*.unitypackage" | sort -V | tail -n1) + +if [ -z "$UNITY_PACKAGE" ]; then + print_error "UnityPackage not found in $BUILDS_DIR. Package generation failed." +fi + +print_debug "Found package: $UNITY_PACKAGE" +print_debug "Package file size: $(du -h "$UNITY_PACKAGE" | cut -f1)" + +VERSION=$(echo "$UNITY_PACKAGE" | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' | head -1) +if [ -z "$VERSION" ]; then + print_error "Could not extract version from package filename" +fi + +print_success "Found UnityPackage: $UNITY_PACKAGE (version $VERSION)" + +# Step 2: Extract the Unity package +print_step "Extracting Unity package..." + +# Create temporary directory +rm -rf "$TEMP_DIR" 2>/dev/null +mkdir -p "$TEMP_DIR" +print_debug "Created temp directory: $TEMP_DIR" + +# Extract package to temp directory +print_debug "Extracting with: tar -xzf \"$UNITY_PACKAGE\" -C \"$TEMP_DIR\"" +tar -xzf "$UNITY_PACKAGE" -C "$TEMP_DIR" + +if [ $? -ne 0 ]; then + print_error "Failed to extract Unity package. Check if the file is a valid tar.gz archive." +fi + +# Count extracted items +EXTRACTED_COUNT=$(find "$TEMP_DIR" -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' ') +print_debug "Number of GUID directories extracted: $EXTRACTED_COUNT" + +if [ "$EXTRACTED_COUNT" -eq 0 ]; then + print_error "No GUID directories found in the package. Either the package is empty or not a valid Unity package." +fi + +print_success "Package extracted to $TEMP_DIR ($EXTRACTED_COUNT items)" + +# Step 3: Modify the pathname files +print_step "Modifying pathname files to change asset paths..." + +# Find all directories in the temp dir - these are the GUIDs +MODIFIED_COUNT=0 +find "$TEMP_DIR" -mindepth 1 -maxdepth 1 -type d | while read guid_dir; do + PATHNAME_FILE="$guid_dir/pathname" + + if [ -f "$PATHNAME_FILE" ]; then + # Read current path + CURRENT_PATH=$(cat "$PATHNAME_FILE") + + # Check if path starts with Assets/ + if [[ "$CURRENT_PATH" == Assets/* ]]; then + # Change Assets/ to Packages/ (without escape characters) + NEW_PATH="Packages/${CURRENT_PATH#Assets/}" + + # Write new path back to file + echo "$NEW_PATH" > "$PATHNAME_FILE" + if [ "$DEBUG_MODE" = true ]; then + echo "Changed: $CURRENT_PATH -> $NEW_PATH" + fi + MODIFIED_COUNT=$((MODIFIED_COUNT + 1)) + else + print_debug "Skipping non-Assets path: $CURRENT_PATH" + fi + else + print_debug "No pathname file in $(basename "$guid_dir")" + fi +done + +print_debug "Modified $MODIFIED_COUNT pathname files" +print_success "All pathname files processed" + +# Step 4: Create new archive +print_step "Creating new archive..." + +NEW_PACKAGE="${UNITY_PACKAGE%.unitypackage}.modified.tar.gz" +print_debug "Creating new package: $NEW_PACKAGE" + +# Create tarball from the temp directory +tar -czf "$NEW_PACKAGE" -C "$TEMP_DIR" . + +if [ $? -ne 0 ]; then + print_error "Failed to create new archive" +fi + +print_debug "New package size: $(du -h "$NEW_PACKAGE" | cut -f1)" +print_success "New archive created: $NEW_PACKAGE" + +# Step 5: Replace original file +print_step "Replacing original unity package..." + +# Replace with our modified version (no backup) +mv "$NEW_PACKAGE" "$UNITY_PACKAGE" + +if [ $? -ne 0 ]; then + print_error "Failed to rename modified package" +fi + +print_success "Original package replaced with modified version" + +# Cleanup +print_step "Cleaning up..." +rm -rf "$TEMP_DIR" +print_success "Temporary files removed" + +print_success "Package processing completed successfully" +echo "Final package: $UNITY_PACKAGE" \ No newline at end of file diff --git a/src/mpath-source/Migs.MPath.Core/publish-nuget.sh b/ci/publish-nuget.sh similarity index 100% rename from src/mpath-source/Migs.MPath.Core/publish-nuget.sh rename to ci/publish-nuget.sh diff --git a/ci/release.sh b/ci/release.sh new file mode 100755 index 0000000..2020928 --- /dev/null +++ b/ci/release.sh @@ -0,0 +1,134 @@ +#!/bin/bash + +# ANSI color codes +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Function to print colored step messages +print_step() { + echo -e "${YELLOW}STEP: $1${NC}" +} + +# Function to print success messages +print_success() { + echo -e "${GREEN}SUCCESS: $1${NC}" +} + +# Function to print error messages and exit +print_error() { + echo -e "${RED}ERROR: $1${NC}" + exit 1 +} + +# Function to check if the user wants to continue +ask_continue() { + read -p "Continue? (y/n): " choice + case "$choice" in + y|Y ) return 0;; + * ) print_error "Operation cancelled by user";; + esac +} + +# Step 1: Check current branch +print_step "Checking current branch" +CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) +if [ "$CURRENT_BRANCH" != "master" ]; then + echo -e "${YELLOW}Warning: Current branch is $CURRENT_BRANCH, not master.${NC}" + echo "It's recommended to run this script on the master branch." + read -p "Continue on $CURRENT_BRANCH branch? (y/n): " continue_nonmaster + if [[ ! "$continue_nonmaster" =~ ^[Yy]$ ]]; then + print_error "Operation cancelled by user. Please switch to master branch." + fi + print_success "Continuing on $CURRENT_BRANCH branch" +else + print_success "Current branch is master" +fi + +# Step 2: Check for unstaged or uncommitted changes +print_step "Checking for unstaged or uncommitted changes" +if ! git diff --quiet || ! git diff --cached --quiet; then + print_error "There are unstaged or uncommitted changes. Please commit or stash them first." +fi +print_success "No unstaged or uncommitted changes found" + +# Step 3: Pull the latest code from remote +print_step "Pulling latest code from remote" +if ! git pull; then + print_error "Failed to pull latest code from remote" +fi +print_success "Successfully pulled latest code" + +# Step 4: Ask if version increment is needed +print_step "Version increment" +read -p "Increment version? (y/n): " increment_version +if [[ "$increment_version" =~ ^[Yy]$ ]]; then + read -p "Which part to increment? [major/minor/patch] (default: minor): " increment_part + increment_part=${increment_part:-minor} + + NEW_VERSION=$(./ci/version-increment.sh "$increment_part") + if [ $? -ne 0 ]; then + print_error "Failed to increment version" + fi + + # Extract the version number from the output (last line) + VERSION=$(echo "$NEW_VERSION" | tail -n1) + print_success "Version incremented to $VERSION" +else + # Get current version from package.json + VERSION=$(grep -o '"version": "[^"]*"' "src/mpath-unity-project/Packages/MPath/package.json" | cut -d'"' -f4) + print_success "Using existing version: $VERSION" +fi + +# Step 5: Check if git tag already exists +print_step "Checking if git tag $VERSION already exists" +if git rev-parse "$VERSION" >/dev/null 2>&1; then + print_error "Tag $VERSION already exists" +fi +print_success "Tag $VERSION does not exist yet" + +# Step 6: Build the solution +print_step "Building solution" +if ! dotnet build src/mpath-source/Migs.MPath.sln -c Release; then + print_error "Build failed" +fi +print_success "Build completed successfully" + +# Step 7: Run unit tests +print_step "Running unit tests" +if ! dotnet test src/mpath-source/Migs.MPath.Tests/Migs.MPath.Tests.csproj -c Release --no-build; then + print_error "Tests failed" +fi +print_success "All tests passed" + +# Step 8: Copy NuGet package to builds directory +print_step "Copying NuGet package to builds directory" +mkdir -p builds + +# Find the NuGet package +NUGET_PACKAGE=$(find src/mpath-source/Migs.MPath.Core/bin/Release -name "Migs.MPath.*.nupkg" | sort -V | tail -n1) +if [ -z "$NUGET_PACKAGE" ]; then + print_error "NuGet package not found" +fi + +cp "$NUGET_PACKAGE" builds/ +print_success "NuGet package copied to builds directory" + +# Step 9: Create package tarball with modified paths +print_step "Creating Unity package with proper paths" +if ! ./ci/process-unity-package.sh; then + print_error "Failed to create and process Unity package" +fi +print_success "Unity package created successfully" + +# Step 10: Create a version tag locally +print_step "Creating local version tag $VERSION" +git tag "$VERSION" +print_success "Tag $VERSION created locally" +echo -e "${YELLOW}Note: Tag was only created locally. Use 'git push origin $VERSION' to push it to remote when ready.${NC}" + +echo -e "\n${GREEN}Release process completed successfully!${NC}" +echo "Release artifacts are available in the builds directory:" +ls -la builds/ +echo -e "\n${YELLOW}Note: All changes are local. You can review them before pushing to remote.${NC}" \ No newline at end of file diff --git a/ci/version-increment.sh b/ci/version-increment.sh new file mode 100755 index 0000000..b82c6b0 --- /dev/null +++ b/ci/version-increment.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +# Default to minor version increment if not specified +VERSION_PART=${1:-minor} + +# Validate arguments +if [[ ! "$VERSION_PART" =~ ^(major|minor|patch)$ ]]; then + echo "Error: Version part must be one of [major, minor, patch]" + echo "Usage: ./version-increment.sh [major|minor|patch]" + exit 1 +fi + +# File paths +CSPROJ_PATH="src/mpath-source/Migs.MPath.Core/Migs.MPath.Core.csproj" +PACKAGE_JSON_PATH="src/mpath-unity-project/Packages/MPath/package.json" + +# Check if files exist +if [ ! -f "$CSPROJ_PATH" ]; then + echo "Error: $CSPROJ_PATH not found" + exit 1 +fi + +if [ ! -f "$PACKAGE_JSON_PATH" ]; then + echo "Error: $PACKAGE_JSON_PATH not found" + exit 1 +fi + +# Extract current version from package.json +CURRENT_VERSION=$(grep -o '"version": "[^"]*"' "$PACKAGE_JSON_PATH" | cut -d'"' -f4) + +if [ -z "$CURRENT_VERSION" ]; then + echo "Error: Could not extract version from $PACKAGE_JSON_PATH" + exit 1 +fi + +# Split version into components +IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION" + +# Increment the appropriate part +case $VERSION_PART in + major) + MAJOR=$((MAJOR+1)) + MINOR=0 + PATCH=0 + ;; + minor) + MINOR=$((MINOR+1)) + PATCH=0 + ;; + patch) + PATCH=$((PATCH+1)) + ;; +esac + +# Create new version string +NEW_VERSION="$MAJOR.$MINOR.$PATCH" + +echo "Incrementing $VERSION_PART version: $CURRENT_VERSION -> $NEW_VERSION" + +# Update package.json +sed -i "" "s/\"version\": \"$CURRENT_VERSION\"/\"version\": \"$NEW_VERSION\"/" "$PACKAGE_JSON_PATH" + +# Update version in .csproj file (handles both Version and AssemblyVersion) +sed -i "" "s/$CURRENT_VERSION<\/Version>/$NEW_VERSION<\/Version>/" "$CSPROJ_PATH" +sed -i "" "s/$CURRENT_VERSION<\/AssemblyVersion>/$NEW_VERSION<\/AssemblyVersion>/" "$CSPROJ_PATH" + +echo "Version updated to $NEW_VERSION in both files" +echo "$NEW_VERSION" \ No newline at end of file diff --git a/src/mpath-source/Migs.MPath.Tools/Migs.MPath.Tools.csproj b/src/mpath-source/Migs.MPath.Tools/Migs.MPath.Tools.csproj index 3ea86b5..e6fb8e3 100644 --- a/src/mpath-source/Migs.MPath.Tools/Migs.MPath.Tools.csproj +++ b/src/mpath-source/Migs.MPath.Tools/Migs.MPath.Tools.csproj @@ -12,7 +12,8 @@ - + + diff --git a/src/mpath-unity-project/Packages/MPath/package.json.bak.meta b/src/mpath-unity-project/Assets/Editor.meta similarity index 67% rename from src/mpath-unity-project/Packages/MPath/package.json.bak.meta rename to src/mpath-unity-project/Assets/Editor.meta index f95ad14..d2c6d4a 100644 --- a/src/mpath-unity-project/Packages/MPath/package.json.bak.meta +++ b/src/mpath-unity-project/Assets/Editor.meta @@ -1,5 +1,6 @@ fileFormatVersion: 2 -guid: 3cb076e36262848dda4cff218692b3bb +guid: 9c228730e04894687b99e538209ad38e +folderAsset: yes DefaultImporter: externalObjects: {} userData: diff --git a/src/mpath-unity-project/Assets/Editor/PackageExporter.cs b/src/mpath-unity-project/Assets/Editor/PackageExporter.cs new file mode 100644 index 0000000..efcb70f --- /dev/null +++ b/src/mpath-unity-project/Assets/Editor/PackageExporter.cs @@ -0,0 +1,185 @@ +using UnityEngine; +using UnityEditor; +using System.IO; +using System; + +namespace Migs.MPath.Editor +{ + [Serializable] + public class PackageInfo + { + public string version; + } + + public static class PackageExporter + { + private const string PackagesPath = "Packages"; + private const string AssetsPath = "Assets"; + private const string MPathFolder = "MPath"; + private const string PackageNameFormat = "migs-mpath-{0}.unitypackage"; + + [MenuItem("MPath/Export Package")] + public static void ExportPackage() + { + ExportPackageInternal(); + } + + // Public method for CI/batch mode execution + public static void ExportPackageFromBatchMode() + { + try + { + Debug.Log("Starting ExportPackageFromBatchMode"); + ExportPackageInternal(); + Debug.Log("ExportPackageFromBatchMode completed successfully"); + } + catch (Exception ex) + { + Debug.LogError($"Error in ExportPackageFromBatchMode: {ex.Message}"); + Debug.LogError($"Stack trace: {ex.StackTrace}"); + EditorApplication.Exit(1); + return; + } + + EditorApplication.Exit(0); + } + + private static void ExportPackageInternal() + { + var sourcePath = Path.Combine(PackagesPath, MPathFolder); + var targetPath = Path.Combine(AssetsPath, MPathFolder); + + Debug.Log($"Package source path: {sourcePath}, exists: {Directory.Exists(sourcePath)}"); + + string packageJsonPath = Path.Combine(PackagesPath, MPathFolder, "package.json"); + try + { + // Get version from package.json before moving folders + Debug.Log($"Reading package.json from: {packageJsonPath}, exists: {File.Exists(packageJsonPath)}"); + + var json = File.ReadAllText(packageJsonPath); + Debug.Log($"Package.json content: {json}"); + + // Parse version using JsonUtility + var packageInfo = JsonUtility.FromJson(json); + if (packageInfo == null) + { + Debug.LogError("Failed to parse package.json"); + return; + } + + var version = packageInfo.version; + Debug.Log($"Parsed version: {version}"); + + // Ensure builds directory exists + var buildsDirectory = Path.Combine(Application.dataPath, "../../../builds"); + + Debug.Log($"Full builds directory path: {buildsDirectory}"); + + if (!Directory.Exists(buildsDirectory)) + { + Debug.Log($"Creating builds directory: {buildsDirectory}"); + Directory.CreateDirectory(buildsDirectory); + } + + // Move MPath from Packages to Assets + Debug.Log("Moving MPath from Packages to Assets..."); + + // Make sure Assets/MPath doesn't already exist + if (Directory.Exists(targetPath)) + { + Directory.Delete(targetPath, true); + } + + // List files in source directory + Debug.Log("Files in source directory:"); + foreach (var file in Directory.GetFiles(sourcePath)) + { + Debug.Log($" - {Path.GetFileName(file)}"); + } + + // Move the directory + try + { + Debug.Log($"Moving from {sourcePath} to {targetPath}"); + Directory.Move(sourcePath, targetPath); + AssetDatabase.Refresh(); + Debug.Log("Move completed successfully"); + } + catch (Exception ex) + { + Debug.LogError($"Failed to move directory: {ex.Message}"); + Debug.LogError($"Exception details: {ex.GetType().Name}"); + return; + } + + // Create the output path + var outputPath = Path.Combine(buildsDirectory, string.Format(PackageNameFormat, version)); + Debug.Log($"Output path: {outputPath}"); + + try + { + // Export the package - now from Assets/MPath + string exportPath = Path.Combine(AssetsPath, MPathFolder); + Debug.Log($"Exporting from: {exportPath}"); + + AssetDatabase.ExportPackage( + exportPath, + outputPath, + ExportPackageOptions.Recurse + ); + + Debug.Log($"Package exported to: {outputPath}"); + } + catch (Exception ex) + { + Debug.LogError($"Failed to export package: {ex.Message}"); + Debug.LogError($"Stack trace: {ex.StackTrace}"); + } + finally + { + // Move MPath back to Packages folder + Debug.Log("Moving MPath back to Packages..."); + try + { + Debug.Log($"Moving from {targetPath} back to {sourcePath}"); + Directory.Move(targetPath, sourcePath); + AssetDatabase.Refresh(); + Debug.Log("Move back completed successfully"); + } + catch (Exception ex) + { + Debug.LogError($"Failed to move directory back: {ex.Message}. Manual intervention required!"); + Debug.LogError($"Exception details: {ex.GetType().Name}"); + Debug.LogError($"Stack trace: {ex.StackTrace}"); + } + + // Ensure Assets/MPath is deleted in case it still exists + try + { + if (Directory.Exists(targetPath)) + { + Debug.Log($"Target directory still exists after move back. Deleting: {targetPath}"); + Directory.Delete(targetPath, true); + File.Delete($"{targetPath}.meta"); + AssetDatabase.Refresh(); + Debug.Log("Successfully deleted target directory"); + } + } + catch (Exception ex) + { + Debug.LogError($"Failed to delete target directory: {ex.Message}"); + Debug.LogError($"Exception details: {ex.GetType().Name}"); + Debug.LogError($"Stack trace: {ex.StackTrace}"); + } + } + } + catch (Exception ex) + { + Debug.LogError($"Global error in ExportPackageInternal: {ex.Message}"); + Debug.LogError($"Exception type: {ex.GetType().Name}"); + Debug.LogError($"Stack trace: {ex.StackTrace}"); + } + } + } +} \ No newline at end of file diff --git a/src/mpath-unity-project/Assets/Editor/PackageExporter.cs.meta b/src/mpath-unity-project/Assets/Editor/PackageExporter.cs.meta new file mode 100644 index 0000000..c76495a --- /dev/null +++ b/src/mpath-unity-project/Assets/Editor/PackageExporter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a9d51bba3ce324c168523c75c7b3e31e \ No newline at end of file diff --git a/src/mpath-unity-project/Packages/MPath/package.json.bak b/src/mpath-unity-project/Packages/MPath/package.json.bak deleted file mode 100644 index 3ce5873..0000000 --- a/src/mpath-unity-project/Packages/MPath/package.json.bak +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "com.migsweb.pathfinding", - "displayName": "Migs.MPath", - "description": "Unsafe implementation of A* Pathfinding", - "version": "0.9.0", - "unity": "2019.2", - "documentationUrl": "" -}