# How to Use the gogcli --select Flag for JSON Field Projection: Complete Guide

> Master the gogcli --select flag for JSON field projection. Learn to filter output with dot-path notation like id,name,owner.email with this complete guide.

- Repository: [Peter Steinberger/gogcli](https://github.com/steipete/gogcli)
- Tags: how-to-guide
- Published: 2026-02-16

---

**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`](https://github.com/steipete/gogcli/blob/main/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`](https://github.com/steipete/gogcli/blob/main/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`](https://github.com/steipete/gogcli/blob/main/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`](https://github.com/steipete/gogcli/blob/main/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:

```bash
gog drive ls --json --select=id,name

```

### Projecting Nested Fields

To retrieve the subject and start time of calendar events, accessing nested objects:

```bash
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:

```bash
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:

```bash
gog drive ls --json --select=id,name --results-only

```

### Using Aliases

The `--pick` alias functions identically to `--select`:

```bash
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`](https://github.com/steipete/gogcli/blob/main/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 **`--select` flag** (aliases `--pick`, `--project`) enables client-side field projection for JSON output in `gogcli`.
- It accepts **comma-separated dot-paths** (e.g., `owner.email`, `messages.0.snippet`) parsed by `splitCommaList` in [`internal/cmd/auth.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/auth.go).
- The projection is applied by the **`outfmt` package** ([`internal/outfmt/outfmt.go`](https://github.com/steipete/gogcli/blob/main/internal/outfmt/outfmt.go)) via `selectFields` and `getAtPath` just before serialization.
- The flag is **JSON-only** and global, available on all commands that support JSON output.
- **`--fields` is rewritten to `--select`** for 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`](https://github.com/steipete/gogcli/blob/main/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`](https://github.com/steipete/gogcli/blob/main/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.