Skip to content

Commit

Permalink
Merge pull request #705 from exercism/path-vs-filepath
Browse files Browse the repository at this point in the history
Distinguish between path and filepath
  • Loading branch information
Katrina Owen authored Aug 21, 2018
2 parents 02810c4 + 60b6ed7 commit 78cbd41
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 16 deletions.
23 changes: 12 additions & 11 deletions cmd/submit.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"mime/multipart"
"os"
"path/filepath"
"strings"

"github.com/exercism/cli/api"
"github.com/exercism/cli/config"
Expand Down Expand Up @@ -125,6 +124,8 @@ func runSubmit(cfg config.Config, flags *pflag.FlagSet, args []string) error {
exerciseDir = dir
}

exercise := workspace.NewExerciseFromDir(exerciseDir)

solution, err := workspace.NewSolution(exerciseDir)
if err != nil {
return err
Expand All @@ -143,7 +144,7 @@ func runSubmit(cfg config.Config, flags *pflag.FlagSet, args []string) error {
return fmt.Errorf(msg, BinaryName, solution.Exercise, solution.Track)
}

paths := make([]string, 0, len(args))
exercise.Documents = make([]workspace.Document, 0, len(args))
for _, file := range args {
// Don't submit empty files
info, err := os.Stat(file)
Expand All @@ -161,10 +162,14 @@ func runSubmit(cfg config.Config, flags *pflag.FlagSet, args []string) error {
fmt.Fprintf(Err, msg, file)
continue
}
paths = append(paths, file)
doc, err := workspace.NewDocument(exercise.Filepath(), file)
if err != nil {
return err
}
exercise.Documents = append(exercise.Documents, doc)
}

if len(paths) == 0 {
if len(exercise.Documents) == 0 {
msg := `
No files found to submit.
Expand All @@ -176,18 +181,14 @@ func runSubmit(cfg config.Config, flags *pflag.FlagSet, args []string) error {
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)

for _, path := range paths {
file, err := os.Open(path)
for _, doc := range exercise.Documents {
file, err := os.Open(doc.Filepath())
if err != nil {
return err
}
defer file.Close()

dirname := fmt.Sprintf("%s%s%s", string(os.PathSeparator), solution.Exercise, string(os.PathSeparator))
pieces := strings.Split(path, dirname)
filename := pieces[len(pieces)-1]

part, err := writer.CreateFormFile("files[]", filename)
part, err := writer.CreateFormFile("files[]", doc.Path())
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/submit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func TestSubmitFiles(t *testing.T) {
assert.Equal(t, 3, len(submittedFiles))

assert.Equal(t, "This is file 1.", submittedFiles["file-1.txt"])
assert.Equal(t, "This is file 2.", submittedFiles[filepath.Join("subdir", "file-2.txt")])
assert.Equal(t, "This is file 2.", submittedFiles["subdir/file-2.txt"])
assert.Equal(t, "This is the readme.", submittedFiles["README.md"])
}

Expand Down Expand Up @@ -278,7 +278,7 @@ func TestSubmitFilesForTeamExercise(t *testing.T) {
assert.Equal(t, 2, len(submittedFiles))

assert.Equal(t, "This is file 1.", submittedFiles["file-1.txt"])
assert.Equal(t, "This is file 2.", submittedFiles[filepath.Join("subdir", "file-2.txt")])
assert.Equal(t, "This is file 2.", submittedFiles["subdir/file-2.txt"])
}

func TestSubmitOnlyEmptyFile(t *testing.T) {
Expand Down
34 changes: 34 additions & 0 deletions workspace/document.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package workspace

import "path/filepath"

// Document is a file in a directory.
type Document struct {
Root string
RelativePath string
}

// NewDocument creates a document from the filepath.
// The root is typically the root of the exercise, and
// path is the absolute path to the file.
func NewDocument(root, path string) (Document, error) {
path, err := filepath.Rel(root, path)
if err != nil {
return Document{}, err
}
return Document{
Root: root,
RelativePath: path,
}, nil
}

// Filepath is the absolute path to the document on the filesystem.
func (doc Document) Filepath() string {
return filepath.Join(doc.Root, doc.RelativePath)
}

// Path is the normalized path.
// It uses forward slashes regardless of the operating system.
func (doc Document) Path() string {
return filepath.ToSlash(doc.RelativePath)
}
43 changes: 43 additions & 0 deletions workspace/document_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package workspace

import (
"io/ioutil"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
)

func TestNormalizedDocumentPath(t *testing.T) {
root, err := ioutil.TempDir("", "docpath")
assert.NoError(t, err)
defer os.RemoveAll(root)

err = os.MkdirAll(filepath.Join(root, "subdirectory"), os.FileMode(0755))
assert.NoError(t, err)

testCases := []struct {
filepath string
path string
}{
{
filepath: filepath.Join(root, "file.txt"),
path: "file.txt",
},
{
filepath: filepath.Join(root, "subdirectory", "file.txt"),
path: "subdirectory/file.txt",
},
}

for _, tc := range testCases {
err = ioutil.WriteFile(tc.filepath, []byte("a file"), os.FileMode(0600))
assert.NoError(t, err)

doc, err := NewDocument(root, tc.filepath)
assert.NoError(t, err)

assert.Equal(t, doc.Path(), tc.path)
}
}
16 changes: 13 additions & 3 deletions workspace/exercise.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,19 @@ import (

// Exercise is an implementation of a problem in a track.
type Exercise struct {
Root string
Track string
Slug string
Root string
Track string
Slug string
Documents []Document
}

// NewExerciseFromDir constructs an exercise given the exercise directory.
func NewExerciseFromDir(dir string) Exercise {
slug := filepath.Base(dir)
dir = filepath.Dir(dir)
track := filepath.Base(dir)
root := filepath.Dir(dir)
return Exercise{Root: root, Track: track, Slug: slug}
}

// Path is the normalized relative path.
Expand Down
9 changes: 9 additions & 0 deletions workspace/exercise_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,12 @@ func TestHasMetadata(t *testing.T) {
assert.NoError(t, err)
assert.False(t, ok)
}

func TestNewFromDir(t *testing.T) {
dir := filepath.Join("something", "another", "whatever", "the-track", "the-exercise")

exercise := NewExerciseFromDir(dir)
assert.Equal(t, filepath.Join("something", "another", "whatever"), exercise.Root)
assert.Equal(t, "the-track", exercise.Track)
assert.Equal(t, "the-exercise", exercise.Slug)
}

0 comments on commit 78cbd41

Please sign in to comment.