2525package main
2626
2727import (
28- "github.com/jkaninda/okapi"
29- "github.com/jkaninda/okapi/okapicli"
28+ "fmt"
3029 "log/slog"
3130 "os"
3231 "time"
32+
33+ "github.com/jkaninda/okapi"
34+ "github.com/jkaninda/okapi/okapicli"
3335)
3436
3537type ServerConfig struct {
@@ -47,69 +49,78 @@ type Config struct {
4749}
4850
4951func main () {
50- cfg := & ServerConfig {}
51- // Create default Okapi instance
5252 o := okapi .Default ()
53+ cli := okapicli .New (o , "myapp" )
5354
54- // Create CLI instance
55- cli := okapicli .New (o , "Okapi CLI Example" ).FromStruct (cfg )
56- // Or
57- // cli := okapicli.New(o, "Okapi CLI Example").
58- // String("config", "c", "config.yaml", "Path to configuration file").
59- // Int("port", "p", 8000, "HTTP server port").
60- // Bool("debug", "d", false, "Enable debug mode")
61-
62- // Parse flags
63- if err := cli .Parse (); err != nil {
64- panic (err )
65- }
66-
67- // Apply CLI options
68- o .WithPort (cfg .Port )
69- // Or
70- // o.WithPort(cli.GetInt("port"))
71- if cli .GetBool ("debug" ) {
72- o .WithDebug ()
73- }
55+ // Subcommand: serve
56+ serveCfg := & ServerConfig {}
57+ cli .Command ("serve" , "Start the HTTP server" , func (cmd * okapicli.Command ) error {
58+ // Apply parsed config
59+ cmd .Okapi ().WithPort (serveCfg .Port )
60+ if serveCfg .Debug {
61+ cmd .Okapi ().WithDebug ()
62+ }
7463
75- // Load configuration
76- config := & Config {}
77- if path := cli .GetString ("config" ); path != "" {
78- slog .Info ("Loading configuration" , "path" , path )
79- if err := cli .LoadConfig (path , config ); err != nil {
80- slog .Error ("Failed to load configuration" , "error" , err )
64+ // Load app config from file
65+ config := & Config {}
66+ if path := serveCfg .Config ; path != "" {
67+ slog .Info ("Loading configuration" , "path" , path )
68+ if err := cmd .CLI ().LoadConfig (path , config ); err != nil {
69+ slog .Error ("Failed to load configuration" , "error" , err )
70+ }
8171 }
82- }
8372
84- // Define routes
85- o .Get ("/" , func (ctx * okapi.Context ) error {
86- return ctx .OK (okapi.M {
87- "message" : "Hello, Okapi!" ,
73+ // Define routes
74+ cmd .Okapi ().Get ("/" , func (ctx * okapi.Context ) error {
75+ return ctx .OK (okapi.M {"message" : "Hello, Okapi!" })
8876 })
77+
78+ // Run server with lifecycle hooks
79+ return cmd .CLI ().RunServer (& okapicli.RunOptions {
80+ ShutdownTimeout : 30 * time .Second ,
81+ Signals : []os.Signal {okapicli .SIGINT , okapicli .SIGTERM },
82+ OnStart : func () {
83+ slog .Info ("Preparing resources before startup" )
84+ if config .DatabaseURL != "" {
85+ slog .Info ("Connecting to database" )
86+ }
87+ },
88+ OnStarted : func () {
89+ slog .Info ("Server started successfully" )
90+ },
91+ OnShutdown : func () {
92+ slog .Info ("Cleaning up before shutdown" )
93+ },
94+ })
95+ }).FromStruct (serveCfg )
96+
97+ // Subcommand: worker
98+ cli .Command ("worker" , "Start application worker" , func (cmd * okapicli.Command ) error {
99+
100+ fmt .Println ("Starting myapp wortker..." )
101+ sleepTime := cmd .GetDuration ("sleep" ) * time .Second
102+ slog .Info ("Worker started successfully" , "concurrency" , cmd .GetInt ("concurrency" ), "sleep" , sleepTime )
103+
104+ time .Sleep (sleepTime )
105+ fmt .Println ("Stoping myapp wortker..." )
106+ return nil
107+ }).Int ("concurrency" , "c" , 3 , "concurrency jobs" ).Duration ("sleep" , "" , 5 , "Sleep time" )
108+ // Subcommand: version
109+ cli .Command ("version" , "Show the worker" , func (cmd * okapicli.Command ) error {
110+ fmt .Println ("myapp v1.0.0" )
111+ return nil
89112 })
90113
91- // Run server with lifecycle hooks
92- if err := cli .RunServer (& okapicli.RunOptions {
93- ShutdownTimeout : 30 * time .Second , // Optional: customize shutdown timeout
94- Signals : []os.Signal {okapicli .SIGINT , okapicli .SIGTERM }, // Optional: customize shutdown signals
95- OnStart : func () {
96- slog .Info ("Preparing resources before startup" )
97- if config .DatabaseURL != "" {
98- slog .Info ("Connecting to database" )
99- }
100- },
101- OnStarted : func () {
102- slog .Info ("Server started successfully" )
103- },
104- OnShutdown : func () {
105- slog .Info ("Cleaning up before shutdown" )
106- },
107- }); err != nil {
108- panic (err )
109- }
114+ // Set "serve" as the default command (runs when no subcommand is given)
115+ cli .DefaultCommand ("serve" )
110116
111- // Or use defaults
112- // if err := cli.Run(); err != nil {
113- // panic(err)
114- // }
117+ // Execute: parses os.Args for the subcommand and runs it
118+ // Usage:
119+ // myapp serve --port 9090 --debug
120+ // myapp worker --concurrency 5 --slep 5
121+ // myapp version
122+ if err := cli .Execute (); err != nil {
123+ slog .Error ("Error" , "error" , err )
124+ os .Exit (1 )
125+ }
115126}
0 commit comments