关于 justfile
justfile 是用于创建、检查和迁移项目 Justfile 的技能,面向使用 just 管理项目命令的开发者。它以统一规范、工作流、模板和结构检查指导 Justfile 编写。
主要功能
- 01引导创建与迁移 Justfile
- 02统一命名和格式规范
- 03提供模板与语法参考
- 04结构检查指导
- 05配方设计与模块组织
适用场景
- 01为项目创建 Justfile
- 02将 Makefile 转换为 just
- 03检查并 lint 现有 Justfile
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ julianobarbosa/ claude-code-skills --skill justfile安装后在 Claude Code 中输入/justfile确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
Templates.mdReferences/MakeMigration.mdPatterns.mdSyntax.mdTools/lint.tsWorkflows/CheckJustfile.mdCreateJustfile.mdMigrateFromMake.md详细介绍
Justfile 技能
just 是一个命令运行器(而非构建系统),可以将项目专属命令保存在名为 Justfile 的文件中并运行这些命令。它采用受 make 启发的语法,但更简单、更具可移植性,不存在 make 的种种特性怪癖(.PHONY、对制表符敏感、隐式规则、时间戳跟踪)。
此技能推行统一的风格规范,让各个项目中的 Justfile 都保持一致。以下规则是权威规范;Tools/lint.ts 会验证其中可确定的规则。
工作流路由
| 触发语 | 工作流 |
|---|---|
| “create a justfile”、“set up just”、“add a recipe/module” | Workflows/CreateJustfile.md |
| “migrate Makefile to just”、“convert make to just” | Workflows/MigrateFromMake.md |
| “check/lint this justfile”、“is this justfile correct” | Workflows/CheckJustfile.md |
何时使用 Just,而非 Make
| 场景 | 工具 |
|---|---|
| 项目任务自动化(构建、测试、部署、lint) | just |
| 跨平台命令运行器 | just |
实际基于文件的构建依赖(编译 .c → .o) | make |
| 已经深度使用 make 的旧项目 | make(或进行迁移) |
常见错误——不要这样做
模型经常会错误生成以下模式。请对照此列表检查输出。
| 错误 | 正确 |
|---|---|
justfile(小写) | Justfile(J 大写) |
mod docker(未指定路径) | mod docker '.justfiles/docker.just' |
将模块放在 docker.just 或 just/docker.just | 将模块放在 .justfiles/docker.just |
default: | _default:(必须带下划线) |
@just --list | @just --list --unsorted(模块)或 --unsorted --list-submodules(根文件包含模块时) |
env("NAME", "val") | env_var_or_default("NAME", "val") |
| 模块文件没有三行文件头 | 每个文件都必须包含完整的文件头 |
模块文件没有自己的 _default 配方 | 每个文件都必须有自己的 _default |
按工具命名模块(psql.just) | 按关注点命名模块(db.just) |
因为测试在容器中运行,就把测试放在 docker.just 中 | 将测试放在 test.just 中——按用途分类,而非按实现方式分类 |
| 根配方重复模块逻辑 | 根快捷配方委托给模块:build: docker-build |
随意命名(run-tests、do-lint) | 使用标准名称:test、lint、build、dev、fmt、check |
在模块配方中使用相对路径(bash tests/run.sh) | 使用 source_directory() 获取绝对路径 |
强制规则 — 适用于创建或编辑的每个文件
- 根文件必须命名为
Justfile(首字母 J 大写)。 - 每个文件(根文件和每个
.just模块)都必须以以下三行标头开头:
适当时使用#!/usr/bin/env just --justfile set shell := ["bash", "-euo", "pipefail", "-c"] set dotenv-load := trueset dotenv-load := false,但必须始终包含这一行。 - 每个文件都必须将
_default作为第一个配方:
含有模块的根 Justfile 使用# List all available recipes _default: @just --list --unsorted@just --list --unsorted --list-submodules。模块文件使用@just --list --unsorted(不含--list-submodules)。 - 每个文件中的章节顺序:变量 → 模块导入 → 配方。
- 模块文件必须位于
.justfiles/<name>.just;绝不能放在just/中,也不能与根文件放在同一目录。 - 使用显式路径导入模块:
mod name '.justfiles/name.just';绝不能使用不带路径的mod name。 - 使用
env_var_or_default("NAME", "value")设置变量默认值;绝不能使用env()。 - 每个配方都必须在正上方一行添加
#文档注释。 - 参数化配方必须为每个参数添加说明:
# param - description (default: value)。 - 私有/辅助配方以
_开头。 - 依赖项写在定义行上:
build: _lint test。 - 具有破坏性的配方必须提示用户确认;文档注释需写明 "DESTRUCTIVE, prompts for confirmation"。
- 按领域关注点提取模块,并以关注点命名(
db.just),而不是以工具命名(psql.just)。根 Justfile 应是精简的协调器:包含_default、快捷配方,以及check/clean等项目级配方。 - 根文件应为常用工作流提供快捷配方,并委托给模块,让开发者可以通过扁平命名空间执行日常任务。
- 将下方的标准配方词汇用作公共 API。绝不能自行发明
run-tests、do-lint、compile、format。 - 模块中绝不能使用不带前缀的相对路径——模块配方以模块目录作为 CWD 运行。定义
root := source_directory() / "..",并以{{root}}/tests/run.sh的形式引用文件。
标准配方词汇
开发者应能在任何项目中直接运行 just test、just dev 或 just check,而无需猜测配方名称。使用以下确切名称;仅包含适用的配方。
| 配方 | 用途 | 适用条件 |
|---|---|---|
dev | 启动开发环境(服务器、监视、REPL) | 项目有开发循环 |
test | 运行测试套件 | 始终包含 |
build | 构建或编译 | 项目有构建步骤 |
lint | 运行代码检查工具 | 已配置代码检查工具 |
fmt | 格式化代码 | 已配置格式化工具 |
check | 运行所有质量门禁(check: lint test) | 始终包含 |
clean | 移除构建产物、缓存和生成文件 | 项目会产生输出 |
check 是元配方——依赖适用的质量门禁,并酌情添加格式检查(cargo fmt --check、ruff format --check)。
按关注点命名空间
按领域分组,而不是按工具。根据用途分类:在 Docker 中运行的测试属于测试配方(test.just),而不是 Docker 配方。使用 kubectl 的迁移属于数据库配方(db.just)。
| 关注点 | 模块 | 常见配方 |
|---|---|---|
| 开发 | dev.just | build、test、lint、fmt、bench |
| 测试 | test.just | run、list、watch、coverage |
| 容器 | docker.just | build、push、run、compose-up |
| CI/CD | ci.just | lint、deploy、release |
| 数据库 | db.just | migrate、seed、reset、dump、restore |
| 基础设施 | infra.just | plan、apply、destroy |
| Kubernetes | k8s.just | apply、diff、rollback、logs |
| 文档 | docs.just | build、serve、publish |
单一关注点项目(例如仅包含 build/test/lint/fmt 的 Go/Rust 项目)使用一个 dev.just;根文件仍应保持精简。模块必须自包含:拥有自己的变量和 _default,且不依赖其他模块的配方。
模板与参考
- 模板(根目录 + 模块,复制并调整):
Templates.md - just 语言参考(变量、参数、依赖、条件、属性、函数、安装):
References/Syntax.md - 按项目类型整理的配方片段(Terraform、Go、Python、Docker、Azure、Ansible):
References/Patterns.md - Makefile → just 迁移指南:
References/MakeMigration.md
代码检查
创建或编辑任何 Justfile 或 .just 模块后,都要运行结构检查,并修复所有失败项:
bun Tools/lint.ts <project-dir>
该检查会检查文件命名、三行头部、作为首个配方的 _default、--unsorted/--list-submodules 标志、env_var_or_default() 的用法、所有配方的文档注释、显式模块导入路径,以及各区段的顺序。任何 FAIL 都是缺陷——请修复并重新运行,直到检查通过。该检查无法判断是否按关注点命名、是否自包含或是否使用标准词汇——请通过检查确认这些内容(参见 Workflows/CheckJustfile.md)。
注意事项
- 默认情况下,每行配方都会在单独的 shell 中运行——一行运行
cd foo,下一行运行ls,后者会在原始目录中执行。多行脚本请使用 shebang 配方。 set dotenv-load会从 justfile 所在目录加载.env,而非调用目录——在子目录中运行just时,会加载父目录的.env。使用set dotenv-path覆盖。- 反引号变量会在解析时求值,且每次调用都会执行——
git_hash := \git rev-parse HEAD`会在每次调用just` 时运行 git,即使配方无关。大型代码仓库中会比较慢;如果不需要全局使用,请将其移入配方。 - 配方参数不会自动添加 shell 引号——
just deploy "my server"会传入两个参数。使用set positional-arguments和"$@",或包装为{{quote(target)}}。 set shell := ["bash", "-c"]会破坏set -euo pipefail的语义,因为每行都会作为单独的-c调用——pipefail只对该行生效。需要正确实现失败即停止的脚本时,请使用 shebang 配方。just --list会隐藏以_开头和标记为[private]的配方,但仍可调用——这只是隐藏,不是访问控制。- 跨平台的
[macos]/[linux]属性会在其他操作系统上静默跳过配方——如果只有[linux]/[macos]变体,在 Windows 上运行just install会以状态码 0 退出且不报错,看起来就像成功了一样。 - 该检查验证的是结构,而非行为——配方可能通过所有检查,却仍然运行错误的命令。运行
just --dry-run <recipe>验证展开结果。