附录:外部 Repository 配置
通过三份 1.0.0 TOML 约定声明、锁定、物化、绑定并在本地覆盖外部 Repository。
适用人群: 开发者、集成方与发布工程师
外部 Repository 配置#
1.0.0 把作者意图、确切解析结果和本地开发覆盖项,拆成三个 TOML 文件:
| 文件 | 权威 |
|---|---|
ait-external.toml | 由 Repository 编写的直接声明。 |
ait-external.lock | 解析完成的完整依赖图,带确切的 Snapshot 锁定;由 AIT 生成。 |
ait-external.links.toml | 由 AIT 命令管理的本地路径覆盖项。 |
ait-external.toml#
每一条 [[external]] 指明一个直接的外部 Repository,以及它的内容物化到 哪里。
[[external]]
name = "shared-core"
repo_name = "shared-core"
repository_index = 23
remote = "origin"
line = "main"
snapshot = "SNP-0123456789AB"
materialize_to = ".ait-external/shared-core"
license = "Apache-2.0"
version = "1.2.0"
[external.bindings.rust]
kind = "cargo-path"
path = "rust/crates/shared-core"
package = "shared-core"
[external.bindings.python]
kind = "python-path"
path = "python"
package = "shared-core"
module = "shared_core"声明字段#
| 字段 | 类型与含义 |
|---|---|
name | 必填,非空的本地外部名。它用来标识这条声明和对应的 link 覆盖项。 |
repo_name | 必填,非空的源 Repository 名。 |
repository_index | 必填,无符号 32 位的 server Repository 索引。 |
remote | 必填,非空的已配置远程名,用来解析源。 |
line | 必填,非空的源 Line。 |
snapshot | 必填,非空且确切的源 Snapshot ID。这是锁定,不只是一个分支提示。 |
materialize_to | 必填,规范化的仓库相对目标路径。绝对路径和 .. 穿越会被拒绝。 |
license | 必填,非空的已声明许可证表达式或标签。 |
version | 可选,非空的、给人看的版本字符串。内容权威仍然是 Snapshot。 |
bindings | 可选映射,每种受支持的语言最多一条绑定。 |
直接名称必须无歧义。物化路径和绑定路径会按仓库相对路径校验,不能逃出 它们所属的根目录。
绑定字段#
| 表 | 必填字段 | 可选元数据 |
|---|---|---|
[external.bindings.rust] | kind = "cargo-path"、path | package |
[external.bindings.python] | kind = "python-path"、path | package、module |
[external.bindings.node] | kind = "file-package"、path | package |
[external.bindings.go] | kind = "replace-path"、path | module |
每个 path 都是相对于该外部 Repository 物化位置的。元数据只要写了就必须 非空。绑定校验还会检查相应的语言工具和依赖文件;光是 TOML 形状合法, 并不能证明这条包绑定真的能用。
ait-external.lock#
不要凭空造这个文件,也别随手手改。ait external update 会解析直接和 传递的外部依赖、规范化顺序、校验依赖图,并原子地写入 lock。
format = "ait.external.lock"
[[node]]
name = "shared-core"
repo_name = "shared-core"
repository_index = 23
remote = "origin"
line = "main"
snapshot = "SNP-0123456789AB"
parent_path = ""
materialize_to = ".ait-external/shared-core"
license = "Apache-2.0"
version = "1.2.0"
[[node.binding]]
language = "rust"
kind = "cargo-path"
path = "rust/crates/shared-core"
package = "shared-core"Lock 字段#
| 字段 | 约定 |
|---|---|
format | 确切字符串 ait.external.lock。 |
[[node]] | 零个或多个规范化的直接与传递依赖图节点。 |
node.name | 必填非空名称,与 parent_path 组合后唯一。 |
node.repo_name | 必填,非空的源 Repository 名。 |
node.repository_index | 必填,无符号 32 位的源 Repository 索引。 |
node.remote | 必填,非空的远程名。 |
node.line | 必填,非空的源 Line。 |
node.snapshot | 必填,非空且确切的 Snapshot ID。 |
node.parent_path | 直接根节点为空;否则是规范化的相对祖先路径。 |
node.materialize_to | 必填,规范化的相对目标路径。 |
node.license | 必填,非空的许可证标签。 |
node.version | 可选的版本字符串。 |
[[node.binding]] | 零个或多个规范化的绑定摘要。 |
node.binding.language | rust、python、node 或 go。 |
node.binding.kind | 该语言允许的确切 kind。 |
node.binding.path | 规范化的相对路径。 |
node.binding.package | 可选,非空的包名。 |
node.binding.module | 可选,非空的模块名。 |
lock 会拿 ait-external.toml 来比对,查出缺失的、多余的和字段漂移的 直接根节点。干净的 lock 必须和清单一起提交,这样每个 worktree 和远程 构建看到的才是同一张依赖图。
ait-external.links.toml#
本地 link 让开发者可以临时把某个具名外部从一个已有目录物化出来,而不是 用它锁定的 Snapshot。
[[link]]
name = "shared-core"
path = "../shared-core"每一条只有 name 和 path 这两个操作值。name 指向一条外部声明;path 必须能解析到一个已存在的目录。用拥有它的那两条命令:
ait external link shared-core ../shared-core
ait external unlink shared-core最后一条 link 被移除时,AIT 会把这个文件删掉。本地 link 属于开发者覆盖 项,在锁定的或可发布的物化过程中会被拒绝。它们从不修改已声明的 Snapshot 或生成的 lock。
更新与验证流程#
ait external update
ait external status
ait external doctor
ait diff ait-external.toml ait-external.lock像评审一次依赖升级那样评审 lock 的改动:在记录最终的 Snapshot 之前,先 核对 Repository 索引、Line、Snapshot、物化目标、许可证和绑定漂移。