Skip to content

Commit 99fdbd6

Browse files
committed
Merge pull request #171 from Tonkpils/skip-exercise
Add Skip command to skip specific problems
2 parents f3b2c1b + b3afaef commit 99fdbd6

4 files changed

Lines changed: 107 additions & 1 deletion

File tree

api/api.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,29 @@ func (c *Client) Tracks() ([]*Track, error) {
264264

265265
return payload.Tracks, nil
266266
}
267+
268+
func (c *Client) Skip(language, slug string) error {
269+
url := fmt.Sprintf("%s/api/v1/iterations/%s/%s/skip?key=%s", c.APIHost, language, slug, c.APIKey)
270+
271+
req, err := http.NewRequest("POST", url, nil)
272+
if err != nil {
273+
return err
274+
}
275+
276+
res, err := c.Do(req, nil)
277+
if err != nil {
278+
return err
279+
}
280+
281+
defer res.Body.Close()
282+
if res.StatusCode == http.StatusNoContent {
283+
return nil
284+
}
285+
286+
var pe PayloadError
287+
if err := json.NewDecoder(res.Body).Decode(&pe); err != nil {
288+
return err
289+
}
290+
291+
return errors.New(pe.Error)
292+
}

api/api_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,46 @@ func TestFetchASpecificProblem(t *testing.T) {
8686
assert.NoError(t, err)
8787
}
8888

89+
func TestSkipProblem(t *testing.T) {
90+
var (
91+
APIKey = "mykey"
92+
language = "go"
93+
problem = "leap"
94+
)
95+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
96+
skipAPI := fmt.Sprintf("/api/v1/iterations/%s/%s/skip?key=%s", language, problem, APIKey)
97+
assert.Equal(t, skipAPI, req.RequestURI)
98+
99+
w.WriteHeader(http.StatusNoContent)
100+
}))
101+
defer ts.Close()
102+
103+
client := NewClient(&config.Config{API: ts.URL, APIKey: APIKey})
104+
105+
err := client.Skip(language, problem)
106+
assert.NoError(t, err)
107+
}
108+
109+
func TestSkipProblemErrorResponse(t *testing.T) {
110+
var (
111+
APIKey = "mykey"
112+
language = "go"
113+
problem = "leap"
114+
)
115+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
116+
skipAPI := fmt.Sprintf("/api/v1/iterations/%s/%s/skip?key=%s", language, problem, APIKey)
117+
assert.Equal(t, skipAPI, req.RequestURI)
118+
119+
w.Write([]byte(`{"error":"exercise skipped"}`))
120+
}))
121+
defer ts.Close()
122+
123+
client := NewClient(&config.Config{API: ts.URL, APIKey: APIKey})
124+
125+
err := client.Skip(language, problem)
126+
assert.Error(t, err)
127+
}
128+
89129
func TestGetSubmission(t *testing.T) {
90130
var (
91131
APIKey = "mykey"

cmd/skip.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
"github.com/codegangsta/cli"
8+
"github.com/exercism/cli/api"
9+
"github.com/exercism/cli/config"
10+
)
11+
12+
func Skip(ctx *cli.Context) {
13+
c, err := config.New(ctx.GlobalString("config"))
14+
if err != nil {
15+
log.Fatal(err)
16+
}
17+
args := ctx.Args()
18+
19+
if len(args) != 2 {
20+
msg := "Usage: exercism skip LANGUAGE SLUG"
21+
log.Fatal(msg)
22+
}
23+
24+
var (
25+
language = args[0]
26+
slug = args[1]
27+
)
28+
29+
client := api.NewClient(c)
30+
if err := client.Skip(language, slug); err != nil {
31+
log.Fatal(err)
32+
}
33+
34+
fmt.Printf("Exercise %q in %q has been skipped.\n", slug, language)
35+
}

exercism/main.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const (
2424
descFetch = "Fetches your current problems on exercism.io, as well as the next unstarted problem in each language."
2525
descRestore = "Restores completed and current problems on from exercism.io, along with your most recent iteration for each."
2626
descSubmit = "Submits a new iteration to a problem on exercism.io."
27+
descSkip = "Skips a problem given a language and slug."
2728
descUnsubmit = "Deletes the most recently submitted iteration."
2829
descTracks = "List the available language tracks"
2930
descOpen = "Opens the current submission of the specified exercise"
@@ -103,6 +104,11 @@ func main() {
103104
Description: descLongRestore,
104105
Action: cmd.Restore,
105106
},
107+
{
108+
Name: "skip",
109+
Usage: descSkip,
110+
Action: cmd.Skip,
111+
},
106112
{
107113
Name: "submit",
108114
ShortName: "s",
@@ -141,7 +147,6 @@ func main() {
141147
},
142148
}
143149
if err := app.Run(os.Args); err != nil {
144-
145150
log.Fatal(err)
146151
}
147152
}

0 commit comments

Comments
 (0)