# Scope
## 要解决的问题
monorepo 里有多个组件(CLI、web、studio),每个组件:
- 独立发版,不同版本号
- 各自有 Cargo.toml、CHANGELOG.md
- 可能用不同语言和构建工具
没有 scope 时,所有 tag 平铺在根命名空间下,分不清 `v0.1.0` 是哪个组件的,`release status` 也没法按组件展示。
## 核心逻辑
**Scope = 命名边界。** 它把一个名字(`cli`)绑定到一个目录(`src/cli`),所有操作都在这个边界内执行。
```
tag 命名空间
┌─────────────────────────┐
scope "cli" ───────┤ cli/v0.1.0 │
dir: src/cli │ cli/v0.2.0 │
├─────────────────────────┤
scope "web" ───────┤ web/v0.1.0 │
dir: src/web │ web/v0.2.0 │
├─────────────────────────┤
(root) ───────┤ v0.1.0 │
dir: . │ v0.2.0 │
└─────────────────────────┘
```
### 三件事
**1. tag 隔离** — tag 带 scope 前缀,不同 scope 的 tag 不会冲突
```
cli/v0.1.0 ← scope "cli" 的 tag
web/v0.1.0 ← scope "web" 的 tag,可以和 cli 同版本号
v0.1.0 ← root scope(无前缀)
```
**2. 目录绑定** — 所有文件操作定位到 scope 的目录
| 读版本号 | `src/cli/Cargo.toml` | `Cargo.toml` |
| 更新 CHANGELOG | `src/cli/CHANGELOG.md` | `CHANGELOG.md` |
| git tag | `cli/v0.2.0` | `v0.2.0` |
**3. 配置继承** — scope 有值覆盖全局,无值走默认
```
全局 stages.test.threshold = 70
↓
cli scope 声明 test_threshold: 90
↓
cli 的测试阈值 = 90(覆盖全局)
web 没有声明 → 70(走全局)
```
## 数据流
```
release publish -v cli/v0.2.0
│
▼
1. 从版本号提取 scope 名:"cli"
│
▼
2. 从 contract.scopes 查找 name="cli"
│
▼
3. 取 scope.dir → "src/cli" → 拼出 scope_dir
│
▼
4. 所有文件读写 → scope_dir 下
Cargo.toml → repo_root/src/cli/Cargo.toml
CHANGELOG → repo_root/src/cli/CHANGELOG.md
│
▼
5. tag 创建 → git tag cli/v0.2.0
```
## 路径匹配
`find_scope_by_path` 用于"当前目录属于哪个 scope"的判断(`plan status` 省略 scope 参数时):
```
scopes:
cli: dir: src/cli
root: dir: .
当前在 src/cli/sub/ → 匹配 cli(最长前缀)
当前在 src/web/ → 匹配 root(兜底)
```
匹配规则:按 `dir` 长度排序,最长的优先。
## 结构定义
```rust
pub struct Scope {
pub name: String, // scope 名称 → tag 前缀
pub dir: String, // 相对 repo 根的子目录 → 文件定位
pub language: Language, // 语言(声明的跳过文件检测)
pub framework: String, // 框架名,展示用
pub build_tool: BuildTool, // 构建工具(按 language 推断)
pub registry: Registry, // 制品库
pub release: StageRelease, // 覆盖全局 stages.release
pub test_threshold: Option<f64>, // 覆盖全局 stages.test.threshold
pub ci_workflow: Option<String>, // CI workflow 名
}
```
## YAML 示例
```yaml
scopes:
cli:
dir: src/cli
language: rust
build_tool: cargo
registry: crates
test_threshold: 90
release:
changelog: CHANGELOG.md
ci_workflow: build-cli
```