How to Use the gogcli --select Flag for JSON Field Projection: Complete Guide
The gogcli --select flag (aliases --pick and --project) filters JSON output to specific fields using dot-path notation such as id,name,owner.email, and is implemented in the internal/outfmt package of the steipete/gogcli repository.
The gogcli CLI tool for Google Workspace APIs provides a powerful field projection mechanism through its global --select flag. This feature allows you to reduce JSON payload size and improve readability by returning only the specific fields you need. In this guide, we examine how the --select flag works under the hood in the steipete/gogcli codebase and how to use it effectively across different commands.
What Is the gogcli --select Flag?
The --select flag is a global CLI option available on every gogcli command that outputs JSON. It accepts a comma-separated list of field paths that define which keys should appear in the final JSON output. The flag has two aliases: --pick and --project, which behave identically.
Key characteristics:
- Only functions when
--json(or an implicit JSON output mode) is active - Supports nested field access via dot notation (e.g.,
owner.email) - Supports array indexing (e.g.,
messages.0.snippet) - Is parsed once at startup and applied to all JSON responses
How Field Projection Works Under the Hood
The implementation spans the command layer and the output formatting layer. Here is the path from CLI argument to filtered JSON.
Flag Definition and Parsing
The flag is declared in internal/cmd/root.go within the RootFlags struct at line 38. When the CLI initializes, the raw string value is processed by splitCommaList, a utility defined at line 1153 of internal/cmd/auth.go. This function splits the comma-separated string into a clean slice of field paths.
Context Injection and Transformation
After parsing, the field slice is attached to the request context via outfmt.WithJSONTransform (see the Execute function in root.go, lines 48-49). This ensures that every subsequent command execution carries the projection instructions without needing to pass the flag value through every function call manually.
Path Resolution and Nested Fields
The actual filtering occurs in internal/outfmt/outfmt.go. When WriteJSON (lines 82-90) is called to emit the response, it invokes applyJSONTransform. If the Select slice is non-empty (lines 18-21), it triggers selectFields.
The selectFields function (lines 8-22) handles both single objects and slices. For each item, it calls selectFieldsFromItem (lines 22-36), which constructs a new map containing only the requested keys. Nested paths are resolved by getAtPath (lines 38-70), which traverses dot-separated keys and supports numeric indices for array access.
Using --select with gogcli Commands
The --select flag integrates with any command that supports JSON output. Below are practical examples demonstrating syntax for various Google Workspace APIs.
Basic Field Selection
To list only the file ID and name from Google Drive:
gog drive ls --json --select=id,name
Projecting Nested Fields
To retrieve the subject and start time of calendar events, accessing nested objects:
gog calendar events ls --json --select=items.0.summary,items.0.start.dateTime --results-only
Array Indexing
To extract the thread ID and the snippet of the first message in Gmail threads:
gog gmail threads list --json --select=id,messages.0.snippet
Combining with --results-only
To drop envelope metadata and return only the projected data array:
gog drive ls --json --select=id,name --results-only
Using Aliases
The --pick alias functions identically to --select:
gog drive ls --json --pick=id,name
The Relationship Between --select and --fields
Many gogcli commands accept a --fields flag intended for the underlying Google API's partial response mechanism. To provide a consistent CLI experience, root.go contains the rewriteDesirePathArgs function (lines 94-122), which automatically rewrites --fields arguments to --select for all commands except the Calendar events family.
This means you can often use --fields as a synonym for --select, but be aware that for Calendar events, --fields is passed directly to the Google API rather than being processed by the local projection engine.
Summary
- The
--selectflag (aliases--pick,--project) enables client-side field projection for JSON output ingogcli. - It accepts comma-separated dot-paths (e.g.,
owner.email,messages.0.snippet) parsed bysplitCommaListininternal/cmd/auth.go. - The projection is applied by the
outfmtpackage (internal/outfmt/outfmt.go) viaselectFieldsandgetAtPathjust before serialization. - The flag is JSON-only and global, available on all commands that support JSON output.
--fieldsis rewritten to--selectfor most commands, except Calendar events where it retains its API-specific behavior.
Frequently Asked Questions
Does the --select flag work with non-JSON output formats?
No. The --select flag only affects output when JSON mode is active (typically via the --json flag). The projection logic resides in internal/outfmt/outfmt.go and is triggered exclusively during JSON serialization. If you use table or text output modes, the flag is ignored.
Can I use array indices in the --select path?
Yes. The getAtPath function in internal/outfmt/outfmt.go supports numeric indices for array access. For example, messages.0.snippet retrieves the snippet field from the first element of the messages array. This works for any level of nesting within the JSON structure.
What is the difference between --select and --fields in gogcli?
The --select flag performs client-side field projection on the JSON output after the API response is received. The --fields flag is typically passed to the Google API for server-side partial responses. However, gogcli rewrites --fields to --select for most commands (except Calendar events) to provide a consistent CLI experience, meaning --fields often behaves like --select locally.
Why does my --select flag not filter any fields?
This usually happens when the output format is not JSON. Ensure you have added the --json flag to your command. Additionally, verify that your dot-paths match the actual JSON structure exactly, including case sensitivity. The projection occurs in outfmt.WriteJSON only when the Select slice is non-empty and the output mode is JSON.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →