...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package v1
16
17 import (
18 "fmt"
19 "sort"
20 "strings"
21 )
22
23
24 type Platform struct {
25 Architecture string `json:"architecture"`
26 OS string `json:"os"`
27 OSVersion string `json:"os.version,omitempty"`
28 OSFeatures []string `json:"os.features,omitempty"`
29 Variant string `json:"variant,omitempty"`
30 Features []string `json:"features,omitempty"`
31 }
32
33 func (p Platform) String() string {
34 if p.OS == "" {
35 return ""
36 }
37 var b strings.Builder
38 b.WriteString(p.OS)
39 if p.Architecture != "" {
40 b.WriteString("/")
41 b.WriteString(p.Architecture)
42 }
43 if p.Variant != "" {
44 b.WriteString("/")
45 b.WriteString(p.Variant)
46 }
47 if p.OSVersion != "" {
48 b.WriteString(":")
49 b.WriteString(p.OSVersion)
50 }
51 return b.String()
52 }
53
54
55 func ParsePlatform(s string) (*Platform, error) {
56 var p Platform
57 parts := strings.Split(strings.TrimSpace(s), ":")
58 if len(parts) == 2 {
59 p.OSVersion = parts[1]
60 }
61 parts = strings.Split(parts[0], "/")
62 if len(parts) > 0 {
63 p.OS = parts[0]
64 }
65 if len(parts) > 1 {
66 p.Architecture = parts[1]
67 }
68 if len(parts) > 2 {
69 p.Variant = parts[2]
70 }
71 if len(parts) > 3 {
72 return nil, fmt.Errorf("too many slashes in platform spec: %s", s)
73 }
74 return &p, nil
75 }
76
77
78
79 func (p Platform) Equals(o Platform) bool {
80 return p.OS == o.OS &&
81 p.Architecture == o.Architecture &&
82 p.Variant == o.Variant &&
83 p.OSVersion == o.OSVersion &&
84 stringSliceEqualIgnoreOrder(p.OSFeatures, o.OSFeatures) &&
85 stringSliceEqualIgnoreOrder(p.Features, o.Features)
86 }
87
88
89
90
91
92
93
94
95
96
97 func (p Platform) Satisfies(spec Platform) bool {
98 return satisfies(spec.OS, p.OS) &&
99 satisfies(spec.Architecture, p.Architecture) &&
100 satisfies(spec.Variant, p.Variant) &&
101 satisfies(spec.OSVersion, p.OSVersion) &&
102 satisfiesList(spec.OSFeatures, p.OSFeatures) &&
103 satisfiesList(spec.Features, p.Features)
104 }
105
106 func satisfies(want, have string) bool {
107 return want == "" || want == have
108 }
109
110 func satisfiesList(want, have []string) bool {
111 if len(want) == 0 {
112 return true
113 }
114
115 set := map[string]struct{}{}
116 for _, h := range have {
117 set[h] = struct{}{}
118 }
119
120 for _, w := range want {
121 if _, ok := set[w]; !ok {
122 return false
123 }
124 }
125
126 return true
127 }
128
129
130 func stringSliceEqual(a, b []string) bool {
131 if len(a) != len(b) {
132 return false
133 }
134 for i, elm := range a {
135 if elm != b[i] {
136 return false
137 }
138 }
139 return true
140 }
141
142
143 func stringSliceEqualIgnoreOrder(a, b []string) bool {
144 if a != nil && b != nil {
145 sort.Strings(a)
146 sort.Strings(b)
147 }
148 return stringSliceEqual(a, b)
149 }
150
View as plain text