Skip to content

Commit f58dd42

Browse files
committed
Merge pull request #212 from lcowell/master
move config code concerned with paths in to separate package
2 parents 6ad8f9c + c47e014 commit f58dd42

6 files changed

Lines changed: 214 additions & 172 deletions

File tree

cmd/debug.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
"github.com/codegangsta/cli"
1212
"github.com/exercism/cli/config"
13+
"github.com/exercism/cli/paths"
1314
)
1415

1516
// Debug provides information about the user's environment and configuration.
@@ -37,11 +38,7 @@ func Debug(ctx *cli.Context) {
3738
fmt.Printf("Build ARMv%s\n", BuildARM)
3839
}
3940

40-
dir, err := config.Home()
41-
if err != nil {
42-
log.Fatal(err)
43-
}
44-
fmt.Printf("Home Dir: %s\n", dir)
41+
fmt.Printf("Home Dir: %s\n", paths.Home)
4542

4643
c, err := config.New(ctx.GlobalString("config"))
4744
if err != nil {

cmd/demo.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/codegangsta/cli"
88
"github.com/exercism/cli/api"
99
"github.com/exercism/cli/config"
10+
"github.com/exercism/cli/paths"
1011
"github.com/exercism/cli/user"
1112
)
1213

@@ -25,7 +26,7 @@ func Demo(ctx *cli.Context) {
2526
}
2627

2728
if dirOpt := ctx.String("dir"); dirOpt != "" {
28-
c.SetDir(dirOpt)
29+
c.Dir = paths.Exercises(dirOpt)
2930
}
3031

3132
fmt.Printf("Your exercises will be saved at: %s\n", c.Dir)

config/config.go

Lines changed: 7 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,20 @@ import (
44
"bufio"
55
"bytes"
66
"encoding/json"
7-
"errors"
87
"fmt"
98
"io"
109
"log"
1110
"os"
12-
"path/filepath"
13-
"runtime"
1411
"strings"
12+
13+
"github.com/exercism/cli/paths"
1514
)
1615

1716
const (
18-
// File is the default name of the JSON file where the config written.
19-
// The user can pass an alternate filename when using the CLI.
20-
File = ".exercism.json"
21-
// LegacyFile is the name of the original config file.
22-
// It is a misnomer, since the config was in json, not go.
23-
LegacyFile = ".exercism.go"
24-
2517
// hostAPI is the endpoint to submit solutions to, and to get personalized data
2618
hostAPI = "http://exercism.io"
2719
// hostXAPI is the endpoint to fetch problems from
2820
hostXAPI = "http://x.exercism.io"
29-
30-
// DirExercises is the default name of the directory for active users.
31-
// Make this non-exported when handlers.Login is deleted.
32-
DirExercises = "exercism"
33-
)
34-
35-
var (
36-
errHomeNotFound = errors.New("unable to locate home directory")
3721
)
3822

3923
// Config represents the settings for particular user.
@@ -45,33 +29,12 @@ type Config struct {
4529
API string `json:"api"`
4630
XAPI string `json:"xapi"`
4731
File string `json:"-"` // full path to config file
48-
home string // cache user's home directory
49-
}
50-
51-
// Home returns the user's canonical home directory.
52-
// See: http://stackoverflow.com/questions/7922270/obtain-users-home-directory
53-
// we can't cross compile using cgo and use user.Current()
54-
func Home() (string, error) {
55-
var dir string
56-
if runtime.GOOS == "windows" {
57-
dir = os.Getenv("USERPROFILE")
58-
if dir == "" {
59-
dir = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
60-
}
61-
} else {
62-
dir = os.Getenv("HOME")
63-
}
64-
65-
if dir == "" {
66-
return dir, errHomeNotFound
67-
}
68-
return dir, nil
6932
}
7033

7134
// New returns a configuration struct with content from the exercism.json file
7235
func New(path string) (*Config, error) {
7336
c := &Config{}
74-
err := c.load(path)
37+
err := c.load(paths.Config(path))
7538
return c, err
7639
}
7740

