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"
@@ -36,11 +37,14 @@ type Manifest2822Entry struct {
36
37
GitFetch string
37
38
GitCommit string
38
39
Directory string
40
+ // architecture-specific versions of the above fields are in Paragraph.Values as ARCH-Field, ala s390x-Directory
39
41
40
42
Constraints []string `delim:"," strip:"\n\r\t "`
41
43
}
42
44
43
45
var DefaultManifestEntry = Manifest2822Entry {
46
+ Architectures : []string {"amd64" },
47
+
44
48
GitFetch : "refs/heads/master" ,
45
49
Directory : "." ,
46
50
}
@@ -50,6 +54,7 @@ func (entry Manifest2822Entry) Clone() Manifest2822Entry {
50
54
entry .Maintainers = append ([]string {}, entry .Maintainers ... )
51
55
entry .Tags = append ([]string {}, entry .Tags ... )
52
56
entry .SharedTags = append ([]string {}, entry .SharedTags ... )
57
+ entry .Architectures = append ([]string {}, entry .Architectures ... )
53
58
entry .Constraints = append ([]string {}, entry .Constraints ... )
54
59
return entry
55
60
}
@@ -68,36 +73,44 @@ func (entry Manifest2822Entry) SharedTagsString() string {
68
73
return strings .Join (entry .SharedTags , StringSeparator2822 )
69
74
}
70
75
71
- func (entry Manifest2822Entry ) ConstraintsString () string {
72
- return strings .Join (entry .Constraints , StringSeparator2822 )
73
- }
74
-
75
76
func (entry Manifest2822Entry ) ArchitecturesString () string {
76
77
return strings .Join (entry .Architectures , StringSeparator2822 )
77
78
}
78
79
80
+ func (entry Manifest2822Entry ) ConstraintsString () string {
81
+ return strings .Join (entry .Constraints , StringSeparator2822 )
82
+ }
83
+
79
84
// if this method returns "true", then a.Tags and b.Tags can safely be combined (for the purposes of building)
80
85
func (a Manifest2822Entry ) SameBuildArtifacts (b Manifest2822Entry ) bool {
81
- for key ,val := range a .Paragraph .Values {
82
- if isArchField (key ) && val != b .Paragraph .Values [key ] {
83
- return false
84
- }
85
- }
86
- for key ,val := range b .Paragraph .Values {
87
- if isArchField (key ) && val != a .Paragraph .Values [key ] {
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 ] {
88
89
return false
89
90
}
90
91
}
91
92
92
- return a .GitRepo == b .GitRepo && a .GitFetch == b .GitFetch && a .GitCommit == b .GitCommit && a .Directory == b .Directory && a .ConstraintsString () == b .ConstraintsString () && a .ArchitecturesString () == b .ArchitecturesString ()
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 ()
93
94
}
94
95
95
96
func isArchField (field string ) bool {
96
97
return strings .HasSuffix (field , "-GitRepo" ) || strings .HasSuffix (field , "-GitFetch" ) || strings .HasSuffix (field , "-GitCommit" ) || strings .HasSuffix (field , "-Directory" )
97
98
}
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
109
+ }
110
+
99
111
// returns a new Entry with any of the values that are equal to the values in "defaults" cleared
100
112
func (entry Manifest2822Entry ) ClearDefaults (defaults Manifest2822Entry ) Manifest2822Entry {
113
+ entry = entry .Clone () // make absolutely certain we have a deep clone
101
114
if entry .MaintainersString () == defaults .MaintainersString () {
102
115
entry .Maintainers = nil
103
116
}
@@ -107,6 +120,9 @@ func (entry Manifest2822Entry) ClearDefaults(defaults Manifest2822Entry) Manifes
107
120
if entry .SharedTagsString () == defaults .SharedTagsString () {
108
121
entry .SharedTags = nil
109
122
}
123
+ if entry .ArchitecturesString () == defaults .ArchitecturesString () {
124
+ entry .Architectures = nil
125
+ }
110
126
if entry .GitRepo == defaults .GitRepo {
111
127
entry .GitRepo = ""
112
128
}
@@ -119,17 +135,14 @@ func (entry Manifest2822Entry) ClearDefaults(defaults Manifest2822Entry) Manifes
119
135
if entry .Directory == defaults .Directory {
120
136
entry .Directory = ""
121
137
}
122
- if entry .ConstraintsString () == defaults .ConstraintsString () {
123
- entry .Constraints = nil
124
- }
125
- if entry .ArchitecturesString () == defaults .ArchitecturesString () {
126
- entry .Architectures = nil
127
- }
128
- for key ,val := range defaults .Paragraph .Values {
129
- if isArchField (key ) && val == entry .Paragraph .Values [key ] {
138
+ for _ , key := range defaults .archFields () {
139
+ if defaults .Paragraph .Values [key ] == entry .Paragraph .Values [key ] {
130
140
delete (entry .Paragraph .Values , key )
131
141
}
132
142
}
143
+ if entry .ConstraintsString () == defaults .ConstraintsString () {
144
+ entry .Constraints = nil
145
+ }
133
146
return entry
134
147
}
135
148
@@ -144,6 +157,9 @@ func (entry Manifest2822Entry) String() string {
144
157
if str := entry .SharedTagsString (); str != "" {
145
158
ret = append (ret , "SharedTags: " + str )
146
159
}
160
+ if str := entry .ArchitecturesString (); str != "" {
161
+ ret = append (ret , "Architectures: " + str )
162
+ }
147
163
if str := entry .GitRepo ; str != "" {
148
164
ret = append (ret , "GitRepo: " + str )
149
165
}
@@ -156,17 +172,14 @@ func (entry Manifest2822Entry) String() string {
156
172
if str := entry .Directory ; str != "" {
157
173
ret = append (ret , "Directory: " + str )
158
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
+ }
159
180
if str := entry .ConstraintsString (); str != "" {
160
181
ret = append (ret , "Constraints: " + str )
161
182
}
162
- if str := entry .ArchitecturesString (); str != "" {
163
- ret = append (ret , "Architectures: " + str )
164
- }
165
- for key ,val := range entry .Paragraph .Values {
166
- if isArchField (key ) {
167
- ret = append (ret , key + ": " + val )
168
- }
169
- }
170
183
return strings .Join (ret , "\n " )
171
184
}
172
185
@@ -186,28 +199,28 @@ func (manifest Manifest2822) String() string {
186
199
}
187
200
188
201
func (entry Manifest2822Entry ) ArchGitRepo (arch string ) string {
189
- if val ,ok := entry .Paragraph .Values [arch + "-GitRepo" ]; ok {
202
+ if val , ok := entry .Paragraph .Values [arch + "-GitRepo" ]; ok && val != "" {
190
203
return val
191
204
}
192
205
return entry .GitRepo
193
206
}
194
207
195
208
func (entry Manifest2822Entry ) ArchGitFetch (arch string ) string {
196
- if val ,ok := entry .Paragraph .Values [arch + "-GitFetch" ]; ok {
209
+ if val , ok := entry .Paragraph .Values [arch + "-GitFetch" ]; ok && val != "" {
197
210
return val
198
211
}
199
212
return entry .GitFetch
200
213
}
201
214
202
215
func (entry Manifest2822Entry ) ArchGitCommit (arch string ) string {
203
- if val ,ok := entry .Paragraph .Values [arch + "-GitCommit" ]; ok {
216
+ if val , ok := entry .Paragraph .Values [arch + "-GitCommit" ]; ok && val != "" {
204
217
return val
205
218
}
206
219
return entry .GitCommit
207
220
}
208
221
209
222
func (entry Manifest2822Entry ) ArchDirectory (arch string ) string {
210
- if val ,ok := entry .Paragraph .Values [arch + "-Directory" ]; ok {
223
+ if val , ok := entry .Paragraph .Values [arch + "-Directory" ]; ok && val != "" {
211
224
return val
212
225
}
213
226
return entry .Directory
@@ -429,6 +442,10 @@ func Parse2822(readerIn io.Reader) (*Manifest2822, error) {
429
442
for {
430
443
entry := manifest .Global .Clone ()
431
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
+
432
449
err := decoder .Decode (& entry )
433
450
if err == io .EOF {
434
451
break
@@ -437,6 +454,13 @@ func Parse2822(readerIn io.Reader) (*Manifest2822, error) {
437
454
return nil , err
438
455
}
439
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
+
440
464
if ! GitFetchRegex .MatchString (entry .GitFetch ) {
441
465
return nil , fmt .Errorf (`Tags %q has invalid GitFetch (must be "refs/heads/..." or "refs/tags/..."): %q` , entry .TagsString (), entry .GitFetch )
442
466
}
0 commit comments