...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package runfiles
16
17 import (
18 "bufio"
19 "fmt"
20 "os"
21 "path"
22 "path/filepath"
23 "strings"
24 )
25
26
27
28
29 type ManifestFile string
30
31 func (f ManifestFile) new(sourceRepo SourceRepo) (*Runfiles, error) {
32 m, err := f.parse()
33 if err != nil {
34 return nil, err
35 }
36 env := []string{
37 manifestFileVar + "=" + string(f),
38 }
39
40
41 if strings.HasSuffix(string(f), ".runfiles_manifest") ||
42 strings.HasSuffix(string(f), "/MANIFEST") ||
43 strings.HasSuffix(string(f), "\\MANIFEST") {
44
45
46 d := string(f)[:len(string(f))-len("_manifest")]
47 env = append(env,
48 directoryVar+"="+d,
49 legacyDirectoryVar+"="+d)
50 }
51 r := &Runfiles{
52 impl: m,
53 env: env,
54 sourceRepo: string(sourceRepo),
55 }
56 err = r.loadRepoMapping()
57 return r, err
58 }
59
60 type manifest map[string]string
61
62 func (f ManifestFile) parse() (manifest, error) {
63 r, err := os.Open(string(f))
64 if err != nil {
65 return nil, fmt.Errorf("runfiles: can’t open manifest file: %w", err)
66 }
67 defer r.Close()
68
69 s := bufio.NewScanner(r)
70 m := make(manifest)
71 for s.Scan() {
72 fields := strings.SplitN(s.Text(), " ", 2)
73 if len(fields) != 2 || fields[0] == "" {
74 return nil, fmt.Errorf("runfiles: bad manifest line %q in file %s", s.Text(), f)
75 }
76 m[fields[0]] = filepath.FromSlash(fields[1])
77 }
78
79 if err := s.Err(); err != nil {
80 return nil, fmt.Errorf("runfiles: error parsing manifest file %s: %w", f, err)
81 }
82
83 return m, nil
84 }
85
86 func (m manifest) path(s string) (string, error) {
87 r, ok := m[s]
88 if ok && r == "" {
89 return "", ErrEmpty
90 }
91 if ok {
92 return r, nil
93 }
94
95
96
97
98 for prefix := s; prefix != ""; prefix, _ = path.Split(prefix) {
99 prefix = strings.TrimSuffix(prefix, "/")
100 if prefixMatch, ok := m[prefix]; ok {
101 return prefixMatch + filepath.FromSlash(strings.TrimPrefix(s, prefix)), nil
102 }
103 }
104
105 return "", os.ErrNotExist
106 }
107
View as plain text