diff --git a/cmd/debug.go b/cmd/debug.go index 616b66800..35d796dfb 100644 --- a/cmd/debug.go +++ b/cmd/debug.go @@ -70,7 +70,7 @@ func Debug(ctx *cli.Context) error { fmt.Println("API Key: Please set your API Key to access all of the CLI features") } } else { - fmt.Println("Config file: ") + fmt.Printf("Config file: %s (not configured)\n", c.File) fmt.Println("API Key: Please set your API Key to access all of the CLI features") } fmt.Printf("Exercises Directory: %s\n", c.Dir) diff --git a/config/config.go b/config/config.go index 993a39d40..47fcbd3dd 100644 --- a/config/config.go +++ b/config/config.go @@ -34,8 +34,20 @@ type Config struct { // New returns a configuration struct with content from the exercism.json file func New(path string) (*Config, error) { - c := &Config{} - err := c.load(paths.Config(path)) + configPath := paths.Config(path) + _, err := os.Stat(configPath) + if err != nil && os.IsNotExist(err) { + if path == "" { + configPath = paths.DefaultConfig + } + } else if err != nil { + return nil, err + } + + c := &Config{ + File: configPath, + } + err = c.load() return c, err } @@ -84,9 +96,7 @@ func (c *Config) Write() error { return nil } -func (c *Config) load(argPath string) error { - c.File = argPath - +func (c *Config) load() error { if err := c.read(); err != nil { return err } diff --git a/config/config_test.go b/config/config_test.go index 6b1169fa7..c31af77dc 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -17,15 +17,19 @@ func TestLoad(t *testing.T) { if err != nil { t.Fatal(err) } - configPath := filepath.Join(tmpDir, "config.json") + + paths.Home = tmpDir + paths.ConfigHome = tmpDir + paths.DefaultConfig = filepath.Join(tmpDir, "default.json") + + configPath := filepath.Join(paths.ConfigHome, "config.json") if err := os.Link(fixturePath(t, "config.json"), configPath); err != nil { t.Fatal(err) } - dirtyPath := filepath.Join(tmpDir, "dirty.json") + dirtyPath := filepath.Join(paths.ConfigHome, "dirty.json") if err := os.Link(fixturePath(t, "dirty.json"), dirtyPath); err != nil { t.Fatal(err) } - paths.Home = tmpDir testCases := []struct { desc string @@ -36,7 +40,7 @@ func TestLoad(t *testing.T) { { desc: "defaults", in: "", - out: paths.Config(""), + out: paths.DefaultConfig, dir: paths.Exercises(""), key: "", api: hostAPI, diff --git a/paths/paths.go b/paths/paths.go index da3551dda..d4f154d7c 100644 --- a/paths/paths.go +++ b/paths/paths.go @@ -11,7 +11,7 @@ import ( const ( // File is the default name of the JSON file where the config written. // The user can pass an alternate filename when using the CLI. - File = ".exercism.json" + File = "exercism.json" // DirExercises is the default name of the directory for active users. // Make this non-exported when handlers.Login is deleted. DirExercises = "exercism" @@ -20,31 +20,37 @@ const ( var ( // Home by default will contact the location of your home directory. Home string + // ConfigHome will contain $XDG_CONFIG_HOME if it is set or default config home directory. + ConfigHome string + // DefaultConfig will contain default path to config, according to Home + DefaultConfig string - // XDGConfigHome will contain $XDG_CONFIG_HOME if it exists. - XDGConfigHome string errHomeNotFound = errors.New("unable to locate home directory") ) func init() { - // on startup set default values - Recalculate() + var err error + Home, err = findHome() + if err != nil { + panic(err) + } + ConfigHome = os.Getenv("XDG_CONFIG_HOME") + if ConfigHome == "" { + ConfigHome = filepath.Join(Home, ".config") + } + DefaultConfig = filepath.Join(Home, "." + File) } // Config will return the correct input path given any input. -// Blank input will return the default configuration location. +// Blank input will return the default configuration location based +// on ConfigHome. // Non-blank input will expand home to be an absolute path. // If the target is known to be a directory, the config filename // will be appended. func Config(path string) string { if path == "" { - if XDGConfigHome == "" { - return filepath.Join(Home, File) - } - - return filepath.Join(XDGConfigHome, File) + return filepath.Join(ConfigHome, File) } - expandedPath := expandPath(path) if IsDir(path) { expandedPath = filepath.Join(expandedPath, File) @@ -62,18 +68,6 @@ func Exercises(path string) string { return expandPath(path) } -// Recalculate sets exercism paths based on Home. -func Recalculate() { - if Home == "" { - home, err := findHome() - if err != nil { - panic(err) - } - Home = home - } - XDGConfigHome = os.Getenv("XDG_CONFIG_HOME") -} - // IsDir determines whether the given path is a valid directory path. func IsDir(path string) bool { fi, _ := os.Stat(path) @@ -114,7 +108,7 @@ func makeAbsolute(path string) string { } func expandHome(path string) string { - if path[:2] == "~"+string(os.PathSeparator) { + if strings.HasPrefix(path, "~"+string(os.PathSeparator)) { return strings.Replace(path, "~", Home, 1) } return path diff --git a/paths/paths_test.go b/paths/paths_test.go index b9325a0a4..f1bdd9e6a 100644 --- a/paths/paths_test.go +++ b/paths/paths_test.go @@ -12,11 +12,19 @@ func TestHome(t *testing.T) { assert.Equal(t, os.Getenv("HOME"), Home) } +func TestConfigHome(t *testing.T) { + xdgConfigHome := os.Getenv("XDG_CONFIG_HOME") + if xdgConfigHome == "" { + assert.Equal(t, filepath.Join(Home, ".config"), ConfigHome) + } else { + assert.Equal(t, xdgConfigHome, ConfigHome) + } +} + func TestExercises(t *testing.T) { dir, err := os.Getwd() assert.NoError(t, err) Home = "/test/home" - Recalculate() testCases := []struct { givenPath string @@ -40,7 +48,7 @@ func TestConfig(t *testing.T) { assert.NoError(t, err) Home = dir - Recalculate() + ConfigHome = dir testCases := []struct { desc string @@ -50,7 +58,7 @@ func TestConfig(t *testing.T) { { "blank path", "", - filepath.Join(Home, ".exercism.json"), + filepath.Join(ConfigHome, File), }, { "unknown path is expanded, but not modified", @@ -74,10 +82,3 @@ func TestConfig(t *testing.T) { assert.Equal(t, tc.expectedPath, actual, tc.desc) } } - -func TestXDGConfig(t *testing.T) { - XDGConfigHome = "/home/user/.xdg_config" - - assert.Equal(t, filepath.Join(XDGConfigHome, File), Config("")) - -}