Skip to content
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

fix: Config path prefers local dir vs. home dir #184

Merged
merged 1 commit into from
Sep 12, 2024
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
10 changes: 8 additions & 2 deletions cmd/generate/codeowners/codeowners.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ type Options struct {
// telemetry for capturing CLI events via PostHog
telemetry *utils.PosthogCliClient

config *config.Spec
config *config.Spec
configLoadedPath string
}

const codeownersLongDesc string = `Generates a CODEOWNERS file for a given git repository. The generated file specifies up to 3 owners for EVERY file in the git tree based on the number of lines touched in that specific file over the specified range of time.
Expand Down Expand Up @@ -109,7 +110,11 @@ pizza generate codeowners . --config /path/to/.sauced.yaml
opts.telemetry = utils.NewPosthogCliClient(!disableTelem)

configPath, _ := cmd.Flags().GetString("config")
opts.config, err = config.LoadConfig(configPath)
if configPath == "" {
configPath = filepath.Join(opts.path, ".sauced.yaml")
}

opts.config, opts.configLoadedPath, err = config.LoadConfig(configPath)
if err != nil {
return err
}
Expand Down Expand Up @@ -155,6 +160,7 @@ func run(opts *Options, cmd *cobra.Command) error {
return fmt.Errorf("could not build logger: %w", err)
}
opts.logger.V(logging.LogDebug).Style(0, colors.FgBlue).Infof("Built logger with log level: %d\n", opts.loglevel)
opts.logger.V(logging.LogDebug).Style(0, colors.FgBlue).Infof("Loaded config from: %s\n", opts.configLoadedPath)

repo, err := git.PlainOpen(opts.path)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func NewRootCommand() (*cobra.Command, error) {
cmd.PersistentFlags().StringP(constants.FlagNameEndpoint, "e", constants.EndpointProd, "The API endpoint to send requests to")
cmd.PersistentFlags().Bool(constants.FlagNameBeta, false, fmt.Sprintf("Shorthand for using the beta OpenSauced API endpoint (\"%s\"). Supersedes the '--%s' flag", constants.EndpointBeta, constants.FlagNameEndpoint))
cmd.PersistentFlags().Bool(constants.FlagNameTelemetry, false, "Disable sending telemetry data to OpenSauced")
cmd.PersistentFlags().StringP("config", "c", "~/.sauced.yaml", "The codeowners config")
cmd.PersistentFlags().StringP("config", "c", "", "The codeowners config")
cmd.PersistentFlags().StringP("log-level", "l", "info", "The logging level. Options: error, warn, info, debug")
cmd.PersistentFlags().Bool("tty-disable", false, "Disable log stylization. Suitable for CI/CD and automation")

Expand Down
74 changes: 38 additions & 36 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,55 +9,57 @@ import (
"gopkg.in/yaml.v3"
)

// LoadConfig loads a configuration file at a given path. It attempts to load
// the default location of a ".sauced.yaml" in the current working directory if an
// empty path is provided. If none is found, it tries to load
// "~/.sauced.yaml" from the fallback path, which is the user's home directory.
func LoadConfig(path string) (*Spec, error) {
println("Config path loading from -c flag", path)
// LoadConfig loads a configuration file at a given path.
// If the provided path does not exist or doesn't contain a ".sauced.yaml" file,
// "~/.sauced.yaml" from the fallback path, which is the user's home directory, is used.
//
// This function returns the config Spec, the location the spec was loaded from, and an error
func LoadConfig(path string) (*Spec, string, error) {
givenPathSpec, givenLoadedPath, givenPathErr := loadSpecAtPath(path)
if givenPathErr == nil {
return givenPathSpec, givenLoadedPath, nil
}

homePathSpec, homeLoadedPath, homePathErr := loadSpecAtHome()
if homePathErr == nil {
return homePathSpec, homeLoadedPath, nil
}

return nil, "", fmt.Errorf("could not load config at given path: %w - could not load config at home: %w", givenPathErr, homePathErr)
}

func loadSpecAtPath(path string) (*Spec, string, error) {
config := &Spec{}

absPath, err := filepath.Abs(path)
if err != nil {
return nil, fmt.Errorf("error resolving absolute path: %w", err)
return nil, "", fmt.Errorf("error resolving absolute path: %s - %w", path, err)
}

data, err := os.ReadFile(absPath)
if err != nil {
// If the file does not exist, check if the fallback path exists
if os.IsNotExist(err) {
// load the default file path under the user's home dir
usr, err := user.Current()

if err != nil {
return nil, fmt.Errorf("could not get user home directory: %w", err)
}

homeDirPathConfig, err := filepath.Abs(filepath.Join(usr.HomeDir, ".sauced.yaml"))

if err != nil {
return nil, fmt.Errorf("error home directory absolute path: %w", err)
}

_, err = os.Stat(homeDirPathConfig)
if err != nil {
return nil, fmt.Errorf("error reading config file from %s", homeDirPathConfig)
}

data, err = os.ReadFile(homeDirPathConfig)
if err != nil {
return nil, fmt.Errorf("error reading config file from %s or %s", absPath, homeDirPathConfig)
}
} else {
return nil, fmt.Errorf("error reading config file: %w", err)
}
return nil, "", fmt.Errorf("error reading config file from given absolute path: %s - %w", absPath, err)
}

err = yaml.Unmarshal(data, config)
if err != nil {
return nil, fmt.Errorf("error unmarshaling config: %w", err)
return nil, "", fmt.Errorf("error unmarshaling config at: %s - %w", absPath, err)
}

return config, absPath, nil
}

func loadSpecAtHome() (*Spec, string, error) {
usr, err := user.Current()
if err != nil {
return nil, "", fmt.Errorf("could not get user home directory: %w", err)
}

path := filepath.Join(usr.HomeDir, ".sauced.yaml")
conf, loadedPath, err := loadSpecAtPath(path)
if err != nil {
return nil, "", fmt.Errorf("could not load spec at home: %s - %w", path, err)
}

return config, nil
return conf, loadedPath, nil
}
6 changes: 3 additions & 3 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ attribution:

require.NoError(t, os.WriteFile(configFilePath, []byte(fileContents), 0600))

config, err := LoadConfig(configFilePath)
config, _, err := LoadConfig(configFilePath)
require.NoError(t, err)
assert.NotNil(t, config)

Expand All @@ -47,7 +47,7 @@ attribution:
tmpDir := t.TempDir()
nonExistentPath := filepath.Join(tmpDir, ".sauced.yaml")

config, err := LoadConfig(nonExistentPath)
config, _, err := LoadConfig(nonExistentPath)
require.Error(t, err)
assert.Nil(t, config)
})
Expand Down Expand Up @@ -78,7 +78,7 @@ attribution:
_, err := os.ReadFile(fallbackPath)
require.NoError(t, err)

config, err := LoadConfig(fallbackPath)
config, _, err := LoadConfig(fallbackPath)

require.NoError(t, err)
assert.NotNil(t, config)
Expand Down
Loading