Merge branch 'compression' of https://github.com/jasonish/packr into jasonish-compression
Mark Bates
6 years ago
7 | 7 | "path/filepath" |
8 | 8 | "runtime" |
9 | 9 | "strings" |
10 | ||
11 | "compress/gzip" | |
10 | 12 | |
11 | 13 | "github.com/pkg/errors" |
12 | 14 | ) |
73 | 75 | return true |
74 | 76 | } |
75 | 77 | |
78 | func (b Box) decompress(bb []byte) []byte { | |
79 | reader, err := gzip.NewReader(bytes.NewReader(bb)) | |
80 | if err != nil { | |
81 | return bb | |
82 | } | |
83 | data, err := ioutil.ReadAll(reader) | |
84 | if err != nil { | |
85 | return bb | |
86 | } | |
87 | return data | |
88 | } | |
89 | ||
76 | 90 | func (b Box) find(name string) (File, error) { |
77 | 91 | name = strings.TrimPrefix(name, "/") |
78 | 92 | name = filepath.ToSlash(name) |
79 | 93 | if _, ok := data[b.Path]; ok { |
80 | 94 | if bb, ok := data[b.Path][name]; ok { |
95 | bb = b.decompress(bb) | |
81 | 96 | return newVirtualFile(name, bb), nil |
82 | 97 | } |
83 | 98 | if filepath.Ext(name) != "" { |
6 | 6 | "path/filepath" |
7 | 7 | "strings" |
8 | 8 | |
9 | "bytes" | |
10 | "compress/gzip" | |
11 | ||
9 | 12 | "github.com/pkg/errors" |
10 | 13 | ) |
11 | 14 | |
12 | 15 | type box struct { |
13 | Name string | |
14 | Files []file | |
16 | Name string | |
17 | Files []file | |
18 | compress bool | |
15 | 19 | } |
16 | 20 | |
17 | 21 | func (b *box) Walk(root string) error { |
32 | 36 | if err != nil { |
33 | 37 | return errors.WithStack(err) |
34 | 38 | } |
39 | if b.compress { | |
40 | bb, err = compressFile(bb) | |
41 | if err != nil { | |
42 | return errors.WithStack(err) | |
43 | } | |
44 | } | |
35 | 45 | bb, err = json.Marshal(bb) |
36 | 46 | if err != nil { |
37 | 47 | return errors.WithStack(err) |
42 | 52 | return nil |
43 | 53 | }) |
44 | 54 | } |
55 | ||
56 | func compressFile(bb []byte) ([]byte, error) { | |
57 | var buf bytes.Buffer | |
58 | writer := gzip.NewWriter(&buf) | |
59 | _, err := writer.Write(bb) | |
60 | if err != nil { | |
61 | return bb, errors.WithStack(err) | |
62 | } | |
63 | err = writer.Close() | |
64 | if err != nil { | |
65 | return bb, errors.WithStack(err) | |
66 | } | |
67 | return buf.Bytes(), nil | |
68 | } |
22 | 22 | IgnoredBoxes []string |
23 | 23 | pkgs map[string]pkg |
24 | 24 | moot *sync.Mutex |
25 | Compress bool | |
25 | 26 | } |
26 | 27 | |
27 | 28 | // Run the builder. |
95 | 96 | } |
96 | 97 | } |
97 | 98 | bx := &box{ |
98 | Name: n, | |
99 | Files: []file{}, | |
99 | Name: n, | |
100 | Files: []file{}, | |
101 | compress: b.Compress, | |
100 | 102 | } |
101 | 103 | p := filepath.Join(pk.Dir, bx.Name) |
102 | 104 | if err := bx.Walk(p); err != nil { |
44 | 44 | r.True(bytes.Contains(bb, []byte(`packr.PackJSONBytes("../templates", "index.html", "\"PCFET0NUWVBFIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiIC8+CiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoIiAvPgogICAgPHRpdGxlPklOREVYPC90aXRsZT4KICAgIGxpbmsKICA8L2hlYWQ+CiAgPGJvZHk+CiAgICBib2R5CiAgPC9ib2R5Pgo8L2h0bWw+Cg==\"")`))) |
45 | 45 | } |
46 | 46 | |
47 | func Test_Builder_Run_Compress(t *testing.T) { | |
48 | r := require.New(t) | |
49 | ||
50 | root := filepath.Join("..", "example") | |
51 | defer Clean(root) | |
52 | ||
53 | exPackr := filepath.Join(root, "example-packr.go") | |
54 | r.False(fileExists(exPackr)) | |
55 | ||
56 | fooPackr := filepath.Join(root, "foo", "foo-packr.go") | |
57 | r.False(fileExists(fooPackr)) | |
58 | ||
59 | b := New(context.Background(), root) | |
60 | b.Compress = true | |
61 | err := b.Run() | |
62 | r.NoError(err) | |
63 | ||
64 | r.True(fileExists(exPackr)) | |
65 | r.True(fileExists(fooPackr)) | |
66 | ||
67 | bb, err := ioutil.ReadFile(exPackr) | |
68 | r.NoError(err) | |
69 | r.True(bytes.Contains(bb, []byte(`packr.PackJSONBytes("./assets", "app.css", "\"H4sIAAAAAAAA/0rKT6lUqOZSUEhKTM5OL8ovzUuxUihKTbHmquUCBAAA//8hHmttHAAAAA==\"`))) | |
70 | r.True(bytes.Contains(bb, []byte(`packr.PackJSONBytes("./assets", "app.js", "\"H4sIAAAAAAAA/0rMSS0q0VDKSM3JyVdU0rTmAgQAAP//8IaimBEAAAA=\"")`))) | |
71 | ||
72 | bb, err = ioutil.ReadFile(fooPackr) | |
73 | r.NoError(err) | |
74 | r.True(bytes.Contains(bb, []byte(`packr.PackJSONBytes("../assets", "app.css", "\"H4sIAAAAAAAA/0rKT6lUqOZSUEhKTM5OL8ovzUuxUihKTbHmquUCBAAA//8hHmttHAAAAA==\"")`))) | |
75 | r.True(bytes.Contains(bb, []byte(`packr.PackJSONBytes("../assets", "app.js", "\"H4sIAAAAAAAA/0rMSS0q0VDKSM3JyVdU0rTmAgQAAP//8IaimBEAAAA=\"")`))) | |
76 | r.True(bytes.Contains(bb, []byte(`packr.PackJSONBytes("../templates", "index.html", "\"H4sIAAAAAAAA/0yOvQ7CMAyEd57CZK+yMjhdaAcWYGCAMSRGicgPKqYVb4+SCMHkO3866cP1cNieLscRHMfQr7AdAHSkbQkAGIk1GKenJ7ESL751GwHyHyYdSYnZ0/LIEwswOTElVmLxlp2yNHtDXS2/JXsO1O/2w3hG2UoFwad7MZBfBbxm+26spMraC2Xz/QQAAP//5yPZVscAAAA=\"")`))) | |
77 | } | |
78 | ||
47 | 79 | func Test_Binary_Builds(t *testing.T) { |
48 | 80 | r := require.New(t) |
49 | 81 | pwd, _ := os.Getwd() |
8 | 8 | ) |
9 | 9 | |
10 | 10 | var input string |
11 | var compress bool | |
11 | 12 | |
12 | 13 | var rootCmd = &cobra.Command{ |
13 | 14 | Use: "packr", |
14 | 15 | Short: "compiles static files into Go files", |
15 | 16 | RunE: func(cmd *cobra.Command, args []string) error { |
16 | 17 | b := builder.New(context.Background(), input) |
18 | b.Compress = compress | |
17 | 19 | return b.Run() |
18 | 20 | }, |
19 | 21 | } |
21 | 23 | func init() { |
22 | 24 | pwd, _ := os.Getwd() |
23 | 25 | rootCmd.Flags().StringVarP(&input, "input", "i", pwd, "path to scan for packr Boxes") |
26 | rootCmd.Flags().BoolVarP(&compress, "compress", "z", false, "compress box contents") | |
24 | 27 | } |
25 | 28 | |
26 | 29 | // Execute the commands |
2 | 2 | import ( |
3 | 3 | "encoding/json" |
4 | 4 | "sync" |
5 | "bytes" | |
6 | "compress/gzip" | |
5 | 7 | ) |
6 | 8 | |
7 | 9 | var gil = &sync.Mutex{} |
17 | 19 | data[box][name] = bb |
18 | 20 | } |
19 | 21 | |
22 | // PackBytesGzip packets the gzipped compressed bytes into a box. | |
23 | func PackBytesGzip(box string, name string, bb []byte) error { | |
24 | var buf bytes.Buffer | |
25 | w := gzip.NewWriter(&buf) | |
26 | _, err := w.Write(bb) | |
27 | if err != nil { | |
28 | return err | |
29 | } | |
30 | err = w.Close() | |
31 | if err != nil { | |
32 | return err | |
33 | } | |
34 | PackBytes(box, name, buf.Bytes()) | |
35 | return nil | |
36 | } | |
37 | ||
20 | 38 | // PackJSONBytes packs JSON encoded bytes for a file into a box. |
21 | 39 | func PackJSONBytes(box string, name string, jbb string) error { |
22 | 40 | bb := []byte{} |