Untitled

 avatar
unknown
plain_text
10 months ago
23 kB
15
Indexable
# PackageUEPlugin.ps1 (PowerShell 5.1) - Fixed plugin resolution + fresh prompts each run
# Key fixes:
# 1) Alternative approach: Use -PluginPath with dependency resolution
# 2) No persistent configuration - prompt fresh each time
# 3) Better plugin search paths and validation
# 4) Multiple fallback strategies for plugin building

[CmdletBinding()] param()
$ErrorActionPreference = "Stop"
Add-Type -AssemblyName System.Windows.Forms -ErrorAction SilentlyContinue | Out-Null

function Pick-File($title,$filter="All (*.*)|*.*"){
  Write-Host "Attempting to open file dialog: $title" -ForegroundColor Gray
  try {
    $dlg=New-Object System.Windows.Forms.OpenFileDialog
    $dlg.Title=$title
    $dlg.Filter=$filter
    $dlg.Multiselect=$false
    $dlg.CheckFileExists=$true
    $dlg.CheckPathExists=$true
    
    Write-Host "Showing file dialog..." -ForegroundColor Gray
    $result = $dlg.ShowDialog()
    Write-Host "File dialog result: $result" -ForegroundColor Gray
    
    if($result -eq [System.Windows.Forms.DialogResult]::OK){ 
      Write-Host "Selected file: $($dlg.FileName)" -ForegroundColor Green
      return $dlg.FileName 
    } else { 
      Write-Host "File dialog cancelled or closed" -ForegroundColor Yellow
      return $null 
    }
  } catch {
    Write-Host "Error with file dialog: $($_.Exception.Message)" -ForegroundColor Red
    Write-Host "Falling back to text input..." -ForegroundColor Yellow
    $path = Read-Host "Please enter the full path to your .uplugin file"
    if(Test-Path $path) {
      return $path
    } else {
      Write-Host "Path does not exist: $path" -ForegroundColor Red
      return $null
    }
  }
}

function Pick-Folder($desc){
  Write-Host "Attempting to open folder dialog: $desc" -ForegroundColor Gray
  try {
    $dlg=New-Object System.Windows.Forms.FolderBrowserDialog
    $dlg.Description=$desc
    $dlg.ShowNewFolderButton=$true
    
    Write-Host "Showing folder dialog..." -ForegroundColor Gray
    $result = $dlg.ShowDialog()
    Write-Host "Folder dialog result: $result" -ForegroundColor Gray
    
    if($result -eq [System.Windows.Forms.DialogResult]::OK){ 
      Write-Host "Selected folder: $($dlg.SelectedPath)" -ForegroundColor Green
      return $dlg.SelectedPath 
    } else { 
      Write-Host "Folder dialog cancelled or closed" -ForegroundColor Yellow
      return $null 
    }
  } catch {
    Write-Host "Error with folder dialog: $($_.Exception.Message)" -ForegroundColor Red
    Write-Host "Falling back to text input..." -ForegroundColor Yellow
    $path = Read-Host "Please enter the full path to the folder"
    if(Test-Path $path) {
      return $path
    } else {
      Write-Host "Path does not exist: $path" -ForegroundColor Red
      return $null
    }
  }
}

function Ask($prompt,$def=""){
  if([string]::IsNullOrWhiteSpace($def)){
    $v = Read-Host $prompt
  } else {
    $v = Read-Host "$prompt [$def]"
    if([string]::IsNullOrWhiteSpace($v)){ $v = $def }
  }
  return $v
}

function Ask-YesNo($prompt, $default=$true){
  $suffix = if($default) { "(Y/n)" } else { "(y/N)" }
  $v = Read-Host "$prompt $suffix"
  if([string]::IsNullOrWhiteSpace($v)){ return $default }
  return ($v -match '^(?i)y|yes$')
}

function Ensure-Dir($p){ 
  if(-not(Test-Path -LiteralPath $p)){ 
    New-Item -ItemType Directory -Force -Path $p | Out-Null 
  } 
}

