diff --git a/Build-Plugin.ps1 b/Build-Plugin.ps1 index 9bf4b7d..5b5cb7a 100644 --- a/Build-Plugin.ps1 +++ b/Build-Plugin.ps1 @@ -1,16 +1,15 @@ # Build-Plugin.ps1 # Builds and packages the AD Compare plugin for Disco ICT import # -# Prerequisites: -# - Visual Studio or MSBuild installed -# - Disco solution built (for assembly references and ManifestGenerator) -# # Usage: -# .\Build-Plugin.ps1 -DiscoSolutionPath "C:\Path\To\Disco" +# .\Build-Plugin.ps1 -DiscoBinPath "C:\Program Files\Disco\WebApp\bin" +# +# Or if you have the Disco source solution built: +# .\Build-Plugin.ps1 -DiscoBinPath "C:\Source\Disco\Disco.Web\bin" param( [Parameter(Mandatory=$true)] - [string]$DiscoSolutionPath, + [string]$DiscoBinPath, [string]$Configuration = "Release" ) @@ -20,68 +19,77 @@ $PluginDir = $PSScriptRoot $PluginName = "Disco.Plugins.ADCompare" Write-Host "=== AD Compare Plugin Builder ===" -ForegroundColor Cyan +Write-Host "Disco bin path: $DiscoBinPath" -ForegroundColor Gray -# --- Validate Disco solution path --- -$discoServicesDir = Join-Path $DiscoSolutionPath "Disco.Services\bin\$Configuration" -$discoModelsDir = Join-Path $DiscoSolutionPath "Disco.Models\bin\$Configuration" -$discoDataDir = Join-Path $DiscoSolutionPath "Disco.Data\bin\$Configuration" -$manifestGenDir = Join-Path $DiscoSolutionPath "Disco.Services.Plugins.ManifestGenerator\bin\$Configuration" - -$requiredDlls = @( - (Join-Path $discoServicesDir "Disco.Services.dll"), - (Join-Path $discoModelsDir "Disco.Models.dll"), - (Join-Path $discoDataDir "Disco.Data.dll") -) +# --- Validate Disco bin path and required DLLs --- +if (-not (Test-Path $DiscoBinPath)) { + Write-Error "Disco bin path not found: $DiscoBinPath" + exit 1 +} +$requiredDlls = @("Disco.Services.dll", "Disco.Models.dll", "Disco.Data.dll") foreach ($dll in $requiredDlls) { - if (-not (Test-Path $dll)) { - Write-Error "Required assembly not found: $dll`nMake sure the Disco solution is built first ($Configuration configuration)." + $dllPath = Join-Path $DiscoBinPath $dll + if (-not (Test-Path $dllPath)) { + Write-Error "Required assembly not found: $dllPath`nMake sure '$DiscoBinPath' contains the Disco assemblies." exit 1 } } - -$manifestGenExe = Join-Path $manifestGenDir "Disco.Services.Plugins.ManifestGenerator.exe" -if (-not (Test-Path $manifestGenExe)) { - Write-Warning "ManifestGenerator not found at: $manifestGenExe" - Write-Warning "Will create manifest.json manually instead." - $useManifestGen = $false -} else { - $useManifestGen = $true -} +Write-Host "All required Disco assemblies found" -ForegroundColor Green # --- Find MSBuild --- $msbuild = $null + +# Try VS2022/2019 via vswhere $vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" if (Test-Path $vsWhere) { - $msbuild = & $vsWhere -latest -requires Microsoft.Component.MSBuild -find "MSBuild\**\Bin\MSBuild.exe" | Select-Object -First 1 + $msbuild = & $vsWhere -latest -requires Microsoft.Component.MSBuild -find "MSBuild\**\Bin\MSBuild.exe" 2>$null | Select-Object -First 1 } + +# Try .NET Framework MSBuild if (-not $msbuild -or -not (Test-Path $msbuild)) { - $msbuild = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" + $frameworkMSBuild = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" + if (Test-Path $frameworkMSBuild) { + $msbuild = $frameworkMSBuild + } } -if (-not (Test-Path $msbuild)) { - Write-Error "MSBuild not found. Install Visual Studio or .NET Framework SDK." + +if (-not $msbuild -or -not (Test-Path $msbuild)) { + Write-Error "MSBuild not found. Install Visual Studio Build Tools or .NET Framework 4.7.2 Developer Pack." exit 1 } Write-Host "Using MSBuild: $msbuild" -ForegroundColor Gray -# --- Update assembly references to point at actual Disco build --- +# --- Create temp csproj with resolved assembly paths --- $csproj = Join-Path $PluginDir "$PluginName.csproj" $csprojContent = Get-Content $csproj -Raw -$csprojContent = $csprojContent -replace '\.\.\\Disco\.Models\\bin\\Debug\\Disco\.Models\.dll', "$($discoModelsDir)\Disco.Models.dll" -$csprojContent = $csprojContent -replace '\.\.\\Disco\.Data\\bin\\Debug\\Disco\.Data\.dll', "$($discoDataDir)\Disco.Data.dll" -$csprojContent = $csprojContent -replace '\.\.\\Disco\.Services\\bin\\Debug\\Disco\.Services\.dll', "$($discoServicesDir)\Disco.Services.dll" -$newtonsoftPath = Get-ChildItem -Path $discoServicesDir -Filter "Newtonsoft.Json.dll" -ErrorAction SilentlyContinue | Select-Object -First 1 -if ($newtonsoftPath) { - $csprojContent = $csprojContent -replace '\.\.\\packages\\Newtonsoft\.Json[^<]+', "$($newtonsoftPath.FullName)" +# Replace all HintPaths to point at the single Disco bin directory +$csprojContent = $csprojContent -replace '[^<]*Disco\.Models\.dll', "$DiscoBinPath\Disco.Models.dll" +$csprojContent = $csprojContent -replace '[^<]*Disco\.Data\.dll', "$DiscoBinPath\Disco.Data.dll" +$csprojContent = $csprojContent -replace '[^<]*Disco\.Services\.dll', "$DiscoBinPath\Disco.Services.dll" + +# Newtonsoft.Json - use from Disco bin +$newtonsoftPath = Join-Path $DiscoBinPath "Newtonsoft.Json.dll" +if (Test-Path $newtonsoftPath) { + $csprojContent = $csprojContent -replace '[^<]*Newtonsoft\.Json\.dll', "$newtonsoftPath" +} + +# System.Web.Mvc - use from Disco bin if available +$mvcPath = Join-Path $DiscoBinPath "System.Web.Mvc.dll" +if (Test-Path $mvcPath) { + # Replace the strong-name reference with a HintPath reference + $csprojContent = $csprojContent -replace '', "$mvcPathFalse" } $tempCsproj = Join-Path $PluginDir "$PluginName.build.csproj" $csprojContent | Set-Content $tempCsproj -Encoding UTF8 +Write-Host "Assembly references resolved" -ForegroundColor Green # --- Build --- Write-Host "`nBuilding $PluginName ($Configuration)..." -ForegroundColor Yellow $buildOutput = Join-Path $PluginDir "bin\$Configuration" + & $msbuild $tempCsproj /p:Configuration=$Configuration /p:OutputPath=$buildOutput /t:Build /v:minimal if ($LASTEXITCODE -ne 0) { @@ -101,19 +109,31 @@ Write-Host "Build successful: $pluginDll" -ForegroundColor Green # --- Generate Manifest --- Write-Host "`nGenerating manifest..." -ForegroundColor Yellow +# Copy Disco assemblies to build output for ManifestGenerator resolution foreach ($dll in $requiredDlls) { - Copy-Item $dll $buildOutput -Force -ErrorAction SilentlyContinue + $src = Join-Path $DiscoBinPath $dll + Copy-Item $src $buildOutput -Force -ErrorAction SilentlyContinue } +# Copy other dependencies from Disco bin $depDlls = @("EntityFramework.dll", "System.Web.Mvc.dll", "RazorGenerator.Mvc.dll", "Newtonsoft.Json.dll") foreach ($dep in $depDlls) { - $depPath = Join-Path $discoServicesDir $dep + $depPath = Join-Path $DiscoBinPath $dep if (Test-Path $depPath) { Copy-Item $depPath $buildOutput -Force -ErrorAction SilentlyContinue } } -if ($useManifestGen) { +# Try Disco's ManifestGenerator if it exists in the bin path or nearby +$useManifestGen = $false +$manifestGenExe = Join-Path $DiscoBinPath "Disco.Services.Plugins.ManifestGenerator.exe" +if (-not (Test-Path $manifestGenExe)) { + # Check parent directory + $manifestGenExe = Join-Path (Split-Path $DiscoBinPath -Parent) "Disco.Services.Plugins.ManifestGenerator.exe" +} +if (Test-Path $manifestGenExe) { + $useManifestGen = $true + Write-Host "Found ManifestGenerator: $manifestGenExe" -ForegroundColor Gray & $manifestGenExe $pluginDll if ($LASTEXITCODE -ne 0) { Write-Warning "ManifestGenerator failed, creating manifest manually..." @@ -122,8 +142,9 @@ if ($useManifestGen) { } if (-not $useManifestGen) { + # Create manifest.json manually $version = [System.Reflection.AssemblyName]::GetAssemblyName($pluginDll).Version - $manifest = @{ + $manifest = [ordered]@{ Id = $PluginName Name = "AD Compare" Author = "Jess" @@ -142,22 +163,30 @@ if (-not $useManifestGen) { # --- Package as .discoPlugin --- Write-Host "`nPackaging .discoPlugin file..." -ForegroundColor Yellow +# Disco-provided assemblies to exclude from the package $excludePatterns = @( "Disco.Models.*", "Disco.Data.*", "Disco.Services.*", "Disco.Web.*", "Disco.BI.*", "EntityFramework.*", "System.Web.Mvc.*", "RazorGenerator.Mvc.*", "Newtonsoft.Json.*", "*.build.csproj", "*.discoPlugin" ) +if (-not $version) { + $version = [System.Reflection.AssemblyName]::GetAssemblyName($pluginDll).Version +} + $packageName = "$PluginName-$($version.ToString()).discoPlugin" $packagePath = Join-Path $PluginDir $packageName +# Remove old packages Get-ChildItem $PluginDir -Filter "*.discoPlugin" | Remove-Item -Force +# Collect files for packaging (exclude Disco-provided assemblies) $filesToPackage = Get-ChildItem $buildOutput -Recurse -File | Where-Object { $file = $_.Name -not ($excludePatterns | Where-Object { $file -like $_ }) } +# Build package in temp directory $tempPkg = Join-Path $env:TEMP "discoplugin_$([guid]::NewGuid().ToString('N'))" New-Item -ItemType Directory -Path $tempPkg -Force | Out-Null foreach ($f in $filesToPackage) { @@ -168,8 +197,14 @@ foreach ($f in $filesToPackage) { Copy-Item $f.FullName $destPath -Force } +Write-Host "Files in package:" -ForegroundColor Gray +Get-ChildItem $tempPkg -Recurse -File | ForEach-Object { + Write-Host " $($_.FullName.Substring($tempPkg.Length + 1))" -ForegroundColor Gray +} + Compress-Archive -Path "$tempPkg\*" -DestinationPath $packagePath -Force Remove-Item $tempPkg -Recurse -Force -Write-Host "`n=== Package created: $packagePath ===" -ForegroundColor Green -Write-Host "Import this file into Disco ICT via: Configuration > Plugins > Install" -ForegroundColor Cyan +$packageSize = [math]::Round((Get-Item $packagePath).Length / 1KB, 1) +Write-Host "`n=== Package created: $packagePath ($($packageSize) KB) ===" -ForegroundColor Green +Write-Host "Import into Disco ICT via: Configuration > Plugins > Install Plugin" -ForegroundColor Cyan