#58 refactor cli commands#65
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors the CLI command structure by separating the server binary (otto) from the CLI control tool (ottoctl). The main changes involve moving command-line functionality from the cmd/ package into a new cmd/ottoctl/ package, centralizing version management, and simplifying the main server entry point.
Key Changes:
- Split the monolithic CLI into two distinct binaries:
otto(server) andottoctl(CLI client) - Introduced a centralized version constant in
version.go - Added
/versionHTTP endpoint to the server with GetVersion client method
Reviewed changes
Copilot reviewed 33 out of 34 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| version.go | New file defining the version constant (0.0.12) |
| otto.go | Removed init function, added /version endpoint handler, added empty ServeHTTP method |
| otto_test.go | Removed TestOttOBrokerShutdown test |
| cmd/otto/main.go | Simplified to directly start server without cobra commands |
| cmd/ottoctl/ | New package containing refactored CLI commands (version, stats, stations, cli) |
| cmd/ottoctl/ottoctl/main.go | New entry point for ottoctl binary |
| cmd/ottoctl/testdata/ | New test data files for version, stats, stations, and help |
| cmd/cmd_*.go | Removed old command files (serve, version, ticker, stats, stations, file) |
| client/client.go | Added GetVersion method to retrieve server version |
| Makefile | Updated to build both otto and ottoctl binaries |
| .gitignore | Updated to include ottoctl binary |
Comments suppressed due to low confidence (4)
cmd/ottoctl/cmd_stats.go:23
- The GetClient function now always returns a non-nil client because the serverURL flag has a default value of "http://localhost:8011" (line 31). This means the nil check on line 21 will never be true, causing the error message on line 22 to be unreachable. If a nil client is a valid scenario, the default value should be empty string, or the logic should handle the default differently.
cmd/ottoctl/cmd_root.go:61 - The ottoRun function is empty but is set as the Run handler for the root command. According to the removed code history (cmd/cmd_root.go line 60-61), this used to call serveRun. The function should either have a meaningful implementation or display usage/help information when no subcommand is provided.
cmd/ottoctl/cmd_root.go:32 - The 'format' flag is defined and documented (line 32) but is never used in any of the command implementations. Commands like stations and stats always output JSON format. Either implement the format flag to allow human-readable output or remove it if not needed.
cmd/ottoctl/cmd_root.go:63 - The GetClient comment states it returns nil "if remote mode is enabled" but this is backwards - it should say "returns an Otto client if a server URL is configured, nil otherwise" to accurately reflect the function's behavior.
| @@ -0,0 +1 @@ | |||
| package ottoctl | |||
There was a problem hiding this comment.
The cmd_stations_test.go file only contains a package declaration with no test functions. Since other command files in this package have test coverage (e.g., cmd_version_test.go, cmd_root_test.go, cmd_cli_test.go), the stations command should also have test coverage to maintain consistency and ensure the command works correctly.
| otto [command] | ||
|
|
||
| Available Commands: | ||
| cli Run auto in interactive CLI mode |
There was a problem hiding this comment.
The command description has a typo: "Run auto in interactive CLI mode" should be "Run otto in interactive CLI mode". The word "auto" should be "otto" to match the application name.
| cli Run auto in interactive CLI mode | |
| cli Run otto in interactive CLI mode |
| o.Server.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) { | ||
| w.Write([]byte(fmt.Sprintf(`{"version": "%s"}`, version))) | ||
| }) |
There was a problem hiding this comment.
The version handler references an unexported variable 'version' (lowercase), but this file defines an exported 'Version' (uppercase) variable at line 167. This will cause a compilation error. The handler should use the version constant from the new version.go file or the exported Version variable.
| if client == nil { | ||
| fmt.Fprintf(cmdOutput, "Failed to get an otto client") | ||
| return | ||
| } |
There was a problem hiding this comment.
The GetClient function now always returns a non-nil client because the serverURL flag has a default value of "http://localhost:8011" (cmd_root.go line 31). This means the nil check on line 20 will never be true, causing the error message on line 21 to be unreachable. If a nil client is a valid scenario, the default value should be empty string, or the logic should handle the default differently.
| if client == nil { | |
| fmt.Fprintf(cmdOutput, "Failed to get an otto client") | |
| return | |
| } |
| func (o *OttO) ServeHTTP(w *http.ResponseWriter, r http.Request) { | ||
|
|
||
| } |
There was a problem hiding this comment.
The ServeHTTP method is empty and appears to be unused. If this method is intended to implement the http.Handler interface, it should have a proper implementation. If it's not needed, it should be removed. Additionally, the method signature is incorrect - the ResponseWriter parameter should be a value, not a pointer (http.ResponseWriter is already an interface).
| @@ -0,0 +1 @@ | |||
| package ottoctl | |||
There was a problem hiding this comment.
The cmd_stats_test.go file only contains a package declaration with no test functions. Since other command files in this package have test coverage (e.g., cmd_version_test.go, cmd_root_test.go, cmd_cli_test.go), the stats command should also have test coverage to maintain consistency and ensure the command works correctly.
| go build -o ${OTTOCTL_BINARY} -ldflags "-X github.com/rustyeddy/otto/cmd.version=${VERSION}" ./cmd/ottoctl/ottoctl | ||
|
|
||
| otto: | ||
| go build -o ${OTTO_BINARY} -ldflags "-X github.com/rustyeddy/otto/cmd.version=${VERSION}" ./cmd/otto |
There was a problem hiding this comment.
The ldflags parameter attempts to set a version variable in the wrong package path. It references "github.com/rustyeddy/otto/cmd.version" but the cmd package no longer exists in this refactoring. Since version is now defined in version.go as an unexported variable in the otto package, the ldflags should either be removed or updated to set the correct variable path like "github.com/rustyeddy/otto.version" (if the variable is made exported).
| go build -o ${OTTOCTL_BINARY} -ldflags "-X github.com/rustyeddy/otto/cmd.version=${VERSION}" ./cmd/ottoctl/ottoctl | |
| otto: | |
| go build -o ${OTTO_BINARY} -ldflags "-X github.com/rustyeddy/otto/cmd.version=${VERSION}" ./cmd/otto | |
| go build -o ${OTTOCTL_BINARY} ./cmd/ottoctl/ottoctl | |
| otto: | |
| go build -o ${OTTO_BINARY} ./cmd/otto |
| if err != nil { | ||
| fmt.Fprintln(cmdOutput, "Failed to get otto client", err) | ||
| } | ||
| version, ex := vmap["version"] | ||
| if !ex { | ||
| fmt.Fprintf(errOutput, "%s\n", "failed to get version") | ||
| return errors.New("failed to get version") |
There was a problem hiding this comment.
The error message format is inconsistent. Line 25 uses "Failed to get otto client" with Fprintln, while line 29 writes to errOutput and line 30 returns a proper error. These should be consolidated - either return the original error from line 24 immediately, or write a consistent error message to errOutput.
| type tstInput struct { | ||
| response string | ||
| buffer *bytes.Buffer | ||
| errbuf *bytes.Buffer | ||
| cmd *cobra.Command | ||
| args []string | ||
| } |
There was a problem hiding this comment.
The type name 'tstInput' uses an abbreviated name that is unclear. Following Go naming conventions and the project's guidelines for clear naming, this should be renamed to something more descriptive like 'testInput' or 'commandTestInput' to better indicate its purpose.
| @@ -25,18 +25,3 @@ func TestOttOInit(t *testing.T) { | |||
| }() | |||
| o.Stop() | |||
| } | |||
There was a problem hiding this comment.
The TestOttOBrokerShutdown test has been removed without replacement. This test was validating important shutdown behavior for the broker. If this functionality is still relevant, consider adding an equivalent test to ensure proper shutdown handling is maintained.
#58