关于 justfile
用于生成符合 just 惯例的 justfile 的 Skill,可根据项目语言和现有构建命令调整配方,并强调统一验证命令,同时更新 Agent 指南和 CI。
主要功能
- 01检测项目生态和构建文件
- 02为 just 命令运行器生成配方
- 03设置 build 和 CI 验证门禁
- 04更新 Agent 指南与 CI 命令
- 05支持多生态模块
适用场景
- 01将部分 Makefile 目标迁移为配方
- 02设置统一的本地验证命令
- 03让 CI 验证与 justfile 保持一致
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ paulnsorensen/ skillz-that-grillz --skill justfile安装后在 Claude Code 中输入/justfile确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/agent-build.mdcomposition.mdgo.mdmanual.mdpython.mdrtk.mdruby.mdrust.mdtypescript.md详细介绍
justfile
为任何项目生成符合惯例的 justfile。用简洁、易于发现的命令运行器替代 Makefile 和临时编写的 shell 脚本。
为什么选择 just,而不是 Make
- 不需要
.PHONY变通方案——所有配方都是命令,而不是文件目标 - 不会遇到制表符缩进问题——任何空白字符都可以
- 原生支持参数、dotenv 加载、操作系统检测和模块
just --list可通过文档注释即时展示可用命令- Shebang 配方可让你直接内联编写 Python/Ruby/Node 代码
若要了解官方的功能设计理由——最常用的功能、让 justfile 真正物有所值的特殊用例,以及带深层链接的章节索引——请参阅
references/manual.md,其中的内容以
Just Programmer's Manual 为依据。
默认做法:一个规范命令
此技能生成的每个 justfile 都会提供一个 Agent 在每次更改后运行的单一命令——just build——以及对应的不执行自动修复的 CI 命令 just ci。build 是默认配方。两者都会运行完整的检查流程(格式化/代码检查 → 类型检查 → 测试 → 覆盖率),并精简输出:每个通过的步骤显示 ✓ <step>,只有失败时才输出完整工具信息和文件:行号。
这是每个生成的 justfile 的默认设置,而不是可选项——除非用户明确要求不同的布局。相关理由(统一命令、确定的通过/失败结果,以及仅显示精简的错误输出有助于 Agent 更快达成一致,并附有引用)以及完整的配方模板、_gate 辅助配方,还有必须更新的 AGENTS.md / CI,都位于 references/agent-build.md。编写任何 justfile 之前,请先阅读该文件。
build = 检查流程(启用自动修复)。ci = 检查流程(禁用自动修复)。用于编译或打包产物的配方名为 dist(或 release)——绝不能命名为 build,因为该名称专用于检查流程。
流程
1. 检测项目
扫描项目根目录,查找生态系统标记:
| 文件 | 生态系统 | 参考资料 |
|---|---|---|
Cargo.toml | Rust | references/rust.md |
pyproject.toml、setup.py、uv.lock | Python | references/python.md |
package.json | TypeScript/JS | references/typescript.md |
go.mod | Go | references/go.md |
Gemfile | Ruby | references/ruby.md |
阅读相关参考文件,了解语言专属配方。
如果存在多个标记(例如,Rust 后端 + TypeScript 前端),请组合使用相应模式。对于真正的单体仓库,请使用模块(mod frontend、mod backend)——根目录的 build 检查流程会汇总各模块的检查流程,因此 just build 仍表示“验证所有内容”。关于完整的模块/导入组合模式(以及何时选择 import 而不是 mod),请参阅 references/composition.md。
多生态系统命名: 当项目使用多种语言(例如,使用 Rust + TypeScript 的 Tauri)时,请使用生态系统后缀,区分职责重叠的配方:
test-rust、test-ts(不要使用通用的test,以免无法看出运行的内容)fmt-rust、fmt-ts(分别使用各生态系统的格式化工具)lint-rust(clippy)、lint-ts(eslint/biome)- 聚合配方将它们组合起来:
test: test-rust test-ts、fmt: fmt-rust fmt-ts - 跨越两个生态系统的共享配方使用简洁名称:
dev、build、clean
2. 检查现有构建文件
查找 Makefile、Taskfile.yml、Rakefile、package.json 中的脚本,或 scripts/、bin/ 目录中的 shell 脚本。如果找到:
- 迁移:将现有目标转换为 just 配方(参见下方的迁移表)
- 保留:保留 just 无法替代的复杂逻辑(例如,Make 对实际构建产物的文件目标依赖跟踪)
- 删除:只有在与用户确认后,才删除旧文件
3. 编写 justfile
将 justfile 放在项目根目录。遵循以下约定:
结构顺序:
- 设置项(
set dotenv-load、set shell) - 变量(版本、二进制名称等)
- 默认配方 —
default: build(规范的质量门)。只有在用户明确要求不设默认质量门时,才使用@just --list - 质量门:
build(自动修复)+ci(不自动修复)+_gate辅助项 — 参见references/agent-build.md - 质量门组合调用的细粒度配方:test、lint、fmt、typecheck、coverage
- 按用途划分的其他配方:run/dev、dist/release、docs
- 实用配方(clean 等)
- 私有辅助项(
_前缀或[private])
配方命名:
- 使用 kebab-case:
test-coverage、build-release - 使用动词:
build、test、lint、deploy(不要用builder、tests) - 对较大的文件使用前缀分组:
db-migrate、db-seed、db-reset - 默认配方应是最常用的操作或
--list
文档注释:
每个公共配方的上一行都要有注释 — 这是 just --list 显示的内容:
# Run the full test suite
test *args:
cargo test {{args}}
参数:
- 为可选参数设置默认值:
test filter="" - 对透传参数使用可变参数:
run *args - 谨慎使用
+args(至少需要 1 个参数) - 对于易用的 CLI 标志(
just build --target x86_64),使用[arg()]属性(v1.46+ — 参见下文“配方参数标志”)
别名: 对开发者每天会输入多次的配方添加单字母别名。在配方下一行定义,这样 just --list 会优先显示规范名称:
# Run tests
test *args:
cargo test {{args}}
alias t := test
不要为每个配方都创建别名 — 只为常用操作路径创建。
始终包含的设置项:
set dotenv-load
set shell := ["bash", "-euo", "pipefail", "-c"]
-euo pipefail 会让 shell 配方在遇到任何错误、未设置的变量或断开的管道时立即失败 — 与编写良好的 bash 脚本采用相同的严格策略。如果某个配方需要更宽松的行为,请在单条命令前使用 - 前缀来忽略错误,而不要使用较弱的 shell 标志。对于 Windows 目标或没有 bash 依赖的项目,跳过 set shell 行 — 默认的 /bin/sh 足以应付大多数配方。
常见功能已不再需要 set unstable:模块(自 just 1.31 起稳定)、[script] 属性(1.44)和 [arg()] 标志(1.46)在当前版本的 just 中都可用。只有在需要支持早于相关功能稳定版本的 just 时,才添加 set unstable。
dotenv 加固: 缺少 .env 时,set dotenv-load 会静默无操作。如果项目确实需要 .env(数据库 URL、API 密钥),则应让缺失情况明确报错 — 尽早失败,而不是使用空变量继续运行:
set dotenv-load
set dotenv-required # error if no dotenv file is found
# Pick ONE of the following (omit both to load ./.env):
set dotenv-path := ".env.local" # explicit path (relative to justfile), OR…
# set dotenv-filename := ".env.dev" # …a filename to search for up the tree
dotenv-required 会将缺少环境文件转为硬错误,而不是静默无操作 — 这符合“尽早且明确地失败”的策略。使用 dotenv-path 指定一个确切文件,或使用 dotenv-filename 更改 just 在目录树中查找的文件名。参见
设置 § dotenv。
工具依赖 — require()
如果配方依赖的工具不是标准系统命令,请在 justfile 顶部声明,以便缺少该工具时 just --evaluate 能立即失败:
# https://github.com/jqlang/jq
jq := require("jq")
# https://github.com/casey/just (yes, just itself)
just := require("just")
使用 {{ jq }} 通过已解析的路径调用,或直接正常调用 jq — require() 已在求值时确认该工具存在,因此两种形式都可用。URL 注释也可作为安装提示。对于 git、curl 或语言工具链等常见工具,请跳过 require() — 只声明新机器上可能缺少的工具。
4. 经过 Token 优化的输出(默认启用,无需选择启用)
build 和 ci 会通过 references/agent-build.md 中的 _gate 助手运行。该助手已精简输出:每个通过的步骤仅显示 ✓ <step>,只有失败时才显示完整工具输出(含 file:line)。覆盖率检查在 gate 中运行——成功时会省略其表格,未达到阈值时则会完整显示。(这取代了旧的“跳过覆盖率检查以节省 Token”建议:保留 gate 中的覆盖率检查;让精简处理 Token 成本,而不是省略检查。)
对于 gate 组合的细粒度配方,仍请遵循以下做法:
-
@前缀 + 工具标志。 隐去配方回显;向 npm 传入--silent --no-audit --no-fund,以省去横幅、审计和资金相关噪声。 -
升级到 rtk。 如果项目已安装 rtk,请将
_gate中的step调用替换为rtk test/rtk err,在成功时保持安静的基础上,获得逐工具的智能过滤。shell 封装模式以及 npm 脚本命名方面的注意事项,请参见references/rtk.md。rtk 是升级选项,绝非必需——bashstep助手是可移植的基础方案。
5. 更新项目文档(必须)
生成 recipes 只是工作的一半——如果没有任何内容告诉 Agent 使用它,统一命令的价值就无从体现。创建 justfile 后,务必完成以下两项更新。完整片段见 references/agent-build.md。
Agent 上下文文件(AGENTS.md、CLAUDE.md、GEMINI.md、.cursor/rules,或所用框架中的其他文件;如果不存在,则创建 AGENTS.md)——添加或替换构建部分,告知 Agent 务必运行这条命令,并将失败视为必须停止的信号:
## Build & verification
This project has ONE canonical verification command. ALWAYS run it after
changing code, and treat a non-zero exit as a hard stop.
- `just build` — autofix, then lint, typecheck, test, and coverage. Run after
every change.
- `just ci` — the same gate with no autofixes; exactly what CI runs.
Output is compacted: `✓ <step>` on success, full output (file:line) only on
failure. Don't invent ad-hoc test/lint commands — run `just build`.
CI 工作流——将现有验证步骤指向 just ci,使本地和 CI 运行完全相同的检查。此技能不会设计流水线;它只会重定向验证步骤(例如,用单个 run: just ci 替换单独的 lint/test/coverage 步骤)。参见 references/agent-build.md 中的 Actions 片段。
README.md——添加「开发」或「入门」部分:
## Development
### Prerequisites
- [just](https://github.com/casey/just) — `brew install just` / `cargo install just`
### Quick Start
```bash
just install # Install dependencies
just test # Run tests
just # See all available commands
Don't duplicate the full recipe list — `just --list` is self-documenting.
## Makefile Migration Table
| Makefile | justfile |
|----------|----------|
| `.PHONY: target` | (not needed) |
| `$(VAR)` | `{{var}}` |
| `$(shell cmd)` | `` `cmd` `` |
| `-include .env` | `set dotenv-load` |
| `ifeq ($(OS),Darwin)` | `if os() == "macos" { ... }` |
| `ifndef VAR` / `$(or ...)` | `env_var_or_default("VAR", "default")` |
| `make -C subdir` | `mod subdir` |
| `$(MAKE) target` | `just target` |
| `.DEFAULT_GOAL := help` | First recipe is default |
| `@cmd` (suppress echo) | `@cmd` (same) |
| Tab indentation | Any whitespace |
| `%:` pattern rules | Not applicable — just has no file targets |
## Key Syntax Reference
**Variables:**
```just
VERSION := "1.0.0"
GIT_HASH := `git rev-parse --short HEAD`
DB_URL := env_var_or_default("DATABASE_URL", "postgres://localhost/dev")
OPEN := if os() == "macos" { "open" } else { "xdg-open" }
Recipe 属性:
[confirm("Deploy to production?")]
deploy: build test
[macos]
open-docs:
open target/doc/index.html
[linux]
open-docs:
xdg-open target/doc/index.html
[private]
_setup:
mkdir -p tmp/
# Group recipes in `just --list` output
[group("checks")]
lint:
cargo clippy
[group("checks")]
fmt:
cargo fmt
# Multiple attributes — same line (comma-separated) or stacked
[group("dev"), no-cd]
status:
git status
**Recipe 参数标志(v1.46+):**使用 [arg()] 将参数设为 CLI 选项,而不是位置参数。最适合由用户在提示符下运行的 recipes:
[arg("target", long, help="Build target architecture")]
[arg("release", long, value="true", help="Build in release mode")]
build target release="false":
cargo build --target {{target}} {{ if release == "true" { "--release" } else { "" } }}
用法:just build --target x86_64 --release。运行 just --usage build 查看生成的帮助信息。
**脚本块([script]):**比 shebang recipes 更简洁;当脚本主体包含不希望逐行重新求值的 shell 控制流时,优先使用此方式(自 just 1.44 起稳定可用——无需 set unstable):
[script("bash")]
deploy env:
set -e
case {{env}} in
prod) URL="https://prod.example.com" ;;
stage) URL="https://stage.example.com" ;;
*) echo "unknown env: {{env}}"; exit 1 ;;
esac
curl -X POST "$URL/deploy"
[script("python3")]
analyze:
import json
print(json.load(open("results.json"))["total"])
为实现跨平台可移植性,并确保整个主体作为一个代码块运行,优先使用 [script()],而非 #!/usr/bin/env shebang。
**内置颜色常量:**可全局使用,无需定义——RED、GREEN、YELLOW、BLUE、CYAN、MAGENTA,以及用于重置的 BOLD、UNDERLINE 和 NORMAL。适用于多步骤 recipes 中的状态输出:
@check:
cargo check
echo -e '{{ GREEN }}✓ check passed{{ NORMAL }}'
@fail-loudly:
echo -e '{{ BOLD + RED }}deploy aborted{{ NORMAL }}'
不要在每个 recipe 中都穿插颜色——仅在概括汇总步骤的状态行中使用。
**监听/开发循环:**just 没有内置的监听标志——手册中的做法是让 watchexec 在受监听的文件发生变化时重新运行 recipe:watchexec just <recipe>。这是与检查关卡相对应的内部开发循环。可将常用做法封装在 dev recipe 中,并声明依赖项:
# https://github.com/watchexec/watchexec
watchexec := require("watchexec")
# Re-run the fast checks on every save (Ctrl-C to stop).
dev:
watchexec just test
watchexec just test 是日常内部开发循环;规范的 build 检查关卡仍用于每次更改后的验证。参见文件变更时重新运行 recipes。
**模块(单体仓库):**完整模式见
references/composition.md——将各模块的检查关卡汇总到根目录的 build,以及 mod 与 import 的区别。
mod api # looks for api/justfile or api.just
mod web
mod? local # optional — no error if missing
# Usage: just api::test, just web::build
Shebang recipes(多行脚本,无需 set unstable):
analyze:
#!/usr/bin/env python3
import json
data = json.load(open("results.json"))
print(f"Total: {len(data)}")
just 版本 ≥ 1.44 时,优先使用 [script("python3")],而非 shebang(该功能稳定,无需 set unstable)——它会将主体作为一个代码块运行,并避免 shebang 的可移植性问题。
反模式
- 不要重新创建 Make 的文件目标系统——just 是命令运行器,不是构建系统
- 除非有充分理由,否则不要使用
set positional-arguments——{{arg}}更清晰 - 不要将密钥放入 justfiles——请使用 dotenv 或环境变量
- 不要编写 200 行的 justfiles——使用模块(
mod)按关注点拆分 - 不要逐条复制 CI 流水线步骤——将它们合并到
build/ci检查关卡中 - 不要将产物/编译 recipe 命名为
build——该名称用于检查关卡;请使用dist或release
你不应做的事
- 不要从头设计 CI 流水线或 GitHub Actions 工作流——但要将现有 CI 验证步骤重定向到
just ci(参见第 5 步) - 不要创建 Dockerfile 或容器配置
- 不要替换实际的构建系统(cargo、webpack、go build)——just 只是对它们进行封装
- 未经用户确认,不要移除现有 Makefile
注意事项
just二进制文件可能不在 PATH 中——生成配方前,使用which just检查- 为确保 shebang 配方在不同系统上都能移植,必须显式指定
#!/usr/bin/env dotenv-load会将所有环境变量暴露给所有配方——对于包含大量密钥的项目,应避免使用- 模块路径相对于 justfile 所在位置,而非工作目录
set positional-arguments会改变配方中$1的工作方式——使用时应说明require("tool")会在求值时进行验证——使用{{ jq }}通过解析出的路径调用,或直接调用jq;require确认工具存在后,两种方式都可用[script()]自 just 1.44 起稳定,模块自 1.31 起稳定,[arg()]自 1.46 起稳定——当前版本的 just 均无需设置set unstable。只有在使用较旧版本的 just 时才添加set unstable;如果依赖这些功能,请在 README 中注明相关的最低版本