Skip to content

Commit

Permalink
download: Infer track and exercise slug from CWD
Browse files Browse the repository at this point in the history
If I'm in the `exercism/c` directory and invoke:

    exercism download --exercise hello-world

I would like `--track c` to be inferred.

If I'm in the `exercism/c/hello-world` directory and invoke without
arguments:

    exercism download

I would like both `--track c` and `--exercise hello-world` to be
inferred.
  • Loading branch information
petertseng committed Sep 15, 2019
1 parent d95de6b commit 6a223b8
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
34 changes: 34 additions & 0 deletions cmd/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,27 @@ Download other people's solutions by providing the UUID.
},
}

func nthComponentAfterWorkspace(workspace string, n int) (string, bool) {
cwd, err := os.Getwd()
if err != nil {
return "", false
}

if !strings.HasPrefix(cwd, workspace) {
return "", false
}
remaining := cwd[len(workspace):]
if remaining[0] == '/' {
remaining = remaining[1:]
}

components := strings.Split(remaining, "/")
if n < len(components) {
return components[n], true
}
return "", false
}

func runDownload(cfg config.Config, flags *pflag.FlagSet, args []string) error {
usrCfg := cfg.UserViperConfig
if err := validateUserConfig(usrCfg); err != nil {
Expand Down Expand Up @@ -162,6 +183,19 @@ func newDownload(flags *pflag.FlagSet, usrCfg *viper.Viper) (*download, error) {
d.apibaseurl = usrCfg.GetString("apibaseurl")
d.workspace = usrCfg.GetString("workspace")

if d.uuid == "" {
if d.slug == "" {
if slug, ok := nthComponentAfterWorkspace(d.workspace, 1); ok {
d.slug = slug
}
}
if d.track == "" && d.team == "" {
if track, ok := nthComponentAfterWorkspace(d.workspace, 0); ok {
d.track = track
}
}
}

if err = d.needsSlugXorUUID(); err != nil {
return nil, err
}
Expand Down
57 changes: 57 additions & 0 deletions cmd/download_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,63 @@ func TestDownloadWithoutFlags(t *testing.T) {
}
}

func TestDownloadInferringFlags(t *testing.T) {
co := newCapturedOutput()
co.override()
defer co.reset()

originalCwd, err := os.Getwd()
defer os.Chdir(originalCwd)
assert.NoError(t, err)

testCases := []struct {
cwd string
flags map[string]string
}{
{
cwd: "bogus-track",
flags: map[string]string{"exercise": "bogus-exercise"},
},
{
cwd: "bogus-track/bogus-exercise",
flags: nil,
},
}

for _, tc := range testCases {
tmpDir, err := ioutil.TempDir("", "download-infer")
defer os.RemoveAll(tmpDir)
assert.NoError(t, err)

subdir := filepath.Join(tmpDir, tc.cwd)
err = os.MkdirAll(subdir, 0755)
assert.NoError(t, err)
os.Chdir(subdir)

ts := fakeDownloadServer(strconv.FormatBool(true), "")
defer ts.Close()

v := viper.New()
v.Set("workspace", tmpDir)
v.Set("apibaseurl", ts.URL)
v.Set("token", "abc123")

cfg := config.Config{
UserViperConfig: v,
}
flags := pflag.NewFlagSet("fake", pflag.PanicOnError)
setupDownloadFlags(flags)
for name, value := range tc.flags {
flags.Set(name, value)
}

err = runDownload(cfg, flags, []string{})
assert.NoError(t, err)

assertDownloadedCorrectFiles(t, tmpDir)
}
}

func TestSolutionFile(t *testing.T) {
testCases := []struct {
name, file, expectedPath, expectedURL string
Expand Down

0 comments on commit 6a223b8

Please sign in to comment.