diff --git a/cmd/transpile/main.go b/cmd/transpile/main.go index 84f3293..00c9dee 100644 --- a/cmd/transpile/main.go +++ b/cmd/transpile/main.go @@ -73,7 +73,6 @@ func (t *T) ParseArgs() (Command, error) { } else { t.fs = t.BaseFs } - log.Println(t.Args, t.fs) return cmd, nil } @@ -107,7 +106,6 @@ func (t *T) DumpFile() error { switch t.filename { case "puzzle.json", "": - // BUG(neale): we need a way to tell the transpiler to strip answers p, err := puzzle.Puzzle() if err != nil { return err diff --git a/cmd/transpile/main_test.go b/cmd/transpile/main_test.go index 67c353a..ad79cef 100644 --- a/cmd/transpile/main_test.go +++ b/cmd/transpile/main_test.go @@ -3,7 +3,6 @@ package main import ( "bytes" "encoding/json" - "log" "testing" "github.com/dirtbags/moth/pkg/transpile" @@ -27,21 +26,22 @@ YAML body func newTestFs() afero.Fs { fs := afero.NewMemMapFs() afero.WriteFile(fs, "cat0/1/puzzle.md", testMothYaml, 0644) - afero.WriteFile(fs, "cat0/1/moo.txt", testMothYaml, 0644) + afero.WriteFile(fs, "cat0/1/moo.txt", []byte("Moo."), 0644) afero.WriteFile(fs, "cat0/2/puzzle.moth", testMothYaml, 0644) afero.WriteFile(fs, "cat0/3/puzzle.moth", testMothYaml, 0644) afero.WriteFile(fs, "cat0/4/puzzle.md", testMothYaml, 0644) afero.WriteFile(fs, "cat0/5/puzzle.md", testMothYaml, 0644) afero.WriteFile(fs, "cat0/10/puzzle.md", testMothYaml, 0644) afero.WriteFile(fs, "unbroken/1/puzzle.md", testMothYaml, 0644) + afero.WriteFile(fs, "unbroken/1/moo.txt", []byte("Moo."), 0644) afero.WriteFile(fs, "unbroken/2/puzzle.md", testMothYaml, 0644) + afero.WriteFile(fs, "unbroken/2/moo.txt", []byte("Moo."), 0644) return fs } func (tp T) Run(args ...string) error { tp.Args = append([]string{"transpile"}, args...) command, err := tp.ParseArgs() - log.Println(tp.fs) if err != nil { return err } @@ -81,12 +81,11 @@ func TestEverything(t *testing.T) { t.Error(err) } if stdout.String() != "Moo." { - t.Error("Wrong file pulled") + t.Error("Wrong file pulled", stdout.String()) } stdout.Reset() - if err := tp.Run("mothball", "-dir=cat0"); err != nil { - t.Log(tp.BaseFs) + if err := tp.Run("mothball", "-dir=unbroken"); err != nil { t.Log(tp.fs) t.Error(err) } diff --git a/pkg/transpile/basepath.go b/pkg/transpile/basepath.go index 60d6f69..c40a3fd 100644 --- a/pkg/transpile/basepath.go +++ b/pkg/transpile/basepath.go @@ -18,11 +18,16 @@ type RecursiveBasePathFs struct { // NewRecursiveBasePathFs returns a new RecursiveBasePathFs. func NewRecursiveBasePathFs(source afero.Fs, path string) *RecursiveBasePathFs { - return &RecursiveBasePathFs{ - Fs: afero.NewBasePathFs(source, path), + ret := &RecursiveBasePathFs{ source: source, path: path, } + if path == "" { + ret.Fs = source + } else { + ret.Fs = afero.NewBasePathFs(source, path) + } + return ret } // RealPath returns the real path to a file, "breaking out" of the RecursiveBasePathFs. diff --git a/pkg/transpile/category_test.go b/pkg/transpile/category_test.go index 575c056..80eac5a 100644 --- a/pkg/transpile/category_test.go +++ b/pkg/transpile/category_test.go @@ -63,6 +63,12 @@ func TestOsFsCategory(t *testing.T) { t.Error("Wrong authors", p.Pre.Authors) } + if p, err := static.Puzzle(3); err != nil { + t.Error(err) + } else if len(p.Pre.Authors) != 1 { + t.Error("Wrong authors", p.Pre.Authors) + } + generated := NewFsCategory(fs, "generated") if inv, err := generated.Inventory(); err != nil { diff --git a/pkg/transpile/mothball.go b/pkg/transpile/mothball.go index 2126f9f..1ef87f2 100644 --- a/pkg/transpile/mothball.go +++ b/pkg/transpile/mothball.go @@ -6,7 +6,6 @@ import ( "encoding/json" "fmt" "io" - "log" ) // Mothball packages a Category up for a production server run. @@ -36,7 +35,6 @@ func Mothball(c Category) (*bytes.Reader, error) { if err != nil { return nil, err } - log.Println(puzzlePath) puzzle, err := c.Puzzle(points) if err != nil { return nil, err diff --git a/pkg/transpile/mothball_test.go b/pkg/transpile/mothball_test.go index 8430506..753d536 100644 --- a/pkg/transpile/mothball_test.go +++ b/pkg/transpile/mothball_test.go @@ -3,18 +3,32 @@ package transpile import ( "archive/zip" "io/ioutil" + "os" + "path" + "runtime" "testing" "github.com/spf13/afero" "github.com/spf13/afero/zipfs" ) -func TestMothballs(t *testing.T) { +func TestMothballsMemFs(t *testing.T) { + static := NewFsCategory(newTestFs(), "cat1") + if _, err := Mothball(static); err != nil { + t.Error(err) + } +} + +func TestMothballsOsFs(t *testing.T) { + _, testfn, _, _ := runtime.Caller(0) + os.Chdir(path.Dir(testfn)) + fs := NewRecursiveBasePathFs(afero.NewOsFs(), "testdata") static := NewFsCategory(fs, "static") mb, err := Mothball(static) if err != nil { t.Error(err) + return } mbr, err := zip.NewReader(mb, int64(mb.Len())) diff --git a/pkg/transpile/puzzle.go b/pkg/transpile/puzzle.go index 8feb56d..11f6b9c 100644 --- a/pkg/transpile/puzzle.go +++ b/pkg/transpile/puzzle.go @@ -338,14 +338,18 @@ type FsCommandPuzzle struct { timeout time.Duration } -// Puzzle returns a Puzzle struct for the current puzzle. -func (fp FsCommandPuzzle) Puzzle() (Puzzle, error) { +func (fp FsCommandPuzzle) run(args ...string) ([]byte, error) { ctx, cancel := context.WithTimeout(context.Background(), fp.timeout) defer cancel() - cmd := exec.CommandContext(ctx, fp.command) + cmd := exec.CommandContext(ctx, "./"+path.Base(fp.command), args...) cmd.Dir = path.Dir(fp.command) - stdout, err := cmd.Output() + return cmd.Output() +} + +// Puzzle returns a Puzzle struct for the current puzzle. +func (fp FsCommandPuzzle) Puzzle() (Puzzle, error) { + stdout, err := fp.run() if exiterr, ok := err.(*exec.ExitError); ok { return Puzzle{}, errors.New(string(exiterr.Stderr)) } else if err != nil { @@ -375,13 +379,8 @@ func (c nopCloser) Close() error { // Open returns a newly-opened file. // BUG(neale): FsCommandPuzzle.Open() reads everything into memory, and will suck for large files. func (fp FsCommandPuzzle) Open(filename string) (ReadSeekCloser, error) { - ctx, cancel := context.WithTimeout(context.Background(), fp.timeout) - defer cancel() - - cmd := exec.CommandContext(ctx, fp.command, "--file", filename) - cmd.Dir = path.Dir(fp.command) - out, err := cmd.Output() - buf := nopCloser{bytes.NewReader(out)} + stdout, err := fp.run("--file", filename) + buf := nopCloser{bytes.NewReader(stdout)} if err != nil { return buf, err } @@ -391,18 +390,13 @@ func (fp FsCommandPuzzle) Open(filename string) (ReadSeekCloser, error) { // Answer checks whether the given answer is correct. func (fp FsCommandPuzzle) Answer(answer string) bool { - ctx, cancel := context.WithTimeout(context.Background(), fp.timeout) - defer cancel() - - cmd := exec.CommandContext(ctx, fp.command, "--answer", answer) - cmd.Dir = path.Dir(fp.command) - out, err := cmd.Output() + stdout, err := fp.run("--answer", answer) if err != nil { log.Printf("ERROR: checking answer: %s", err) return false } - switch strings.TrimSpace(string(out)) { + switch strings.TrimSpace(string(stdout)) { case "correct": return true } diff --git a/pkg/transpile/puzzle_test.go b/pkg/transpile/puzzle_test.go index 914624e..288cde5 100644 --- a/pkg/transpile/puzzle_test.go +++ b/pkg/transpile/puzzle_test.go @@ -28,6 +28,19 @@ func TestPuzzle(t *testing.T) { if p.Pre.Body != "
YAML body
\n" { t.Errorf("Body parsed wrong: %#v", p.Pre.Body) } + + f, err := pd.Open("moo.txt") + if err != nil { + t.Error(err) + } + defer f.Close() + buf := new(bytes.Buffer) + if _, err := io.Copy(buf, f); err != nil { + t.Error(err) + } + if buf.String() != "Moo." { + t.Error("Attachment wrong: ", buf.String()) + } } {