You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 lines
7.8 KiB
PowerShell

param(
[string]$RunRoot = "",
[string]$LibPackRoot = "",
[string]$OcctRoot = "",
[string]$RuntimeRoot = "",
[switch]$SkipRuntimeJson
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
function Resolve-NormalizedPath {
param(
[Parameter(Mandatory = $true)]
[string]$Path
)
return [System.IO.Path]::GetFullPath($Path)
}
function Resolve-ConfiguredPath {
param(
[string]$ConfiguredPath,
[string[]]$EnvironmentVariableNames
)
if (-not [string]::IsNullOrWhiteSpace($ConfiguredPath)) {
return Resolve-NormalizedPath -Path $ConfiguredPath
}
foreach ($variableName in $EnvironmentVariableNames) {
$value = [Environment]::GetEnvironmentVariable($variableName)
if (-not [string]::IsNullOrWhiteSpace($value)) {
return Resolve-NormalizedPath -Path $value
}
}
return ""
}
function Ensure-Directory {
param(
[Parameter(Mandatory = $true)]
[string]$Path
)
if (-not (Test-Path -LiteralPath $Path)) {
New-Item -ItemType Directory -Path $Path | Out-Null
}
}
function Copy-MatchingFiles {
param(
[Parameter(Mandatory = $true)]
[string]$SourceDir,
[Parameter(Mandatory = $true)]
[string[]]$Patterns,
[Parameter(Mandatory = $true)]
[string]$DestinationDir
)
if (-not (Test-Path -LiteralPath $SourceDir)) {
return
}
foreach ($pattern in $Patterns) {
Get-ChildItem -LiteralPath $SourceDir -Filter $pattern -File -ErrorAction SilentlyContinue | ForEach-Object {
Copy-Item -LiteralPath $_.FullName -Destination (Join-Path $DestinationDir $_.Name) -Force
}
}
}
function Copy-PluginDirectory {
param(
[Parameter(Mandatory = $true)]
[string]$SourceDir,
[Parameter(Mandatory = $true)]
[string]$DestinationDir
)
if (-not (Test-Path -LiteralPath $SourceDir)) {
return
}
Ensure-Directory -Path $DestinationDir
Get-ChildItem -LiteralPath $SourceDir -Force | ForEach-Object {
Copy-Item -LiteralPath $_.FullName -Destination $DestinationDir -Recurse -Force
}
}
function Resolve-RuntimeRoot {
param([string]$ConfiguredRoot)
if (-not [string]::IsNullOrWhiteSpace($ConfiguredRoot)) {
return Resolve-NormalizedPath -Path $ConfiguredRoot
}
$localAppData = [Environment]::GetEnvironmentVariable("LOCALAPPDATA")
if ([string]::IsNullOrWhiteSpace($localAppData)) {
throw "LOCALAPPDATA is not available."
}
return Resolve-NormalizedPath -Path (Join-Path $localAppData "QETDeps")
}
function Read-ExistingRuntimeJson {
param([string]$RuntimeConfigPath)
if (-not (Test-Path -LiteralPath $RuntimeConfigPath)) {
return $null
}
return Get-Content -LiteralPath $RuntimeConfigPath -Raw -Encoding UTF8 | ConvertFrom-Json
}
function Resolve-OcctRoot {
param(
[string]$ConfiguredRoot,
$ExistingRuntime
)
$resolvedConfiguredRoot = Resolve-ConfiguredPath -ConfiguredPath $ConfiguredRoot -EnvironmentVariableNames @(
"FREECAD_OCCT_ROOT",
"QET_OCCT_ROOT"
)
if (-not [string]::IsNullOrWhiteSpace($resolvedConfiguredRoot)) {
return $resolvedConfiguredRoot
}
if ($null -ne $ExistingRuntime -and $ExistingRuntime.PSObject.Properties.Name -contains "occt_root") {
$existingOcctRoot = [string]$ExistingRuntime.occt_root
if (-not [string]::IsNullOrWhiteSpace($existingOcctRoot) -and (Test-Path -LiteralPath $existingOcctRoot)) {
return Resolve-NormalizedPath -Path $existingOcctRoot
}
}
return ""
}
$resolvedRunRoot = Resolve-ConfiguredPath -ConfiguredPath $RunRoot -EnvironmentVariableNames @(
"FREECAD_RUN_ROOT",
"QET_FREECAD_RUN_ROOT"
)
if ([string]::IsNullOrWhiteSpace($resolvedRunRoot)) {
throw "RunRoot is required. Pass -RunRoot or set FREECAD_RUN_ROOT / QET_FREECAD_RUN_ROOT."
}
$resolvedLibPackRoot = Resolve-ConfiguredPath -ConfiguredPath $LibPackRoot -EnvironmentVariableNames @(
"FREECAD_LIBPACK_ROOT",
"QET_FREECAD_LIBPACK_ROOT"
)
if ([string]::IsNullOrWhiteSpace($resolvedLibPackRoot)) {
throw "LibPackRoot is required. Pass -LibPackRoot or set FREECAD_LIBPACK_ROOT / QET_FREECAD_LIBPACK_ROOT."
}
$runBinDir = Join-Path $resolvedRunRoot "bin"
if (-not (Test-Path -LiteralPath $runBinDir)) {
throw "Run directory bin folder was not found: $runBinDir"
}
if (-not (Test-Path -LiteralPath $resolvedLibPackRoot)) {
throw "LibPack root was not found: $resolvedLibPackRoot"
}
$copySpecs = @(
@{ Source = (Join-Path $resolvedLibPackRoot "bin"); Patterns = @("*.dll") },
@{ Source = (Join-Path $resolvedLibPackRoot "lib"); Patterns = @("*.dll") },
@{ Source = (Join-Path $resolvedLibPackRoot "bin"); Patterns = @("python.exe", "pythonw.exe", "py.exe", "python*.zip") },
@{ Source = (Join-Path $resolvedLibPackRoot "bin\Lib\site-packages\shiboken6"); Patterns = @("*.dll", "*.pyd") },
@{ Source = (Join-Path $resolvedLibPackRoot "bin\Lib\site-packages\PySide6"); Patterns = @("*.dll", "*.pyd") }
)
foreach ($copySpec in $copySpecs) {
Copy-MatchingFiles -SourceDir $copySpec.Source -Patterns $copySpec.Patterns -DestinationDir $runBinDir
}
$pluginRoot = Join-Path $resolvedLibPackRoot "bin\Lib\site-packages\PySide6\plugins"
$pluginDirs = @(
"platforms",
"imageformats",
"iconengines",
"platformthemes",
"styles"
)
foreach ($pluginDir in $pluginDirs) {
Copy-PluginDirectory `
-SourceDir (Join-Path $pluginRoot $pluginDir) `
-DestinationDir (Join-Path $runBinDir $pluginDir)
}
Copy-PluginDirectory `
-SourceDir (Join-Path $resolvedLibPackRoot "bin\Lib") `
-DestinationDir (Join-Path $runBinDir "Lib")
Copy-PluginDirectory `
-SourceDir (Join-Path $resolvedLibPackRoot "bin\DLLs") `
-DestinationDir (Join-Path $runBinDir "DLLs")
if (-not $SkipRuntimeJson) {
$resolvedRuntimeRoot = Resolve-RuntimeRoot -ConfiguredRoot $RuntimeRoot
Ensure-Directory -Path $resolvedRuntimeRoot
$runtimeConfigPath = Join-Path $resolvedRuntimeRoot "runtime.json"
$diagnosticLogPath = Join-Path $resolvedRuntimeRoot "bootstrap.log"
$existingRuntime = Read-ExistingRuntimeJson -RuntimeConfigPath $runtimeConfigPath
$resolvedOcctRoot = Resolve-OcctRoot -ConfiguredRoot $OcctRoot -ExistingRuntime $existingRuntime
$resolvedFreeCadPython = ""
$pythonCandidate = Join-Path $runBinDir "python.exe"
if (Test-Path -LiteralPath $pythonCandidate) {
$resolvedFreeCadPython = $pythonCandidate
}
$resolvedFreeCadCmd = ""
$cmdCandidate = Join-Path $runBinDir "FreeCADCmd.exe"
if (Test-Path -LiteralPath $cmdCandidate) {
$resolvedFreeCadCmd = $cmdCandidate
}
$qet3dPython = if (-not [string]::IsNullOrWhiteSpace($resolvedFreeCadPython)) {
$resolvedFreeCadPython
} else {
$resolvedFreeCadCmd
}
$runtimeObject = [ordered]@{
schema_version = 1
runtime_root = $resolvedRuntimeRoot
runtime_config = $runtimeConfigPath
diagnostic_log = $diagnosticLogPath
occt_root = $resolvedOcctRoot
freecad_root = $resolvedRunRoot
freecad_lib = $runBinDir
freecad_python = $resolvedFreeCadPython
freecad_cmd = $resolvedFreeCadCmd
qet_3d_python = $qet3dPython
path_prefix = @($runBinDir)
}
($runtimeObject | ConvertTo-Json -Depth 5) | Set-Content -LiteralPath $runtimeConfigPath -Encoding UTF8
}
Write-Host "FreeCAD runtime deployment completed."
Write-Host (" Run root: {0}" -f $resolvedRunRoot)
Write-Host (" LibPack root: {0}" -f $resolvedLibPackRoot)
if (-not $SkipRuntimeJson) {
Write-Host (" runtime.json: {0}" -f (Join-Path (Resolve-RuntimeRoot -ConfiguredRoot $RuntimeRoot) "runtime.json"))
}