function Read-Json($p){ 
  (Get-Content -Raw -LiteralPath $p) | ConvertFrom-Json 
}

function Write-Json($obj,$p){ 
  ($obj|ConvertTo-Json -Depth 20) | Out-File -LiteralPath $p -Encoding UTF8 
}

function Parse-Platforms($s){
  if([string]::IsNullOrWhiteSpace($s)){ return @('Win64') }
  return ($s -split '[,\s]+' | Where-Object { $_.Trim() } | ForEach-Object { $_.Trim() })
}

function Find-UE-Installations {
  $candidates = @()
  
  # Common Epic Games locations
  $epicPaths = @(
    "$env:ProgramFiles\Epic Games",
    "${env:ProgramFiles(x86)}\Epic Games",
    "$env:ProgramW6432\Epic Games"
  )
  
  foreach($path in $epicPaths) {
    if(Test-Path $path) {
      $ueVersions = Get-ChildItem -Path $path -Directory | Where-Object { $_.Name -match '^UE_\d+\.\d+' }
      foreach($ue in $ueVersions) {
        $runUAT = Join-Path $ue.FullName "Engine\Build\BatchFiles\RunUAT.bat"
        if(Test-Path $runUAT) {
          $candidates += @{
            Path = $ue.FullName
            Version = ($ue.Name -replace '^UE_', '')
            Display = "$($ue.Name) - $($ue.FullName)"
          }
        }
      }
    }
  }
  
  return $candidates | Sort-Object Version -Descending
}

function Prompt-UE-Selection {
  Write-Host ""
  Write-Host "=== Unreal Engine Selection ===" -ForegroundColor Cyan
  
  $installations = Find-UE-Installations
  
  if($installations.Count -gt 0) {
    Write-Host "Found UE installations:" -ForegroundColor Yellow
    for($i = 0; $i -lt $installations.Count; $i++) {
      Write-Host "  [$($i+1)] $($installations[$i].Display)" -ForegroundColor Green
    }
    Write-Host "  [0] Browse for different location" -ForegroundColor Gray
    
    do {
      $choice = Read-Host "Select UE installation (1-$($installations.Count) or 0 to browse)"
      $choiceNum = $choice -as [int]
    } while($choiceNum -lt 0 -or $choiceNum -gt $installations.Count)
    
    if($choiceNum -eq 0) {
      return Pick-Folder "Select UE root directory (e.g. C:\Program Files\Epic Games\UE_5.5)"
    } else {
      return $installations[$choiceNum - 1].Path
    }
  } else {
    Write-Host "No UE installations found automatically." -ForegroundColor Yellow
    return Pick-Folder "Select UE root directory (e.g. C:\Program Files\Epic Games\UE_5.5)"
  }
}

function Find-Plugins-In-Directory($dir, $recursive = $true) {
  if(-not (Test-Path $dir)) { return @() }
  
  $plugins = @()
  
  if($recursive) {
    $upluginFiles = Get-ChildItem -Path $dir -Filter "*.uplugin" -Recurse -ErrorAction SilentlyContinue
  } else {
    $upluginFiles = Get-ChildItem -Path $dir -Filter "*.uplugin" -ErrorAction SilentlyContinue
  }
  
  $upluginFiles | ForEach-Object {
    try {
      $json = Read-Json $_.FullName
      $plugins += @{
        Path = $_.FullName
        Name = [IO.Path]::GetFileNameWithoutExtension($_.Name)
        FriendlyName = if($json.FriendlyName) { $json.FriendlyName } else { [IO.Path]::GetFileNameWithoutExtension($_.Name) }
        Directory = $_.Directory.FullName
        Version = if($json.VersionName) { $json.VersionName } elseif($json.Version) { $json.Version.ToString() } else { "1.0.0" }
      }
    } catch {
      Write-Warning "Could not parse plugin: $($_.FullName)"
    }
  }
  
  return $plugins
}

