mcpField
J
justfile

justfile

github.com/paulnsorensen开发093 次安装3 周前更新
代码仓库

关于 justfile

justfile 是一项为项目生成惯用 justfile 的技能,帮助开发者将 Makefile 和零散 Shell 脚本整理为可发现的命令入口。它以统一的 build 验证门和配套文档更新为默认方案。

主要功能

  1. 01按项目生态生成 justfile
  2. 02将现有命令迁移为 recipes
  3. 03提供 build 与 ci 验证门
  4. 04更新 Agent 指引与 CI 配置
  5. 05支持多生态模块组合

适用场景

  1. 01为新项目建立统一验证命令
  2. 02将 Makefile 和脚本迁移到 just
  3. 03为多语言仓库汇总各生态检查

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/paulnsorensen/git-gouda --skill justfile

安装后在 Claude Code 中输入/justfile确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

evals/
evals.json
references/
agent-build.md
composition.md
go.md
manual.md
python.md
ruby.md
rust.md
typescript.md

详细介绍

justfile

为任何项目生成符合惯例的 justfile。用简洁、易于发现的命令运行器替代 Makefile 和临时编写的 shell 脚本。

为什么选择 just,而不是 Make

  • 无需 .PHONY 变通方法——所有配方都是命令,而不是文件目标
  • 没有制表符缩进问题——任何空白字符都可以
  • 一流支持参数、dotenv 加载、操作系统检测和模块
  • just --list 配合文档注释即可立即发现可用命令
  • Shebang 配方让你可以直接内联编写 Python/Ruby/Node 代码

如需了解官方的功能选择理由——最常用的功能、让 justfile 真正物有所值的特殊用例,以及带深层链接的章节索引——请参阅 references/manual.md,其内容基于 Just 程序员手册。

默认做法:一个规范命令

此技能生成的每个 justfile 都会提供一个 Agent 在每次更改后运行的唯一命令——just build——以及对应的、不执行自动修复的 CI 命令 just ci。build 是默认配方。两者都会运行完整的检查流程(格式化/ lint → 类型检查 → 测试 → 覆盖率),并精简输出:每个通过的步骤显示 ✓ <step>,只有失败时才显示完整工具输出和文件:行号。

这是每个生成的 justfile 的默认设置,并非可选项——除非用户明确要求采用其他布局。相关理由(Agent 使用统一命令、确定的通过/失败结果以及精简的错误专用输出后,能够更快达成一致;附有引用)和完整配方模板、_gate 辅助配方,以及必须进行的 AGENTS.md / CI 更新,都位于 references/agent-build.md 中。编写任何 justfile 前都要阅读该文件。

build = 检查流程(启用自动修复)。ci = 检查流程(禁用自动修复)。用于编译或打包构件的配方命名为 dist(或 release)——绝不能命名为 build,因为该名称专用于检查流程。

协议

1. 检测项目

扫描项目根目录,查找生态标记:

文件生态系统参考文档
Cargo.tomlRustreferences/rust.md
pyproject.toml、setup.py、uv.lockPythonreferences/python.md
package.jsonTypeScript/JSreferences/typescript.md
go.modGoreferences/go.md
GemfileRubyreferences/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 对实际构建构件进行的文件目标依赖跟踪)
  • 移除:只有在向用户确认后,才能删除旧文件

同时检查是否已有 justfile。如果存在,请向用户展示拟议更改的差异,并等待用户明确授权后再覆盖。

3. 编写 justfile

将 justfile 放在项目根目录中。遵循以下约定:

结构顺序:

  1. 设置项(set dotenv-load、set shell)
  2. 变量(版本、二进制文件名等)
  3. 默认配方 — default: build(标准门禁)。仅当用户明确不需要默认门禁时,才使用 @just --list
  4. 门禁:build(自动修复)+ ci(不自动修复)+ _gate 辅助配方 — 参见 references/agent-build.md
  5. 门禁组合使用的细分配方:test、lint、fmt、typecheck、coverage
  6. 按用途划分的其他配方:run/dev、dist/release、docs
  7. 实用配方(clean 等)
  8. 私有辅助配方(使用 _ 前缀或 [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 dist --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 在目录树中查找的文件名。参见 Settings § 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. 经令牌优化的输出(默认启用,无需选择)

build 和 ci 通过 references/agent-build.md 中的 _gate 辅助程序运行,该程序已进行精简:每个通过的步骤显示 ✓ <step>,只有失败时才显示完整工具输出(含文件:行号)。覆盖率检查在 gate 内运行——成功时会隐藏其表格,未达到阈值时则完整显示。(这取代了旧的“跳过覆盖率以节省令牌”建议:将覆盖率检查保留在 gate 中;由精简处理令牌成本,而不是省略检查。)

对于 gate 组合的细粒度配方,使用 @ 前缀以静默配方回显,并向 npm 传递 --silent --no-audit --no-fund,以去除横幅、审计和赞助信息。

5. 更新项目文档(必需)

生成配方只完成了一半——如果没有内容告知 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 运行相同的 gate。此技能不负责设计流水线;它只会重定向验证步骤(例如,将单独的 lint/test/coverage 步骤替换为单个 run: just ci)。请参阅 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" }

配方属性:

[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

配方参数标志(v1.46+): 使用 [arg()] 将参数作为 CLI 选项公开,而不是作为位置参数。最适合用户在提示符下运行的配方:

[arg("target", long, help="Build target architecture")]
[arg("release", long, value="true", help="Build in release mode")]
dist target release="false":
    cargo build --target {{target}} {{ if release == "true" { "--release" } else { "" } }}

用法:just dist --target x86_64 --release。运行 just --usage dist 查看生成的帮助信息。

脚本块([script]): 比 shebang 配方更简洁;如果脚本主体包含不希望逐行重新求值的 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。适用于多步骤配方中的状态输出:

@check:
    cargo check
    echo -e '{{ GREEN }}✓ check passed{{ NORMAL }}'

@fail-loudly:
    echo -e '{{ BOLD + RED }}deploy aborted{{ NORMAL }}'

不要在每个配方中随意添加颜色——仅在用于概述汇总步骤的状态行中使用颜色。

监视/开发循环: just 没有内置的监视标志——手册中的做法是让 watchexec 在监视的文件发生变化时重新运行配方:watchexec just <recipe>。这是与 gate 相对应的快速迭代循环。可将常见用例封装在 dev 配方中,并声明依赖项:

# 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 gate 则继续用于每次更改后的验证。请参阅文件变更时重新运行配方。

模块(单体仓库): 完整模式请参阅 references/composition.md——将各模块的 gate 汇总到一个根级 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 配方(多行脚本,无需 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 门禁中
  • 不要将产物/编译配方命名为 build——该名称用于门禁;请使用 dist 或 release

不要做的事

  • 不要从头设计 CI 流水线或 GitHub Actions 工作流——但要 将现有 CI 验证步骤重定向到 just ci(参见第 5 步)
  • 不要创建 Dockerfiles 或容器配置
  • 不要替换实际的构建系统(cargo、webpack、go build)——just 只是对它们进行封装
  • 未经用户确认,不要移除现有 Makefiles

注意事项

  • 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 中注明相应的最低版本

评论

支持 Markdown