gogcli 的gog calendar calendars命令详解:日历列表、分页机制与面向 Agent 的脚本化输出
【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli
gog calendar calendars是 gogcli(Google Workspace 命令行工具)中用于列出当前账户全部 Google Calendar 日历的命令。本篇以官方命令参考页 gog-calendar-calendars.md 为主体,完整继承其命令用法与全部参数说明,并结合 internal/cmd/calendar_list_cmds.go 等源码,深入讲解该命令的分页实现、JSON/表格双模式输出、空结果退出码,以及它与--readonly、--fail-empty等安全参数配合用于 CI 与 LLM Agent 场景的实战方式。
命令定位与基本用法
gog calendar calendars(别名gog cal calendars)的功能是List calendars——列出当前 Google 账户可见的所有日历(主日历、二级日历、订阅的他人共享日历等)。该命令在命令树中的注册位置见 internal/cmd/calendar.go:
Calendars CalendarCalendarsCmd `cmd:"" name:"calendars" help:"List calendars"`它隶属于gog calendar命令组,完整命令组文档见 gog-calendar.md。基本用法:
gog calendar (cal) calendars [flags]典型调用示例:
# 默认列出最多 100 个日历(表格形式) gog calendar calendars # JSON 输出,适合脚本与 LLM 消费 gog calendar calendars --json # 拉取全部分页 gog calendar calendars --all # 无结果时以退出码 3 失败(CI 断言) gog calendar calendars --fail-empty命令实现入口为CalendarCalendarsCmd.Run(internal/cmd/calendar_list_cmds.go),执行流程为:校验--max→ 解析账户(requireAccount)→ 构建 calendar API 服务(calendarService)→ 分页拉取CalendarListEntry→ 按输出模式写 JSON 或表格。
命令专属 Flags 详解
以下参数在CalendarCalendarsCmd结构体中定义(internal/cmd/calendar_list_cmds.go),是本文档参考页 Flags 表格中与本命令直接相关的部分:
| Flag | Type | Default | Help |
|---|---|---|---|
--max--limit | int64 | 100 | Max results |
--page--cursor | string | Page token | |
--all--all-pages--allpages | bool | Fetch all pages | |
--fail-empty--non-empty--require-results | bool | Exit with code 3 if no results |
逐项说明:
--max/--limit(默认 100):单次请求的最大条目数,直接映射到 Google Calendar API 的maxResults。源码中先做合法性校验:Max <= 0会直接返回usage("max must be > 0")错误。测试用例 internal/cmd/calendar_max_validation_test.go 明确验证了Max: 0和Max: -1两种非法输入都会被拒绝。--page/--cursor:传入上一页返回的nextPageToken,从指定位置继续拉取。源码中先做strings.TrimSpace,空串则不附加PageToken(internal/cmd/calendar_list_cmds.go)。--all/--all-pages/--allpages:自动循环翻页直到nextPageToken为空,返回全部日历。--fail-empty/--non-empty/--require-results:结果为空时以退出码 3 退出。实现见 internal/cmd/paging.go:定义了emptyResultsExitCode = 3,failEmptyExit在启用该标志且无结果时返回&ExitError{Code: 3},未启用时正常返回nil。
全局(Root)Flags 完整参考
参考页中的完整 Flags 表还包含作用于所有 gog 命令的全局参数,这里完整保留,便于在脚本中直接复用:
| Flag | Type | Default | Help |
|---|---|---|---|
--access-token | string | Use provided access token directly (bypasses stored refresh tokens; token expires in ~1h) | |
-a--account--acct | string | Account email, alias, or auto for authenticated Google API commands | |
--client | string | OAuth client name (selects stored credentials + token bucket) | |
--color | string | auto | Color output: auto|always|never |
--disable-commands | string | Comma-separated list of disabled commands; dot paths allowed | |
-n--dry-run--dryrun--noop--preview | bool | Do not make changes; print intended actions and exit successfully | |
--enable-commands | string | Comma-separated list of enabled command prefixes; dot paths allowed (restricts CLI) | |
--enable-commands-exact | string | Comma-separated list of exact enabled commands; dot paths allowed and parent commands do not enable children | |
-y--force--assume-yes--yes | bool | Skip confirmations for destructive commands | |
--gmail-no-send | bool | false | Block Gmail send operations (agent safety) |
-h--help | kong.helpFlag | Show context-sensitive help. | |
--home | string | Override gogcli config/data/state/cache root (equivalent to GOG_HOME) | |
-j--json--machine | bool | false | Output JSON to stdout (best for scripting) |
--no-input--non-interactive--noninteractive | bool | Never prompt; fail instead (useful for CI) | |
-p--plain--tsv | bool | false | Output stable, parseable text to stdout (TSV; no colors) |
--quota-project | string | Google Cloud project to bill for API usage (sent as X-Goog-User-Project; some APIs require it with --access-token or ADC) | |
--readonly | bool | false | Block mutating API requests at runtime; auth add also requests read-only OAuth scopes |
--results-only | bool | In JSON mode, emit only the primary result (drops envelope fields like nextPageToken) | |
--select--pick--project | string | In JSON mode, select comma-separated fields (best-effort; supports dot paths). Desire path: use --fields for most commands. | |
-v--verbose | bool | Enable verbose logging | |
--version | kong.VersionFlag | Print version and exit | |
--wrap-untrusted | bool | false | In JSON/raw output, wrap fetched text fields in external untrusted-content markers |
其中与 Agent/CI 场景关系最密切的几个:--readonly(运行时阻断一切写操作,本命令本身只读,加上它可形成双重保险)、--no-input(禁止任何交互提示,直接失败,适合无人值守)、--json与--results-only(稳定机器可读输出)、--wrap-untrusted(把拉取到的文本字段包裹在“外部不可信内容”标记中,降低提示注入风险)。
源码级实现剖析
API 调用与分页闭环
Run方法内部定义了一个fetch闭包封装单页请求(internal/cmd/calendar_list_cmds.go):
fetch := func(pageToken string) ([]*calendar.CalendarListEntry, string, error) { call := svc.CalendarList.List().MaxResults(c.Max) if strings.TrimSpace(pageToken) != "" { call = call.PageToken(pageToken) } r, callErr := call.Do() if callErr != nil { return nil, "", callErr } return r.Items, r.NextPageToken, nil }可见--max逐字透传为MaxResults,--page仅在非空时才附加PageToken。随后调用通用分页辅助函数loadPagedItems(c.Page, c.All, fetch)(internal/cmd/paged_list_helpers.go):
- 未指定
--all:只执行一次fetch(page),返回当页数据与nextPageToken; - 指定
--all:走collectAllPages,循环调用 fetch 直到 token 为空。
collectAllPages底层是带安全护栏的collectPages(internal/cmd/paging.go):
- 以10000 页作为上限(
maxPages),防止分页死循环;超过上限返回pagination exceeded max pages错误; - 通过
pageTokenGuard追踪已见 page token,对重复 token 提前报错,避免 API 异常返回相同 token 导致的无限翻页; - 每轮
next均做TrimSpace,空 token 即终止。
这种“上限 + 已见 token 集合”的双重防护,是 gogcli 所有分页列表命令共享的通用模式。
双模式输出:JSON 与表格
输出逻辑(internal/cmd/calendar_list_cmds.go)分两支:
JSON 模式(--json):
outfmt.WriteJSON(ctx, stdoutWriter(ctx), map[string]any{ "calendars": items, "nextPageToken": nextPageToken, })稳定输出{"calendars": [...], "nextPageToken": "..."}信封结构:calendars为CalendarListEntry数组(含id、summary、accessRole等字段),nextPageToken供下一页续拉。配合--results-only可丢弃信封字段,配合--select id,summary可按点路径挑选字段(best-effort)。
表格模式(默认):
outfmt.WriteTable(ctx, stdoutWriter(ctx), compactCalendarRows(items), calendarListColumns(), ) printNextPageHintWithAll(u, nextPageToken, "--all/--all-pages")表格列定义在calendarListColumns(internal/cmd/calendar_presentation.go)中,固定为三列:
| Header | 来源字段 |
|---|---|
| ID | entry.Id(日历 ID,如邮箱地址或长 ID) |
| NAME | entry.Summary(显示名称) |
| ROLE | entry.AccessRole(owner/reader 等访问角色) |
compactCalendarRows会把空值行紧凑化,减少表格视觉噪声。若仍存在下一页且未加--all,printNextPageHintWithAll会在输出末尾提示使用--all/--all-pages获取全量。
空结果与退出码
两种输出模式下,items为空时行为一致:
- JSON 模式:正常写完 JSON(
calendars为空数组)后再判断; - 表格模式:向 stderr 打印
No calendars; - 若启用
--fail-empty,统一通过failEmptyExit(c.FailEmpty)以退出码 3失败(internal/cmd/paging.go)。
这个设计让gog calendar calendars --json --fail-empty可以直接作为“该账户是否还有日历”的布尔断言用在 CI 或自动化脚本中。
与其他 calendar 子命令的协作
calendars列出的 ID 是其他gog calendar子命令的输入。从 internal/cmd/calendar.go 的命令注册可以看出典型协作链:
gog calendar calendars拿到 ID;- 用该 ID 调用
gog calendar acl <calendarId>(查看共享权限)、gog calendar events <calendarId>(列事件)、gog calendar freebusy(查忙闲)等; - 管理类命令
create-calendar/delete-calendar/subscribe/unsubscribe用于增删二级日历——例如subscribe命令的参数定义(internal/cmd/calendar_list_cmds.go)支持--color-id(1-24)、--hidden、--selected,并带有-n/--dry-run预演保护。
此外,gog calendar alias子命令可以为长日历 ID 建立短别名,便于在后续命令中直接以别名引用(相关实现与测试见 internal/cmd/calendar_alias_resolution_test.go)。
Agent 与 CI 场景实战
综合上述参数,面向自动化与 LLM Agent 的推荐组合如下:
# 1. 全量列出日历的 ID 与角色(JSON,供程序解析) gog calendar calendars --all --json # 2. 只挑 ID 与名称(字段级裁剪,减少上下文体积) gog calendar calendars --json --select id,summary # 3. CI 中做断言:无日历则失败(退出码 3) gog calendar calendars --json --fail-empty # 4. 安全沙箱:显式账号 + 只读 + 禁止交互 + 包裹不可信内容 gog calendar calendars -a myalias --readonly --no-input --wrap-untrusted --json要点回顾:
--all与--page二选一思路:前者自动翻全量(带 10000 页护栏),后者手动续拉;--max必须为正整数,默认 100,非法值(0 或负数)会被命令直接拒绝;--fail-empty的退出码 3 与普通错误区分开,方便脚本精确判断“结果为空”这一语义;- 全局安全参数(
--readonly、--no-input、--wrap-untrusted)使该命令可以被谨慎地纳入受限 Agent 的执行面;结合仓库中--enable-commands/--disable-commands的点路径前缀机制(见 safety-profiles/agent-safe.yaml 等安全档案),还可以进一步收窄 CLI 可用命令集。
参考索引
| 资源 | 路径 |
|---|---|
| 命令参考页(本文主体) | docs/commands/gog-calendar-calendars.md |
| calendar 命令组文档 | docs/commands/gog-calendar.md |
| 命令总索引 | docs/commands/README.md |
| 命令结构与注册 | internal/cmd/calendar.go |
| 命令实现(Calendars/Subscribe/ACL) | internal/cmd/calendar_list_cmds.go |
| 表格列定义与行紧凑化 | internal/cmd/calendar_presentation.go |
| 分页与空结果退出码 | internal/cmd/paging.go |
| 分页辅助(loadPagedItems) | internal/cmd/paged_list_helpers.go |
| max 参数校验测试 | internal/cmd/calendar_max_validation_test.go |
| Agent 安全档案示例 | safety-profiles/agent-safe.yaml |
注意该参考页由gog schema --json自动生成(页首注明 “Do not edit this page by hand; runmake docs-commands”),因此其 Flags 表格与源码中的 kong 标签始终保持一致;如命令行行为有出入,以 internal/cmd/calendar_list_cmds.go 的实际实现为准。
【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考