Taskfile 中定义脚本变量

其实 taskfile 用的 mvdan/sh 在 Windows 上能很好地支持基础 Shell 语法。并且会替换命令文本中的 $variable

  symlink-quartz-windows:
    platforms: [windows]
    cmds:
      - |
        modules_root="./node_modules"
        patches_root="./node_modules/.pnpm_patches/"
        if [ -d "$patches_root" ]; then
          modules_root="$patches_root"
        fi
        pwsh -NoProfile -Command - << EOF
          New-Item -Force -ItemType SymbolicLink -Value $modules_root/@jackyzha0/quartz/quartz        -Path quartz
          New-Item -Force -ItemType SymbolicLink -Value $modules_root/@jackyzha0/quartz/tsconfig.json -Path tsconfig.json
        EOF

我之前纳闷为什么报错这么奇怪呢,我尝试直接在 EOF 块中用 PowerShell 的语法定义变量,然而变量名被 Shell 替换成了当前运行环境的值(空的)

task: [symlink-quartz-windows]
pwsh -NoProfile -Command - << EOF
  $modules_root = "./node_modules"
EOF
 
=: The term '=' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

Git Shallow Clone 后再添加一个分支

云端 CI 任务一般只会拉一个提交下来,如果想要访问仓库其他分支光是 fetch 不够,需要先让 git 知道该分支。

git remote set-branches --add origin [remote-branch]
git fetch origin [remote-branch]:[local-branch]

PNPM Patch 忽略某些文件

之前在 Publish Obsidian Vault 中用到 pnpm patch 对依赖源代码做修改。但注意到本地运行修改后的源代码项目会在项目目录中产生临时文件,如果不加处理直接运行 pnpm commit-patch,这些内容会包含到 patch 文件中。

好在看 源码,PNPM 是执行 git diff 指令创建 patch 文件的,虽然添加了 GIT_CONFIG_NOSYSTEM,但 .gitignore 还是可用的。

Taskfile.yml
tasks:
  prepare-patch:
    desc: 准备对 Quartz 源代码的补丁
    cmds:
      - pnpm patch @jackyzha0/quartz
      # 避免运行时产生的临时文件被包含到 patch 中
      - echo ".quartz_cache" >> node_modules/.pnpm_patches/@jackyzha0/quartz/.gitignore

2025-10-23 但注意,在 patch hexo-highlight-shiki 时发现,似乎 commit-patch 只会包含打包结果中有效的文件。如果 package.json 中有 files 属性,就只有这些文件以及 package.json / README.md 等文件的 diff 会被记录,意味着随便在根目录新建个文件,默认就是不会被包含的。这个方法只在 files 属性不存在时有效。
如果一个文件已经在 git index 中,想要忽略不记录它的 diff,目前没找到办法

Windows Docker Desktop 传递文件变更事件

目前 Docker Desktop on Windows 是不支持主机上的文件变更 inotifiy 事件传递给容器的,在 Docker for Windows: Watch Bindings 早有记录并且给了个解决方法:主机上监听变更并在容器里产生事件。

不过仓库许久没更新,不支持 WSL2 的文件路径格式,好在已经有 fix: parsing multiple filepath formats by biplobmanna · 拉取请求 #24 · merofeev/docker-windows-volume-watcher PR 了。

直接用 uv tool install git+https://github.com/biplobmanna/docker-windows-volume-watcher@multi-format-host-filepath 就行

另外还有个文件,产生的事件中 dest_path 为空字符串会报错 no path specified。

FileModifiedEvent(src_path='D:\\content.md', dest_path='', event_type='modified', is_directory=False, is_synthetic=False)
Exception in thread Thread-1:
Traceback (most recent call last):
...
  File "docker_volume_watcher\container_notifier.py", line 88, in __change_handler
    relative_host_path = relpath(host_path, self.host_dir).replace('\\', '/')
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen ntpath>", line 787, in relpath
ValueError: no path specified

还得要改一行,我直接创建个 fork https://github.com/enihsyou/docker-windows-volume-watcher.git

docker_volume_watcher/container_notifier.py
    def __change_handler(self, event):
        host_path = event.dest_path if hasattr(event, 'dest_path') else event.src_path
        host_path = event.dest_path if getattr(event, 'dest_path', '') else event.src_path
        relative_host_path = relpath(host_path, self.host_dir).replace('\\', '/')

就能用 uv tool install https://github.com/enihsyou/docker-windows-volume-watcher.git 安装了