function Prompt-Plugin-Selection {
  Write-Host ""
  Write-Host "=== Main Plugin Selection ===" -ForegroundColor Cyan
  Write-Host "Select the .uplugin file you want to package..." -ForegroundColor Yellow
  
  $selected = Pick-File "Select the main .uplugin file to package" "Unreal Plugin (*.uplugin)|*.uplugin|All (*.*)|*.*"
  if(-not $selected) {
    Write-Host "No plugin selected." -ForegroundColor Red
    return $null
  }
  
  return $selected
}

function Find-Dependencies-OneLevel-Up($mainPluginPath, $depNames) {
  Write-Host ""
  Write-Host "Looking for dependencies one level up from main plugin..." -ForegroundColor Yellow
  
  # Get the parent directory of the main plugin
  $mainPluginDir = Split-Path -Parent $mainPluginPath
  $oneLevelUp = Split-Path -Parent $mainPluginDir
  
  Write-Host "Main plugin directory: $mainPluginDir" -ForegroundColor Gray
  Write-Host "Searching for dependencies in: $oneLevelUp" -ForegroundColor Gray
  
  $foundDeps = @()
  
  foreach($depName in $depNames) {
    Write-Host "  Looking for: $depName" -ForegroundColor Cyan
    
    # Look for DepName/DepName.uplugin in the parent directory
    $depDir = Join-Path $oneLevelUp $depName
    $depUplugin = Join-Path $depDir ($depName + ".uplugin")
    
    if(Test-Path $depUplugin) {
      Write-Host "    Found: $depUplugin" -ForegroundColor Green
      $foundDeps += $depUplugin
    } else {
      Write-Host "    Not found at: $depUplugin" -ForegroundColor Red
      
      # Also check if there's a subdirectory with the dependency
      $subDirs = Get-ChildItem -Path $oneLevelUp -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -eq $depName }
      if($subDirs) {
        $subDepUplugin = Join-Path $subDirs[0].FullName ($depName + ".uplugin")
        if(Test-Path $subDepUplugin) {
          Write-Host "    Found in subdirectory: $subDepUplugin" -ForegroundColor Green
          $foundDeps += $subDepUplugin
        }
      }
    }
  }
  
  return $foundDeps
}

function Copy-PluginFolder($pluginUPluginPath, $destPluginsRoot){
  $srcPluginDir = Split-Path -Parent $pluginUPluginPath
  $name = [IO.Path]::GetFileNameWithoutExtension($pluginUPluginPath)
  $destDir = Join-Path $destPluginsRoot $name
  
  if(Test-Path $destDir){ Remove-Item -Recurse -Force -LiteralPath $destDir }
  Write-Host "  Copying $name -> $destDir" -ForegroundColor Green
  
  # Use robocopy for reliable copying
  $robocopyResult = & robocopy "$srcPluginDir" "$destDir" /E /NFL /NDL /NJH /NJS /NP 2>$null
  if($LASTEXITCODE -ge 8){ 
    # Fallback to PowerShell copy
    Copy-Item -Path $srcPluginDir -Destination $destDir -Recurse -Force
  }
  
  return $destDir
}

function Try-BuildPlugin-Method1($runUAT, $pluginPath, $packageDir, $platforms) {
  Write-Host ""
  Write-Host "==> Trying Method 1: Direct BuildPlugin (no HostProject)" -ForegroundColor Yellow
  
  $platArg = ($platforms -join '+')
  $uatArgs = @(
    'BuildPlugin',
    ('-Plugin="{0}"' -f $pluginPath),
    ('-Package="{0}"' -f $packageDir),
    ('-TargetPlatforms={0}' -f $platArg),
    '-Rocket', '-NoP4'
  )
  
  Write-Host "UAT Command: $($uatArgs -join ' ')" -ForegroundColor Gray
  
  try {
    & $runUAT @uatArgs
    return $LASTEXITCODE -eq 0
  } catch {
    Write-Host "Method 1 failed with exception: $($_.Exception.Message)" -ForegroundColor Red
    return $false
  }
}

