/
glob.go
91 lines (85 loc) · 2.21 KB
/
glob.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package build
import (
"fmt"
"os"
"path/filepath"
"sort"
"strings"
"sync"
"github.com/distr1/distri"
)
var globCache = struct {
sync.Mutex
C map[string]string
}{C: make(map[string]string)}
func (b *Ctx) Glob1(imgDir, pkg string) (string, error) {
if b.GlobHook != nil {
return b.GlobHook(imgDir, pkg)
}
key := imgDir + "/" + pkg
globCache.Lock()
globbed, ok := globCache.C[key]
globCache.Unlock()
if ok {
return globbed, nil
}
if st, err := os.Lstat(filepath.Join(imgDir, pkg+".meta.textproto")); err == nil && st.Mode().IsRegular() {
return pkg, nil // pkg already contains the version
}
pkgPattern := pkg
if suffix, ok := distri.HasArchSuffix(pkg); !ok {
pkgPattern = pkgPattern + "-" + b.Arch
} else {
pkg = strings.TrimSuffix(pkg, "-"+suffix)
}
pattern := filepath.Join(imgDir, pkgPattern+"-*.meta.textproto")
matches, err := filepath.Glob(pattern)
if err != nil {
return "", err
}
var candidates []string
for _, m := range matches {
if st, err := os.Lstat(m); err != nil || !st.Mode().IsRegular() {
continue
}
candidates = append(candidates, strings.TrimSuffix(filepath.Base(m), ".meta.textproto"))
}
if len(candidates) > 1 {
// default to the most recent package revision. If building against an
// older version is desired, that version must be specified explicitly.
sort.Slice(candidates, func(i, j int) bool {
return distri.PackageRevisionLess(candidates[i], candidates[j])
})
globbed := candidates[len(candidates)-1]
globCache.Lock()
globCache.C[key] = globbed
globCache.Unlock()
return globbed, nil
}
if len(candidates) == 0 {
if !b.Hermetic {
// no package found, fall back to host tools in non-hermetic mode
return "", nil
}
return "", fmt.Errorf("package %q not found (pattern %s)", pkg, pattern)
}
globbed = candidates[0]
globCache.Lock()
globCache.C[key] = globbed
globCache.Unlock()
return globbed, nil
}
func (b *Ctx) Glob(imgDir string, pkgs []string) ([]string, error) {
globbed := make([]string, 0, len(pkgs))
for _, pkg := range pkgs {
tmp, err := b.Glob1(imgDir, pkg)
if err != nil {
return nil, fmt.Errorf("glob1(%v): %w", pkg, err)
}
if tmp == "" {
continue
}
globbed = append(globbed, tmp)
}
return globbed, nil
}