From 5a2925f8467eb7af829e456b27c9d6b15f185829 Mon Sep 17 00:00:00 2001 From: csh Date: Thu, 22 Jan 2026 17:30:15 +0800 Subject: [PATCH] :bug: fix(scripts): repair windows script parsing fix powershell here-strings and help alias conflicts\nadd windows script lint test and run it in CI --- .gitea/workflows/test.yml | 1 + scripts/install_codex_skills.ps1 | 2 +- scripts/sync_standards.bat | 31 +++++++------- scripts/sync_standards.ps1 | 12 +++--- scripts/sync_templates.ps1 | 2 +- scripts/vendor_playbook.ps1 | 2 +- tests/README.md | 13 +++++- tests/scripts/test_windows_script_lints.bats | 44 ++++++++++++++++++++ 8 files changed, 83 insertions(+), 24 deletions(-) create mode 100644 tests/scripts/test_windows_script_lints.bats diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index d768348..fc037ed 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -140,6 +140,7 @@ jobs: run_bats "sync_templates" "test_sync_templates.bats" run_bats "vendor_playbook" "test_vendor_playbook.bats" run_bats "install_codex_skills" "test_install_codex_skills.bats" + run_bats "windows_script_lints" "test_windows_script_lints.bats" echo "========================================" echo "📄 模板验证测试" diff --git a/scripts/install_codex_skills.ps1 b/scripts/install_codex_skills.ps1 index ee2c188..03cafe9 100644 --- a/scripts/install_codex_skills.ps1 +++ b/scripts/install_codex_skills.ps1 @@ -13,7 +13,7 @@ [CmdletBinding()] param( - [Alias('h', 'help', '?')] + [Alias('h', '?')] [switch]$Help, [switch]$Local, diff --git a/scripts/sync_standards.bat b/scripts/sync_standards.bat index 70f4791..eef5294 100644 --- a/scripts/sync_standards.bat +++ b/scripts/sync_standards.bat @@ -35,21 +35,6 @@ set "GITATTR_DST=%ROOT%\.gitattributes" set "SYNC_GITATTR_MODE=%SYNC_GITATTR_MODE%" if "%SYNC_GITATTR_MODE%"=="" set "SYNC_GITATTR_MODE=append" -:show_help -echo Usage: -echo sync_standards.bat -echo sync_standards.bat -langs tsl,cpp -echo. -echo Options: -echo -langs Comma/space-separated list of languages ^(required^). -echo -h, -help Show this help. -echo. -echo Env: -echo SYNC_ROOT Target project root ^(default: git root^). -echo AGENTS_NS Single ruleset name ^(default: tsl^). -echo SYNC_GITATTR_MODE append^|overwrite^|block^|skip ^(default: append^). -exit /b 0 - set "LANG_LIST=" :parse_args if "%~1"=="" goto args_done @@ -417,3 +402,19 @@ if exist "%GITATTR_SRC%" ( :AfterGitAttr echo Done. endlocal +exit /b 0 + +:show_help +echo Usage: +echo sync_standards.bat +echo sync_standards.bat -langs tsl,cpp +echo. +echo Options: +echo -langs Comma/space-separated list of languages ^(required^). +echo -h, -help Show this help. +echo. +echo Env: +echo SYNC_ROOT Target project root ^(default: git root^). +echo AGENTS_NS Single ruleset name ^(default: tsl^). +echo SYNC_GITATTR_MODE append^|overwrite^|block^|skip ^(default: append^). +exit /b 0 diff --git a/scripts/sync_standards.ps1 b/scripts/sync_standards.ps1 index 366f3c8..f682d99 100644 --- a/scripts/sync_standards.ps1 +++ b/scripts/sync_standards.ps1 @@ -5,7 +5,7 @@ [CmdletBinding()] param( [Parameter(Mandatory = $false)] - [Alias('h', 'help', '?')] + [Alias('h', '?')] [switch]$Help, # Sync multiple rulesets in one run: @@ -143,7 +143,7 @@ if ($relSnapshot) { $AgentsIndex = Join-Path $AgentsRoot "index.md" if (-not (Test-Path $AgentsIndex)) { -@' + $agentsIndexContent = @' # .agents(多语言) 本目录用于存放仓库级/语言级的代理规则集。 @@ -163,7 +163,8 @@ if (-not (Test-Path $AgentsIndex)) { - `.agents/cpp/index.md`(C++ 规则集入口) - `.agents/markdown/index.md`(Markdown 规则集入口) - `docs/standards/playbook/docs/`(人类开发规范快照:`tsl/`、`cpp/`、`python/`、`common/`) -'@ | Set-Content -Path $AgentsIndex -Encoding UTF8 +'@ + Set-Content -Path $AgentsIndex -Encoding UTF8 -Value $agentsIndexContent Write-Host "Created .agents/index.md" } @@ -192,11 +193,12 @@ $agentsBlock = @" "@ if (-not (Test-Path $AgentsMd)) { - @" + $agentsMdContent = @" # Agent Instructions $agentsBlock -"@ | Set-Content -Path $AgentsMd -Encoding UTF8 +"@ + Set-Content -Path $AgentsMd -Encoding UTF8 -Value $agentsMdContent Write-Host "Created AGENTS.md" } else { $content = Get-Content -Raw -Path $AgentsMd diff --git a/scripts/sync_templates.ps1 b/scripts/sync_templates.ps1 index 53613eb..aa68d59 100644 --- a/scripts/sync_templates.ps1 +++ b/scripts/sync_templates.ps1 @@ -7,7 +7,7 @@ [CmdletBinding()] param( [Parameter(Mandatory = $false)] - [Alias('h', 'help', '?')] + [Alias('h', '?')] [switch]$Help, [Parameter(Mandatory = $false)] diff --git a/scripts/vendor_playbook.ps1 b/scripts/vendor_playbook.ps1 index 0451944..c90029d 100644 --- a/scripts/vendor_playbook.ps1 +++ b/scripts/vendor_playbook.ps1 @@ -18,7 +18,7 @@ [CmdletBinding()] param( [Parameter(Mandatory = $false)] - [Alias('h', 'help', '?')] + [Alias('h', '?')] [switch]$Help, [Parameter(Mandatory = $false)] diff --git a/tests/README.md b/tests/README.md index d315471..f0f232b 100644 --- a/tests/README.md +++ b/tests/README.md @@ -11,7 +11,8 @@ tests/ │ ├── test_sync_standards.bats # sync_standards.sh 测试 │ ├── test_sync_templates.bats # sync_templates.sh 测试 │ ├── test_vendor_playbook.bats # vendor_playbook.sh 测试 -│ └── test_install_codex_skills.bats # install_codex_skills.sh 测试 +│ ├── test_install_codex_skills.bats # install_codex_skills.sh 测试 +│ └── test_windows_script_lints.bats # Windows 脚本 lint 测试 ├── templates/ # 模板验证测试 │ ├── validate_python_templates.sh # Python 模板验证 │ ├── validate_cpp_templates.sh # C++ 模板验证 @@ -153,6 +154,16 @@ sh check_doc_links.sh - **幂等性**: - 多次安装结果一致 +#### test_windows_script_lints.bats + +测试 Windows 脚本的基础 lint 规则: + +- **PowerShell**: + - here-string 终止符不与管道同一行 + - Help 参数别名不与参数名冲突 +- **Batch**: + - `:show_help` 标签不应阻断参数解析 + ### 2. 模板验证测试 (templates/) 验证项目模板文件的正确性和完整性。 diff --git a/tests/scripts/test_windows_script_lints.bats b/tests/scripts/test_windows_script_lints.bats new file mode 100644 index 0000000..6436b30 --- /dev/null +++ b/tests/scripts/test_windows_script_lints.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats +# Windows script lint tests (PowerShell/Batch) + +setup() { + export PLAYBOOK_ROOT="$(cd "$BATS_TEST_DIRNAME/../.." && pwd)" +} + +@test "sync_standards.ps1 - here-string terminator not piped" { + run grep -nE "^[[:space:]]*['\\\"]@\\s*\\|" "$PLAYBOOK_ROOT/scripts/sync_standards.ps1" + [ "$status" -ne 0 ] +} + +@test "sync_standards.ps1 - Help alias does not shadow parameter name" { + run grep -niE "Alias\\([^)]*['\"]help['\"]" "$PLAYBOOK_ROOT/scripts/sync_standards.ps1" + [ "$status" -ne 0 ] +} + +@test "install_codex_skills.ps1 - Help alias does not shadow parameter name" { + run grep -niE "Alias\\([^)]*['\"]help['\"]" "$PLAYBOOK_ROOT/scripts/install_codex_skills.ps1" + [ "$status" -ne 0 ] +} + +@test "sync_templates.ps1 - Help alias does not shadow parameter name" { + run grep -niE "Alias\\([^)]*['\"]help['\"]" "$PLAYBOOK_ROOT/scripts/sync_templates.ps1" + [ "$status" -ne 0 ] +} + +@test "vendor_playbook.ps1 - Help alias does not shadow parameter name" { + run grep -niE "Alias\\([^)]*['\"]help['\"]" "$PLAYBOOK_ROOT/scripts/vendor_playbook.ps1" + [ "$status" -ne 0 ] +} + +@test "sync_standards.bat - show_help label follows parse_args" { + local file="$PLAYBOOK_ROOT/scripts/sync_standards.bat" + local show_line + local parse_line + + show_line=$(grep -n "^:show_help" "$file" | head -n 1 | cut -d: -f1) + parse_line=$(grep -n "^:parse_args" "$file" | head -n 1 | cut -d: -f1) + + [ -n "$show_line" ] + [ -n "$parse_line" ] + [ "$show_line" -gt "$parse_line" ] +}