function Try-BuildPlugin-Method2($runUAT, $pluginPath, $packageDir, $platforms, $workDir) {
  Write-Host ""
  Write-Host "==> Trying Method 2: BuildPlugin with minimal HostProject" -ForegroundColor Yellow
  
  # Create minimal host project
  $hostProjDir = Join-Path $workDir "HostProject"
  $hostProjFile = Join-Path $hostProjDir "HostProject.uproject"
  Ensure-Dir $hostProjDir
  
  # Get engine version from plugin or use default
  try {
    $pluginJson = Read-Json $pluginPath
    $engineVer = if($pluginJson.EngineVersion) { $pluginJson.EngineVersion } else { "5.5" }
  } catch {
    $engineVer = "5.5"
  }
  
  # Create simple .uproject
  @"
{
  "FileVersion": 3,
  "EngineAssociation": "$engineVer",
  "Category": "",
  "Description": "Minimal host project for BuildPlugin"
}
"@ | Out-File -LiteralPath $hostProjFile -Encoding UTF8
  
  $platArg = ($platforms -join '+')
  $uatArgs = @(
    'BuildPlugin',
    ('-Plugin="{0}"' -f $pluginPath),
    ('-Package="{0}"' -f $packageDir),
    ('-TargetPlatforms={0}' -f $platArg),
    ('-HostProject="{0}"' -f $hostProjFile),
    '-Rocket', '-NoP4'
  )
  
  Write-Host "UAT Command: $($uatArgs -join ' ')" -ForegroundColor Gray
  
  try {
    & $runUAT @uatArgs
    return $LASTEXITCODE -eq 0
  } catch {
    Write-Host "Method 2 failed with exception: $($_.Exception.Message)" -ForegroundColor Red
    return $false
  }
}

function Try-BuildPlugin-Method3($runUAT, $pluginPath, $depPluginPaths, $packageDir, $platforms, $workDir) {
  Write-Host ""
  Write-Host "==> Trying Method 3: BuildPlugin with dependency copying to HostProject" -ForegroundColor Yellow
  
  # Create host project with copied dependencies
  $hostProjDir = Join-Path $workDir "HostProjectWithDeps"
  $hostProjFile = Join-Path $hostProjDir "HostProject.uproject"
  $hostPluginsDir = Join-Path $hostProjDir "Plugins"
  
  if(Test-Path $hostProjDir) { Remove-Item -Recurse -Force $hostProjDir }
  Ensure-Dir $hostPluginsDir
  
  # Copy all dependencies to host project
  $copiedPaths = @()
  foreach($depPath in $depPluginPaths) {
    $copied = Copy-PluginFolder -pluginUPluginPath $depPath -destPluginsRoot $hostPluginsDir
    $copiedPaths += $copied
  }
  
  # Also copy main plugin
  $mainCopied = Copy-PluginFolder -pluginUPluginPath $pluginPath -destPluginsRoot $hostPluginsDir
  $mainPluginName = [IO.Path]::GetFileNameWithoutExtension($pluginPath)
  $copiedMainPlugin = Join-Path $hostPluginsDir "$mainPluginName\$mainPluginName.uplugin"
  
  # Create enhanced .uproject
  try {
    $pluginJson = Read-Json $pluginPath
    $engineVer = if($pluginJson.EngineVersion) { $pluginJson.EngineVersion } else { "5.5" }
  } catch {
    $engineVer = "5.5"
  }
  
  # Build plugin references
  $pluginRefs = @()
  foreach($depPath in $depPluginPaths) {
    $depName = [IO.Path]::GetFileNameWithoutExtension($depPath)
    $pluginRefs += @{ "Name" = $depName; "Enabled" = $true }
  }
  $pluginRefs += @{ "Name" = $mainPluginName; "Enabled" = $true }
  
  $uprojectContent = @{
    "FileVersion" = 3
    "EngineAssociation" = $engineVer
    "Category" = ""
    "Description" = "Host project with dependencies for BuildPlugin"
    "Plugins" = $pluginRefs
  }
  
  Write-Json $uprojectContent $hostProjFile
  
  $platArg = ($platforms -join '+')
  $uatArgs = @(
    'BuildPlugin',
    ('-Plugin="{0}"' -f $copiedMainPlugin),
    ('-Package="{0}"' -f $packageDir),
    ('-TargetPlatforms={0}' -f $platArg),
    ('-HostProject="{0}"' -f $hostProjFile),
    '-Rocket', '-NoP4'
  )
  
  Write-Host "UAT Command: $($uatArgs -join ' ')" -ForegroundColor Gray
  
  try {
    & $runUAT @uatArgs
    return $LASTEXITCODE -eq 0
  } catch {
    Write-Host "Method 3 failed with exception: $($_.Exception.Message)" -ForegroundColor Red
    return $false
  }
}

