关于 aif-build-automation
aif-build-automation 是面向各类项目的构建自动化技能,可从零生成或改进现有构建文件。它支持 Makefile、Taskfile.yml、Justfile 和 Magefile.go,并会结合项目技术栈与约定配置目标。
主要功能
- 01生成四种构建文件
- 02分析并补充现有目标
- 03识别项目语言与框架
- 04遵循项目专属规则
适用场景
- 01为没有构建文件的项目创建自动化配置
- 02为现有构建文件补充缺失目标
- 03按项目技术栈设置构建和检查命令
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lee-to/ ai-factory --skill aif-build-automation安装后在 Claude Code 中输入/aif-build-automation确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/BEST-PRACTICES.mdDOC-INTEGRATION.mdSUMMARY-FORMAT.mdtemplates/justfile-gojustfile-gradlejustfile-mavenjustfile-nodejustfile-phpjustfile-pythonjustfile-rubyjustfile-rustmagefile-basic.gomagefile-full.gomakefile-go.mkmakefile-gradle.mkmakefile-maven.mkmakefile-node.mkmakefile-php.mkmakefile-python.mkmakefile-ruby.mkmakefile-rust.mktaskfile-go.ymltaskfile-gradle.ymltaskfile-maven.ymltaskfile-node.ymltaskfile-php.ymltaskfile-python.ymltaskfile-ruby.ymltaskfile-rust.yml详细介绍
构建自动化生成器
为任何项目生成或增强构建自动化文件。支持 Makefile、Taskfile.yml、Justfile 和 Magefile.go。
两种模式:
- 生成 — 不存在构建文件 → 使用最佳实践模板从头创建
- 增强 — 已存在构建文件 → 分析缺失项,添加缺少的目标,修复反模式,并保留现有内容
步骤 0:加载项目上下文
如果有项目描述,请阅读:
Read .ai-factory/DESCRIPTION.md
保存项目上下文(技术栈、框架、架构),供后续步骤使用。如果文件不存在也没关系——我们会在步骤 2 中检测所有信息。
阅读 .ai-factory/skill-context/aif-build-automation/SKILL.md——如果文件存在,则必须阅读。
此文件包含 /aif-evolve 根据补丁、
代码库约定和技术栈分析积累的项目特定规则。这些规则针对当前项目量身定制。
如何应用 skill-context 规则:
- 将它们视为本技能通用指令的项目级覆盖规则
- 当 skill-context 规则与此 SKILL.md 中的通用规则冲突时, 以 skill-context 规则为准(更具体的上下文优先——遵循嵌套 CLAUDE.md 文件的相同原则)
- 如果没有冲突,则同时应用:SKILL.md 中的通用规则和 skill-context 中的项目规则
- 即使 skill-context 规则似乎与此技能的默认规则矛盾,也不得忽略它们—— 它们的存在是因为项目经验证明默认规则不足
- 重要:skill-context 规则适用于此技能的所有输出,包括生成的 构建文件(Makefile、Taskfile、justfile、magefile)。此技能中的模板只是基础结构。 如果 skill-context 规则要求“构建文件必须包含目标 X”或“必须遵循约定 Y”, 则必须遵守。生成违反 skill-context 规则的构建自动化属于错误。
**执行要求:**生成任何输出产物后,都要根据所有 skill-context 规则进行验证。 如果违反任何规则,请在向用户展示前修正输出。
步骤 1:检测现有构建文件并确定模式
1.1 扫描现有构建文件
在执行其他操作之前,检查项目是否已有构建自动化:
Glob: Makefile, makefile, GNUmakefile, Taskfile.yml, Taskfile.yaml, taskfile.yml, justfile, Justfile, .justfile, magefile.go, magefiles/*.go
根据结果建立 EXISTING_FILES 列表。
1.2 确定模式
模式 A——增强现有文件(如果 EXISTING_FILES 不为空):
- 设置
MODE = "enhance" - 根据检测到的文件自动设置
TARGET_TOOL(Makefile →makefile、Taskfile.yml →taskfile等) - 如果存在多个构建文件,且
$ARGUMENTS指定了其中一个,则使用该参数选择要增强的文件 - 如果存在多个构建文件,且没有提供参数,则询问要增强哪一个:
AskUserQuestion: This project has multiple build files. Which one should I improve?
Options (dynamic, based on what exists):
1. Makefile — Enhance the existing Makefile
2. Taskfile.yml — Enhance the existing Taskfile
...
- 阅读现有文件内容——这是增强操作的基准
- 保存为
EXISTING_CONTENT
模式 B——生成新文件(如果 EXISTING_FILES 为空):
- 设置
MODE = "generate" - 解析
$ARGUMENTS以确定工具:
| 参数 | 工具 | 输出文件 |
|---|---|---|
makefile 或 make | GNU Make | Makefile |
taskfile 或 task | Taskfile | Taskfile.yml |
justfile 或 just | Just | justfile |
mage 或 magefile | Mage | magefile.go |
- 如果
$ARGUMENTS为空或不匹配,请与用户交互并询问:
AskUserQuestion: Which build automation tool do you want to generate?
Options:
1. Makefile — GNU Make (universal, no install needed)
2. Taskfile.yml — Task runner (YAML, modern, cross-platform)
3. justfile — Just command runner (simple, fast, ergonomic)
4. magefile.go — Mage (Go-native, type-safe, no shell scripts)
将所选工具保存为 TARGET_TOOL。
步骤 2:分析项目
使用 Glob 和 Grep 扫描仓库,以检测项目概况。所有技术栈都使用相同流程:主要语言 → 包管理器/构建入口 → 框架 → Docker → CI → 迁移 → 测试 → 代码检查工具 → 单体仓库,然后生成 Summary 对象。JVM 项目在这些步骤中处理(而不是使用单独的流程)。
2.1 主要语言
检查以下文件(按下表顺序,以第一个匹配项为准)。对于 Java / Kotlin (JVM),根据构建文件推断语言:默认使用 Java,除非 Kotlin 插件 / kotlin("jvm") / 占主导的 .kt 布局表明应使用 Kotlin。
| 文件 / 信号 | 语言 |
|---|---|
go.mod | Go |
package.json | Node.js / JavaScript / TypeScript |
pyproject.toml 或 setup.py 或 setup.cfg | Python |
Cargo.toml | Rust |
composer.json | PHP |
Gemfile | Ruby |
| JVM:Gradle 根目录文件或包装器(见 §2.2) | Java / Kotlin (JVM) |
JVM:pom.xml | Java / Kotlin (JVM) |
*.csproj 或 *.sln | C# / .NET |
2.2 包管理器与构建入口
锁定文件和包装器(与 package-lock.json → npm 的思路相同):
| 文件 | 包管理器 / 工具 |
|---|---|
bun.lockb | bun |
pnpm-lock.yaml | pnpm |
yarn.lock | yarn |
package-lock.json | npm |
poetry.lock | poetry |
uv.lock | uv |
Pipfile.lock | pipenv |
gradle/wrapper/gradle-wrapper.properties | ./gradlew |
.mvn/wrapper/maven-wrapper.properties | ./mvnw |
Java / Kotlin (JVM) — Gradle 与 Maven:通过一批检查检测 Gradle(对以下路径执行单次 Glob,或并行检查文件是否存在 — 避免冗余的顺序遍历):
settings.gradle、settings.gradle.kts、build.gradle、build.gradle.kts(仓库根目录)、gradle/wrapper/gradle-wrapper.properties
如果匹配到任何 Gradle 信号 → 表示使用 Gradle。pom.xml 表示使用 Maven。根据此表设置 PROJECT_PROFILE.java_build.build_tool:
| 条件 | build_tool | 说明 |
|---|---|---|
| 存在 Gradle 信号 | gradle | 将目标关联到下方的 Gradle 命令。 |
没有 Gradle,存在 pom.xml | maven | 将目标关联到下方的 Maven 命令。 |
同时存在 Gradle 和 pom.xml | gradle | 设置 java_build.mixed_maven_gradle: true,并向 PROJECT_PROFILE.warnings 添加一条警告(两种构建方式均存在;配方采用 Gradle — 由用户确认权威构建方式)。 |
**具体 JVM 入口:**根据包装器是否存在,将检测到的入口保存到 PROJECT_PROFILE.build_entrypoint:
- 如果
build_tool为gradle:若存在gradlew或gradle/wrapper/gradle-wrapper.properties,则使用./gradlew;否则回退到gradle。 - 如果
build_tool为maven:若存在mvnw或.mvn/wrapper/maven-wrapper.properties,则使用./mvnw;否则回退到mvn。
唯一事实来源:上述判断条件与 JVM 模板在 shell 中实现的规则相同(ENTRYPOINT / entrypoint — 检查 ./gradlew 或 gradle/wrapper/gradle-wrapper.properties;检查 ./mvnw 或 .mvn/wrapper/maven-wrapper.properties)。生成或增强构建文件时,将 PROJECT_PROFILE.build_entrypoint 设为这些检查所隐含的结果(./gradlew 与 gradle、./mvnw 与 mvn 二选一)。除非用户覆盖该设置(例如 Makefile 中的 ENTRYPOINT=…),否则不要输出与该判断条件不同的入口字符串。模板会在配方运行时重新解析,因此克隆后无需编辑即可保持正确。
**版本目录:**如果存在 gradle/libs.versions.toml,则设置 java_build.has_version_catalog,并在适当时通过注释说明 PROJECT_PROFILE.build_entrypoint / 目录的用法。
要关联到 JVM 的 Makefile / Taskfile / Just 中的命令(与其他技术栈中的 npm run build / pytest 作用相同;Windows 上使用 gradlew.bat):
| 目标 | Gradle | Maven |
|---|---|---|
| 完整编译 + 检查 | <build_entrypoint> build | <build_entrypoint> verify |
| 单元测试 / 集成测试 | <build_entrypoint> test | <build_entrypoint> test |
| 验证(测试 + 已配置的静态分析) | <build_entrypoint> check | <build_entrypoint> verify |
| 仅打包 | <build_entrypoint> assemble(或 jar / bootJar) | <build_entrypoint> package |
| 开发服务器 — Spring Boot(参见 §2.3) | <build_entrypoint> bootRun | <build_entrypoint> spring-boot:run |
| 开发服务器 — Quarkus | <build_entrypoint> quarkusDev | <build_entrypoint> quarkus:dev |
| 开发服务器 — Micronaut | <build_entrypoint> run | <build_entrypoint> mn:run |
| 开发服务器 — Vert.x | <build_entrypoint> vertxRun | <build_entrypoint> vertx:run |
| Spring Boot — 可运行 JAR | <build_entrypoint> bootJar | <build_entrypoint> package(spring-boot repackage) |
| 清理 | <build_entrypoint> clean | <build_entrypoint> clean |
| 多模块 | <build_entrypoint> :subproject:build | <build_entrypoint> -pl module -am package |
dev 目标(模板 + 生成文件): 根据与 §2.3 相同的信号,按固定优先级(第一个匹配项优先)解析框架开发任务/目标:Quarkus → Micronaut → Vert.x → Spring Boot。扫描 Gradle: build.gradle、build.gradle.kts、settings.gradle、settings.gradle.kts、gradle/libs.versions.toml,并使用与 §2.3 相同的 grep -E 模式(quarkus / io.quarkus;micronaut / io.micronaut;Vert.x Gradle 插件 — vertx-plugin 或 io.vertx.vertx;Spring Boot — 回退项)。扫描 Maven: 仅扫描 pom.xml;Vert.x Maven — vertx-maven-plugin 或 io.reactiverse。如果仓库根目录是聚合器,且检测未命中,请覆盖模板的开发任务变量(与 JVM_MODULE 的用法相同)。
模板: JVM Makefile/Taskfile/Just 提供一个固定目录:lint → Gradle check / Maven verify;fmt → spotlessApply / spotless:apply;lint-checkstyle、lint-spotbugs、lint-pmd、lint-spotless(Taskfile lint:*);db-migrate-liquibase、db-migrate-flyway(Taskfile db:migrate:*)。多模块:通过 JVM_MODULE 使用 module-*。第 5 步会移除仓库未接入的目录条目(参见 JVM 模板规则)。
2.3 框架检测
对于 Node.js 项目,检查 package.json 中的依赖:
next→ Next.jsnuxt→ Nuxt@remix-run/node→ Remixexpress→ Expressfastify→ Fastifyhono→ Hono@nestjs/core→ NestJS
对于 Python 项目,检查 pyproject.toml 或导入项:
fastapi→ FastAPIdjango→ Djangoflask→ Flask
对于 PHP 项目,检查 composer.json 中的 require:
laravel/framework→ Laravelsymfony/framework-bundle→ Symfonyslim/slim→ Slimcakephp/cakephp→ CakePHP
对于 Go 项目,检查 go.mod:
gin-gonic/gin→ Ginlabstack/echo→ Echogofiber/fiber→ Fibergo-chi/chi→ Chi
对于 Rust 项目,读取 Cargo.toml(workspace 成员以及 [dependencies] / [workspace.dependencies]):
axum→ Axumactix-web→ Actix Webrocket→ Rocketwarp→ Warp
对于 Ruby 项目,读取 Gemfile:
rails→ Ruby on Railssinatra→ Sinatrahanami→ Hanamiroda→ Roda
对于 Java / JVM 项目,读取 pom.xml、build.gradle* 和 gradle/libs.versions.toml(如存在)中的依赖和插件——检查深度与 Node 项目的 package.json 相同:
spring-boot、spring-boot-starter、spring-boot-parent→ Spring Bootgrpc、protobuf、spring-grpc或仓库中的*.proto→ gRPC / protobufquarkus、io.quarkus→ Quarkusmicronaut→ Micronautvertx/ Vert.x 栈 → Vert.x- 依赖中包含
liquibase或存在db.changelog*→ Liquibase(参见 §2.6) pom.xml、build.gradle*或gradle/libs.versions.toml中的 Flywayorg.flywaydb/flyway-core/flyway-maven-plugin/ Flyway Gradle 插件 → Flyway(参见 §2.6)- Java 9+ / Spring Boot 3+ 优先使用 Jakarta(
jakarta.*);如果两者都出现,则标记旧版javax.*迁移
将发现结果映射到 framework / java_build 标志(spring_boot、grpc、liquibase、flyway),类似其他生态系统将 Express 与 NestJS 区分开来。
2.4 Docker(深度扫描)
Glob: Dockerfile, Dockerfile.*, docker-compose.yml, docker-compose.yaml, compose.yml, compose.yaml, .dockerignore
如果存在任何此类文件,则设置 HAS_DOCKER=true 并进行深入分析:
读取 Dockerfile 以检测:
- 多阶段构建(分开的
dev/prod阶段)→DOCKER_MULTISTAGE=true - 暴露的端口 →
DOCKER_PORTS(例如,3000、8080) - 基础镜像 →
DOCKER_BASE(例如,node:20-alpine、golang:1.22) - Entrypoint/CMD → 了解应用在容器内的启动方式
读取 docker-compose / compose 文件以检测:
- 服务名称 →
DOCKER_SERVICES(例如,app、db、redis、worker) - 卷挂载 → 了解开发与生产环境的设置
- Profiles(如有)→
dev、production、test - 依赖服务(postgres、redis、rabbitmq 等)→
DOCKER_DEPS
存储为 DOCKER_PROFILE:
has_compose:布尔值has_multistage:布尔值services:服务名称列表deps:基础设施服务列表(数据库、缓存、队列)ports:暴露的端口has_dev_stage:布尔值(Dockerfile 是否包含dev或development阶段)
2.5 CI/CD
Glob: .github/workflows/*.yml, .gitlab-ci.yml, .circleci/config.yml, Jenkinsfile, .travis.yml
注明使用的 CI 系统。
2.6 数据库与迁移
搜索迁移工具:
Grep: prisma|drizzle|knex|typeorm|sequelize|alembic|django.*migrate|goose|migrate|atlas|sqlx|liquibase|flyway
检查是否存在:
prisma/schema.prisma→ Prismadrizzle.config.ts→ Drizzlealembic/目录 → Alembicmigrations/目录 → 通用迁移- Liquibase —
db.changelog*、Gradle/Maven 中的liquibase或资源文件 → Liquibase(JVM 及其他);设置java_build.liquibase: true - Flyway —
pom.xml、build.gradle*或gradle/libs.versions.toml中的依赖或插件(org.flywaydb、flyway-core、flyway-maven-plugin、Flyway Gradle 插件);设置java_build.flyway: true
2.7 测试框架
| 语言 | 检查内容 |
|---|---|
| Node.js | package.json 中的 jest、vitest、mocha、ava |
| Python | pyproject.toml/requirements 中的 pytest,以及 unittest 导入 |
| Go | Go 内置测试;检查 go.mod 中的 testify |
| Rust | 内置测试;检查集成测试目录 tests/ |
| Ruby | Gemfile 中的 rspec → RSpec;minitest / minitest- gems → Minitest;否则,当 Rakefile 存在时,默认为 rake test |
| Java / Kotlin(JVM) | Gradle/Maven / libs.versions.toml 中的 junit-jupiter、junit-jupiter-api、JUnitPlatform、JUnit5、testcontainers、mockito、rest-assured、cucumber |
2.8 Linter 和格式化工具
扫描格式化工具和 linter 的配置(EditorConfig、JVM 上的 Checkstyle、ESLint/Prettier/Biome、Python 工具、PHP、Go、Rust、Ruby):
Glob: .eslintrc*, eslint.config.*, .prettierrc*, biome.json, biome.jsonc, .golangci.yml, .golangci.yaml
Glob: checkstyle.xml, .checkstyle.xml, config/checkstyle/checkstyle.xml, .editorconfig
Glob: ruff.toml, .ruff.toml, .flake8, phpcs.xml, phpcs.xml.dist
Glob: rustfmt.toml, .rustfmt.toml, clippy.toml, .rubocop.yml, .rubocop_todo.yml, .standard.yml
Grep in pyproject.toml: ruff|black|flake8|pylint|isort
Grep in build.gradle*, pom.xml: spotless|spotbugs|pmd|errorprone|checkstyle (when not covered by config files alone)
将匹配到的 JVM 工具合并到 PROJECT_PROFILE.linters 中,使用规范化的 ID(例如 checkstyle、spotless、spotbugs、pmd、errorprone),以便在配置 lint / fmt 目标时使用(步骤 5)。
2.9 Monorepo 检测
Glob: turbo.json, nx.json, lerna.json, pnpm-workspace.yaml
摘要
构建一个 PROJECT_PROFILE 对象,包含:
language:主要语言package_manager:检测到的包管理器(npm、pnpm、Gradle、Maven 等)build_entrypoint:检测到的准确入口命令(例如./gradlew、mvn、npm、cargo)framework:检测到的框架(如果有);JVM 框架在此处的映射方式与 NestJS 或 Django 相同warnings:可选的字符串数组(例如 §2.2 中的 Maven+Gradle 混用)java_build:可选项——当语言为 JVM 时:{ build_tool: "gradle"|"maven", mixed_maven_gradle?: boolean, has_version_catalog: boolean, spring_boot: boolean, grpc: boolean, liquibase: boolean, flyway: boolean }has_docker:布尔值docker_profile:DOCKER_PROFILE对象(如果has_docker)ci_system:检测到的 CI(如果有)has_migrations:布尔值 + 工具名称test_framework:检测到的测试运行器linters:检测到的 linter 列表is_monorepo:布尔值has_dev_server:布尔值(带有开发服务器的框架)
步骤 3:阅读最佳实践
阅读所选工具的最佳实践参考:
Read skills/aif-build-automation/references/BEST-PRACTICES.md
重点阅读与 TARGET_TOOL 对应的部分:
- Makefile → 第 1 节
- Taskfile → 第 2 节
- Justfile → 第 3 节
- Magefile → 第 4 节
另请阅读“跨领域注意事项”部分,了解标准目标。
步骤 4:选择并读取模板
根据 language + TARGET_TOOL 选择最匹配的模板:
| 工具 | Go | Node.js | Python | PHP | Rust | Ruby | Java / JVM | 其他 |
|---|---|---|---|---|---|---|---|---|
| Makefile | makefile-go.mk | makefile-node.mk | makefile-python.mk | makefile-php.mk | makefile-rust.mk | makefile-ruby.mk | makefile-gradle.mk 或 makefile-maven.mk | 使用最接近的模板 |
| Taskfile | taskfile-go.yml | taskfile-node.yml | taskfile-python.yml | taskfile-php.yml | taskfile-rust.yml | taskfile-ruby.yml | taskfile-gradle.yml 或 taskfile-maven.yml | 使用最接近的模板 |
| Justfile | justfile-go | justfile-node | justfile-python | justfile-php | justfile-rust | justfile-ruby | justfile-gradle 或 justfile-maven | 使用最接近的模板 |
| Magefile | magefile-basic.go | magefile-full.go | magefile-full.go | 不适用(使用 Makefile) | 不适用(使用 Makefile) | 不适用(使用 Makefile) | 不适用(使用 Makefile) | 不适用(使用 Makefile) |
对于 Java / JVM,根据 PROJECT_PROFILE.java_build.build_tool 选择 Gradle 或 Maven 模板。
如果上表中的 language 不是 Go、Node.js、Python、PHP、Rust、Ruby 或 Java / JVM,则使用 Node.js 模板作为结构上的后备模板,并根据检测到的 build_entrypoint 和语言惯例进行调整(例如,dotnet build)。
对于 Magefile:如果 HAS_DOCKER 或 has_migrations 为 true,则使用 magefile-full.go,否则使用 magefile-basic.go。
对于 PHP、Rust、Ruby 或 Java/JVM + Magefile:Mage 是 Go 专用工具,通常不适用于这些技术栈。如果用户明确要求在此类项目中使用 mage,请说明这一点,并建议将 Makefile 作为最接近的替代方案(通用且无需安装)。通过 AskUserQuestion 询问是否改用 Makefile。
读取所选模板:
Read skills/aif-build-automation/templates/<selected-template>
步骤 5:生成或增强文件
模式 B — 生成新文件
以 PROJECT_PROFILE、最佳实践和模板为参考,从头生成自定义构建文件。
生成规则
- 以工具所需的前置内容开头(来自最佳实践)
- 包含所选模板中的所有标准目标(help/default、build、test、lint、clean、dev、fmt、
ci)。JVM:模板是完整目录;在模式 B 中,按步骤 5 的 JVM 规则精简目标(不要臆造一次性的lint配方)。 - 根据项目配置文件添加条件目标:
- Docker 目标 → 仅当
has_docker为 true 时添加 - 数据库目标 → 仅当
has_migrations为 true 时添加(非 JVM);**JVM:**仅当匹配的java_build标志为 true 时,才使用规范的db-migrate-liquibase/db-migrate-flyway(或 Taskfiledb:migrate:*)——省略另一个 - 部署目标 → 仅当检测到 CI/CD 时添加
- Generate 目标 → 仅当检测到代码生成时添加
- Typecheck 目标 → 仅当检测到 TypeScript 或 mypy 时添加
- Docker 目标 → 仅当
- 使用正确的包管理器——与
PROJECT_PROFILE(§2.2) 匹配:JVM →<build_entrypoint>(来自 §2.2);Node → npm/pnpm/yarn/bun;Python → uv/poetry/pip;Go →go;Rust →cargo;Ruby → Bundler(bundle、bundle exec);不要替换为错误的生态系统(例如,在仅使用 Gradle 的仓库中使用 npm 脚本) - 包含 CI 汇总目标——JVM 上默认
ci= clean + build(已运行check/verify);仅当精简后仍保留lint/fmt目标时,才将它们添加到ci - 遵循模板的结构进行组织和分组
- 调整变量名以匹配实际项目(模块名称、二进制文件名称、源目录);JVM 多模块仓库 → 为
module-*目标设置JVM_MODULE(§2.2) - 通过 git 检测版本/提交/构建时间
- 适配 Docker 的目标——如果
has_docker为 true,则生成专门的 Docker 部分(见下文) JVM 模板目录(固定名称;在模式 B 中删除未使用的工具)——权威来源为skills/aif-build-automation/templates/*gradle*和*maven*。生成的文件始终使用这些确切的 Gradle/Maven 任务名称,除非构建文件对同一插件使用了不同的官方任务名称(在配方旁的注释中说明)。
| 目标(Make/Just) | Taskfile 任务 | Gradle 命令 | Maven 命令 |
|---|---|---|---|
lint | lint | check | verify |
fmt | fmt | spotlessApply | spotless:apply |
lint-checkstyle | lint:checkstyle | checkstyleMain | checkstyle:check |
lint-spotbugs | lint:spotbugs | spotbugsMain | spotbugs:check |
lint-pmd | lint:pmd | pmdMain | pmd:check |
lint-spotless | lint:spotless | spotlessCheck | spotless:check |
db-migrate-liquibase | db:migrate:liquibase | liquibaseUpdate | liquibase:update |
db-migrate-flyway | db:migrate:flyway | flywayMigrate | flyway:migrate |
dev | dev | 参见 §2.2 开发任务 + 模板 DEV_GRADLE_TASK 解析器(§2.3 优先级) | 参见 §2.2 开发目标 + 模板 DEV_MAVEN_GOAL 解析器(§2.3 优先级) |
- 模式 B(生成):从模板复制目录,然后删除工具不存在的目标:例如,如果
checkstyle∉linters,则删除lint-checkstyle;如果缺少对应的 ID,则删除lint-spotbugs/lint-pmd;如果spotless∉linters,则删除fmt和lint-spotless;如果不是java_build.liquibase,则删除db-migrate-liquibase;如果不是java_build.flyway,则删除db-migrate-flyway。除非项目确实没有 Java 插件生命周期(罕见),否则始终保留lint(=check/verify)。绝不要用verify -DskipTests或check -x test替代lint。对于dev,模板会根据构建文件解析任务/目标;增强时,如果常量bootRun/spring-boot:run有误,应替换为PROJECT_PROFILE中正确的框架命令(与模板解析器使用相同的字符串)。 - **模式 A(增强):**优先补齐缺少的目录目标,而不是使用临时命名;删除与
java_build/linters相矛盾的配方。
Docker 感知型目标生成
当 has_docker 为 true 时,生成两层命令:
第 1 层——容器生命周期(检测到 Docker 时始终生成):
| 目标 | 用途 |
|---|---|
docker-build 或 docker:build | 构建 Docker 镜像 |
docker-run 或 docker:run | 运行容器 |
docker-stop 或 docker:stop | 停止运行中的容器 |
docker-logs 或 docker:logs | 持续输出容器日志 |
docker-push 或 docker:push | 将镜像推送到镜像仓库 |
docker-clean 或 docker:clean | 删除镜像和已停止的容器 |
第 2 层——开发与生产环境分离(检测到 compose 或多阶段构建时):
##@ Docker — Development
docker-dev: ## Start all services in dev mode (with hot reload, mounted volumes)
docker-dev-build: ## Rebuild dev containers
docker-dev-down: ## Stop dev environment and remove volumes
##@ Docker — Production
docker-prod-build: ## Build production image (optimized, multi-stage)
docker-prod-run: ## Run production container locally for testing
docker-prod-push: ## Push production image to registry
生成逻辑:
- 如果
has_compose→ 使用docker compose命令(不要使用docker-compose) - 如果 compose 配置包含 profiles → 使用
--profile dev/--profile production - 如果
has_multistage→ 开发构建使用--target dev,生产构建不指定目标(或使用--target production) - 如果存在
docker_profile.deps(db、redis 等)→ 添加infra-up/infra-down目标,以启动/停止应用之外的基础设施服务 - 如果检测到 compose →
docker-dev应使用正确的 profile/服务运行docker compose up - 如果没有 compose,但有 Dockerfile →
docker-dev应运行docker build --target dev,再使用卷挂载运行docker run
第 3 层——基于容器的命令(通过容器镜像宿主机命令):
当项目基于 Docker 时,还要生成容器执行变体,以便在 Docker 中运行所有内容的用户可以使用相同的目标:
# Run tests inside the container
docker-test: ## Run tests inside the Docker container
docker compose exec app [test command]
# Run linter inside the container
docker-lint: ## Run linter inside the Docker container
docker compose exec app [lint command]
# Open shell in the container
docker-shell: ## Open a shell inside the running container
docker compose exec app sh
只有当项目似乎以 Docker 为主(compose 文件将源代码挂载为卷,或未发现本地语言运行时设置)时,才生成 docker-* 执行变体。
根据项目配置文件进行自定义
- JVM(
java_build/ Gradle 或 Maven):每次调用工具时,都使用 §2.2 摘要中的PROJECT_PROFILE.build_entrypoint。质量和数据库:仅使用 JVM 模板目录(第 5 步表格)中的规范目标名称和任务名称;增强时,添加或移除配方以匹配java_build和linters,不要凭空猜测。 - 二进制名称:使用
go.mod、package.json或目录中的实际项目名称 - 源代码目录:使用实际的源代码目录(例如
src/、app/、cmd/) - 开发服务器命令:与框架匹配(例如
next dev、uvicorn --reload、air;JVM →build_entrypoint加上 §2.2 中针对检测到的技术栈的开发任务 — QuarkusquarkusDev/quarkus:dev、Micronautrun/mn:run、Vert.xvertxRun/vertx:run、Spring BootbootRun/spring-boot:run) - 测试命令:与检测到的测试运行器(§2.7)匹配
- Lint 命令(JVM):精简后,
lint必须保留为check/verify;每种工具对应的行使用第 5 步目录表格 - 迁移命令(JVM):根据
java_build使用db-migrate-liquibase与db-migrate-flyway(或 Taskfiledb:migrate:*) - 端口号:使用框架默认值(Node 为 3000,Python 为 8000,Go 为 8080)
模式 A — 增强现有文件
当 MODE = "enhance" 时,不要从头替换文件,而要分析文件并有针对性地改进。
5A.1 分析现有文件
将 EXISTING_CONTENT 与 PROJECT_PROFILE 及最佳实践进行比较,并进行差距分析:
缺少前置配置/配置项 — 检查文件是否包含建议的前置配置:
- Makefile:
SHELL := bash、.ONESHELL、.SHELLFLAGS、.DELETE_ON_ERROR、MAKEFLAGS - Taskfile:
version: '3'、output:、dotenv: - Justfile:
set shell、set dotenv-load、set export - Magefile:
//go:build mage、正确的导入
缺少标准目标 — 检查以下目标中缺少哪些:
help/default(自说明)build、test、lint、clean、dev、fmt和 JVM 目录中的目标(lint-checkstyle、db-migrate-flyway等),精简模板后ci(聚合目标)
缺少项目特定目标 — 根据 PROJECT_PROFILE,检查是否需要以下目标:
- Docker 目标(如果有
has_docker,但文件中没有 Docker 目标) - 数据库:与
java_build匹配的规范db-migrate-*/db:migrate:* - 类型检查目标(如果检测到 TypeScript/mypy,但没有类型检查目标)
- 代码生成目标(如果检测到代码生成工具)
- 覆盖率目标(如果存在测试目标,但没有覆盖率变体)
- JVM:当设置了
java_build时,build/test/check应委托给<build_entrypoint>(而不是仅使用通用 shell 或错误的生态系统) - JVM 多模块:当仓库是 Gradle 多项目或 Maven reactor,且按模块执行命令有用时,添加
module-build/module-test/module-check(或 Taskfilemodule:*)
质量问题 — 检查是否存在违反最佳实践的反模式:
- **JVM:**不在第 5 步目录表格中的配方(或配方使用了错误的工具,例如仅使用 Flyway 的仓库中却使用 Liquibase 任务)——替换为目录中的名称或删除
- 未提供描述/文档的目标
- 缺少
.PHONY声明(Makefile) - 应设为变量却硬编码的工具路径
- 缺少版本/提交检测
- 没有自说明的帮助目标
5A.2 规划更改
列出要进行的具体更改:
CHANGES = [
{ type: "add_preamble", detail: "Add .SHELLFLAGS and .DELETE_ON_ERROR" },
{ type: "add_target", name: "docker-build", detail: "Dockerfile detected but no docker target" },
{ type: "add_target", name: "help", detail: "No self-documenting help target" },
{ type: "fix_quality", detail: "Add ## comments to 3 targets missing descriptions" },
{ type: "add_variable", detail: "Add VERSION/COMMIT detection via git" },
...
]
5A.3 应用更改
- 保留现有结构——保留用户的排序、命名和风格
- 原样保留现有目标——除非是修复明确的错误或补充缺失的说明,否则不要修改可正常工作的目标
- 在适当的部分添加新目标——遵循现有的分组模式(如果文件使用
##@部分,则添加到对应部分;如果没有部分,则按逻辑顺序追加) - 在顶部、现有内容之前补充缺失的前导行
- 在现有变量声明附近补充缺失的变量
- 以模板为参考了解新目标的语法,但要调整以符合文件中已有的风格(例如,如果现有 Makefile 使用制表符和简单配方,就不要引入复杂的多行脚本)
质量检查(两种模式均适用)
写入文件之前,请确认:
- 所有目标均有说明或文档(## 注释、desc:、[doc()]、文档注释)
- 没有本应设为变量的硬编码路径
- 包管理器/构建入口点检测与仓库相符(Gradle/Maven 包装器、npm/pnpm 等)
- 包含自说明的帮助目标
- 为所有非文件目标声明
.PHONY(仅适用于 Makefile) - 危险操作带有确认提示(Justfile)或警告
第 6 步:写入文件并报告
6.1 写入文件
模式 B(生成新文件):
使用 Write 工具写入生成的内容:
| 工具 | 输出路径 |
|---|---|
| Makefile | Makefile |
| Taskfile | Taskfile.yml |
| Justfile | justfile |
| Magefile | magefile.go |
模式 A(增强现有文件):
将增强后的内容写入找到现有文件的同一路径(保留原始文件名的大小写和位置)。文件将原地更新——由于我们是在改进而非替换文件,因此无需询问是否覆盖。
6.2 显示摘要
使用 references/SUMMARY-FORMAT.md 中的格式显示摘要。对于模式 B(生成),显示目标表、使用的项目概况和快速启动命令;对于模式 A(增强),显示更改内容以及新增/现有目标。如果工具需要设置,请包含安装提示。
第 7 步:集成项目文档
写入构建文件后,将快速命令集成到项目文档中。
详细的集成流程(README、AGENTS.md、现有 Markdown)→ 阅读 references/DOC-INTEGRATION.md
简要说明:扫描现有命令部分,更新或添加快速参考;如果缺少 AGENTS.md,则建议创建。
工件归属和配置策略
- 主要归属:生成或增强的构建自动化文件(
Makefile、Taskfile.yml、justfile、magefile.go)。 - 允许的配套更新:在现有文档或
AGENTS.md中添加与生成的构建工作流直接相关的快速命令片段。 - 配置策略:本设计不依赖特定配置。此技能使用仓库检测和固定的 AI Factory 上下文文件,而非
config.yaml。