@@ -87,11 +50,8 @@ func (c *Config) Update(key, host, dir, xapi string) error {
8750
c.API = host
8851
}
8952

90-
dir = strings.TrimSpace(dir)
9153
if dir != "" {
92-
if err := c.SetDir(dir); err != nil {
93-
return err
94-
}
54+
c.Dir = paths.Exercises(dir)
9555
}
9656

9757
xapi = strings.TrimSpace(xapi)
@@ -124,11 +84,8 @@ func (c *Config) Write() error {
12484
}
12585

12686
func (c *Config) load(argPath string) error {
127-
path, err := c.resolvePath(argPath)
128-
if err != nil {
129-
return err
130-
}
131-
c.File = path
87+
fmt.Println("resolved path:", argPath)
88+
c.File = argPath
13289

13390
if err := c.read(); err != nil {
13491
return err
@@ -207,33 +164,6 @@ func (c *Config) IsAuthenticated() bool {
207164
return c.APIKey != ""
208165
}
209166

210-
// homeDir caches the lookup of the user's home directory.
211-
func (c *Config) homeDir() (string, error) {
212-
if c.home != "" {
213-
return c.home, nil // only set during testing
214-
}
215-
return Home()
216-
}
217-
218-
func (c *Config) resolvePath(argPath string) (string, error) {
219-
path := argPath
220-
if path == "" {
221-
path = filepath.Join("~", File)
222-
}
223-
h, err := c.homeDir()
224-
if err != nil {
225-
return "", err
226-
}
227-
path = expandHome(path, h)
228-
229-
fi, _ := os.Stat(path)
230-
if fi != nil && fi.IsDir() {
231-
path = filepath.Join(path, File)
232-
}
233-
234-
return path, nil
235-
}
236-
237167
func (c *Config) setDefaults() error {
238168
if c.API == "" {
239169
c.API = hostAPI
@@ -243,49 +173,7 @@ func (c *Config) setDefaults() error {
243173
c.XAPI = hostXAPI
244174
}
245175

246-
if err := c.SetDir(c.Dir); err != nil {
247-
return err
248-
}
176+
c.Dir = paths.Exercises(c.Dir)
249177

250178
return nil
251179
}
252-
253-
// SetDir sets the configuration directory to the given path
254-
// or defaults to the home exercism directory
255-
func (c *Config) SetDir(path string) error {
256-
home, err := c.homeDir()
257-
if err != nil {
258-
return err
259-
}
260-
261-
var dir string
262-
263-
if path == "" {
264-
dir = filepath.Join(home, DirExercises)
265-
} else {
266-
dir = path
267-
}
268-
269-
dir = expandHome(dir, home)
270-
271-
// if the user has provided us with a relative path, make it absolute so
272-
// it will always work
273-
if !filepath.IsAbs(dir) {
274-
wd, err := os.Getwd()
275-
if err != nil {
276-
return err
277-
}
278-
dir = filepath.Join(wd, dir)
279-
}
280-
281-
c.Dir = dir
282-
283-
return nil
284-
}
285-
286-
func expandHome(path, home string) string {
287-
if path[:2] == "~"+string(os.PathSeparator) {
288-
return strings.Replace(path, "~", home, 1)
289-
}
290-
return path
291-
}

config/config_test.go

Lines changed: 12 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,10 @@ import (
88
"runtime"
99
"testing"
1010

11+
"github.com/exercism/cli/paths"
1112
"github.com/stretchr/testify/assert"
1213
)
1314

14-
func TestSetDir(t *testing.T) {
15-
dir, err := os.Getwd()
16-
assert.NoError(t, err)
17-
18-
testCases := []struct {
19-
givenPath string
20-
expectedPath string
21-
}{
22-
{"", "/test/home/exercism"},
23-
{"~/foobar", "/test/home/foobar"},
24-
{"/foobar/~/noexpand", "/foobar/~/noexpand"},
25-
{"/no/modification", "/no/modification"},
26-
{"relativePath", filepath.Join(dir, "relativePath")},
27-
}
28-
29-
for _, testCase := range testCases {
30-
config := &Config{home: "/test/home"}
31-
config.SetDir(testCase.givenPath)
32-
assert.Equal(t, testCase.expectedPath, config.Dir)
33-
}
34-
}
35-
3615
func TestLoad(t *testing.T) {
3716
tmpDir, err := ioutil.TempDir("", "")
3817
if err != nil {
@@ -46,6 +25,8 @@ func TestLoad(t *testing.T) {
4625
if err := os.Link(fixturePath(t, "dirty.json"), dirtyPath); err != nil {
4726
t.Fatal(err)
4827
}
28+
paths.Home = tmpDir
29+
4930
testCases := []struct {
5031
desc string
5132
in string // the name of the file passed as a command line argument
@@ -55,17 +36,8 @@ func TestLoad(t *testing.T) {
5536
{
5637
desc: "defaults",
5738
in: "",
58-
out: filepath.Join(tmpDir, File),
59-
dir: filepath.Join(tmpDir, DirExercises),
60-
key: "",
61-
api: hostAPI,
62-
xapi: hostXAPI,
63-
},
64-
{
65-
desc: "no such file",
66-
in: filepath.Join(tmpDir, "no-such.json"),
67-
out: filepath.Join(tmpDir, "no-such.json"),
68-
dir: filepath.Join(tmpDir, DirExercises),
39+
out: paths.Config(""),
40+
dir: paths.Exercises(""),
6941
key: "",
7042
api: hostAPI,
7143
xapi: hostXAPI,
@@ -100,9 +72,8 @@ func TestLoad(t *testing.T) {
10072
}
10173

10274
for _, tc := range testCases {
103-
c := &Config{home: tmpDir}
104-
105-
if err := c.load(tc.in); err != nil {
75+
c, err := New(tc.in)
76+
if err != nil {
10677
t.Fatal(err)
10778
}
10879
assert.Equal(t, tc.out, c.File, tc.desc)
@@ -121,15 +92,9 @@ func TestReadDirectory(t *testing.T) {
12192
myConfig, err := New(tmpDir)
12293
assert.NoError(t, err)
12394

124-
expected := filepath.Join(tmpDir, File)
95+
expected := filepath.Join(tmpDir, paths.File)
12596
actual := myConfig.File
12697
assert.Equal(t, expected, actual)
127-
128-
// if it can't determine if the provided path is a directory, don't modify
129-
// the path
130-
myConfig, err = New("badpath")
131-
assert.NoError(t, err)
132-
assert.Equal(t, "badpath", myConfig.File)
13398
}
13499

135100
func TestLoad_InvalidJSON(t *testing.T) {
@@ -141,17 +106,16 @@ func TestLoad_InvalidJSON(t *testing.T) {
141106
if err := os.Link(fixturePath(t, "config_invalid.json"), invalidPath); err != nil {
142107
t.Fatal(err)
143108
}
144-
c := &Config{home: tmpDir}
145109

146-
err = c.load("~/config_invalid.json")
110+
_, err = New(invalidPath)
147111
if assert.Error(t, err) {
148112
assert.Contains(t, err.Error(), "invalid JSON syntax")
149113
}
150114
}
151115

152116
func TestReadingWritingConfig(t *testing.T) {
153117
tmpDir, err := ioutil.TempDir("", "")
154-
filename := fmt.Sprintf("%s/%s", tmpDir, File)
118+
filename := fmt.Sprintf("%s/%s", tmpDir, paths.File)
155119
assert.NoError(t, err)
156120

157121
c1 := &Config{
@@ -178,8 +142,9 @@ func TestUpdateConfig(t *testing.T) {
178142
if err != nil {
179143
t.Fatal(err)
180144
}
145+
paths.Home = tmpDir
146+
181147
c := &Config{
182-
home: tmpDir,
183148
APIKey: "MyKey",
184149
API: "localhost",
185150
Dir: "/exercism/directory",

0 commit comments

Comments
 (0)