Neale Pickett
·
2021-02-24
mothball.go
1package transpile
2
3import (
4 "archive/zip"
5 "bytes"
6 "encoding/json"
7 "fmt"
8 "io"
9 "os/exec"
10)
11
12// Mothball packages a Category up for a production server run.
13func Mothball(c Category, w io.Writer) error {
14 zf := zip.NewWriter(w)
15
16 inv, err := c.Inventory()
17 if err != nil {
18 return err
19 }
20
21 puzzlesTxt := new(bytes.Buffer)
22 answersTxt := new(bytes.Buffer)
23
24 for _, points := range inv {
25 fmt.Fprintln(puzzlesTxt, points)
26
27 puzzlePath := fmt.Sprintf("%d/puzzle.json", points)
28 pw, err := zf.Create(puzzlePath)
29 if err != nil {
30 return err
31 }
32 puzzle, err := c.Puzzle(points)
33 if err != nil {
34 return fmt.Errorf("Puzzle %d: %s", points, err)
35 }
36
37 // Record answers in answers.txt
38 for _, answer := range puzzle.Answers {
39 fmt.Fprintln(answersTxt, points, answer)
40 }
41
42 // Remove answers and debugging from puzzle object
43 puzzle.Answers = []string{}
44 puzzle.Debug.Errors = []string{}
45 puzzle.Debug.Hints = []string{}
46 puzzle.Debug.Log = []string{}
47 puzzle.Debug.Summary = ""
48
49 // Write out Puzzle object
50 penc := json.NewEncoder(pw)
51 if err := penc.Encode(puzzle); err != nil {
52 return fmt.Errorf("Puzzle %d: %s", points, err)
53 }
54
55 // Write out all attachments and scripts
56 attachments := append(puzzle.Attachments, puzzle.Scripts...)
57 for _, att := range attachments {
58 attPath := fmt.Sprintf("%d/%s", points, att)
59 aw, err := zf.Create(attPath)
60 if err != nil {
61 return err
62 }
63 ar, err := c.Open(points, att)
64 if exerr, ok := err.(*exec.ExitError); ok {
65 return fmt.Errorf("Puzzle %d: %s: %s: %s", points, att, err, string(exerr.Stderr))
66 } else if err != nil {
67 return fmt.Errorf("Puzzle %d: %s: %s", points, att, err)
68 }
69 if _, err := io.Copy(aw, ar); err != nil {
70 return fmt.Errorf("Puzzle %d: %s: %s", points, att, err)
71 }
72 }
73 }
74
75 pf, err := zf.Create("puzzles.txt")
76 if err != nil {
77 return err
78 }
79 puzzlesTxt.WriteTo(pf)
80
81 af, err := zf.Create("answers.txt")
82 if err != nil {
83 return err
84 }
85 answersTxt.WriteTo(af)
86
87 zf.Close()
88
89 return nil
90}