Repository: exercism/cli
Pull request #563 (2018-06-22 01:43:50)

Rework download command to take exercise flag
Hi! This very minimally solves https://github.com/exercism/cli/issues/545

This is my first contribution (and actually the first time I've ever touched go code) - so I hope it's alright.

### The fix:

* Changed the command to take ONLY flags
* Check for the exercise flag instead of relying on the arg
* Lifted the check for exercise name to the beginning of the function so it can thow an error early if there is no exercise name OR uuid

### About me:

I've played very in a very minor way with exercism a while back and thought it was awesome (but not immediately useful to me).

A good friend of mine recently started programming and I showed her exercism. She immediately connected with it and is having an awesome experience which reinvigorated my excitement and I thought I would help where I can! (though I have no go experience)

❤️ Hope this helps and thanks for the amazing community you've created! ❤️



kytrinyx: ❤️ 💛 💚 💙 💜 🖤 Thank you! I'm going to take the time to review this properly on the weekend, I just wanted to say thanks so much for tackling it (and in an unfamiliar language, even!).
strickinato: Thanks for the feedback!

I'm expecting to get to this in the late morning (EST) tomorrow.

On quick glance the conflict doesn't look bad - so I should be able to tackle without too much problem.


strickinato: I think this should be good to go according to your feedback.

I am slightly concerned that I put the `CommandTest.Setup` and `CommandTest.Teardown` etc. within a loop. It's probably slower than it needs to be - but I wasn't sure a better way to test both cases.

Let me know if there is more I can do!
strickinato: @kytrinyx Just a friendly bump in case you missed the updates (don't want it to go stale).
kytrinyx: Oh! Yes I completely missed this. I'll get this merged today. Thank you ❤️ 

Patch:
diff --git a/cmd/download.go b/cmd/download.go
index d4b3904..735f438 100644
--- a/cmd/download.go
+++ b/cmd/download.go
@@ -29,7 +29,6 @@ latest solution.
 
 Download other people's solutions by providing the UUID.
 `,
-	Args: cobra.ExactArgs(1),
 	RunE: func(cmd *cobra.Command, args []string) error {
 		token, err := cmd.Flags().GetString("token")
 		if err != nil {
@@ -45,9 +44,12 @@ Download other people's solutions by providing the UUID.
 		if err != nil {
 			return err
 		}
-		if uuid == "" && len(args) == 0 {
-			// TODO: usage
-			return errors.New("need an exercise name or a solution --uuid")
+		exercise, err := cmd.Flags().GetString("exercise")
+		if err != nil {
+			return err
+		}
+		if uuid == "" && exercise == "" {
+			return errors.New("need an --exercise name or a solution --uuid")
 		}
 		usrCfg, err := config.NewUserConfig()
 		if err != nil {
@@ -76,10 +78,6 @@ Download other people's solutions by providing the UUID.
 		if err != nil {
 			return err
 		}
-		var exercise string
-		if len(args) > 0 {
-			exercise = args[0]
-		}
 
 		if uuid == "" {
 			q := req.URL.Query()
@@ -222,6 +220,7 @@ type downloadPayload struct {
 func initDownloadCmd() {
 	downloadCmd.Flags().StringP("uuid", "u", "", "the solution UUID")
 	downloadCmd.Flags().StringP("track", "t", "", "the track ID")
+	downloadCmd.Flags().StringP("exercise", "e", "", "the exercise slug")
 	downloadCmd.Flags().StringP("token", "k", "", "authentication token used to connect to the site")
 }
 


Test patch:
diff --git a/cmd/download_test.go b/cmd/download_test.go
index c86e9ee..977bf37 100644
--- a/cmd/download_test.go
+++ b/cmd/download_test.go
@@ -56,7 +56,7 @@ func TestDownload(t *testing.T) {
 	cmdTest := &CommandTest{
 		Cmd:    downloadCmd,
 		InitFn: initDownloadCmd,
-		Args:   []string{"fakeapp", "download", "bogus-exercise"},
+		Args:   []string{"fakeapp", "download", "--exercise=bogus-exercise"},
 	}
 	cmdTest.Setup(t)
 	defer cmdTest.Teardown(t)
@@ -138,3 +138,32 @@ func makeMockServer() *httptest.Server {
 	return server
 
 }
+
+func TestDownloadArgs(t *testing.T) {
+	tests := []struct {
+		args          []string
+		expectedError string
+	}{
+		{
+			args:          []string{"bogus"}, // providing just an exercise slug without the flag
+			expectedError: "need an --exercise name or a solution --uuid",
+		},
+		{
+			args:          []string{""}, // providing no args
+			expectedError: "need an --exercise name or a solution --uuid",
+		},
+	}
+
+	for _, test := range tests {
+		cmdTest := &CommandTest{
+			Cmd:    downloadCmd,
+			InitFn: initDownloadCmd,
+			Args:   append([]string{"fakeapp", "download"}, test.args...),
+		}
+		cmdTest.Setup(t)
+		defer cmdTest.Teardown(t)
+		err := cmdTest.App.Execute()
+
+		assert.EqualError(t, err, test.expectedError)
+	}
+}