Skip to content

Commit 55e4b78

Browse files
inhereclaude
andcommitted
docs: 记录 D2.6 AppOptions 拆分, D2 收官
CHANGELOG 增破坏性变更条目(GlobalOpts 迁出每-App 字段, 新增 AppOptions); plan 记录 D2.6 方案与破坏面; TODO 勾选 D2 全部完成。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 7e52e9a commit 55e4b78

3 files changed

Lines changed: 27 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ and this project adheres to semantic-ish versioning.
1414
the other sub-packages (e.g. `gflag`). The old `events` package no longer
1515
exists; update your imports. The event-name constants themselves are unchanged
1616
(`OnAppInitAfter`, `OnCmdRunBefore`, ...).
17+
- **Per-app parse state moved out of `GlobalOpts` into a new `AppOptions` type.**
18+
The runtime fields `ShowHelp` / `ShowVersion` / `inCompletion` / `genCompletion`
19+
are no longer on `GlobalOpts`; each `App` (and standalone command) now owns its
20+
own `AppOptions`, so concurrent `App` instances no longer share these. `App.Opts()`
21+
still returns the process-level `*GlobalOpts` (so `app.Opts() == gcli.GOpts()` and
22+
`app.Opts().Verbose` are unchanged); use the new `App.AppOpts()` for the per-app
23+
state. Process-level config (`Verbose` / strict / `EnhanceShort` and the logger)
24+
stays in the package singleton, so log-level behavior is unaffected.
1725

1826
### Added
1927

docs/TODO.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@
5656
- [x] 泛型 API:`gflag.Opt[T]/BindVar[T]`,类型安全、可扩展,老 API 保留(commit 99ffdfa)
5757
- 对标:kong / go-arg / go-flags 原生支持 slice/map/enum/Duration(go-arg 连 Duration 都内置)
5858

59-
- [ ] **D2 共享选项(SharedOpts)继承模型**伤筋动骨、建议独立里程碑)— [plans/feat-D2-persistent-options.md](plans/feat-D2-persistent-options.md)
59+
- [x] **D2 共享选项(SharedOpts)继承模型**独立里程碑,已完成)— [plans/feat-D2-persistent-options.md](plans/feat-D2-persistent-options.md)
6060
- [x] 新增「共享选项」中间层:`Command.SharedOpts() *gflag.Flags` + `Parser.InheritOptsFrom`
6161
dispatch 时沿祖先链 merge 进叶子 flag set(与 args 重排契合);Required 延后到执行命令校验
6262
(commit 323219f/77f2391/bf4ef0c/87951f0)
63-
- [ ] 进程级单例 `gOpts` 改为 per-App 实例,解决多 App/并发共享(CHANGELOG v3.4.0 已记此坑)— 风险高,待评估
63+
- [x] 抽出 `AppOptions`:每-App 解析状态(help/version/completion)不再共享单例;全局配置仍走 gOpts(不复现 v3.4.0 verbose 坑)(commit 7e52e9a)
6464
- [x] 明确「全局(App) / 共享(命令子树) / 局部(命令)」三层语义 + 文档(README/CHANGELOG)+ 专项测试(commit a42019e)
6565
- [x] help 渲染:祖先继承选项归入 "Inherited Options" 分组;ShowHelp 补幂等合并(commit b704f29)
6666
- 对标:cobra 的 `PersistentFlags` / `LocalFlags` / `InheritedFlags` 三层模型

docs/plans/feat-D2-persistent-options.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# 功能实现计划:D2 共享选项继承模型(SharedOpts,≈ cobra PersistentFlags)
22

3-
> 状态:**D2.1 + D2.5 已完成**(提交拆分 1-5 + 复核修复);D2.6(gOpts per-App) 待评估
3+
> 状态:**全部完成**D2.1 + D2.5 + D2.6)。D2.6 采用「抽出 `AppOptions`」方案(见下)。
44
> 范围:`cmd.go`(共享选项存储/合并/分发)+ 新增 gflag 合并基元 + 可选的 `gcli.go`(gOpts per-App)。
55
> 依据:[../compare-with-others.zh-CN.md](../compare-with-others.zh-CN.md) 差距 5;[../TODO.md](../TODO.md) D2。
66
> 对标:cobra 的 `PersistentFlags` / `LocalFlags` / `InheritedFlags` 三层模型。
@@ -199,12 +199,26 @@ if !c.sharedMerged {
199199
4.`docs: 三层选项模型说明(README/CHANGELOG)`(commit a42019e)
200200
- ✅ 复核修复:共享 Required 改用类型感知 `CliOpt.IsEmpty()`(commit 87951f0)
201201
5.`feat(gcli): help 渲染继承选项分组(Inherited Options)`(commit b704f29)
202-
6. ⏳(可选/独立评估)`refactor(gcli): gOpts 改 per-App 实例 + 多 App 测试` — 风险最高,需先确认
202+
6. `refactor(gcli): 抽出 AppOptions, 每-App 解析状态不再共享单例`(commit 7e52e9a)
203203

204-
> 1-5(核心 + 文档 + help 分组)已落地并验证;6 风险最高,需先确认再做
204+
> 1-6 全部落地并验证
205205
> 说明:内置 `help` 命令仅支持单级(help.go 既有 TODO),故 `help top sub` 暂不可用;
206206
> `top sub -h` 正常。help 分组对两条 ShowHelp 路径均生效(ShowHelp 开头补了幂等合并)。
207207
208+
### D2.6 实施方案(抽出 AppOptions,替代原「整体 per-App」设想)
209+
210+
- **拆分而非整体复制**:把 `GlobalOpts` 里的每-App 解析/运行状态
211+
`ShowHelp/ShowVersion/inCompletion/genCompletion`)抽到新类型 **`AppOptions`**
212+
每个 `App`(及 standalone `Command``runOpts`,lazy)持有自己的实例 → 并发多 App 不再共享。
213+
- **全局配置仍走包级单例 `gOpts`**`Verbose/strict/enhanceShort/NoColor` 与 logger、
214+
`gcli.Verbose()/IsDebugMode()/StrictMode()/EnhanceShort()` 全部不动 → **不会复现 v3.4.0 的
215+
verbose 失效坑**(这是当年从 per-App 改回单例的根因)。
216+
- **向后兼容**`App.Opts()` 仍返回 `*GlobalOpts``app.Opts()==GOpts()` 成立、`app.Opts().Verbose`
217+
可读,`TestApp_Opts_singleSource` 不变);新增 `App.AppOpts() *AppOptions` 取每-App 状态。
218+
`bindingOpts` 移到 `AppOptions`(读取全局 `Disable`)。
219+
- **破坏面**`GlobalOpts` 不再含上述 4 个字段(读 `app.Opts().ShowHelp` 等的代码需改 `AppOpts()`);
220+
已在 CHANGELOG 标注。
221+
208222
### 实施备注(复核发现)
209223

210224
- **Required 共享选项校验时机**:因「自身也并入」会让必填共享选项进入中间祖先命令的 flag set,

0 commit comments

Comments
 (0)