function Get-PackagedPluginPath($packageDir, $pluginBase){
  # Look for the packaged plugin directory
  $expectedDir = Join-Path $packageDir $pluginBase
  $expectedUplugin = Join-Path $expectedDir ($pluginBase + ".uplugin")
  if(Test-Path $expectedUplugin){ return $expectedDir }
  
  # Search recursively
  $found = Get-ChildItem -Path $packageDir -Filter ($pluginBase + ".uplugin") -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1
  if($found){ return $found.Directory.FullName }
  
  return $null
}

# ==== MAIN EXECUTION ====

Write-Host "=== UE Plugin Builder with Dependency Resolution ===" -ForegroundColor Cyan

# 1. Select UE Installation
$ueRoot = Prompt-UE-Selection
if(-not $ueRoot) { throw "No UE installation selected" }

$runUAT = Join-Path $ueRoot "Engine\Build\BatchFiles\RunUAT.bat"
if(-not (Test-Path $runUAT)) { throw "RunUAT not found at: $runUAT" }

Write-Host ""
Write-Host "Selected UE: $ueRoot" -ForegroundColor Green

# 2. Select Main Plugin
$mainPluginPath = Prompt-Plugin-Selection
if(-not $mainPluginPath) { throw "No plugin selected" }

Write-Host ""
Write-Host "Selected Plugin: $mainPluginPath" -ForegroundColor Green

# 3. Get plugin info
try {
  $pluginJson = Read-Json $mainPluginPath
  $pluginBase = [IO.Path]::GetFileNameWithoutExtension($mainPluginPath)
  $pluginName = if($pluginJson.FriendlyName) { $pluginJson.FriendlyName } else { $pluginBase }
  $pluginVer = if($pluginJson.VersionName) { $pluginJson.VersionName } elseif($pluginJson.Version) { $pluginJson.Version.ToString() } else { "1.0.0" }
} catch {
  throw "Could not read plugin file: $mainPluginPath"
}

# 4. Get build settings
Write-Host ""
Write-Host "=== Build Configuration ===" -ForegroundColor Cyan
$engineVer = Ask "Engine version" "5.5"
$platformsStr = Ask "Target platforms (comma-separated)" "Win64"
$platforms = Parse-Platforms $platformsStr

# 5. Select output directory
Write-Host ""
$artifactsDir = Pick-Folder "Select output directory for build artifacts"
if(-not $artifactsDir) { throw "No output directory selected" }

Write-Host ""
Write-Host "=== Plugin Information ===" -ForegroundColor Cyan
Write-Host "  Name: $pluginName" -ForegroundColor Green
Write-Host "  Base Name: $pluginBase" -ForegroundColor Green
Write-Host "  Version: $pluginVer" -ForegroundColor Green
Write-Host "  Engine: $engineVer" -ForegroundColor Green
Write-Host "  Platforms: $($platforms -join ', ')" -ForegroundColor Green
Write-Host "  Output: $artifactsDir" -ForegroundColor Green

