380 lines
12 KiB
Batchfile
380 lines
12 KiB
Batchfile
@echo off
|
||
setlocal enabledelayedexpansion
|
||
|
||
rem Vendor a trimmed Playbook snapshot into a target project (offline copy),
|
||
rem then run sync_standards to materialize .agents\<lang>\ and .gitattributes in
|
||
rem the target project root.
|
||
rem
|
||
rem Usage:
|
||
rem scripts\vendor_playbook.bat -project-root <path> (default: tsl)
|
||
rem scripts\vendor_playbook.bat -project-root <path> -langs tsl,cpp
|
||
rem scripts\vendor_playbook.bat -project-root <path> -langs tsl,cpp -apply-templates
|
||
rem
|
||
rem Options:
|
||
rem -project-root Target project root (required)
|
||
rem -apply-templates Apply CI/lang templates to project root (skip if exists)
|
||
rem
|
||
rem Notes:
|
||
rem - Snapshot is written to: <project-root>\docs\standards\playbook\
|
||
rem - Existing snapshot is backed up before overwrite.
|
||
rem - With -apply-templates, CI and lang templates are copied to project root.
|
||
|
||
set "SCRIPT_DIR=%~dp0"
|
||
for %%I in ("%SCRIPT_DIR%..") do set "SRC=%%~fI"
|
||
|
||
if "%~1"=="" goto Usage
|
||
if "%~1"=="-h" goto Usage
|
||
if "%~1"=="-help" goto Usage
|
||
|
||
set "DEST_ROOT="
|
||
set "LANGS="
|
||
set "APPLY_TEMPLATES=0"
|
||
|
||
rem Parse arguments
|
||
:parse_args
|
||
if "%~1"=="" goto args_done
|
||
if "%~1"=="-project-root" (
|
||
if "%~2"=="" (
|
||
echo ERROR: -project-root requires a path.
|
||
exit /b 1
|
||
)
|
||
set "DEST_ROOT=%~2"
|
||
shift /1
|
||
shift /1
|
||
goto parse_args
|
||
)
|
||
if "%~1"=="-langs" (
|
||
if "%~2"=="" (
|
||
echo ERROR: -langs requires a value.
|
||
exit /b 1
|
||
)
|
||
set "LANGS=%~2"
|
||
shift /1
|
||
shift /1
|
||
goto parse_args
|
||
)
|
||
if "%~1"=="-apply-templates" (
|
||
set "APPLY_TEMPLATES=1"
|
||
shift /1
|
||
goto parse_args
|
||
)
|
||
echo ERROR: positional args are not supported. Use -project-root/-langs.
|
||
exit /b 1
|
||
:args_done
|
||
|
||
if "%DEST_ROOT%"=="" (
|
||
echo ERROR: -project-root is required.
|
||
exit /b 1
|
||
)
|
||
|
||
if "%LANGS%"=="" set "LANGS=tsl"
|
||
set "LANGS=%LANGS:,= %"
|
||
|
||
if not exist "%DEST_ROOT%" mkdir "%DEST_ROOT%"
|
||
for %%I in ("%DEST_ROOT%") do set "DEST_ROOT_ABS=%%~fI"
|
||
|
||
set "STANDARDS_DIR=%DEST_ROOT_ABS%\\docs\\standards"
|
||
set "DEST_PREFIX=%STANDARDS_DIR%\\playbook"
|
||
|
||
if not exist "%STANDARDS_DIR%" mkdir "%STANDARDS_DIR%"
|
||
|
||
if exist "%DEST_PREFIX%" (
|
||
set "RAND=%RANDOM%"
|
||
pushd "%STANDARDS_DIR%"
|
||
ren "playbook" "playbook.bak.!RAND!"
|
||
popd
|
||
echo Backed up existing snapshot -^> docs\\standards\\playbook.bak.!RAND!
|
||
)
|
||
|
||
if not exist "%DEST_PREFIX%" mkdir "%DEST_PREFIX%"
|
||
|
||
copy /y "%SRC%\\.gitattributes" "%DEST_PREFIX%\\.gitattributes" >nul
|
||
copy /y "%SRC%\\SKILLS.md" "%DEST_PREFIX%\\SKILLS.md" >nul
|
||
|
||
xcopy "%SRC%\\scripts\\*" "%DEST_PREFIX%\\scripts\\" /e /i /y >nul
|
||
if errorlevel 1 (
|
||
echo ERROR: failed to copy scripts
|
||
exit /b 1
|
||
)
|
||
|
||
xcopy "%SRC%\\codex\\*" "%DEST_PREFIX%\\codex\\" /e /i /y >nul
|
||
if errorlevel 1 (
|
||
echo ERROR: failed to copy codex
|
||
exit /b 1
|
||
)
|
||
|
||
xcopy "%SRC%\\docs\\common\\*" "%DEST_PREFIX%\\docs\\common\\" /e /i /y >nul
|
||
if errorlevel 1 (
|
||
echo ERROR: failed to copy docs\\common
|
||
exit /b 1
|
||
)
|
||
|
||
if not exist "%DEST_PREFIX%\\rulesets" mkdir "%DEST_PREFIX%\\rulesets"
|
||
copy /y "%SRC%\\rulesets\\index.md" "%DEST_PREFIX%\\rulesets\\index.md" >nul
|
||
|
||
if not exist "%DEST_PREFIX%\\templates" mkdir "%DEST_PREFIX%\\templates"
|
||
|
||
if exist "%SRC%\\templates\\ci" (
|
||
xcopy "%SRC%\\templates\\ci\\*" "%DEST_PREFIX%\\templates\\ci\\" /e /i /y >nul
|
||
if errorlevel 1 (
|
||
echo ERROR: failed to copy templates\\ci
|
||
exit /b 1
|
||
)
|
||
)
|
||
|
||
set "LANGS_CSV="
|
||
for %%L in (%LANGS%) do (
|
||
echo %%~L| findstr /r "[\\/]" >nul && (
|
||
echo ERROR: invalid lang=%%~L
|
||
exit /b 1
|
||
)
|
||
echo %%~L| findstr /c:".." >nul && (
|
||
echo ERROR: invalid lang=%%~L
|
||
exit /b 1
|
||
)
|
||
|
||
if not exist "%SRC%\\docs\\%%~L" (
|
||
echo ERROR: docs not found for lang=%%~L "%SRC%\\docs\\%%~L"
|
||
exit /b 1
|
||
)
|
||
if not exist "%SRC%\\rulesets\\%%~L" (
|
||
echo ERROR: agents ruleset not found for lang=%%~L "%SRC%\\rulesets\\%%~L"
|
||
exit /b 1
|
||
)
|
||
|
||
xcopy "%SRC%\\docs\\%%~L\\*" "%DEST_PREFIX%\\docs\\%%~L\\" /e /i /y >nul
|
||
if errorlevel 1 (
|
||
echo ERROR: failed to copy docs for lang=%%~L
|
||
exit /b 1
|
||
)
|
||
|
||
xcopy "%SRC%\\rulesets\\%%~L\\*" "%DEST_PREFIX%\\rulesets\\%%~L\\" /e /i /y >nul
|
||
if errorlevel 1 (
|
||
echo ERROR: failed to copy agents for lang=%%~L
|
||
exit /b 1
|
||
)
|
||
|
||
if exist "%SRC%\\templates\\%%~L" (
|
||
xcopy "%SRC%\\templates\\%%~L\\*" "%DEST_PREFIX%\\templates\\%%~L\\" /e /i /y >nul
|
||
if errorlevel 1 (
|
||
echo ERROR: failed to copy templates for lang=%%~L
|
||
exit /b 1
|
||
)
|
||
)
|
||
|
||
if "!LANGS_CSV!"=="" (
|
||
set "LANGS_CSV=%%~L"
|
||
) else (
|
||
set "LANGS_CSV=!LANGS_CSV!,%%~L"
|
||
)
|
||
)
|
||
|
||
set "DOC_INDEX=%DEST_PREFIX%\\docs\\index.md"
|
||
> "%DOC_INDEX%" echo # 文档导航(Docs Index)
|
||
>> "%DOC_INDEX%" echo.
|
||
>> "%DOC_INDEX%" echo 本快照为裁剪版 Playbook(langs: %LANGS_CSV%)。
|
||
>> "%DOC_INDEX%" echo.
|
||
>> "%DOC_INDEX%" echo ## 跨语言(common)
|
||
>> "%DOC_INDEX%" echo.
|
||
>> "%DOC_INDEX%" echo - 提交信息与版本号:`common/commit_message.md`
|
||
|
||
for %%L in (%LANGS%) do call :AppendDocsSection "%%~L"
|
||
|
||
set "COMMIT="
|
||
for /f "delims=" %%H in ('git -C "%SRC%" rev-parse HEAD 2^>nul') do set "COMMIT=%%H"
|
||
if "%COMMIT%"=="" set "COMMIT=N/A"
|
||
|
||
set "README=%DEST_PREFIX%\\README.md"
|
||
> "%README%" echo # Playbook(裁剪快照)
|
||
>> "%README%" echo.
|
||
>> "%README%" echo 本目录为从 Playbook vendoring 的裁剪快照(langs: %LANGS_CSV%)。
|
||
>> "%README%" echo.
|
||
>> "%README%" echo ## 使用
|
||
>> "%README%" echo.
|
||
>> "%README%" echo 在目标项目根目录执行(多语言一次同步):
|
||
>> "%README%" echo.
|
||
>> "%README%" echo ```sh
|
||
>> "%README%" echo sh docs/standards/playbook/scripts/sync_standards.sh -langs %LANGS_CSV%
|
||
>> "%README%" echo ```
|
||
>> "%README%" echo.
|
||
>> "%README%" echo 查看规范入口:
|
||
>> "%README%" echo.
|
||
>> "%README%" echo - `docs/standards/playbook/docs/index.md`
|
||
>> "%README%" echo - `.agents/index.md`
|
||
>> "%README%" echo.
|
||
>> "%README%" echo ## Codex skills(可选)
|
||
>> "%README%" echo.
|
||
>> "%README%" echo 安装到本机(需要先在 `~/.codex/config.toml` 启用 skills;见 `docs/standards/playbook/SKILLS.md`):
|
||
>> "%README%" echo.
|
||
>> "%README%" echo ```sh
|
||
>> "%README%" echo sh docs/standards/playbook/scripts/install_codex_skills.sh -all
|
||
>> "%README%" echo ```
|
||
>> "%README%" echo.
|
||
>> "%README%" echo ## CI templates(可选)
|
||
>> "%README%" echo.
|
||
>> "%README%" echo 目标项目可复制启用的 CI 示例模板(如 Gitea Actions):`templates/ci/`。
|
||
|
||
set "SOURCE=%DEST_PREFIX%\\SOURCE.md"
|
||
> "%SOURCE%" echo # SOURCE
|
||
>> "%SOURCE%" echo.
|
||
>> "%SOURCE%" echo - Source: %SRC%
|
||
>> "%SOURCE%" echo - Commit: %COMMIT%
|
||
>> "%SOURCE%" echo - Date: %DATE% %TIME%
|
||
>> "%SOURCE%" echo - Langs: %LANGS_CSV%
|
||
>> "%SOURCE%" echo - Generated-by: scripts/vendor_playbook.bat
|
||
|
||
echo Vendored snapshot -^> %DEST_PREFIX%
|
||
|
||
set "PROJECT_AGENTS_ROOT=%DEST_ROOT_ABS%\\.agents"
|
||
set "PROJECT_AGENTS_INDEX=%PROJECT_AGENTS_ROOT%\\index.md"
|
||
if not exist "%PROJECT_AGENTS_ROOT%" mkdir "%PROJECT_AGENTS_ROOT%"
|
||
if not exist "%PROJECT_AGENTS_INDEX%" (
|
||
> "%PROJECT_AGENTS_INDEX%" echo # .agents(多语言)
|
||
>> "%PROJECT_AGENTS_INDEX%" echo.
|
||
>> "%PROJECT_AGENTS_INDEX%" echo 本目录用于存放仓库级/语言级的代理规则集。
|
||
>> "%PROJECT_AGENTS_INDEX%" echo.
|
||
>> "%PROJECT_AGENTS_INDEX%" echo 本项目已启用的规则集:
|
||
for %%L in (%LANGS%) do (
|
||
if /I "%%~L"=="tsl" >> "%PROJECT_AGENTS_INDEX%" echo - .agents/tsl/:TSL 相关规则集(适用于 .tsl/.tsf)
|
||
if /I "%%~L"=="cpp" >> "%PROJECT_AGENTS_INDEX%" echo - .agents/cpp/:C++ 相关规则集(C++23,含 Modules)
|
||
if /I "%%~L"=="python" >> "%PROJECT_AGENTS_INDEX%" echo - .agents/python/:Python 相关规则集
|
||
if /I "%%~L"=="markdown" >> "%PROJECT_AGENTS_INDEX%" echo - .agents/markdown/:Markdown 相关规则集(仅代码格式化)
|
||
)
|
||
>> "%PROJECT_AGENTS_INDEX%" echo.
|
||
>> "%PROJECT_AGENTS_INDEX%" echo 入口建议从:
|
||
for %%L in (%LANGS%) do >> "%PROJECT_AGENTS_INDEX%" echo - .agents/%%~L/index.md
|
||
>> "%PROJECT_AGENTS_INDEX%" echo.
|
||
>> "%PROJECT_AGENTS_INDEX%" echo 标准快照文档入口:
|
||
>> "%PROJECT_AGENTS_INDEX%" echo.
|
||
>> "%PROJECT_AGENTS_INDEX%" echo - docs/standards/playbook/docs/index.md
|
||
)
|
||
|
||
set "OLD_SYNC_ROOT=%SYNC_ROOT%"
|
||
set "SYNC_ROOT=%DEST_ROOT_ABS%"
|
||
pushd "%DEST_ROOT_ABS%"
|
||
call "%DEST_PREFIX%\\scripts\\sync_standards.bat" -langs %LANGS_CSV%
|
||
popd
|
||
set "SYNC_ROOT=%OLD_SYNC_ROOT%"
|
||
|
||
rem Apply templates to project root if requested
|
||
if "%APPLY_TEMPLATES%"=="1" (
|
||
echo.
|
||
echo Applying templates to project root...
|
||
|
||
rem Apply CI templates ^(Gitea workflows^)
|
||
set "CI_SRC=%DEST_PREFIX%\templates\ci\gitea\.gitea"
|
||
if exist "!CI_SRC!" (
|
||
if exist "%DEST_ROOT_ABS%\.gitea" (
|
||
echo Skip ^(exists^): .gitea\
|
||
) else (
|
||
xcopy "!CI_SRC!\*" "%DEST_ROOT_ABS%\.gitea\" /e /i /y >nul 2>nul
|
||
echo Applied: .gitea\
|
||
)
|
||
)
|
||
|
||
rem Apply lang-specific templates
|
||
for %%L in (%LANGS%) do (
|
||
set "LANG_SRC=%DEST_PREFIX%\templates\%%~L"
|
||
if exist "!LANG_SRC!" (
|
||
if /I "%%~L"=="cpp" (
|
||
call :CopyIfNotExists "!LANG_SRC!\.clang-format" "%DEST_ROOT_ABS%\.clang-format"
|
||
call :CopyIfNotExists "!LANG_SRC!\.clangd" "%DEST_ROOT_ABS%\.clangd"
|
||
call :CopyIfNotExists "!LANG_SRC!\CMakeLists.txt" "%DEST_ROOT_ABS%\CMakeLists.txt"
|
||
call :CopyIfNotExists "!LANG_SRC!\CMakeUserPresets.json" "%DEST_ROOT_ABS%\CMakeUserPresets.json"
|
||
call :CopyIfNotExists "!LANG_SRC!\conanfile.txt" "%DEST_ROOT_ABS%\conanfile.txt"
|
||
if exist "!LANG_SRC!\conan" (
|
||
if exist "%DEST_ROOT_ABS%\conan" (
|
||
echo Skip ^(exists^): conan\
|
||
) else (
|
||
xcopy "!LANG_SRC!\conan\*" "%DEST_ROOT_ABS%\conan\" /e /i /y >nul 2>nul
|
||
echo Applied: conan\
|
||
)
|
||
)
|
||
)
|
||
if /I "%%~L"=="python" (
|
||
call :CopyIfNotExists "!LANG_SRC!\.editorconfig" "%DEST_ROOT_ABS%\.editorconfig"
|
||
call :CopyIfNotExists "!LANG_SRC!\.flake8" "%DEST_ROOT_ABS%\.flake8"
|
||
call :CopyIfNotExists "!LANG_SRC!\.pre-commit-config.yaml" "%DEST_ROOT_ABS%\.pre-commit-config.yaml"
|
||
call :CopyIfNotExists "!LANG_SRC!\.pylintrc" "%DEST_ROOT_ABS%\.pylintrc"
|
||
call :CopyIfNotExists "!LANG_SRC!\pyproject.toml" "%DEST_ROOT_ABS%\pyproject.toml"
|
||
if exist "!LANG_SRC!\.vscode" (
|
||
if exist "%DEST_ROOT_ABS%\.vscode" (
|
||
echo Skip ^(exists^): .vscode\
|
||
) else (
|
||
xcopy "!LANG_SRC!\.vscode\*" "%DEST_ROOT_ABS%\.vscode\" /e /i /y >nul 2>nul
|
||
echo Applied: .vscode\
|
||
)
|
||
)
|
||
)
|
||
)
|
||
)
|
||
|
||
echo Templates applied.
|
||
)
|
||
|
||
echo Done.
|
||
endlocal
|
||
exit /b 0
|
||
|
||
:AppendDocsSection
|
||
set "LANG=%~1"
|
||
if /I "%LANG%"=="tsl" (
|
||
>> "%DOC_INDEX%" echo.
|
||
>> "%DOC_INDEX%" echo ## TSL(tsl)
|
||
>> "%DOC_INDEX%" echo.
|
||
>> "%DOC_INDEX%" echo - 代码风格:`tsl/code_style.md`
|
||
>> "%DOC_INDEX%" echo - 命名规范:`tsl/naming.md`
|
||
>> "%DOC_INDEX%" echo - 语法手册:`tsl/syntax_book/index.md`
|
||
>> "%DOC_INDEX%" echo - 工具链与验证命令(模板):`tsl/toolchain.md`
|
||
)
|
||
if /I "%LANG%"=="cpp" (
|
||
>> "%DOC_INDEX%" echo.
|
||
>> "%DOC_INDEX%" echo ## C++(cpp)
|
||
>> "%DOC_INDEX%" echo.
|
||
>> "%DOC_INDEX%" echo - 代码风格:`cpp/code_style.md`
|
||
>> "%DOC_INDEX%" echo - 命名规范:`cpp/naming.md`
|
||
>> "%DOC_INDEX%" echo - 工具链与验证命令(模板):`cpp/toolchain.md`
|
||
>> "%DOC_INDEX%" echo - 第三方依赖(Conan):`cpp/dependencies_conan.md`
|
||
>> "%DOC_INDEX%" echo - clangd 配置:`cpp/clangd.md`
|
||
)
|
||
if /I "%LANG%"=="python" (
|
||
>> "%DOC_INDEX%" echo.
|
||
>> "%DOC_INDEX%" echo ## Python(python)
|
||
>> "%DOC_INDEX%" echo.
|
||
>> "%DOC_INDEX%" echo - 代码风格:`python/style_guide.md`
|
||
>> "%DOC_INDEX%" echo - 工具链:`python/tooling.md`
|
||
>> "%DOC_INDEX%" echo - 配置清单:`python/configuration.md`
|
||
)
|
||
if /I "%LANG%"=="markdown" (
|
||
>> "%DOC_INDEX%" echo.
|
||
>> "%DOC_INDEX%" echo ## Markdown(markdown)
|
||
>> "%DOC_INDEX%" echo.
|
||
>> "%DOC_INDEX%" echo - 代码块与行内代码格式:`markdown/index.md`
|
||
)
|
||
exit /b 0
|
||
|
||
:CopyIfNotExists
|
||
set "SRC_FILE=%~1"
|
||
set "DST_FILE=%~2"
|
||
if exist "%SRC_FILE%" (
|
||
if exist "%DST_FILE%" (
|
||
for %%F in ("%DST_FILE%") do echo Skip ^(exists^): %%~nxF
|
||
) else (
|
||
copy /y "%SRC_FILE%" "%DST_FILE%" >nul
|
||
for %%F in ("%DST_FILE%") do echo Applied: %%~nxF
|
||
)
|
||
)
|
||
exit /b 0
|
||
|
||
:Usage
|
||
echo Usage:
|
||
echo scripts\vendor_playbook.bat -project-root ^<path^> ^(default: tsl^)
|
||
echo scripts\vendor_playbook.bat -project-root ^<path^> -langs tsl,cpp
|
||
echo scripts\vendor_playbook.bat -project-root ^<path^> -langs tsl,cpp -apply-templates
|
||
echo.
|
||
echo Options:
|
||
echo -project-root Target project root ^(required^)
|
||
echo -langs Comma/space-separated list of languages ^(default: tsl^)
|
||
echo -apply-templates Apply CI/lang templates to project root ^(skip if exists^)
|
||
exit /b 1
|