Harness 可复用配置的安装与分发(Install-Harness)

基于 deploy-manifest.json 的 Profile 安装、Git 版本校验与 Cursor 设置双向同步

PowerShell
Windows
工作流
Cursor
Quarto
Author

Harness 技术文档

Published

May 15, 2026

摘要

本仓库通过 scripts/powershell/deploy-manifest.json 声明「源路径 → 目标项目相对路径」的复制规则,并由 scripts/powershell/Install-Harness.ps1 按 Profile 将 ide/、scripts/quarto-sync/、scripts/docker-selenium/、scripts/quarto-docx/ 等资产安装到任意目标项目根目录(如 Quarto Book 仓库)。同一套脚本在 Windows PowerShell 5.1 与 PowerShell 7 下可用;与「本机全局设置 / 符号链接 / 归档回灌」相关的总原则仍见 配置文件分发机制。


1. 前置条件

  • PowerShell:建议 5.1 或 7+;在仓库根或 scripts/powershell 下执行示例命令。
  • Git:若使用 -Ref / -CheckoutRef 做 harness 仓库版本校验或切换,需已安装并在 PATH 中。
  • 目标目录:-ProjectRoot 必须为已存在的目录(安装脚本不会替你创建项目根)。

2. 快速开始

在 harness 仓库根(或任意目录下通过 -HarnessRoot 指定 harness 根)执行:

cd D:\github\harness
.\scripts\powershell\Install-Harness.ps1 `
  -InstallProfile quarto-sync `
  -ProjectRoot "D:\work\my-quarto-book"

仅预览将要复制的文件(不写目标盘):

