Stabilize JSON output schema · Entire

Stabilize JSON output schema

Sessions

Changes

3

108 unmodified lines

Add `--json` to `probe`, `fetch`, `plan`, or `sync` to emit machine-readable output instead of the default text format.

The JSON interface is intentionally stable:

- keys use `snake_case`
- `probe` returns top-level keys such as `source_url`, `target_url`, `protocol`, `ref_prefixes`, `source_capabilities`, `target_capabilities`, `refs`, and `stats`
- `fetch` returns top-level keys such as `source_url`, `protocol`, `wants`, `haves`, `fetched_objects`, and `stats`
- `plan` and `sync` return top-level keys such as `plans`, `pushed`, `skipped`, `blocked`, `deleted`, `dry_run`, `protocol`, and `stats`

Probe both source and target remotes to inspect source fetch capabilities and target `receive-pack` capabilities:

```bash

import (
    "context"
    "encoding/json"
    "errors"
    "fmt"
    "io"
)

// Structs and types definitions

type BranchPlan struct {
    Branch     string
    SourceRef  plumbing.ReferenceName
    TargetRef  plumbing.ReferenceName
    SourceHash plumbing.Hash
    TargetHash plumbing.Hash
    Kind       RefKind
    Action     Action
    Reason     string
}

type Action string

type Result struct {
    Plans    []BranchPlan
    Pushed   int
    Skipped  int
    Blocked  int
    Deleted  int
    DryRun   bool
    Stats    Stats
    Protocol string
}

type Stats struct {
    Enabled bool
    Items   map[string]*ServiceStats
}

type ServiceStats struct {
    Name          string
    Requests      int
    RequestBytes  int64
    ResponseBytes int64
}

// JSON Marshalling implementations

func (p BranchPlan) MarshalJSON() ([]byte, error) {
    type branchPlanJSON struct {
        Branch     string  `json:"branch"`
        SourceRef  string  `json:"source_ref"`
        TargetRef  string  `json:"target_ref"`
        SourceHash string  `json:"source_hash"`
        TargetHash string  `json:"target_hash"`
        Kind       RefKind `json:"kind"`
        Action     Action  `json:"action"`
        Reason     string  `json:"reason"`
    }
    return json.Marshal(branchPlanJSON{
        Branch:     p.Branch,
        SourceRef:  p.SourceRef.String(),
        TargetRef:  p.TargetRef.String(),
        SourceHash: p.SourceHash.String(),
        TargetHash: p.TargetHash.String(),
        Kind:       p.Kind,
        Action:     p.Action,
        Reason:     p.Reason,
    })
}

func (r Result) Lines() []string {
   // Implementation here...
}