cli

package
v0.0.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package cli wires the commands and owns the exit-code contract (R-17). Distinct, documented, scriptable:

0  success — applied, or audit found nothing
1  no-op — nothing to change
2  refused — would violate INV-1 or INV-2 (or S-4 size cap)
3  invalid input — malformed op, unresolvable scope, conflicting batch
4  audit findings present
5  inconclusive — API unavailable, token insufficient, rate limited (R-12)
6  validation failed post-write; rolled back

`sync` and `check` run under a coarser three-code contract of their own (R-19: only 0, 2 and 3), because their question is "did this repo converge?" rather than "what exactly happened?". See sync.go.

`audit --lint` narrows 0 and 4 rather than redefining them: it never returns 1, because a file that needs no repair is that verb's SUCCESS and exiting no-op would make every healthy repo in a fleet read as a failure under `set -e`; and its 4 is still "findings present", counting a fix computed but not written (--dry-run) as one. See lint.go.

Index

Constants

View Source
const (
	ExitOK           = 0
	ExitNoOp         = 1
	ExitRefused      = 2
	ExitInvalid      = 3
	ExitFindings     = 4
	ExitInconclusive = 5
	ExitValidation   = 6
)

Exit codes (R-17).

View Source
const (
	StatusApplied   = "applied"
	StatusUnchanged = "unchanged"
	StatusSkipped   = "skipped"
	StatusRefused   = "refused"
	StatusError     = "error"
)

Sync statuses (R-24). "skipped" is distinct from "unchanged" so a policy that matches nothing anywhere cannot read as "already correct" across a whole fleet.

Variables

View Source
var Version = "dev"

Version is the build this binary is, stamped at link time by the release workflow with

-ldflags "-X github.com/jordonpeterson/codeowners-tool/internal/cli.Version=v0.0.7"

and left as "dev" for anything built locally, which is exactly the honest answer for a binary nobody released. Without it an operator holding a binary cannot tell whether it is the one with a given fix, so both rollback and CVE response are guesswork across a fleet.

Functions

func Run

func Run(argv []string, stdout, stderr io.Writer) int

Run executes argv (without the program name) and returns the exit code.

Types

type SyncRecord added in v0.0.5

type SyncRecord struct {
	Repo string `json:"repo"`
	// CodeownersPath is the repo-relative file this run CHANGED, or under
	// --dry-run would have. A rollout has to stage and commit that file, and
	// which of the three legal locations it is differs per repo (S-8), so a
	// loop without this field can only `git add -A` and hope nothing else moved
	// in the clone.
	//
	// It is emitted only when Status is StatusApplied. Absent therefore means
	// "this run wrote nothing", NOT "no file was chosen": an `unchanged` repo
	// has a perfectly good CODEOWNERS and simply nothing to stage. A refusal
	// names its file in Error instead. One caveat the fleet script has to
	// respect: a --dry-run record reports `applied` for a run that would have
	// written, so DryRun must be checked before anything is staged.
	CodeownersPath string          `json:"codeowners_path,omitempty"`
	Status         string          `json:"status"` // applied|unchanged|skipped|refused|error
	Ops            []plan.OpResult `json:"ops,omitempty"`
	OpsApplied     int             `json:"ops_applied"`
	OpsSkipped     int             `json:"ops_skipped"`
	PathsChanged   int             `json:"paths_changed"`
	Created        bool            `json:"created"`
	// DryRun marks a record produced under --dry-run. Without it a preview row
	// and a row from a real rollout are byte-identical, so an operator holding
	// results.jsonl cannot tell whether the fleet was changed or only modelled —
	// and neither can the script that reads it. omitempty keeps the common case
	// (a real run) at the same six unconditional keys as before.
	DryRun   bool          `json:"dry_run,omitempty"`
	Warnings []string      `json:"warnings,omitempty"`
	Changes  []plan.Change `json:"changes,omitempty"`
	Error    string        `json:"error,omitempty"`
}

SyncRecord is one `sync` run, rendered as one JSON object (R-24). One line per repo is what lets `jq -s` aggregate a fleet without parsing stderr.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL