ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

`mise generate task-stubs`:为 mise 任务生成可直接执行的 stub 脚本

`mise generate task-stubs`:为 mise 任务生成可直接执行的 stub 脚本 mise generate task-stubs为 mise 任务生成可直接执行的 stub 脚本【免费下载链接】misedev tools, env vars, task runner项目地址: https://gitcode.com/GitHub_Trending/mi/misemise generate task-stubs是 misedev tools、env vars、task runner提供的一条生成类命令它的作用是在项目目录默认bin/下为每个任务生成一层薄薄的 stub 脚本让团队成员、CI 乃至尚未安装 mise 的贡献者都能以./bin/task的方式直接运行项目任务。阅读本文后你将掌握该命令的全部参数--dir、--mise-bin、--windows-launcher、stub 的生成原理、Windows 下.cmd/.exe启动器的差异以及重新生成时保证不覆盖用户自有文件的校验机制并能将其与mise generate install-script组合成一套完整的项目任务分发方案。命令概览让任务脱离mise run也能被调用在 docs/cli/generate/task-stubs.md 中该命令被定义为用法mise generate task-stubs [FLAGS]副作用修改文件系统状态生成 stub 文件其核心行为是默认在./bin/task路径下构建每个任务的 stub 脚本。生成出的 stub 是一层极薄的包装内部真正执行的是mise run task $因此任务本身依然由 mise 的任务运行器调度享受任务配置、工具链环境与参数处理等完整能力而调用者只需像运行普通命令一样敲./bin/test即可。mise 将其定位为与mise generate install-script配合使用install-script 负责生成一个下载并执行 mise的安装脚本task-stubs 负责生成任务的调用入口两者结合可以让项目贡献者不安装 mise 也能运行项目任务。对应源码位于 src/cli/generate/task_stubs.rs模块注释中明确写出了这一设计意图。mise tasks add test -- echo running tests mise generate task-stubs ./bin/test # running tests生成的 stub 长什么样从源码实现 src/cli/generate/task_stubs.rs 可以看出一个标准的 POSIX stub 内容为#!/bin/sh # generated by mise task-stubs exec mise run test $这里有几个值得注意的实现细节脚本以# generated by mise task-stubs作为归属标记ownership marker后续重新生成时mise 依靠这行标记判断该文件是否为自己生成、是否可以安全覆盖见 is_generated_task_stub 的逐行解析逻辑。mise_bin默认mise会经过shell_words::quote处理确保包含空格或特殊字符的路径在 shell 中安全展开。任务名使用不带扩展名的 display name如deploy.sh文件任务生成的是bin/deploy而非bin/deploy.sh。exec关键字让 stub 进程直接替换为 mise 进程$原样透传所有调用参数。生成后立即通过file::make_executable赋予可执行权限并打印Wrote to 路径见 run()。源码中还保留了一个旧版 stub 形态generate_legacy不含# generated by mise task-stubs标记行用于识别和迁移旧版本 mise 生成的、没有归属标记的旧 stub——这是重生成时能安全替换历史文件的关键兼容措施。参数详解-d --dir DIRstub 输出目录默认值bin作用指定 stub 生成的目录。例如--dir bin会在bin/下生成--dir tools则在tools/下生成。嵌套任务的 stub 会按任务名层级放入对应子目录见下文嵌套任务一节。-m --mise-bin MISE_BINstub 内部调用的 mise 可执行文件默认值mise作用控制 stub 脚本中exec MISE_BIN run task $的二进制路径。典型用法--mise-bin./bin/mise配合mise generate install-script生成的本地 mise——这样贡献者在没有系统级 mise 的情况下stub 会调用项目自带的./bin/mise。Windows 注意事项Windows 上路径会按原样运行因此./bin/mise这样的路径必须在它旁边配一个 Windows 启动器才能执行需要用mise generate install-script --write ./bin/mise --windows生成。而默认值mise是一个裸名字由 cmd 通过 PATH 解析无需任何额外文件。该参数在 src/cli/generate/task_stubs.rs 中定义。值得注意的是stub 生成方还内置了一个防呆警告warn_if_windows_cannot_run见 src/cli/generate/task_stubs.rs如果--mise-bin指向一个路径、且该路径旁没有 Windows 可直接执行的.cmd/.bat/.exe启动器会在所有平台上发出警告——因为.cmd启动器在任何平台上都会生成stub 是要提交进仓库的Windows 上运行的人不一定是生成它的人而生成者恰恰最可能看不到 Windows 侧的失败。判断逻辑windows_can_run完全遵循 Windows 的规则裸名字视为可执行经 PATH PATHEXT 解析、路径则以扩展名和旁侧文件大小写不敏感匹配为准见 src/cli/generate/task_stubs.rs。--windows-launcher WINDOWS_LAUNCHERWindows 启动器形态可选值cmd、exe默认值cmd作用决定在每个 stub 旁边额外生成的 Windows 启动器形式。之所以需要它是因为 Windows 无法直接执行#!/bin/sh的 stub 脚本因此无论在哪台主机上生成都会为每个 stub 附写一个启动文件stub 与启动器都要提交进仓库见 run() 中的注释说明。两种形态的取舍如下形态生成文件优点代价cmd默认task.cmd任何平台都能生成文件小cmd.exe 在%*展开前会整行重新解析因此从 PowerShell 调用时包含 ^ \| %VAR%等字符的参数无法原样到达任务exetask.exe原生可执行文件从每个 shell 接收的参数都不变是 Windows 构建版自带的 mise-shim.exe 的字节拷贝只能在 Windows 上生成每个任务在通常要提交的目录里多出约 220KB选择exe时实现会通过find_mise_shim_bin见 src/shims.rs在真实 mise.exe 旁或 PATH 中查找mise-shim.exe若找不到例如在 Linux 上生成命令会直接报错而不是悄悄回退到.cmd——因为 stub 是要提交的悄悄写入与请求不同的文件等于把错误塞进别人的提交见 Launchers::resolve。--windows-launcher的定义见 src/cli/generate/task_stubs.rs。-h --help查看帮助打印命令帮助信息与 mise 其他子命令一致。Windows 启动器的底层实现参数恢复协议cmd形态的启动器并不是简单的mise run task %*。源码 windows_launcher_body 展示了一套完整的参数恢复协议值得深入了解问题根源cmd.exe 在批处理文件运行前就会解析整条命令行。从 PowerShell 调用.cmd时PowerShell 不知道目标是批处理文件会把参数不加引号地传给cmd /c于是 ^ | 等字符在%*展开前就丢失了%VAR%也会被提前展开。源码注释记录了一个实测数据同样的 17 种参数形态经mise run转发有 9 种到达结果不同。恢复手段cmd 虽然破坏了参数但原始文本仍保留在CMDCMDLINE伪变量中。启动器将其复制到真实变量使用!CMDCMDLINE!延迟展开因为%CMDCMDLINE%会在特殊字符解析前被替换、在第一个处截断再交给 mise——mise 会用原生程序的运行时规则重新切分参数。参数走环境变量而非命令行传递避免 cmd 获得第二次解析机会。守卫分支当 cmd 并非为这个启动器而启动如交互式提示符、被其他批处理call时参数已经由 shell 正确切分直接走%*回退分支且不能执行exit否则会关闭调用者的 shell当确实由本启动器启动时用exit而非exit /b阻止 cmd 继续执行同一行之后排队的内容避免把后续命令的失败误报为任务的退出码。归属标记启动器第二行固定写入rem generated by mise常量WINDOWS_LAUNCHER_MARKER见 src/cli/generate/mod.rs重新生成时据此识别这是 mise 写的绝不覆盖手写的同名.cmd。无条件加引号嵌入启动器命令行的--mise-bin路径和任务名都会经过cmd_quote见 src/cli/generate/mod.rs——%被写成%%、整体加双引号。加引号是无条件的带引号的裸名字依然能通过 PATH 解析没有任何代价而一条规则永远比判断 cmd 元字符集合更容易保持正确。exe形态则没有这些烦恼原生可执行文件直接接收 argv参数天然无损。这正是--windows-launcherexe存在的原因。e2e 测试 e2e/generate/test_generate_task_stubs 中对启动器的每一处关键特征都有断言mise run xxx __MISE_LAUNCHER_ARGS__ %*、rem generated by mise、!CMDCMDLINE!、goto mise_launcher_fallback与exit !ERRORLEVEL!并明确拒绝%CMDCMDLINE%这种旧写法。嵌套任务父 stub 与_default当父任务与嵌套任务同时存在时父任务的 stub 会被写到parent/_default。例如任务work:containers父与work:containers:pg、work:containers:redis子会生成bin/work/containers/_default # 父任务 work:containers 的 stub bin/work/containers/pg # 子任务 bin/work/containers/redis # 子任务路径解析逻辑在resolve_stub_paths见 src/cli/generate/task_stubs.rs若某个 stub 路径是另一个 stub 路径的前缀父路径父路径就拼接_default若多个任务映射到同一路径则直接报错multiple tasks map to task stub path path。单元测试resolves_parent_and_nested_task_paths见 src/cli/generate/task_stubs.rs精确固定了这一行为e2e 测试中bin/work/containers/_default、bin/work/containers/pg.cmd、bin/work/containers/_default.cmd的存在性也验证了启动器会一并落入嵌套目录。对于同名任务 stub 的迁移源码同样周到文件任务以文件名为名旧版生成bin/build.sh现在改为以任务名命名bin/build。重新生成时若旧路径存在且内容确为 mise 生成的 stub会连同其启动器一起迁移到新路径若旧路径上是别人的文件则整个运行报错中止绝不越权删除见 validate_stub_paths。重新生成的安全性只动自己的东西mise generate task-stubs可以反复执行且刻意设计成可重复、可迁移、不误伤stub 归属校验目标路径若是符号链接、非普通文件、或内容并非 mise 生成的 stub运行直接失败cannot write task stub because ...避免覆盖用户自有脚本。启动器归属校验bin/task.cmd是项目可能已经在用的常见命名因此校验要求该文件必须携带rem generated by mise标记.exe因无法内置标记则通过与 mise-shim.exe 逐字节比较确认归属先比大小、再比内容见 file_contents_eq。无法读取或无法证明归属的文件一律保留原样错误方向永远偏向保守。形态切换清理由于 Windows 解析.exe优先于.cmd同一 stub 的两种启动器是互斥的。一次运行写出新形态启动器的同时会删除自己生成的另一种形态避免切换--windows-launcher后仍运行着刚被替换掉的旧启动器见 remove_owned_launcher若旧.exe无法证明是 mise 写的如在非 Windows 主机上重新生成会发出warn_if_shadowed警告提示手工处理。目录回退当嵌套任务被删除、只剩父任务时重新生成会把已生成的bin/work/containers/目录其中只有 mise 生成的 stub 与启动器整体折叠回单个bin/work/containers叶子 stub目录里若混有用户文件则拒绝折叠并报错见 validate_generated_stub_tree。这些保护在 e2e 测试 e2e/generate/test_generate_task_stubs 中有大量直接证据blocked-bin/work is not a directory、xxx is a symbolic link、xxx.cmd is not a generated launcher、legacy-bin/legacy/user-script is not a generated task stub等失败断言全部确认mise 只替换自己生成的文件绝不触碰用户资产。完整工作流让贡献者不装 mise 也能跑任务将 task-stubs 与 install-script 组合可以构建一套对贡献者零依赖的任务执行方案# 1. 定义一个任务 mise tasks add test -- echo running tests # 2. 生成项目自带的 mise 安装脚本提交进仓库 mise generate install-script --write ./bin/mise # 3. 为 Windows 贡献者生成 mise 的启动器 mise generate install-script --write ./bin/mise --windows # 4. 让 stub 调用项目自带的 mise mise generate task-stubs --mise-bin./bin/mise # 5. 贡献者无需安装 mise直接运行任务 ./bin/test # running tests其中第 2、3 步的详细参数说明见 install-script 文档。需要注意如果省略第 3 步Windows 上的bin/task.cmd会因为找不到可执行的./bin/mise而失败此时生成命令会在所有平台上发出no Windows launcher beside it警告提醒补上--windows。相关文档Tasks 任务总览任务的 TOML 配置、文件任务、运行方式与运行时的环境变量。mise generate 子命令族install-script、config、devcontainer、git-pre-commit、github-action、task-docs、tool-stub等同族命令。全局标志与参数语法mise 所有子命令共用的全局标志--verbose、--debug等。核心实现src/cli/generate/task_stubs.rs、src/cli/generate/mod.rs启动器协议、src/shims.rsfind_mise_shim_bin。端到端验证e2e/generate/test_generate_task_stubs。【免费下载链接】misedev tools, env vars, task runner项目地址: https://gitcode.com/GitHub_Trending/mi/mise创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表