Route help and version through the reporter

This commit is contained in:
2026-10-26 03:02:08 +00:00
parent 49a10690c6
commit 7a1067d387
5 changed files with 146 additions and 83 deletions

View File

@@ -1,8 +1,6 @@
package commandkit
import (
"bytes"
"errors"
"fmt"
"io"
"runtime/debug"
@@ -58,7 +56,7 @@ func (a *App) builtinCommands() []Declaration {
if identity.Version == "" {
identity.Version = "dev"
}
return renderVersionOutcome(identity, input.Format, invocation.Streams)
return renderVersionOutcome(identity, input.Format, invocation.Reporter())
},
})
return []Declaration{help, version}
@@ -78,78 +76,41 @@ func parseVersionFormat(value string) (string, error) {
return value, nil
}
func (a *App) renderHelpOutcome(path []string, streams Streams) Outcome {
session := internalcobra.Prepare(a.routeSnapshot().metadata, commandmeta.ParseOptions{})
return a.renderHelpOutcomeWithSession(path, streams, session)
}
func (a *App) renderHelpTargets(targets []string, streams Streams) Outcome {
session := internalcobra.Prepare(a.routeSnapshot().metadata, commandmeta.ParseOptions{})
return a.renderHelpTargetsWithSession(targets, streams, session)
}
func (a *App) renderHelpTargetsWithSession(targets []string, streams Streams, session *internalcobra.Session) Outcome {
snapshot := a.routeSnapshot()
route := resolveEnteredRoute(targets, snapshot)
if route.kind == routeUnknown {
return a.renderHelpOutcomeWithSession(targets, streams, session)
}
options := commandmeta.ParseOptions{}
switch route.kind {
case routeCanonical:
options.FlagAliases = snapshot.flagAliases[route.canonicalPath.Key()].neutralRecords()
case routeDiscovery:
options.FlagAliases = snapshot.discoveryFlags[route.discoveryPath.Key()].neutralRecords()
}
session = internalcobra.Prepare(snapshot.metadata, options)
return a.renderHelpViewOutcomeWithSession(a.helpView(route, snapshot), streams, session)
}
func (a *App) renderHelpOutcomeWithSession(path []string, streams Streams, session *internalcobra.Session) Outcome {
return a.renderHelpViewOutcomeWithSession(commandmeta.HelpView{EnteredPath: path, CanonicalPath: path}, streams, session)
}
func (a *App) renderHelpViewOutcomeWithSession(view commandmeta.HelpView, streams Streams, session *internalcobra.Session) Outcome {
func (a *App) renderHelpViewOutcomeWithSession(view commandmeta.HelpView, reporter *Reporter, session *internalcobra.Session) Outcome {
content, failure := session.RenderHelpView(view)
if failure != nil {
if failure.Usage {
return Usage(errors.New(failure.Message))
return Usage(failure.Message)
}
return Failure(errors.New(failure.Message))
}
if err := writeReport(streams.Out, []byte(content)); err != nil {
return incompleteReport(err)
return Failure(failure.Message)
}
_ = reporter.RenderOutput(func(w io.Writer) error {
_, err := io.WriteString(w, content)
return err
})
return Success()
}
func renderVersionOutcome(identity Identity, format string, streams Streams) Outcome {
var content []byte
func renderVersionOutcome(identity Identity, format string, reporter *Reporter) Outcome {
if identity.Version == "" {
identity.Version = "dev"
}
switch format {
case "text":
name := identity.Name
if identity.Version == "" {
identity.Version = "dev"
}
line := name + " " + identity.Version
line := identity.Name + " " + identity.Version
if identity.Revision != "" {
line += " (" + identity.Revision + ")"
}
content = []byte(line + "\n")
_ = reporter.RenderOutput(func(w io.Writer) error {
_, err := io.WriteString(w, line+"\n")
return err
})
case "yaml":
if identity.Version == "" {
identity.Version = "dev"
}
var buffer bytes.Buffer
if err := encodeYAML(&buffer, versionDocument{Name: identity.Name, Version: identity.Version, Revision: identity.Revision}); err != nil {
return Failure(err)
}
content = buffer.Bytes()
_ = reporter.RenderOutput(func(w io.Writer) error {
return encodeYAML(w, versionDocument{Name: identity.Name, Version: identity.Version, Revision: identity.Revision})
})
default:
return Usage(fmt.Errorf("unsupported version format %q", format))
}
if err := writeReport(streams.Out, content); err != nil {
return incompleteReport(err)
return Usage(fmt.Sprintf("unsupported version format %q", format))
}
return Success()
}
@@ -160,22 +121,6 @@ func encodeYAML(writer io.Writer, document any) error {
return encoder.Encode(document)
}
func writeReport(writer io.Writer, content []byte) error {
checked := &checkedWriter{writer: writer}
_, err := checked.Write(content)
if err == nil {
err = checked.failure
}
return err
}
func incompleteReport(err error) Outcome {
outcome := Failure(err)
outcome.ReportIncomplete = true
outcome.DeliveryError = err
return outcome
}
func readBuildInfo() *debug.BuildInfo {
info, ok := debug.ReadBuildInfo()
if !ok {