From 3eec75686385f041f387b6d1b525c216c13412cd Mon Sep 17 00:00:00 2001 From: Tink bot Date: Tue, 26 May 2026 22:38:27 +0200 Subject: [PATCH] feat(veans): add cobra root and version subcommand --- veans/cmd/veans/main.go | 15 +++++++++ veans/internal/commands/root.go | 60 +++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 veans/cmd/veans/main.go create mode 100644 veans/internal/commands/root.go diff --git a/veans/cmd/veans/main.go b/veans/cmd/veans/main.go new file mode 100644 index 000000000..d34f33d68 --- /dev/null +++ b/veans/cmd/veans/main.go @@ -0,0 +1,15 @@ +// veans — a beans-shaped CLI for Vikunja. +package main + +import ( + "os" + + "code.vikunja.io/veans/internal/commands" +) + +// version is overwritten via -ldflags at release time. +var version = "dev" + +func main() { + os.Exit(commands.Execute(version)) +} diff --git a/veans/internal/commands/root.go b/veans/internal/commands/root.go new file mode 100644 index 000000000..c18e572de --- /dev/null +++ b/veans/internal/commands/root.go @@ -0,0 +1,60 @@ +// Package commands wires the cobra command tree. Each subcommand lives in a +// sibling file; root.go owns shared flags, the global error handler, and the +// JSON output toggle. +package commands + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + + "code.vikunja.io/veans/internal/output" +) + +// Globals carries flags shared across subcommands. The pointer is bound onto +// the root command's persistent flags; subcommands read it via PostRun. +type Globals struct { + JSON bool + Verbose bool +} + +var globals Globals + +// Root builds the cobra command tree. +func Root(version string) *cobra.Command { + root := &cobra.Command{ + Use: "veans", + Short: "veans — a beans-shaped CLI for Vikunja", + SilenceUsage: true, + SilenceErrors: true, + Version: version, + } + root.PersistentFlags().BoolVar(&globals.JSON, "json", false, "emit JSON output") + root.PersistentFlags().BoolVar(&globals.Verbose, "verbose", false, "verbose logging to stderr") + + root.AddCommand(newVersionCmd(version)) + + return root +} + +// Execute runs the cobra tree and converts errors into the structured output +// envelope. It returns the desired exit code. +func Execute(version string) int { + cmd := Root(version) + if err := cmd.Execute(); err != nil { + output.EmitError(globals.JSON, err, os.Stderr) + return 1 + } + return 0 +} + +func newVersionCmd(version string) *cobra.Command { + return &cobra.Command{ + Use: "version", + Short: "Print the veans version", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println(version) + }, + } +}