153 lines
5.4 KiB
Go
153 lines
5.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strconv"
|
|
|
|
commandkit "gitea.maximumdirect.net/eric/CommandKit"
|
|
)
|
|
|
|
type greetInput struct {
|
|
Count commandkit.Supplied[int]
|
|
Tags commandkit.Supplied[[]string]
|
|
}
|
|
|
|
type reportInput struct {
|
|
Scenario string
|
|
}
|
|
|
|
var (
|
|
errRecoveredFixture = errors.New("a local read failed and was recovered")
|
|
errWarningFixture = errors.New("a local warning has a cause")
|
|
errPartialFixture = errors.New("the local report could not be completed")
|
|
)
|
|
|
|
func newApp() (*commandkit.App, error) {
|
|
countDefault := 1
|
|
tagDefaults := []string{"demo"}
|
|
greet := commandkit.NewCommand(commandkit.CommandSpec[greetInput]{
|
|
Name: "greet",
|
|
Summary: "Show presence-aware values and repeated labels.",
|
|
Flags: []commandkit.Flag[greetInput]{
|
|
commandkit.ValueFlag(commandkit.FlagMeta{Name: "count", Usage: "Greeting count."}, &countDefault, strconv.Atoi, func(input *greetInput, value commandkit.Supplied[int]) {
|
|
input.Count = value
|
|
}),
|
|
commandkit.RepeatFlag(commandkit.FlagMeta{Name: "tag", Usage: "A repeatable label."}, tagDefaults, func(value string) (string, error) { return value, nil }, func(input *greetInput, value commandkit.Supplied[[]string]) {
|
|
input.Tags = value
|
|
}),
|
|
},
|
|
Run: func(invocation commandkit.Invocation, input greetInput) commandkit.Outcome {
|
|
reporter := invocation.Reporter()
|
|
count := fmt.Sprintf("default %d (not supplied)", input.Count.Value)
|
|
if input.Count.Set {
|
|
count = fmt.Sprintf("explicit %d", input.Count.Value)
|
|
}
|
|
tags := fmt.Sprintf("default %v (not supplied)", input.Tags.Value)
|
|
if input.Tags.Set {
|
|
tags = fmt.Sprintf("explicit %v", input.Tags.Value)
|
|
}
|
|
_ = reporter.RenderOutput(func(writer io.Writer) error {
|
|
_, err := fmt.Fprintf(writer, "Hello; count=%s; tags=%s; entered=%q; canonical=%q\n", count, tags, invocation.EnteredPath(), invocation.CanonicalPath())
|
|
return err
|
|
})
|
|
return commandkit.Success()
|
|
},
|
|
})
|
|
report := commandkit.NewCommand(commandkit.CommandSpec[reportInput]{
|
|
Name: "report",
|
|
Summary: "Demonstrate invocation reporting with local scenarios.",
|
|
NewInput: func() reportInput {
|
|
return reportInput{Scenario: "demo"}
|
|
},
|
|
Arguments: []commandkit.Argument[reportInput]{
|
|
commandkit.ValueArgument(commandkit.ArgumentMeta{Name: "scenario", Usage: "demo, recover, warn, warn-error, fail, or partial."}, false, func(value string) (string, error) { return value, nil },
|
|
func(input *reportInput, value commandkit.Supplied[string]) { input.Scenario = value.Value }),
|
|
},
|
|
CheckInput: func(input reportInput) error {
|
|
switch input.Scenario {
|
|
case "demo", "recover", "warn", "warn-error", "fail", "partial":
|
|
return nil
|
|
default:
|
|
return fmt.Errorf("unknown reporting scenario %q", input.Scenario)
|
|
}
|
|
},
|
|
Run: func(invocation commandkit.Invocation, input reportInput) commandkit.Outcome {
|
|
return runReportingExample(invocation, input.Scenario)
|
|
},
|
|
})
|
|
workspace := commandkit.Group("workspace", "Workspace commands.", greet)
|
|
declarations := []commandkit.Declaration{
|
|
workspace,
|
|
report,
|
|
commandkit.Alias("hello", "workspace greet"),
|
|
commandkit.Alias("ws", "workspace"),
|
|
commandkit.FlagAliasFor("workspace greet", "--times", "--count"),
|
|
commandkit.FlagAlias("--hlep", "--help"),
|
|
}
|
|
return commandkit.New(commandkit.Identity{Name: "core-example", Version: "1.0"}, declarations...)
|
|
}
|
|
|
|
func runReportingExample(invocation commandkit.Invocation, scenario string) commandkit.Outcome {
|
|
reporter := invocation.Reporter()
|
|
deferred := reporter.AtEnd()
|
|
switch scenario {
|
|
case "demo":
|
|
_ = reporter.Progress("Loaded one local fixture.")
|
|
_ = deferred.Warn("Optional fixture warning", func(writer io.Writer) error {
|
|
_, err := io.WriteString(writer, "The sample contains an optional note.\n")
|
|
return err
|
|
})
|
|
_ = deferred.Info("Using deterministic local data.")
|
|
_ = deferred.Debug("Selected the built-in reporting example.")
|
|
_ = deferred.Info("Summary", writeExampleSummary)
|
|
_ = reporter.RenderOutput(writeExampleReport)
|
|
return commandkit.Success()
|
|
case "recover":
|
|
return commandkit.Success().WithCause(errRecoveredFixture)
|
|
case "warn":
|
|
_ = deferred.Warn("The local operation completed with a warning.")
|
|
return commandkit.Success()
|
|
case "warn-error":
|
|
_ = deferred.Warn("The local operation completed with a warning.")
|
|
return commandkit.Success().WithCause(errWarningFixture)
|
|
case "fail":
|
|
return commandkit.Failure("The selected local operation could not be completed.")
|
|
case "partial":
|
|
_ = reporter.RenderOutput(writePartialExampleReport)
|
|
return commandkit.Failure("The local report stopped after partial output.").WithCause(errPartialFixture)
|
|
default:
|
|
return commandkit.Usage(fmt.Sprintf("unknown reporting scenario %q", scenario))
|
|
}
|
|
}
|
|
|
|
func writeExampleReport(writer io.Writer) error {
|
|
_, err := fmt.Fprintln(writer, "Prepared a local report from one fixture.")
|
|
return err
|
|
}
|
|
|
|
func writePartialExampleReport(writer io.Writer) error {
|
|
_, err := io.WriteString(writer, "Partial local report: first section complete.\n")
|
|
return err
|
|
}
|
|
|
|
func writeExampleSummary(writer io.Writer) error {
|
|
_, err := io.WriteString(writer, "Processed one local fixture.\n")
|
|
return err
|
|
}
|
|
|
|
func main() {
|
|
app, err := newApp()
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
outcome := app.Execute(context.Background(), os.Args[1:], commandkit.Streams{Out: os.Stdout, Err: os.Stderr})
|
|
if outcome.Status != 0 {
|
|
os.Exit(outcome.Status)
|
|
}
|
|
}
|