forked from Gitlink/gitlink-cli
83 lines
8.0 KiB
Plaintext
83 lines
8.0 KiB
Plaintext
ctx 就是 *common.RuntimeContext。一句话:它是每个 Shortcut
|
||
命令的"工具箱",所有能力(发API请求、读参数、输出结果)都挂在这个对象上。
|
||
|
||
---
|
||
它长什么样(shortcuts/common/types.go:41-50)
|
||
|
||
type RuntimeContext struct {
|
||
Client *client.Client // ← 发 HTTP 请求的客户端
|
||
Owner string // ← --owner 的值(如 "zzx-coder")
|
||
Repo string // ← --repo 的值(如 "gitlink-cli")
|
||
Format string // ← --format 的值("json" / "table" / "yaml")
|
||
CommandName string // ← 当前命令名(如 "wiki +delete")
|
||
Args map[string]string // ← 所有 flag 的键值对(如 {"title":"Home","dry-run":"false"})
|
||
GatewayBaseURL string // ← Wiki/Webhook网关地址(跟标准API不同)
|
||
GatewayHTTPClient *http.Client // ← 网关专用 HTTP 客户端(nil 则自动创建)
|
||
}
|
||
|
||
---
|
||
它怎么创建出来的(types.go:53-80)
|
||
你敲 gitlink-cli wiki +delete --title "Home" 时:
|
||
|
||
第1步:cobra 解析命令行 → flagValues = {"title": "Home"}
|
||
第2步:runner.go:34 → NewRuntimeContext(flagValues, "wiki +delete")
|
||
第3步:NewRuntimeContext 内部:
|
||
→ client.New() // 读取配置文件,拿到 BaseURL + 带 auth 的 HTTP Client
|
||
→ 读取全局 flag // cmdutil.Owner, cmdutil.Repo, cmdutil.Format
|
||
→ 组装成 RuntimeContext // 把所有东西塞进去
|
||
第4步:传给 s.Run(ctx) // 你的业务逻辑拿到这个 ctx
|
||
|
||
---
|
||
它上面的方法(你可以直接用 ctx.XXX() 调用的)
|
||
|
||
┌──────────────────────────────────────┬───────────────────────────────────┬──────────────────────────────────────┐
|
||
│ 方法 │ 做什么 │ 例 │
|
||
├──────────────────────────────────────┼───────────────────────────────────┼──────────────────────────────────────┤
|
||
│ ctx.Arg("title") │ 读用户传入的 flag 值 │ "Home" │
|
||
├──────────────────────────────────────┼───────────────────────────────────┼──────────────────────────────────────┤
|
||
│ ctx.RequireArg("title", "提示") │ 读必填参数,为空就报 CLIError │ 同上,但自动校验 │
|
||
├──────────────────────────────────────┼───────────────────────────────────┼──────────────────────────────────────┤
|
||
│ ctx.CallAPI("GET", path, body) │ 调 GitLink 标准 API │ ctx.CallAPI("GET", "/users/me", nil) │
|
||
├──────────────────────────────────────┼───────────────────────────────────┼──────────────────────────────────────┤
|
||
│ ctx.CallAPIWithQuery("GET", path, │ 带查询参数的 API │ ctx.CallAPIWithQuery("GET", │
|
||
│ query) │ │ "/issues", q) │
|
||
├──────────────────────────────────────┼───────────────────────────────────┼──────────────────────────────────────┤
|
||
│ ctx.Output(env) │ 输出 API 响应(自动选 │ ctx.Output(env) │
|
||
│ │ json/table/yaml) │ │
|
||
├──────────────────────────────────────┼───────────────────────────────────┼──────────────────────────────────────┤
|
||
│ ctx.OutputData(data) │ 包装数据成成功 envelope 再输出 │ ctx.OutputData(myStruct) │
|
||
├──────────────────────────────────────┼───────────────────────────────────┼──────────────────────────────────────┤
|
||
│ ctx.ResolveOwnerRepo() │ 从 git remote 自动推断 owner/repo │ 没传 --owner 时自动填充 │
|
||
├──────────────────────────────────────┼───────────────────────────────────┼──────────────────────────────────────┤
|
||
│ ctx.RepoPath() │ 返回 "/owner/repo" 字符串 │ "/zzx-coder/gitlink-cli" │
|
||
├──────────────────────────────────────┼───────────────────────────────────┼──────────────────────────────────────┤
|
||
│ ctx.IsDryRun() │ 判断用户是否传了 --dry-run │ true / false │
|
||
└──────────────────────────────────────┴───────────────────────────────────┴──────────────────────────────────────┘
|
||
|
||
---
|
||
一条命令里 ctx 的完整生命周期
|
||
|
||
以 wiki +delete --title "Home" 为例:
|
||
|
||
1. runner.go:20-31 收集 flag
|
||
flagValues = {"title": "Home"}
|
||
|
||
2. runner.go:34 创建 ctx
|
||
ctx = NewRuntimeContext({"title":"Home"}, "wiki +delete")
|
||
→ ctx.Client = 带认证的HTTP客户端(BaseURL = https://gitlink.org.cn/api)
|
||
→ ctx.Owner = "zzx-coder"(从 git remote 或 --owner 来的)
|
||
→ ctx.Repo = "gitlink-cli"
|
||
→ ctx.Format = "table"(默认值)
|
||
→ ctx.Args = {"title": "Home"}
|
||
|
||
3. runner.go:60 调用你的业务逻辑
|
||
err = s.Run(ctx)
|
||
|
||
4. wiki.go:747 你的 Run 函数里用 ctx
|
||
title, _ = ctx.RequireArg("title", ...) // → "Home"
|
||
projectID, _ = resolveProjectID(ctx) // → ctx 传进子函数
|
||
body = {..., "pageName": actualPageName}
|
||
callWikiAPI(ctx, "DELETE", ..., body) // → ctx 用于构造网关 Client
|
||
ctx.OutputData(result) // → ctx.Format 决定输出格式
|
||
|
||
--- |