diff --git a/cmd/transpile/main.go b/cmd/transpile/main.go index e8f8331..f4a397c 100644 --- a/cmd/transpile/main.go +++ b/cmd/transpile/main.go @@ -39,7 +39,8 @@ func usage(w io.Writer) { fmt.Fprintln(w, "") fmt.Fprintln(w, " mothball: Compile a mothball") fmt.Fprintln(w, " inventory: Show category inventory") - fmt.Fprintln(w, " open: Open a file for a puzzle") + fmt.Fprintln(w, " puzzle: Print puzzle JSON") + fmt.Fprintln(w, " file: Open a file for a puzzle") fmt.Fprintln(w, " answer: Check correctness of an answer") } @@ -62,7 +63,9 @@ func (t *T) ParseArgs() (Command, error) { flags.StringVar(&t.filename, "out", "", "Path to create mothball (empty for stdout)") case "inventory": cmd = t.PrintInventory - case "open": + case "puzzle": + cmd = t.DumpPuzzle + case "file": cmd = t.DumpFile flags.StringVar(&t.filename, "file", "puzzle.json", "Filename to open") case "answer": @@ -112,31 +115,33 @@ func (t *T) PrintInventory() error { return nil } +// DumpPuzzle writes a puzzle's JSON to the writer. +func (t *T) DumpPuzzle() error { + puzzle := transpile.NewFsPuzzle(t.fs) + + p, err := puzzle.Puzzle() + if err != nil { + return err + } + jp, err := json.Marshal(p) + if err != nil { + return err + } + t.Stdout.Write(jp) + return nil +} + // DumpFile writes a file to the writer. -// BUG(neale): The "open" and "answer" actions don't work on categories with an "mkcategory" executable. func (t *T) DumpFile() error { puzzle := transpile.NewFsPuzzle(t.fs) - switch t.filename { - case "puzzle.json", "": - p, err := puzzle.Puzzle() - if err != nil { - return err - } - jp, err := json.Marshal(p) - if err != nil { - return err - } - t.Stdout.Write(jp) - default: - f, err := puzzle.Open(t.filename) - if err != nil { - return err - } - defer f.Close() - if _, err := io.Copy(t.Stdout, f); err != nil { - return err - } + f, err := puzzle.Open(t.filename) + if err != nil { + return err + } + defer f.Close() + if _, err := io.Copy(t.Stdout, f); err != nil { + return err } return nil @@ -174,12 +179,10 @@ func (t *T) DumpMothball() error { // CheckAnswer prints whether an answer is correct. func (t *T) CheckAnswer() error { c := transpile.NewFsPuzzle(t.fs) - if c.Answer(t.answer) { - fmt.Fprintln(t.Stdout, "correct") - } else { - fmt.Fprintln(t.Stdout, "wrong") - } - return nil + log.Print(c.Puzzle()) + log.Print(t.answer) + _, err := fmt.Fprintf(t.Stdout, `{"Correct":%v}`, c.Answer(t.answer)) + return err } func main() { diff --git a/cmd/transpile/main_test.go b/cmd/transpile/main_test.go index 52e1a1e..5566018 100644 --- a/cmd/transpile/main_test.go +++ b/cmd/transpile/main_test.go @@ -50,7 +50,7 @@ func (tp T) Run(args ...string) error { return command() } -func TestEverything(t *testing.T) { +func TestTranspilerEverything(t *testing.T) { stdout := new(bytes.Buffer) stderr := new(bytes.Buffer) tp := T{ @@ -67,7 +67,7 @@ func TestEverything(t *testing.T) { } stdout.Reset() - if err := tp.Run("open", "-dir=cat0/1"); err != nil { + if err := tp.Run("puzzle", "-dir=cat0/1"); err != nil { t.Error(err) } p := transpile.Puzzle{} @@ -79,12 +79,21 @@ func TestEverything(t *testing.T) { } stdout.Reset() - if err := tp.Run("open", "-dir=cat0/1", "-file=moo.txt"); err != nil { + if err := tp.Run("file", "-dir=cat0/1", "-file=moo.txt"); err != nil { t.Error(err) } if stdout.String() != "Moo." { t.Error("Wrong file pulled", stdout.String()) } + + stdout.Reset() + if err := tp.Run("answer", "-dir=cat0/1", "-answer=YAML answer"); err != nil { + t.Error(err) + } + if stdout.String() != `{"Correct":true}` { + t.Error("Answer validation failed", stdout.String()) + } + } func TestMothballs(t *testing.T) { diff --git a/example-puzzles/mkcategory/mkcategory b/example-puzzles/mkcategory/mkcategory new file mode 100755 index 0000000..fff262d --- /dev/null +++ b/example-puzzles/mkcategory/mkcategory @@ -0,0 +1,33 @@ +#! /bin/sh + +fail () { + echo "ERROR: $*" 1>&2 + exit 1 +} + +case $1 in + inventory) + printf '{"Puzzles":[' + ls -d */[0-9]* | while read p; do + puzzle=${p##*/} + printf "%s%d,10%d" "$comma" "$puzzle" "$puzzle" + comma=, + done + printf ']}' + ;; + puzzle) + points=$(($2 % 100)) + transpile puzzle -dir */$points + ;; + file) + points=$(($2 % 100)) + transpile file -dir */$points "$3" + ;; + answer) + points=$(($2 % 100)) + transpile answer -dir */$points -answer="$3" + ;; + *) + fail "What is $1" 1>&2 + ;; +esac diff --git a/example-puzzles/mkcategory/subcat1/1/puzzle.md b/example-puzzles/mkcategory/subcat1/1/puzzle.md new file mode 100644 index 0000000..18d2e72 --- /dev/null +++ b/example-puzzles/mkcategory/subcat1/1/puzzle.md @@ -0,0 +1,10 @@ +--- +pre: + authors: ["neale"] +answers: ["6"] +--- +This category shows off how to use the transpiler from an +`mkcategory` script to organize puzzles into sub-categories, +and (pointlessly) duplicate every puzzle in the category. + + 1 2 3 4 5 _ diff --git a/example-puzzles/mkcategory/subcat1/2/puzzle.md b/example-puzzles/mkcategory/subcat1/2/puzzle.md new file mode 100644 index 0000000..8c4756b --- /dev/null +++ b/example-puzzles/mkcategory/subcat1/2/puzzle.md @@ -0,0 +1,6 @@ +--- +pre: + authors: ["neale"] +answers: ["C", "c"] +--- + 2 4 6 8 A _ diff --git a/example-puzzles/mkcategory/subcat2/3/puzzle.md b/example-puzzles/mkcategory/subcat2/3/puzzle.md new file mode 100644 index 0000000..151347b --- /dev/null +++ b/example-puzzles/mkcategory/subcat2/3/puzzle.md @@ -0,0 +1,6 @@ +--- +pre: + authors: ["neale"] +answers: ["17"] +--- + 1 2 3 5 7 11 13 _