Skip to content

Commit

Permalink
fix: Config path prefers local dir vs. home dir (#184)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpmcb authored Sep 12, 2024
1 parent 7315a1d commit 859446a
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 42 deletions.
10 changes: 8 additions & 2 deletions cmd/generate/codeowners/codeowners.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,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 @@ -102,7 +103,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 @@ -148,6 +153,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

0 comments on commit 859446a

Please sign in to comment.