# 6. Check for dependencies
$depNames = @()
if($pluginJson.Plugins) {
  foreach($dep in $pluginJson.Plugins) {
    if($dep.Name) { $depNames += $dep.Name }
  }
}
$depNames = $depNames | Select-Object -Unique

$depPluginPaths = @()
if($depNames.Count -gt 0) {
  Write-Host ""
  Write-Host "=== Dependency Resolution ===" -ForegroundColor Cyan
  Write-Host "Dependencies required: $($depNames -join ', ')" -ForegroundColor Yellow
  
  # Look for dependencies one level up from the main plugin
  $foundDeps = Find-Dependencies-OneLevel-Up -mainPluginPath $mainPluginPath -depNames $depNames
  
  foreach($depName in $depNames) {
    $found = $foundDeps | Where-Object { [IO.Path]::GetFileNameWithoutExtension($_) -eq $depName }
    
    if($found) {
      Write-Host ""
      Write-Host "Found dependency: $depName at $found" -ForegroundColor Green
      $useFound = Ask-YesNo "Use this dependency?" $true
      if($useFound) {
        $depPluginPaths += $found
        Write-Host "  Added: $found" -ForegroundColor Green
      } else {
        $manual = Pick-File "Locate $depName.uplugin manually" "Unreal Plugin (*.uplugin)|*.uplugin"
        if($manual) {
          $depPluginPaths += $manual
          Write-Host "  Added: $manual" -ForegroundColor Green
        } else {
          Write-Warning "Dependency $depName not provided - build may fail"
        }
      }
    } else {
      Write-Host ""
      Write-Host "Could not find dependency: $depName" -ForegroundColor Red
      $manual = Pick-File "Locate $depName.uplugin manually" "Unreal Plugin (*.uplugin)|*.uplugin"
      if($manual) {
        $depPluginPaths += $manual
        Write-Host "  Added: $manual" -ForegroundColor Green
      } else {
        Write-Warning "Dependency $depName not provided - build may fail"
      }
    }
  }
} else {
  Write-Host ""
  Write-Host "No dependencies declared in plugin." -ForegroundColor Green
}

# 7. Create work directory and package directory
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$buildStamp = "${pluginBase}_${pluginVer}_UE${engineVer}_$($platforms -join '+')_${timestamp}"
$workDir = Join-Path $artifactsDir "_Work_$buildStamp"
$packageDir = Join-Path $artifactsDir "Package_$buildStamp"

if(Test-Path $workDir) { Remove-Item -Recurse -Force $workDir }
if(Test-Path $packageDir) { Remove-Item -Recurse -Force $packageDir }
Ensure-Dir $workDir
Ensure-Dir $packageDir

Write-Host ""
Write-Host "=== Starting Build Process ===" -ForegroundColor Cyan
Write-Host "Work directory: $workDir" -ForegroundColor Gray
Write-Host "Package directory: $packageDir" -ForegroundColor Gray

# 8. Try multiple build methods
$buildSuccess = $false
$buildMethod = ""

try {
  # Method 1: Direct build (works for plugins without dependencies)
  if(-not $buildSuccess -and $depPluginPaths.Count -eq 0) {
    if(Try-BuildPlugin-Method1 -runUAT $runUAT -pluginPath $mainPluginPath -packageDir $packageDir -platforms $platforms) {
      $buildSuccess = $true
      $buildMethod = "Direct BuildPlugin (no dependencies)"
    }
  }
  
  # Method 2: Minimal host project
  if(-not $buildSuccess) {
    if(Try-BuildPlugin-Method2 -runUAT $runUAT -pluginPath $mainPluginPath -packageDir $packageDir -platforms $platforms -workDir $workDir) {
      $buildSuccess = $true
      $buildMethod = "BuildPlugin with minimal HostProject"
    }
  }
  
  # Method 3: Host project with dependencies
  if(-not $buildSuccess -and $depPluginPaths.Count -gt 0) {
    if(Try-BuildPlugin-Method3 -runUAT $runUAT -pluginPath $mainPluginPath -depPluginPaths $depPluginPaths -packageDir $packageDir -platforms $platforms -workDir $workDir) {
      $buildSuccess = $true
      $buildMethod = "BuildPlugin with HostProject and dependencies"
    }
  }
  
} finally {
  # Cleanup work directory
  if(Test-Path $workDir) {
    try { Remove-Item -Recurse -Force $workDir } catch { Write-Warning "Could not clean up work directory" }
  }
}