.\scripts\powershell\Install-Harness.ps1 `
  -InstallProfile quarto-sync `
  -ProjectRoot "D:\work\my-quarto-book" `
  -NoDeploy

3. 主要参数说明

参数 含义
-InstallProfile 一个或多个 profile 名(见 manifest 的 profiles 键),例如 quarto-sync、cursor、docker-selenium、quarto-docx、quarto-docx-book、book-plot、mathjax-quarto、xaringan-dual、all。
-ProjectRoot 目标项目根目录(绝对路径)。
-HarnessRoot (别名)与 -HarnessLocationOverride 相同:显式指定 harness 仓库根;省略时优先读进程环境变量 HARNESS_ROOT,否则按脚本位置推断。
-Ref (-GitRef 的别名)在 harness 为 git 仓库时,将当前 HEAD 与给定 ref(tag/分支/commit)比较;不一致时默认仅警告,加 -FailIfGitRefMismatch 则失败退出。
-CheckoutRef (-CheckoutGitRef 的别名)在工作区干净时于 harness 根执行 git switch 到 -Ref;常与 -Ref 联用。
-FailIfGitRefMismatch (-StrictRef 的语义别名)-Ref 与 HEAD 不一致时抛错。
-NoDeploy 仅打印将要执行的复制,不写入目标文件(与「计划/预览」同义)。
-SkipBackup 覆盖已存在目标文件前不生成 .bak-时间戳 备份。

命名说明:主参数使用 InstallProfile / GitRef 等名称,以避免与 PowerShell 自动变量 $Profile 及 Windows PowerShell 5.1 下 -File 解析的若干歧义;文档与命令行仍可通过 Attribute 别名使用 -Ref、-StrictRef、-CheckoutRef、-HarnessRoot 等简短写法。


4. Manifest 与 Profile

清单文件:scripts/powershell/deploy-manifest.json。

  • profiles:每个 profile 对应一组 items.id。
  • items:source 为相对 harness 根的路径,dest 为相对 -ProjectRoot 的路径。mode 为 copy(单文件)或 copy-tree(整目录:目标已存在时先备份,再按源目录内容重写)。

新增一类可分发资产时:在 JSON 中增加 items 与 profiles 条目,并更新本文或专题文档中的调用说明。


5. Quarto Book 镜像工作流(与 robocopy 文档的关系)

安装 quarto-sync profile 后,目标项目将获得:

  • R/copy-post-sync.R
  • scripts/mirror-book-sync.ps1
  • .Renviron.example
  • _quarto.harness-post-render.yml(由片段生成,需合并进该书自己的 _quarto.yml)

详细环境变量、Robocopy 行为与迁移清单见 Quarto 项目渲染输出文件夹的 Robocopy 镜像同步工作流。


6. Cursor 工作区设置

cursor profile 会将 ide/cursor-settings/settings.json 复制到目标项目的 .vscode/settings.json(安装前会按需创建 .vscode)。

本机 Cursor 用户级 settings.json 与 harness 中央备份之间的对比、备份与双向同步,请使用 scripts/powershell/Distribute-CursorSettings.ps1,说明见 Cursor 的 settings 配置方案。


7. Docker Selenium

docker-selenium profile 会将 Compose 与 Tasks 片段复制到目标项目(不会覆盖已有 .vscode/tasks.json):

  • docker/docker-compose.selenium.yml
  • .vscode/tasks-selenium.json(请合并进 tasks.json,或在尚无 tasks 时改名为 tasks.json)

拷贝后必须修改 Compose 的 name 与 container_name。RSelenium 1.7.9 用 --profile debug-legacy;CRAN selenium 用无头 chrome 或 --profile debug。详见 Docker Selenium 可复用工作流;资产索引见 scripts/docker-selenium/index.qmd。

此 profile 未包含在 all 中:并非每个课程仓库都需要浏览器自动化。


8. Quarto 中文书稿 docx

quarto-docx profile 会将 Word 参考文档与 Lua 滤镜复制到目标项目(不会改写已有 _quarto.yml):

  • lua/linebreak.lua、lua/crossref-tight-num.lua、lua/docx-table-caption.lua、lua/docx-table-layout.lua
  • template/reference-doc.docx
  • _quarto.harness-docx-filters.yml(请合并进该书 YAML,并设置 format.docx.reference-doc)

硬前提:Quarto 1.8 及以上(已在 1.8.26 与 1.10.18 验证)、网站项目的图/表前缀写成 图N- / 表N-、正文 见 @fig-id。

quarto-docx-book 是 book 剖面。它改为复制 lua/crossref-book-num.lua 与 lua/docx-landscape.lua,滤镜片段落到 _quarto.harness-docx-book-filters.yml。前缀只写「图」「表」,不要写 图2-。横向页用 class landscape,页脚 id 默认 rId14,可用元数据 docx-landscape-footer 覆盖。纸型仍用项目自己的参考文档。

详见 Quarto 中文书稿 docx 滤镜;资产索引见 scripts/quarto-docx/index.qmd。

此 profile 未包含在 all 中:会覆盖目标仓已有 lua/ 同名文件(安装脚本默认先备份)。

8.1 中文书稿 ggplot 出图

book-plot profile 把出图资产复制到目标项目 scripts/book-plot/(不会改写 _quarto.yml、章 YAML 或 .Rprofile):

  • R/ylab-stack.R、R/theme-tech.R、R/knitr-ragg.R、R/httpgd-warmup.R
  • py/check-fig-png.py

章 setup 自行 source() 前三个文件;httpgd-warmup.R 只在用 Cursor / vscode-R httpgd 预览时从 .Rprofile 引入。与 quarto-docx 互补,常一起装:-InstallProfile quarto-docx,book-plot。

详见 中文书稿 ggplot 出图规范;资产索引见 scripts/book-plot/index.qmd。此 profile 未包含在 all 中。


9. Quarto 本地 MathJax 4

mathjax-quarto profile 把 MathJax 4.1.3 运行时整目录复制到目标项目(copy-tree:目标目录已存在时先备份再整目录替换):

  • vendor/mathjax/(load-mathjax.js、tex-chtml.js、input/tex/extensions/boldsymbol.js、woff2/、dynamic/,以及 LICENSE / NOTICE)
  • _quarto.harness-mathjax.yml(合并进 _quarto.yml 的 project.resources 与 html-math-method)

Reveal 模板不在这次复制里。安装后在 harness 根执行 js/mathjax-quarto/patch-reveal-template.ps1,按 HTML 相对输出根的深度写入 vendor/mathjax/reveal-template.html。这套资产服务 Quarto,与 xaringan 的 js/mathjax-xaringan/(MathJax 2,beforeInit)分开。详见 Quarto 本地 MathJax 4。

此 profile 未包含在 all 中:字体目录约 3MB,并非每个仓库都需要离线公式。


10. xaringan 联网稿、离线稿与教室包

xaringan-dual profile 不复制 MathJax 4 运行时。先装 mathjax-quarto,或同一次传入两个 profile。它把下列文件拷到目标项目的 assets-remarkjs/:

  • remark-latest.min.js、fonts/、xaringan-math-spacing.css
  • render-slide.R、pack-offline.R、decks.example.csv、snippets/
  • 从 js/mathjax-xaringan/ 来的 mathjax-config.js 与 wrap-display-math.R

安装后把 decks.example.csv 抄成 decks.csv。详见 xaringan 双工作流。

此 profile 未包含在 all 中:本地字体约 3.8MB,且只服务 xaringan 课件。


11. 局限

  • 安装脚本仅在 Windows 路径语义下测试;目标为 Linux/macOS 时请自行改用 rsync 等方案或仅复制文本资产。
  • -CheckoutRef 会修改 harness 本地 git 检出,请在干净工作区使用。
  • Windows PowerShell 5.1 下请避免在本脚本顶层使用 Split-Path ... -Parent 与若干开关参数的组合(已改为 [IO.Path]::GetDirectoryName 及内联复制逻辑);若你 fork 修改脚本,请注意此类解析陷阱。