...
1
2
3
4
5 package buildutil
6
7 import (
8 "bufio"
9 "bytes"
10 "fmt"
11 "go/build"
12 "io"
13 "path/filepath"
14 "strconv"
15 "strings"
16 )
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 func OverlayContext(orig *build.Context, overlay map[string][]byte) *build.Context {
32
33
34 rc := func(data []byte) (io.ReadCloser, error) {
35 return io.NopCloser(bytes.NewBuffer(data)), nil
36 }
37
38 copy := *orig
39 ctxt := ©
40 ctxt.OpenFile = func(path string) (io.ReadCloser, error) {
41
42 if content, ok := overlay[path]; ok {
43 return rc(content)
44 }
45
46
47
48 for filename, content := range overlay {
49 if sameFile(path, filename) {
50 return rc(content)
51 }
52 }
53
54 return OpenFile(orig, path)
55 }
56 return ctxt
57 }
58
59
60
61
62
63
64
65
66
67 func ParseOverlayArchive(archive io.Reader) (map[string][]byte, error) {
68 overlay := make(map[string][]byte)
69 r := bufio.NewReader(archive)
70 for {
71
72 filename, err := r.ReadString('\n')
73 if err != nil {
74 if err == io.EOF {
75 break
76 }
77 return nil, fmt.Errorf("reading archive file name: %v", err)
78 }
79 filename = filepath.Clean(strings.TrimSpace(filename))
80
81
82 sz, err := r.ReadString('\n')
83 if err != nil {
84 return nil, fmt.Errorf("reading size of archive file %s: %v", filename, err)
85 }
86 sz = strings.TrimSpace(sz)
87 size, err := strconv.ParseUint(sz, 10, 32)
88 if err != nil {
89 return nil, fmt.Errorf("parsing size of archive file %s: %v", filename, err)
90 }
91
92
93 content := make([]byte, size)
94 if _, err := io.ReadFull(r, content); err != nil {
95 return nil, fmt.Errorf("reading archive file %s: %v", filename, err)
96 }
97 overlay[filename] = content
98 }
99
100 return overlay, nil
101 }
102
View as plain text