Skip to content

Commit 8cd67be

Browse files
author
Katrina Owen
committed
Isolate file logic from http and filesystem logic in download
1 parent 1d02944 commit 8cd67be

File tree

1 file changed

+51
-24
lines changed

1 file changed

+51
-24
lines changed

cmd/download.go

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,12 @@ func runDownload(cfg config.Config, flags *pflag.FlagSet, args []string) error {
7575
return err
7676
}
7777

78-
for _, file := range download.payload.Solution.Files {
79-
unparsedURL := fmt.Sprintf("%s%s", download.payload.Solution.FileDownloadBaseURL, file)
80-
parsedURL, err := netURL.ParseRequestURI(unparsedURL)
81-
78+
for _, sf := range download.payload.files() {
79+
url, err := sf.url()
8280
if err != nil {
8381
return err
8482
}
8583

86-
url := parsedURL.String()
87-
8884
req, err := client.NewRequest("GET", url, nil)
8985
if err != nil {
9086
return err
@@ -105,26 +101,12 @@ func runDownload(cfg config.Config, flags *pflag.FlagSet, args []string) error {
105101
continue
106102
}
107103

108-
// TODO: if there's a collision, interactively resolve (show diff, ask if overwrite).
109-
// TODO: handle --force flag to overwrite without asking.
110-
111-
// Work around a path bug due to an early design decision (later reversed) to
112-
// allow numeric suffixes for exercise directories, allowing people to have
113-
// multiple parallel versions of an exercise.
114-
pattern := fmt.Sprintf(`\A.*[/\\]%s-\d*/`, metadata.ExerciseSlug)
115-
rgxNumericSuffix := regexp.MustCompile(pattern)
116-
if rgxNumericSuffix.MatchString(file) {
117-
file = string(rgxNumericSuffix.ReplaceAll([]byte(file), []byte("")))
118-
}
119-
120-
// Rewrite paths submitted with an older, buggy client where the Windows path is being treated as part of the filename.
121-
file = strings.Replace(file, "\\", "/", -1)
122-
123-
relativePath := filepath.FromSlash(file)
124-
dir := filepath.Join(metadata.Dir, filepath.Dir(relativePath))
104+
// TODO: handle collisions
105+
path := sf.relativePath()
106+
dir := filepath.Join(metadata.Dir, filepath.Dir(path))
125107
os.MkdirAll(dir, os.FileMode(0755))
126108

127-
f, err := os.Create(filepath.Join(metadata.Dir, relativePath))
109+
f, err := os.Create(filepath.Join(metadata.Dir, path))
128110
if err != nil {
129111
return err
130112
}
@@ -311,6 +293,51 @@ func (dp downloadPayload) metadata() workspace.ExerciseMetadata {
311293
}
312294
}
313295

296+
func (dp downloadPayload) files() []solutionFile {
297+
fx := make([]solutionFile, 0, len(dp.Solution.Files))
298+
for _, file := range dp.Solution.Files {
299+
f := solutionFile{
300+
path: file,
301+
baseURL: dp.Solution.FileDownloadBaseURL,
302+
slug: dp.Solution.Exercise.ID,
303+
}
304+
fx = append(fx, f)
305+
}
306+
return fx
307+
}
308+
309+
type solutionFile struct {
310+
path, baseURL, slug string
311+
}
312+
313+
func (sf solutionFile) url() (string, error) {
314+
url, err := netURL.ParseRequestURI(fmt.Sprintf("%s%s", sf.baseURL, sf.path))
315+
316+
if err != nil {
317+
return "", err
318+
}
319+
320+
return url.String(), nil
321+
}
322+
323+
func (sf solutionFile) relativePath() string {
324+
file := sf.path
325+
326+
// Work around a path bug due to an early design decision (later reversed) to
327+
// allow numeric suffixes for exercise directories, letting people have
328+
// multiple parallel versions of an exercise.
329+
pattern := fmt.Sprintf(`\A.*[/\\]%s-\d*/`, sf.slug)
330+
rgxNumericSuffix := regexp.MustCompile(pattern)
331+
if rgxNumericSuffix.MatchString(sf.path) {
332+
file = string(rgxNumericSuffix.ReplaceAll([]byte(sf.path), []byte("")))
333+
}
334+
335+
// Rewrite paths submitted with an older, buggy client where the Windows path is being treated as part of the filename.
336+
file = strings.Replace(file, "\\", "/", -1)
337+
338+
return filepath.FromSlash(file)
339+
}
340+
314341
func setupDownloadFlags(flags *pflag.FlagSet) {
315342
flags.StringP("uuid", "u", "", "the solution UUID")
316343
flags.StringP("track", "t", "", "the track ID")

0 commit comments

Comments
 (0)