|
| 1 | +#!/usr/bin/env pwsh |
| 2 | +<# |
| 3 | +.SYNOPSIS |
| 4 | + 构建 PostgreSQL Toolkit 的单文件脚本与帮助文档。 |
| 5 | +
|
| 6 | +.DESCRIPTION |
| 7 | + 将 PostgreSQL Toolkit 的多文件源码按固定顺序拼装为单文件 PowerShell 脚本, |
| 8 | + 并同步输出独立 Markdown 帮助文档,便于分发与离线查看。 |
| 9 | +
|
| 10 | +.PARAMETER SourceRoot |
| 11 | + PostgreSQL Toolkit 源码目录,默认为当前 build 目录的上一级。 |
| 12 | +
|
| 13 | +.PARAMETER OutputScriptPath |
| 14 | + 单文件脚本输出路径。 |
| 15 | +
|
| 16 | +.PARAMETER OutputHelpPath |
| 17 | + 独立帮助文档输出路径。 |
| 18 | +#> |
| 19 | +[CmdletBinding()] |
| 20 | +param( |
| 21 | + [string]$SourceRoot = (Join-Path $PSScriptRoot '..'), |
| 22 | + [string]$OutputScriptPath = (Join-Path $PSScriptRoot '..' '..' 'Postgres-Toolkit.ps1'), |
| 23 | + [string]$OutputHelpPath = (Join-Path $PSScriptRoot '..' '..' 'Postgres-Toolkit.Help.md') |
| 24 | +) |
| 25 | + |
| 26 | +Set-StrictMode -Version Latest |
| 27 | +$ErrorActionPreference = 'Stop' |
| 28 | + |
| 29 | +<# |
| 30 | +.SYNOPSIS |
| 31 | + 读取脚本文件并返回原始内容。 |
| 32 | +
|
| 33 | +.DESCRIPTION |
| 34 | + 在拼装前统一校验文件存在性,避免遗漏源码片段导致 bundle 不完整。 |
| 35 | +
|
| 36 | +.PARAMETER Path |
| 37 | + 待读取的脚本文件路径。 |
| 38 | +
|
| 39 | +.OUTPUTS |
| 40 | + string |
| 41 | + 返回脚本文件的原始文本内容。 |
| 42 | +#> |
| 43 | +function Get-BundleFileContent { |
| 44 | + [CmdletBinding()] |
| 45 | + param( |
| 46 | + [Parameter(Mandatory)] |
| 47 | + [string]$Path |
| 48 | + ) |
| 49 | + |
| 50 | + if (-not (Test-Path -Path $Path -PathType Leaf)) { |
| 51 | + throw "缺少源码片段: $Path" |
| 52 | + } |
| 53 | + |
| 54 | + return Get-Content -Path $Path -Raw |
| 55 | +} |
| 56 | + |
| 57 | +<# |
| 58 | +.SYNOPSIS |
| 59 | + 从 `main.ps1` 提取命令分发函数定义。 |
| 60 | +
|
| 61 | +.DESCRIPTION |
| 62 | + 使用 PowerShell AST 读取 `Invoke-PostgresToolkitCommand` 的源码范围, |
| 63 | + 避免直接拼接 `main.ps1` 时把 `param(...)` 块放到非法位置。 |
| 64 | +
|
| 65 | +.PARAMETER MainScriptPath |
| 66 | + `main.ps1` 的完整路径。 |
| 67 | +
|
| 68 | +.OUTPUTS |
| 69 | + string |
| 70 | + 返回函数定义源码文本。 |
| 71 | +#> |
| 72 | +function Get-MainDispatchFunctionContent { |
| 73 | + [CmdletBinding()] |
| 74 | + param( |
| 75 | + [Parameter(Mandatory)] |
| 76 | + [string]$MainScriptPath |
| 77 | + ) |
| 78 | + |
| 79 | + $tokens = $null |
| 80 | + $errors = $null |
| 81 | + $ast = [System.Management.Automation.Language.Parser]::ParseFile($MainScriptPath, [ref]$tokens, [ref]$errors) |
| 82 | + if ($errors.Count -gt 0) { |
| 83 | + $errorText = ($errors | ForEach-Object { $_.Message }) -join '; ' |
| 84 | + throw "解析 main.ps1 失败: $errorText" |
| 85 | + } |
| 86 | + |
| 87 | + $functionAst = $ast.Find( |
| 88 | + { |
| 89 | + param($node) |
| 90 | + $node -is [System.Management.Automation.Language.FunctionDefinitionAst] -and $node.Name -eq 'Invoke-PostgresToolkitCommand' |
| 91 | + }, |
| 92 | + $true |
| 93 | + ) |
| 94 | + |
| 95 | + if ($null -eq $functionAst) { |
| 96 | + throw "未在 main.ps1 中找到 Invoke-PostgresToolkitCommand。" |
| 97 | + } |
| 98 | + |
| 99 | + return $functionAst.Extent.Text |
| 100 | +} |
| 101 | + |
| 102 | +$bundleParts = @( |
| 103 | + 'core/logging.ps1' |
| 104 | + 'core/process.ps1' |
| 105 | + 'core/arguments.ps1' |
| 106 | + 'core/connection.ps1' |
| 107 | + 'core/context.ps1' |
| 108 | + 'core/formats.ps1' |
| 109 | + 'core/validation.ps1' |
| 110 | + 'platforms/windows.ps1' |
| 111 | + 'platforms/macos.ps1' |
| 112 | + 'platforms/linux.ps1' |
| 113 | + 'commands/help.ps1' |
| 114 | + 'commands/backup.ps1' |
| 115 | + 'commands/restore.ps1' |
| 116 | + 'commands/import-csv.ps1' |
| 117 | + 'commands/install-tools.ps1' |
| 118 | +) |
| 119 | + |
| 120 | +$mainScriptPath = Join-Path $SourceRoot 'main.ps1' |
| 121 | +$bundleContent = New-Object 'System.Collections.Generic.List[string]' |
| 122 | + |
| 123 | +$bundleContent.Add('#!/usr/bin/env pwsh') |
| 124 | +$bundleContent.Add('<#') |
| 125 | +$bundleContent.Add('.SYNOPSIS') |
| 126 | +$bundleContent.Add(' PostgreSQL 常用备份、恢复、CSV 导入与工具安装命令行工具。') |
| 127 | +$bundleContent.Add('') |
| 128 | +$bundleContent.Add('.DESCRIPTION') |
| 129 | +$bundleContent.Add(' 单文件分发产物,内嵌 PostgreSQL Toolkit 的核心 helper、命令翻译和帮助输出。') |
| 130 | +$bundleContent.Add('') |
| 131 | +$bundleContent.Add('.PARAMETER CommandName') |
| 132 | +$bundleContent.Add(' 要执行的子命令名称,例如 `backup`、`restore`、`import-csv`、`install-tools`。') |
| 133 | +$bundleContent.Add('') |
| 134 | +$bundleContent.Add('.PARAMETER RawArguments') |
| 135 | +$bundleContent.Add(' 透传给子命令解析器的剩余参数数组。') |
| 136 | +$bundleContent.Add('#>') |
| 137 | +$bundleContent.Add('[CmdletBinding(PositionalBinding = $false)]') |
| 138 | +$bundleContent.Add('param(') |
| 139 | +$bundleContent.Add(' [Parameter(Position = 0)]') |
| 140 | +$bundleContent.Add(' [string]$CommandName,') |
| 141 | +$bundleContent.Add('') |
| 142 | +$bundleContent.Add(' [Parameter(ValueFromRemainingArguments = $true)]') |
| 143 | +$bundleContent.Add(' [string[]]$RawArguments') |
| 144 | +$bundleContent.Add(')') |
| 145 | +$bundleContent.Add('') |
| 146 | +$bundleContent.Add('Set-StrictMode -Version Latest') |
| 147 | +$bundleContent.Add('$ErrorActionPreference = ''Stop''') |
| 148 | + |
| 149 | +foreach ($relativePath in $bundleParts) { |
| 150 | + $fullPath = Join-Path $SourceRoot $relativePath |
| 151 | + $bundleContent.Add('') |
| 152 | + $bundleContent.Add("# region $relativePath") |
| 153 | + $bundleContent.Add((Get-BundleFileContent -Path $fullPath)) |
| 154 | + $bundleContent.Add("# endregion $relativePath") |
| 155 | +} |
| 156 | + |
| 157 | +$bundleContent.Add('') |
| 158 | +$bundleContent.Add('# region main-dispatch') |
| 159 | +$bundleContent.Add((Get-MainDispatchFunctionContent -MainScriptPath $mainScriptPath)) |
| 160 | +$bundleContent.Add('# endregion main-dispatch') |
| 161 | +$bundleContent.Add('') |
| 162 | +$bundleContent.Add('if ($env:PWSH_TEST_SKIP_POSTGRES_TOOLKIT_MAIN -ne ''1'') {') |
| 163 | +$bundleContent.Add(' $result = Invoke-PostgresToolkitCommand -CommandName $CommandName -RawArguments $RawArguments') |
| 164 | +$bundleContent.Add(' if (-not [string]::IsNullOrWhiteSpace($result.Output)) {') |
| 165 | +$bundleContent.Add(' Write-Output $result.Output') |
| 166 | +$bundleContent.Add(' }') |
| 167 | +$bundleContent.Add('') |
| 168 | +$bundleContent.Add(' exit $result.ExitCode') |
| 169 | +$bundleContent.Add('}') |
| 170 | + |
| 171 | +$scriptDirectory = Split-Path -Path $OutputScriptPath -Parent |
| 172 | +$helpDirectory = Split-Path -Path $OutputHelpPath -Parent |
| 173 | +if (-not [string]::IsNullOrWhiteSpace($scriptDirectory)) { |
| 174 | + New-Item -Path $scriptDirectory -ItemType Directory -Force | Out-Null |
| 175 | +} |
| 176 | +if (-not [string]::IsNullOrWhiteSpace($helpDirectory)) { |
| 177 | + New-Item -Path $helpDirectory -ItemType Directory -Force | Out-Null |
| 178 | +} |
| 179 | + |
| 180 | +Set-Content -Path $OutputScriptPath -Value ($bundleContent -join [Environment]::NewLine) -Encoding utf8NoBOM |
| 181 | +Copy-Item -Path (Join-Path $SourceRoot 'docs/help.md') -Destination $OutputHelpPath -Force |
0 commit comments