@@ -34,10 +34,22 @@ import (
3434 "github.com/blinklabs-io/adder/pipeline"
3535 "github.com/blinklabs-io/adder/plugin"
3636 "github.com/inconshreveable/mousetrap"
37+ "github.com/spf13/cobra"
3738 "go.uber.org/automaxprocs/maxprocs"
3839)
3940
40- var programName string = "adder"
41+ var (
42+ programName string = "adder"
43+ cfg = config .GetConfig ()
44+ rootCmd = & cobra.Command {
45+ Use : programName ,
46+ SilenceUsage : true ,
47+ Args : cobra .NoArgs ,
48+ RunE : func (cmd * cobra.Command , args []string ) error {
49+ return run ()
50+ },
51+ }
52+ )
4153
4254func slogPrintf (format string , v ... any ) {
4355 slog .Info (fmt .Sprintf (format , v ... ))
@@ -46,6 +58,7 @@ func slogPrintf(format string, v ...any) {
4658func init () {
4759 if os .Args != nil && os .Args [0 ] != programName {
4860 programName = os .Args [0 ]
61+ rootCmd .Use = programName
4962 }
5063
5164 // Bail if we were run via double click on Windows, borrowed from ngrok
@@ -64,58 +77,47 @@ func init() {
6477 os .Exit (1 )
6578 }
6679 }
67- }
68-
69- func main () {
70- cfg := config .GetConfig ()
71-
72- if os .Args == nil {
73- fmt .Println ("Failed to detect arguments, aborting" )
74- os .Exit (1 )
75- }
7680
77- if err := cfg .ParseCmdlineArgs (programName , os .Args [1 :]); err != nil {
78- fmt .Printf ("Failed to parse commandline: %s\n " , err )
79- os .Exit (1 )
81+ if err := cfg .BindFlags (rootCmd .Flags ()); err != nil {
82+ panic (err )
8083 }
84+ }
8185
86+ func run () error {
8287 if cfg .Version {
8388 fmt .Printf ("%s %s\n " , programName , version .GetVersionString ())
84- os . Exit ( 0 )
89+ return nil
8590 }
8691
8792 if cfg .Input == "list" {
8893 fmt .Printf ("Available input plugins:\n \n " )
8994 for _ , plugin := range plugin .GetPlugins (plugin .PluginTypeInput ) {
9095 fmt .Printf ("%- 14s %s\n " , plugin .Name , plugin .Description )
9196 }
92- return
97+ return nil
9398 }
9499
95100 if cfg .Output == "list" {
96101 fmt .Printf ("Available output plugins:\n \n " )
97102 for _ , plugin := range plugin .GetPlugins (plugin .PluginTypeOutput ) {
98103 fmt .Printf ("%- 14s %s\n " , plugin .Name , plugin .Description )
99104 }
100- return
105+ return nil
101106 }
102107
103108 // Load config
104109 if err := cfg .Load (cfg .ConfigFile ); err != nil {
105- fmt .Printf ("Failed to load config: %s\n " , err )
106- os .Exit (1 )
110+ return fmt .Errorf ("failed to load config: %w" , err )
107111 }
108112
109113 // Process config for plugins
110114 if err := plugin .ProcessConfig (cfg .Plugin ); err != nil {
111- fmt .Printf ("Failed to process plugin config: %s\n " , err )
112- os .Exit (1 )
115+ return fmt .Errorf ("failed to process plugin config: %w" , err )
113116 }
114117
115118 // Process env vars for plugins
116119 if err := plugin .ProcessEnvVars (); err != nil {
117- fmt .Printf ("Failed to process env vars: %s\n " , err )
118- os .Exit (1 )
120+ return fmt .Errorf ("failed to process env vars: %w" , err )
119121 }
120122
121123 // Configure logging
@@ -128,7 +130,7 @@ func main() {
128130 if err != nil {
129131 // If we hit this, something really wrong happened
130132 logger .Error (err .Error ())
131- os . Exit ( 1 )
133+ return err
132134 }
133135
134136 // Start debug listener
@@ -170,7 +172,7 @@ func main() {
170172 input := plugin .GetPlugin (plugin .PluginTypeInput , cfg .Input )
171173 if input == nil {
172174 logger .Error ("unknown input: " + cfg .Input )
173- os . Exit ( 1 )
175+ return fmt . Errorf ( "unknown input: %s" , cfg . Input )
174176 }
175177 pipe .AddInput (input )
176178
@@ -184,7 +186,7 @@ func main() {
184186 output := plugin .GetPlugin (plugin .PluginTypeOutput , cfg .Output )
185187 if output == nil {
186188 logger .Error ("unknown output: " + cfg .Output )
187- os . Exit ( 1 )
189+ return fmt . Errorf ( "unknown output: %s" , cfg . Output )
188190 }
189191 // Check if output plugin implements APIRouteRegistrar
190192 if registrar , ok := any (output ).(api.APIRouteRegistrar ); ok {
@@ -195,13 +197,13 @@ func main() {
195197 // Start API after plugins are configured
196198 if err := apiInstance .Start (); err != nil {
197199 logger .Error (fmt .Sprintf ("failed to start API: %s" , err ))
198- os . Exit ( 1 )
200+ return fmt . Errorf ( "failed to start API: %w" , err )
199201 }
200202
201203 // Start pipeline and wait for error
202204 if err := pipe .Start (); err != nil {
203205 logger .Error (fmt .Sprintf ("failed to start pipeline: %s" , err ))
204- os . Exit ( 1 )
206+ return fmt . Errorf ( "failed to start pipeline: %w" , err )
205207 }
206208
207209 // Setup graceful shutdown
@@ -225,8 +227,15 @@ func main() {
225227 // Graceful shutdown using Stop() method
226228 if err := pipe .Stop (); err != nil {
227229 logger .Error (fmt .Sprintf ("failed to stop pipeline: %s" , err ))
228- os . Exit ( 1 )
230+ return fmt . Errorf ( "failed to stop pipeline: %w" , err )
229231 }
230232
231233 logger .Info ("Adder stopped gracefully" )
234+ return nil
235+ }
236+
237+ func main () {
238+ if err := rootCmd .Execute (); err != nil {
239+ os .Exit (1 )
240+ }
232241}
0 commit comments