Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func main() {
}

app.Commands = []*cli.Command{
commands.InitCommand,
commands.AuthCommand,
commands.TrackCommand,
commands.GCCommand,
Expand Down
4 changes: 2 additions & 2 deletions commands/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import (
)

var AuthCommand *cli.Command = &cli.Command{
Name: "init",
Usage: "init your shelltime.xyz config",
Name: "auth",
Usage: "Authenticate with shelltime.xyz",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "token",
Expand Down
42 changes: 42 additions & 0 deletions commands/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package commands

import (
"github.com/gookit/color"
"github.com/urfave/cli/v2"
)
Comment on lines +3 to +6
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To support error wrapping in commandInit, the fmt package needs to be imported. This will be used to provide more descriptive error messages if any of the initialization steps fail.

Suggested change
import (
"github.com/gookit/color"
"github.com/urfave/cli/v2"
)
import (
"fmt"
"github.com/gookit/color"
"github.com/urfave/cli/v2"
)


var InitCommand *cli.Command = &cli.Command{
Name: "init",
Usage: "Initialize shelltime: authenticate, install hooks, and start daemon",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "token",
Aliases: []string{"t"},
Usage: "Authentication token",
Required: false,
},
},
Action: commandInit,
}

func commandInit(c *cli.Context) error {
color.Yellow.Println("Initializing ShellTime...")

// Step 1: Authenticate
if err := commandAuth(c); err != nil {
return err
}

// Step 2: Install shell hooks
if err := commandHooksInstall(c); err != nil {
return err
}

// Step 3: Install daemon service
if err := commandDaemonInstall(c); err != nil {
return err
}

color.Green.Println("ShellTime is fully initialized and ready to use!")
return nil
}
Comment on lines +22 to +42
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

For better observability and error diagnosis, I suggest two improvements to the commandInit function:

  1. Add Tracing: Introduce an OpenTelemetry trace span for the entire init command. This will group the authentication, hook installation, and daemon installation steps under a single trace, which is great for monitoring and debugging performance.

  2. Error Wrapping: Wrap the errors returned from each step with fmt.Errorf. This adds context to the error messages, making it much clearer which part of the initialization process failed. For example, instead of a generic error, you'd see authentication failed: <original error>.

func commandInit(c *cli.Context) error {
	ctx, span := commandTracer.Start(c.Context, "init")
	defer span.End()
	c.Context = ctx

	color.Yellow.Println("Initializing ShellTime...")

	// Step 1: Authenticate
	if err := commandAuth(c); err != nil {
		return fmt.Errorf("authentication failed: %w", err)
	}

	// Step 2: Install shell hooks
	if err := commandHooksInstall(c); err != nil {
		return fmt.Errorf("shell hooks installation failed: %w", err)
	}

	// Step 3: Install daemon service
	if err := commandDaemonInstall(c); err != nil {
		return fmt.Errorf("daemon service installation failed: %w", err)
	}

	color.Green.Println("ShellTime is fully initialized and ready to use!")
	return nil
}