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