# How to Use gogcli --json-transform and --results-only for Clean JSON Output

> Learn to use gogcli --json-transform and --results-only to get clean JSON output. Streamline automation by selecting specific fields for script-friendly data extraction from steipete/gogcli.

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

---

**Use `gogcli --json --results-only` to strip envelope metadata and output only the primary data array, then combine it with `--select=<fields>` to project specific columns for script-friendly automation.**

When automating workflows with `steipete/gogcli`, raw JSON output often includes wrapper objects containing pagination tokens and metadata. The `--json-transform` pipeline, controlled by the `--results-only` and `--select` flags, lets you extract clean, focused data directly from the command line without external tools like `jq`.

## Understanding the JSON Transform Pipeline

The transformation system is implemented in [`internal/outfmt/outfmt.go`](https://github.com/steipete/gogcli/blob/main/internal/outfmt/outfmt.go) and orchestrated through the command context. When you invoke `gogcli` with JSON formatting flags, the application:

1. Parses global flags in [`internal/cmd/root.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/root.go)
2. Builds a `JSONTransform` struct and injects it into the context via `outfmt.WithJSONTransform`
3. Applies transformations during `outfmt.WriteJSON` through `applyJSONTransform`

## How --results-only Strips the Envelope

The `--results-only` flag removes wrapper objects like `nextPageToken` and `results`, emitting only the primary payload.

In [`internal/cmd/root.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/root.go), the flag is defined as:

```go
type RootFlags struct {
    ResultsOnly bool   `name:"results-only" help:"In JSON mode, emit only the primary result (drops envelope fields like nextPageToken)"`
    // ...
}

```

The flag value is stored in a `JSONTransform` struct:

```go
type JSONTransform struct {
    ResultsOnly bool
    Select      []string
}

```

When `outfmt.WriteJSON` executes, it checks for the transform and calls `unwrapPrimary` to extract the core data:

```go
if t.ResultsOnly {
    anyV = unwrapPrimary(anyV)
}

```

The `unwrapPrimary` function searches for common envelope keys and returns the first non-metadata field, making it ideal for piping into `jq` or other JSON processors.

## Projecting Fields with --select

The `--select` flag (aliased as `--fields` in some contexts) projects specific fields from the JSON output, supporting dot-path notation for nested objects.

Defined in [`internal/cmd/root.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/root.go):

```go
Select string `name:"select" aliases:"pick,project" help:"In JSON mode, select comma-separated fields (best-effort; supports dot paths)"`

```

The transformation applies via `selectFields` and `selectFieldsFromItem`, which recursively walk arrays and objects to retain only requested paths.

## Practical Usage Examples

Combine both flags for automation scripts that need clean, minimal JSON.

**Extract only the primary array:**

```bash
gogcli drive ls --json --results-only

```

Output becomes a raw array without the `{"files": [...], "nextPageToken": "..."}` wrapper.

**Project specific columns:**

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

```

Result:

```json
[
  { "id": "abc123", "name": "report.pdf", "size": 12345 },
  { "id": "def456", "name": "notes.txt", "size": 678 }
]

```

**Using the --fields alias:**

```bash
gogcli calendar events --json --fields=summary,start,end

```

## Implementation Deep Dive

The transform pipeline relies on context propagation through the command tree. In [`internal/cmd/root.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/root.go), the `PersistentPreRun` hook initializes the transform:

```go
ctx = outfmt.WithJSONTransform(ctx, outfmt.JSONTransform{
    ResultsOnly: cli.ResultsOnly,
    Select:      splitCommaList(cli.Select),
})

```

This context is passed to all subcommands. When a command calls `outfmt.WriteJSON(ctx, w, v)`, the function retrieves the transform via `JSONTransformFromContext` and applies it through `applyJSONTransform`.

The `unwrapPrimary` function in [`internal/outfmt/outfmt.go`](https://github.com/steipete/gogcli/blob/main/internal/outfmt/outfmt.go) implements the envelope removal logic by checking for standard response keys like `results`, `files`, and `threads`, returning the first match to eliminate pagination metadata.

## Summary

- **Use `--results-only`** to strip envelope metadata and output only the primary data array from `gogcli` JSON responses.
- **Use `--select=<fields>`** to project specific fields, supporting dot notation for nested objects.
- **Combine both flags** for clean, script-friendly JSON output ideal for piping into `jq` or other automation tools.
- The transformation pipeline is implemented in [`internal/outfmt/outfmt.go`](https://github.com/steipete/gogcli/blob/main/internal/outfmt/outfmt.go) and activated via context in [`internal/cmd/root.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/root.go).

## Frequently Asked Questions

### What is the difference between --results-only and --select?

`--results-only` removes the outer wrapper object (containing metadata like `nextPageToken`) and outputs only the primary data array or object. `--select` filters the fields within each object, keeping only the specified properties. Use `--results-only` for envelope removal and `--select` for field projection.

### Can I use dot notation with --select?

Yes. The `--select` flag supports dot-path notation for nested fields. For example, `--select=name,owner.displayName` extracts the top-level `name` field and the `displayName` property nested within the `owner` object.

### Where are these flags defined in the source code?

The flags are defined in the `RootFlags` struct in [`internal/cmd/root.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/root.go) (lines 30-39). The transformation logic is implemented in [`internal/outfmt/outfmt.go`](https://github.com/steipete/gogcli/blob/main/internal/outfmt/outfmt.go), specifically in the `applyJSONTransform`, `unwrapPrimary`, and `selectFields` functions.

### Is --fields the same as --select?

Yes, `--fields` is an alias for `--select` in most contexts. The root command defines `--select` with aliases including `pick` and `project`, and some subcommands rewrite `--fields` to use the global `--select` mechanism for consistent JSON field projection.