if(-not $buildSuccess) {
  Write-Host ""
  Write-Host "=== BUILD FAILED ===" -ForegroundColor Red
  Write-Host "All build methods failed. Check the UAT logs above for details." -ForegroundColor Red
  throw "Plugin build failed with all attempted methods"
}

Write-Host ""
Write-Host "=== BUILD SUCCESSFUL ===" -ForegroundColor Green
Write-Host "Method used: $buildMethod" -ForegroundColor Yellow

# 9. Package the result
$packagedDir = Get-PackagedPluginPath -packageDir $packageDir -pluginBase $pluginBase
if(-not $packagedDir) {
  throw "Could not locate packaged plugin in: $packageDir"
}

$zipPath = Join-Path $artifactsDir "${buildStamp}.zip"
if(Test-Path $zipPath) { Remove-Item $zipPath -Force }

Write-Host ""
Write-Host "Creating ZIP package..." -ForegroundColor Yellow
Write-Host "  Source: $packagedDir" -ForegroundColor Gray
Write-Host "  ZIP: $zipPath" -ForegroundColor Gray

Compress-Archive -Path $packagedDir -DestinationPath $zipPath -Force

$hash = (Get-FileHash -Algorithm SHA256 -LiteralPath $zipPath).Hash.ToLower()
Write-Host "  SHA256: $hash" -ForegroundColor Gray

# 10. Create manifest
$zipFileName = [IO.Path]::GetFileName($zipPath)

# Create artifacts hashtable with string keys
$artifactsHash = @{}
$artifactsHash[$platforms[0].ToString()] = $zipFileName

# Create sha256 hashtable with string keys  
$sha256Hash = @{}
$sha256Hash[$platforms[0].ToString()] = $hash

# Create dependencies array
$depsArray = @()
if($depNames.Count -gt 0) {
  $depsArray = $depNames | ForEach-Object { 
    @{ 
      name = [string]$_
      range = $null 
    } 
  }
}

# Create manifest with proper string keys
$manifest = [ordered]@{
  name = [string]$pluginName
  id = [string]$pluginBase
  version = [string]$pluginVer
  engine = [string]$engineVer
  platforms = @([string]$platforms[0])
  artifacts = $artifactsHash
  url = [string]$zipFileName
  sha256 = $sha256Hash
  buildMethod = [string]$buildMethod
  timestamp = (Get-Date).ToString("o")
}

if($depsArray.Count -gt 0) {
  $manifest.dependencies = $depsArray
}

$manifestPath = Join-Path $artifactsDir "${buildStamp}.manifest.json"
Write-Json $manifest $manifestPath

Write-Host ""
Write-Host "=== PACKAGING COMPLETE ===" -ForegroundColor Green
Write-Host "Build Method: $buildMethod" -ForegroundColor Cyan
Write-Host "Package ZIP : $zipPath" -ForegroundColor Cyan  
Write-Host "SHA256      : $hash" -ForegroundColor Cyan
Write-Host "Manifest    : $manifestPath" -ForegroundColor Cyan
Write-Host "Package Dir : $packageDir" -ForegroundColor Cyan
Write-Host ""
Write-Host "Plugin successfully built and packaged!" -ForegroundColor Green
Editor is loading...
Leave a Comment