-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[feat:] Added Config Command to Kitops CLI #523
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Akash Singh <[email protected]>
Signed-off-by: Akash Singh <[email protected]>
@amisevsk Could you please review this PR and suggest upon how we can improve it? |
Signed-off-by: Akash Singh <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution! I have a few initial comments
pkg/cmd/config/config.go
Outdated
// DefaultConfig returns a Config struct with default values. | ||
func DefaultConfig() *Config { | ||
return &Config{ | ||
LogLevel: "info", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should use the constants from the output package
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you confirm if we should also do this for Progress and ConfigDir as well? If so, we will need to change the var names in output package for Progress to Capitalise and export
Signed-off-by: Akash Singh <[email protected]>
@amisevsk Your requested changes have been made :D |
Signed-off-by: Akash <[email protected]>
This commit refactors the code related to loading and saving the configuration file. It introduces a new function `ConfigFilePath` in the `consts.go` file to generate the path for the configuration file based on the `configHome` directory. The `LoadConfig` function now returns the default configuration if the file doesn't exist, and the `SaveConfig` function creates the directory before saving the file. These changes improve the reliability and maintainability of the configuration handling. Fixes jozu-ai#419
@amisevsk Your requested changes have been made! |
Can you add the license header for |
@gorkem license header has been added! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code that manually parses subcommands and arguments has logic errors that needs to be fixed. The code manually inspects args[0] to determine the subcommand, which is not the standard practice. It is better to Define each subcommand (set, get, list, reset) as separate Cobra commands.
pkg/cmd/config/cmd.go
Outdated
if len(args) == 0 { | ||
return fmt.Errorf("no configuration key provided") | ||
} | ||
opts.key = args[0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way that config command is implemented is set/get/list/reset are not subcommands but rather args. Therefore the args[0] in here receives the value of the subcommand (get/set/list/reset). This works for no argument subcommands (list/reset) but everything else does not work.
I think a better way to do this would be to add the (set/get/list/reset) as subcommands.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored to include set/get/list/reset as subcommands.
pkg/cmd/config/config.go
Outdated
cfg = DefaultConfig() | ||
} | ||
|
||
v := reflect.ValueOf(cfg).Elem().FieldByName(strings.Title(opts.key)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace strings.Title
with cases.Title
from the golang.org/x/text/cases
package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored!
pkg/cmd/config/cmd.go
Outdated
} | ||
|
||
cmd.Args = cobra.MinimumNArgs(1) | ||
cmd.Flags().SortFlags = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed if there are no flags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored
Co-authored-by: Gorkem Ercan <[email protected]>
@gorkem Your requested changes have been made, could you kindly review? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much better but setting the logLevel did not work for me. Using reflection to find keys maybe too fragile.
pkg/cmd/config/config.go
Outdated
return "", err | ||
} | ||
|
||
v := reflect.ValueOf(cfg).Elem().FieldByName(strings.Title(opts.key)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also update this to use cases.Title
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactored
pkg/cmd/config/config.go
Outdated
caser := cases.Title(language.Und) | ||
v := reflect.ValueOf(cfg).Elem().FieldByName(caser.String(opts.key)) | ||
if !v.IsValid() { | ||
return fmt.Errorf("unknown configuration key: %s", opts.key) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caser is causing issues here; since we're using camelcase for config settings (LogLevel
), attempting to modify case will mangle fields, turning LogLevel
, logLevel
, etc. into Loglevel
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pkg/cmd/config/cmd.go
Outdated
return fmt.Errorf("failed to complete options: %w", err) | ||
} | ||
if err := setConfig(ctx, opts); err != nil { | ||
return fmt.Errorf("failed to set config: %w", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A quirk of how we've implemented error handling in commands means that returned errors here are gobbled up (we have to do this to avoid Cobra's default error printing, prints the usage doc every time -- see here)
This means the caser issue I mentioned is getting silently eaten, and the CLI is just exiting with status code 1. Instead, you want to replace the returns from RunE
functions with output.Fatalf
or output.Fatalln
(using %s
for errors instead of %w
), both here and in the other subcommands.
With the change:
❯ kit config set LogLevel debug
[ERROR] Failed to set config: unknown configuration key: LogLevel
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a super interesting implementation! I have refactored and fixed this!
…onsistent logging
@amisevsk Your requested changes have been made! |
Description
This PR introduces the new
config
command for the KitOps CLI. It allows users to manage the configuration of CLI settings more easily. With this command, users can set, get, list, and reset configuration values for persistent options like storage paths, credentials, logging levels, and other preferences.Key additions:
Config command: Introduced the
config
command with four subcommands:set
: Allows users to set configuration values.get
: Retrieves the value of a specified configuration key.list
: Lists all current configuration options and their values.reset
: Resets all configurations back to default values.Persistent root flags: The root command now uses configuration settings from the
config.json
file for default values like--log-level
,--progress
, and--verbose
, while still allowing overrides via command-line arguments.Linked Issues
Closes issue #419