@@ -7,16 +7,11 @@ import (
77 "fmt"
88 "net/http"
99 "strings"
10-
11- "github.com/exercism/cli/config"
1210)
1311
1412var (
15- // UserAgent lets the API know where the call is being made from.
16- // It's set from main() so that we have access to the version.
17- UserAgent string
18-
19- UnknownLanguageError = errors .New ("the language is unknown" )
13+ // ErrUnknownLanguage represents an error returned when the language requested does not exist
14+ ErrUnknownLanguage = errors .New ("the language is unknown" )
2015)
2116
2217// PayloadError represents an error message from the API.
@@ -39,22 +34,52 @@ type PayloadSubmission struct {
3934// Fetch retrieves problems from the API.
4035// In most cases these problems consist of a test suite and a README
4136// from the x-api, but it is also used when restoring earlier iterations.
42- func Fetch (url string ) ([]* Problem , error ) {
43- req , err := http .NewRequest ("GET" , url , nil )
37+ func (c * Client ) Fetch (args []string ) ([]* Problem , error ) {
38+ var url string
39+ switch len (args ) {
40+ case 0 :
41+ url = fmt .Sprintf ("%s/v2/exercises?key=%s" , c .XAPIHost , c .APIKey )
42+ case 1 :
43+ language := args [0 ]
44+ url = fmt .Sprintf ("%s/v2/exercises/%s?key=%s" , c .XAPIHost , language , c .APIKey )
45+ case 2 :
46+ language := args [0 ]
47+ problem := args [1 ]
48+ url = fmt .Sprintf ("%s/v2/exercises/%s/%s" , c .XAPIHost , language , problem )
49+ default :
50+ return nil , fmt .Errorf ("Usage: exercism fetch\n or: exercism fetch LANGUAGE\n or: exercism fetch LANGUAGE PROBLEM" )
51+ }
52+
53+ req , err := c .NewRequest ("GET" , url , nil )
4454 if err != nil {
4555 return nil , err
4656 }
4757
48- res , err := http .DefaultClient .Do (req )
58+ payload := & PayloadProblems {}
59+ res , err := c .Do (req , payload )
60+ if err != nil {
61+ return nil , err
62+ }
63+
64+ if res .StatusCode != http .StatusOK {
65+ return nil , fmt .Errorf (`unable to fetch problems (HTTP: %d) - %s` , res .StatusCode , payload .Error )
66+ }
67+
68+ return payload .Problems , nil
69+ }
70+
71+ // Restore fetches the latest revision of a solution and writes it to disk.
72+ func (c * Client ) Restore () ([]* Problem , error ) {
73+ url := fmt .Sprintf ("%s/api/v1/iterations/%s/restore" , c .APIHost , c .APIKey )
74+ req , err := c .NewRequest ("GET" , url , nil )
4975 if err != nil {
5076 return nil , err
5177 }
52- defer res .Body .Close ()
5378
5479 payload := & PayloadProblems {}
55- dec := json . NewDecoder ( res . Body )
56- if err := dec . Decode ( payload ); err != nil {
57- return nil , fmt . Errorf ( "error parsing API response - %s" , err )
80+ res , err := c . Do ( req , payload )
81+ if err != nil {
82+ return nil , err
5883 }
5984
6085 if res .StatusCode != http .StatusOK {
@@ -65,23 +90,18 @@ func Fetch(url string) ([]*Problem, error) {
6590}
6691
6792// Download fetches a solution by submission key and writes it to disk.
68- func Download (url string ) (* Submission , error ) {
69- req , err := http .NewRequest ("GET" , url , nil )
70- if err != nil {
71- return nil , err
72- }
93+ func (c * Client ) Download (submissionID string ) (* Submission , error ) {
94+ url := fmt .Sprintf ("%s/api/v1/submissions/%s" , c .APIHost , submissionID )
7395
74- res , err := http . DefaultClient . Do ( req )
96+ req , err := c . NewRequest ( "GET" , url , nil )
7597 if err != nil {
7698 return nil , err
7799 }
78- defer res .Body .Close ()
79100
80101 payload := & PayloadSubmission {}
81- dec := json .NewDecoder (res .Body )
82- err = dec .Decode (payload )
102+ res , err := c .Do (req , payload )
83103 if err != nil {
84- return nil , fmt . Errorf ( "error parsing API response - %s" , err )
104+ return nil , err
85105 }
86106
87107 if res .StatusCode != http .StatusOK {
@@ -92,38 +112,44 @@ func Download(url string) (*Submission, error) {
92112}
93113
94114// Demo fetches the first problem in each language track.
95- func Demo (c * config.Config ) ([]* Problem , error ) {
96- url := fmt .Sprintf ("%s/problems/demo?key=%s" , c .XAPI , c .APIKey )
115+ func (c * Client ) Demo () ([]* Problem , error ) {
116+ url := fmt .Sprintf ("%s/problems/demo?key=%s" , c .XAPIHost , c .APIKey )
117+ req , err := c .NewRequest ("GET" , url , nil )
118+ if err != nil {
119+ return nil , err
120+ }
97121
98- return Fetch (url )
122+ payload := & PayloadProblems {}
123+ res , err := c .Do (req , payload )
124+ if err != nil {
125+ return nil , err
126+ }
127+
128+ if res .StatusCode != http .StatusOK {
129+ return nil , fmt .Errorf (`unable to fetch problems (HTTP: %d) - %s` , res .StatusCode , payload .Error )
130+ }
131+
132+ return payload .Problems , nil
99133}
100134
101135// Submit posts code to the API
102- func Submit (url string , iter * Iteration ) (* Submission , error ) {
136+ func (c * Client ) Submit (iter * Iteration ) (* Submission , error ) {
137+ url := fmt .Sprintf ("%s/api/v1/user/assignments" , c .APIHost )
103138 payload , err := json .Marshal (iter )
104139 if err != nil {
105140 return nil , err
106141 }
107142
108- req , err := http .NewRequest ("POST" , url , bytes .NewReader (payload ))
143+ req , err := c .NewRequest ("POST" , url , bytes .NewReader (payload ))
109144 if err != nil {
110145 return nil , err
111146 }
112147
113- req .Header .Set ("User-Agent" , UserAgent )
114- req .Header .Set ("Content-Type" , "application/json" )
115-
116- res , err := http .DefaultClient .Do (req )
148+ ps := & PayloadSubmission {}
149+ res , err := c .Do (req , ps )
117150 if err != nil {
118151 return nil , fmt .Errorf ("unable to submit solution - %s" , err )
119152 }
120- defer res .Body .Close ()
121-
122- ps := & PayloadSubmission {}
123- dec := json .NewDecoder (res .Body )
124- if err := dec .Decode (ps ); err != nil {
125- return nil , fmt .Errorf ("error parsing API response - %s" , err )
126- }
127153
128154 if res .StatusCode != http .StatusCreated {
129155 return nil , fmt .Errorf (`unable to submit (HTTP: %d) - %s` , res .StatusCode , ps .Error )
@@ -133,21 +159,22 @@ func Submit(url string, iter *Iteration) (*Submission, error) {
133159}
134160
135161// List available problems for a language
136- func List (language , host string ) ([]string , error ) {
137- url := fmt .Sprintf ("%s/tracks/%s" , host , language )
162+ func ( c * Client ) List (language string ) ([]string , error ) {
163+ url := fmt .Sprintf ("%s/tracks/%s" , c . XAPIHost , language )
138164
139- req , err := http .NewRequest ("GET" , url , nil )
165+ req , err := c .NewRequest ("GET" , url , nil )
140166 if err != nil {
141167 return nil , err
142168 }
143- req . Header . Set ( "User-Agent" , UserAgent )
144- res , err := http . DefaultClient . Do (req )
169+
170+ res , err := c . Do (req , nil )
145171 if err != nil {
146172 return nil , err
147173 }
174+
148175 defer res .Body .Close ()
149176 if res .StatusCode != http .StatusOK {
150- return nil , UnknownLanguageError
177+ return nil , ErrUnknownLanguage
151178 }
152179
153180 var payload struct {
@@ -167,51 +194,35 @@ func List(language, host string) ([]string, error) {
167194}
168195
169196// Unsubmit deletes a submission.
170- func Unsubmit (url string ) error {
171- req , err := http .NewRequest ("DELETE" , url , nil )
197+ func (c * Client ) Unsubmit () error {
198+ url := fmt .Sprintf ("%s/api/v1/user/assignments?key=%s" , c .APIHost , c .APIKey )
199+ req , err := c .NewRequest ("DELETE" , url , nil )
172200 if err != nil {
173201 return err
174202 }
175- req .Header .Set ("User-Agent" , UserAgent )
176-
177- res , err := http .DefaultClient .Do (req )
178- if err != nil {
179- return err
180- }
181- defer res .Body .Close ()
182-
183- if res .StatusCode == http .StatusNoContent {
184- return nil
185- }
186203
187204 pe := & PayloadError {}
188- if err := json . NewDecoder ( res . Body ). Decode ( pe ); err != nil {
189- return fmt .Errorf ("failed to unsubmit - %s" , err )
205+ if _ , err := c . Do ( req , pe ); err != nil {
206+ return fmt .Errorf ("failed to unsubmit - %s" , pe . Error )
190207 }
191- return fmt .Errorf ("failed to unsubmit - %s" , pe .Error )
208+
209+ return nil
192210}
193211
194212// Tracks gets the current list of active and inactive language tracks.
195- func Tracks (url string ) ([]* Track , error ) {
213+ func (c * Client ) Tracks () ([]* Track , error ) {
214+ url := fmt .Sprintf ("%s/tracks" , c .XAPIHost )
196215 req , err := http .NewRequest ("GET" , url , nil )
197216 if err != nil {
198217 return []* Track {}, err
199218 }
200- req .Header .Set ("User-Agent" , UserAgent )
201-
202- res , err := http .DefaultClient .Do (req )
203- if err != nil {
204- return []* Track {}, err
205- }
206- defer res .Body .Close ()
207219
208220 var payload struct {
209221 Tracks []* Track
210222 }
211- dec := json .NewDecoder (res .Body )
212- err = dec .Decode (& payload )
213- if err != nil {
223+ if _ , err := c .Do (req , & payload ); err != nil {
214224 return []* Track {}, err
215225 }
226+
216227 return payload .Tracks , nil
217228}
0 commit comments