Documentation
¶
Overview ¶
Package cli implements the devproof command line.
Every command is a thin adapter: it parses input, calls one public SDK operation, renders the result, and maps a typed error to an exit code (DP-001). No command contains logic that an embedding application could not reach through the SDK.
The stream discipline here is load-bearing. stdout carries the requested result and nothing else, so `devproof build ... | xargs crane` works and keeps working; every diagnostic, warning, progress indicator, and error goes to stderr. A tool that prints "Building..." to stdout is a tool nobody can safely pipe.
Index ¶
- Constants
- func Field(w io.Writer, name, value string)
- func Run(ctx context.Context, args []string, streams Streams) int
- type App
- type Config
- type Envelope
- type ErrorEnvelope
- type ErrorPayload
- type Format
- type Printer
- func (p *Printer) Failure(err error, interrupted bool) int
- func (p *Printer) Info(format string, args ...any)
- func (p *Printer) Progress() *Progress
- func (p *Printer) Result(kind string, result any, quiet string, text func(w io.Writer)) error
- func (p *Printer) Success(format string, args ...any)
- func (p *Printer) Warn(format string, args ...any)
- type Progress
- type Streams
Constants ¶
const EnvelopeAPIVersion = "devproof.thingz.io/cli/v1alpha1"
EnvelopeAPIVersion identifies the CLI's JSON contract. It is versioned separately from the bundle format: the two change for different reasons.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type App ¶
type App struct {
Streams Streams
// contains filtered or unexported fields
}
App is the command tree plus the state a run needs.
type Config ¶
type Config struct {
// Format is the default output rendering.
Format string `yaml:"format,omitempty"`
// Verbose and Debug set default diagnostic levels.
Verbose bool `yaml:"verbose,omitempty"`
Debug bool `yaml:"debug,omitempty"`
// NoColor disables color regardless of terminal detection.
NoColor bool `yaml:"noColor,omitempty"`
// Timeout is the default overall operation deadline, as a duration
// string.
Timeout string `yaml:"timeout,omitempty"`
// Policy is a verification policy applied when --policy is not given.
//
// A default policy can only make verification stricter: without one,
// trust reports not-evaluated. There is no setting that can relax
// verification, because a file that could turn integrity checking off
// would be the most valuable file on the machine to an attacker.
Policy string `yaml:"policy,omitempty"`
// TrustRoot is a default Sigstore trusted root.
TrustRoot string `yaml:"trustRoot,omitempty"`
// FulcioURL and RekorURL select non-default Sigstore instances, which is
// what a private deployment needs.
FulcioURL string `yaml:"fulcioUrl,omitempty"`
RekorURL string `yaml:"rekorUrl,omitempty"`
}
Config is the persisted configuration.
Decoding is strict. A misspelled key in a configuration file is a setting that silently does not apply, and the failure shows up later as behavior nobody can explain.
type Envelope ¶
type Envelope struct {
APIVersion string `json:"apiVersion"`
Kind string `json:"kind"`
Result any `json:"result,omitempty"`
Warnings []string `json:"warnings,omitempty"`
}
Envelope wraps every JSON result.
The shape is the same for every command so that a caller can find the apiVersion and kind without knowing which command produced the output.
type ErrorEnvelope ¶
type ErrorEnvelope struct {
APIVersion string `json:"apiVersion"`
Kind string `json:"kind"`
Error ErrorPayload `json:"error"`
}
ErrorEnvelope is the JSON failure shape.
type ErrorPayload ¶
type ErrorPayload struct {
Code string `json:"code"`
Message string `json:"message"`
Source string `json:"source,omitempty"`
Path string `json:"path,omitempty"`
}
ErrorPayload is the machine-readable half of a failure.
Code and the field names are a stable API. Message is not: it is written for the human deciding what to do next, and nothing should parse it.
type Printer ¶
type Printer struct {
Streams Streams
Format Format
Quiet bool
Verbose bool
Debug bool
NoColor bool
// contains filtered or unexported fields
}
Printer renders results according to the selected output mode.
func (*Printer) Failure ¶
Failure renders an error and returns the process exit code.
In JSON mode the failure envelope goes to stdout, because a caller parsing JSON needs to read the error the same way it reads a result. In text mode stdout stays empty: a pipeline that got no result should receive no bytes.
func (*Printer) Progress ¶
Progress returns the printer's progress reporter.
Owned by the printer so that every path that writes real output can erase a pending progress line first, without each call site having to remember to.
func (*Printer) Result ¶
Result renders a successful outcome.
kind names the result type in JSON. quiet is the single value a pipeline wants — a digest, a path — and is the only thing printed under --quiet, because a script that has to parse prose is a script that breaks.
type Progress ¶
type Progress struct {
// contains filtered or unexported fields
}
Progress reports what a command is currently doing.
It writes to stderr and only when stderr is an interactive terminal. A progress indicator exists for a human watching a slow operation; written to a pipe or a log file it is noise, and written to stdout it is corruption.
Under --verbose the same steps are written as ordinary permanent lines instead, because a CI log is exactly the case where knowing which step was running when something failed is worth the extra output.
type Streams ¶
type Streams struct {
Out io.Writer
Err io.Writer
// IsTerminal reports whether Err is an interactive terminal. Progress and
// color are enabled only when it is.
IsTerminal bool
}
Streams are a command's output destinations.
Passed rather than taken from the process so that a test can capture them and assert the discipline holds, which is the only way to know it does.