5
5
"fmt"
6
6
"io"
7
7
"regexp"
8
+ "sort"
8
9
"strings"
9
10
10
11
"github.com/docker-library/go-dockerlibrary/pkg/stripper"
@@ -30,15 +31,20 @@ type Manifest2822Entry struct {
30
31
Tags []string `delim:"," strip:"\n\r\t "`
31
32
SharedTags []string `delim:"," strip:"\n\r\t "`
32
33
34
+ Architectures []string `delim:"," strip:"\n\r\t "`
35
+
33
36
GitRepo string
34
37
GitFetch string
35
38
GitCommit string
36
39
Directory string
40
+ // architecture-specific versions of the above fields are in Paragraph.Values as ARCH-Field, ala s390x-Directory
37
41
38
42
Constraints []string `delim:"," strip:"\n\r\t "`
39
43
}
40
44
41
45
var DefaultManifestEntry = Manifest2822Entry {
46
+ Architectures : []string {"amd64" },
47
+
42
48
GitFetch : "refs/heads/master" ,
43
49
Directory : "." ,
44
50
}
@@ -48,6 +54,7 @@ func (entry Manifest2822Entry) Clone() Manifest2822Entry {
48
54
entry .Maintainers = append ([]string {}, entry .Maintainers ... )
49
55
entry .Tags = append ([]string {}, entry .Tags ... )
50
56
entry .SharedTags = append ([]string {}, entry .SharedTags ... )
57
+ entry .Architectures = append ([]string {}, entry .Architectures ... )
51
58
entry .Constraints = append ([]string {}, entry .Constraints ... )
52
59
return entry
53
60
}
@@ -66,17 +73,44 @@ func (entry Manifest2822Entry) SharedTagsString() string {
66
73
return strings .Join (entry .SharedTags , StringSeparator2822 )
67
74
}
68
75
76
+ func (entry Manifest2822Entry ) ArchitecturesString () string {
77
+ return strings .Join (entry .Architectures , StringSeparator2822 )
78
+ }
79
+
69
80
func (entry Manifest2822Entry ) ConstraintsString () string {
70
81
return strings .Join (entry .Constraints , StringSeparator2822 )
71
82
}
72
83
73
84
// if this method returns "true", then a.Tags and b.Tags can safely be combined (for the purposes of building)
74
85
func (a Manifest2822Entry ) SameBuildArtifacts (b Manifest2822Entry ) bool {
75
- return a .GitRepo == b .GitRepo && a .GitFetch == b .GitFetch && a .GitCommit == b .GitCommit && a .Directory == b .Directory && a .ConstraintsString () == b .ConstraintsString ()
86
+ // check xxxarch-GitRepo, etc. fields for sameness first
87
+ for _ , key := range append (a .archFields (), b .archFields ()... ) {
88
+ if a .Paragraph .Values [key ] != b .Paragraph .Values [key ] {
89
+ return false
90
+ }
91
+ }
92
+
93
+ return a .ArchitecturesString () == b .ArchitecturesString () && a .GitRepo == b .GitRepo && a .GitFetch == b .GitFetch && a .GitCommit == b .GitCommit && a .Directory == b .Directory && a .ConstraintsString () == b .ConstraintsString ()
94
+ }
95
+
96
+ func isArchField (field string ) bool {
97
+ return strings .HasSuffix (field , "-GitRepo" ) || strings .HasSuffix (field , "-GitFetch" ) || strings .HasSuffix (field , "-GitCommit" ) || strings .HasSuffix (field , "-Directory" )
98
+ }
99
+
100
+ // returns a list of architecture-specific fields in an Entry
101
+ func (entry Manifest2822Entry ) archFields () []string {
102
+ ret := []string {}
103
+ for key , val := range entry .Paragraph .Values {
104
+ if isArchField (key ) && val != "" {
105
+ ret = append (ret , key )
106
+ }
107
+ }
108
+ return ret
76
109
}
77
110
78
111
// returns a new Entry with any of the values that are equal to the values in "defaults" cleared
79
112
func (entry Manifest2822Entry ) ClearDefaults (defaults Manifest2822Entry ) Manifest2822Entry {
113
+ entry = entry .Clone () // make absolutely certain we have a deep clone
80
114
if entry .MaintainersString () == defaults .MaintainersString () {
81
115
entry .Maintainers = nil
82
116
}
@@ -86,6 +120,9 @@ func (entry Manifest2822Entry) ClearDefaults(defaults Manifest2822Entry) Manifes
86
120
if entry .SharedTagsString () == defaults .SharedTagsString () {
87
121
entry .SharedTags = nil
88
122
}
123
+ if entry .ArchitecturesString () == defaults .ArchitecturesString () {
124
+ entry .Architectures = nil
125
+ }
89
126
if entry .GitRepo == defaults .GitRepo {
90
127
entry .GitRepo = ""
91
128
}
@@ -98,6 +135,11 @@ func (entry Manifest2822Entry) ClearDefaults(defaults Manifest2822Entry) Manifes
98
135
if entry .Directory == defaults .Directory {
99
136
entry .Directory = ""
100
137
}
138
+ for _ , key := range defaults .archFields () {
139
+ if defaults .Paragraph .Values [key ] == entry .Paragraph .Values [key ] {
140
+ delete (entry .Paragraph .Values , key )
141
+ }
142
+ }
101
143
if entry .ConstraintsString () == defaults .ConstraintsString () {
102
144
entry .Constraints = nil
103
145
}
@@ -115,6 +157,9 @@ func (entry Manifest2822Entry) String() string {
115
157
if str := entry .SharedTagsString (); str != "" {
116
158
ret = append (ret , "SharedTags: " + str )
117
159
}
160
+ if str := entry .ArchitecturesString (); str != "" {
161
+ ret = append (ret , "Architectures: " + str )
162
+ }
118
163
if str := entry .GitRepo ; str != "" {
119
164
ret = append (ret , "GitRepo: " + str )
120
165
}
@@ -127,6 +172,11 @@ func (entry Manifest2822Entry) String() string {
127
172
if str := entry .Directory ; str != "" {
128
173
ret = append (ret , "Directory: " + str )
129
174
}
175
+ archFields := entry .archFields ()
176
+ sort .Strings (archFields ) // consistent ordering
177
+ for _ , key := range archFields {
178
+ ret = append (ret , key + ": " + entry .Paragraph .Values [key ])
179
+ }
130
180
if str := entry .ConstraintsString (); str != "" {
131
181
ret = append (ret , "Constraints: " + str )
132
182
}
@@ -148,6 +198,34 @@ func (manifest Manifest2822) String() string {
148
198
return strings .Join (ret , "\n \n " )
149
199
}
150
200
201
+ func (entry Manifest2822Entry ) ArchGitRepo (arch string ) string {
202
+ if val , ok := entry .Paragraph .Values [arch + "-GitRepo" ]; ok && val != "" {
203
+ return val
204
+ }
205
+ return entry .GitRepo
206
+ }
207
+
208
+ func (entry Manifest2822Entry ) ArchGitFetch (arch string ) string {
209
+ if val , ok := entry .Paragraph .Values [arch + "-GitFetch" ]; ok && val != "" {
210
+ return val
211
+ }
212
+ return entry .GitFetch
213
+ }
214
+
215
+ func (entry Manifest2822Entry ) ArchGitCommit (arch string ) string {
216
+ if val , ok := entry .Paragraph .Values [arch + "-GitCommit" ]; ok && val != "" {
217
+ return val
218
+ }
219
+ return entry .GitCommit
220
+ }
221
+
222
+ func (entry Manifest2822Entry ) ArchDirectory (arch string ) string {
223
+ if val , ok := entry .Paragraph .Values [arch + "-Directory" ]; ok && val != "" {
224
+ return val
225
+ }
226
+ return entry .Directory
227
+ }
228
+
151
229
func (entry Manifest2822Entry ) HasTag (tag string ) bool {
152
230
for _ , existingTag := range entry .Tags {
153
231
if tag == existingTag {
@@ -364,6 +442,10 @@ func Parse2822(readerIn io.Reader) (*Manifest2822, error) {
364
442
for {
365
443
entry := manifest .Global .Clone ()
366
444
445
+ // reset Architectures and SharedTags so that they can be either inherited or replaced, not additive
446
+ entry .SharedTags = nil
447
+ entry .Architectures = nil
448
+
367
449
err := decoder .Decode (& entry )
368
450
if err == io .EOF {
369
451
break
@@ -372,6 +454,13 @@ func Parse2822(readerIn io.Reader) (*Manifest2822, error) {
372
454
return nil , err
373
455
}
374
456
457
+ if len (entry .SharedTags ) == 0 {
458
+ entry .SharedTags = manifest .Global .SharedTags
459
+ }
460
+ if len (entry .Architectures ) == 0 {
461
+ entry .Architectures = manifest .Global .Architectures
462
+ }
463
+
375
464
if ! GitFetchRegex .MatchString (entry .GitFetch ) {
376
465
return nil , fmt .Errorf (`Tags %q has invalid GitFetch (must be "refs/heads/..." or "refs/tags/..."): %q` , entry .TagsString (), entry .GitFetch )
377
466
}
0 commit comments