Skip to content

Commit 40117df

Browse files
committed
Add more tweaks, functionality, and tests to the Architectures implementation
1 parent 76cdafa commit 40117df

File tree

2 files changed

+75
-41
lines changed

2 files changed

+75
-41
lines changed

manifest/example_test.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ func Example() {
1515
1616
Maintainers: InfoSiftr <[email protected]> (@infosiftr),
1717
Johan Euphrosine <[email protected]> (@proppy)
18-
GitRepo: https://github.com/docker-library/golang.git
1918
GitFetch: refs/heads/master
19+
GitRepo: https://github.com/docker-library/golang.git
2020
SharedTags: latest
2121
2222
@@ -28,15 +28,15 @@ SharedTags: latest
2828
2929
# Go 1.6
3030
Tags: 1.6.1, 1.6, 1
31-
GitCommit: 0ce80411b9f41e9c3a21fc0a1bffba6ae761825a
3231
Directory: 1.6
32+
GitCommit: 0ce80411b9f41e9c3a21fc0a1bffba6ae761825a
3333
Constraints: some-random-build-server
3434
3535
3636
# Go 1.5
3737
Tags: 1.5.3
38-
SharedTags: 1.5.3-debian, 1.5-debian
3938
GitCommit: d7e2a8d90a9b8f5dfd5bcd428e0c33b68c40cc19
39+
SharedTags: 1.5.3-debian, 1.5-debian
4040
Directory: 1.5
4141
4242
@@ -45,6 +45,11 @@ SharedTags: 1.5-debian
4545
GitCommit: d7e2a8d90a9b8f5dfd5bcd428e0c33b68c40cc19
4646
Directory: 1.5
4747
48+
SharedTags: raspbian
49+
GitCommit: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef
50+
Tags: raspbian-s390x
51+
Architectures: s390x
52+
4853
4954
`)))
5055
if err != nil {
@@ -91,19 +96,26 @@ i: g@h j
9196
// Constraints: some-random-build-server
9297
//
9398
// Tags: 1.5.3, 1.5
94-
// SharedTags: latest, 1.5.3-debian, 1.5-debian
99+
// SharedTags: 1.5.3-debian, 1.5-debian
95100
// GitCommit: d7e2a8d90a9b8f5dfd5bcd428e0c33b68c40cc19
96101
// Directory: 1.5
97102
//
103+
// Tags: raspbian-s390x
104+
// SharedTags: raspbian
105+
// Architectures: s390x
106+
// GitCommit: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef
107+
//
98108
// Shared Tag Groups:
99109
//
100110
// - latest
101111
// - 1.6.1, 1.6, 1
102-
// - 1.5.3, 1.5
103112
//
104113
// - 1.5.3-debian, 1.5-debian
105114
// - 1.5.3, 1.5
106115
//
116+
// - raspbian
117+
// - raspbian-s390x
118+
//
107119
// -------------
108120
// line-based:
109121
// Maintainers: InfoSiftr <[email protected]> (@infosiftr), John Smith <[email protected]> (@example-jsmith)
@@ -134,15 +146,14 @@ func ExampleFetch_local() {
134146

135147
fmt.Printf("%s:%s\n\n", repoName, tagName)
136148

137-
fmt.Println(man.GetTag(tagName))
149+
fmt.Println(man.GetTag(tagName).ClearDefaults(manifest.DefaultManifestEntry).String())
138150

139151
// Output:
140152
// bash:4.4
141153
//
142154
// Maintainers: Tianon Gravi <[email protected]> (@tianon)
143155
// Tags: 4.4.12, 4.4, 4, latest
144156
// GitRepo: https://github.com/tianon/docker-bash.git
145-
// GitFetch: refs/heads/master
146157
// GitCommit: 1cbb5cf49b4c53bd5a986abf7a1afeb9a80eac1e
147158
// Directory: 4.4
148159
}
@@ -155,15 +166,14 @@ func ExampleFetch_remote() {
155166

156167
fmt.Printf("%s:%s\n\n", repoName, tagName)
157168

158-
fmt.Println(man.GetTag(tagName))
169+
fmt.Println(man.GetTag(tagName).ClearDefaults(manifest.DefaultManifestEntry).String())
159170

160171
// Output:
161172
// bash:4.4
162173
//
163174
// Maintainers: Tianon Gravi <[email protected]> (@tianon)
164175
// Tags: 4.4.12, 4.4, 4, latest
165176
// GitRepo: https://github.com/tianon/docker-bash.git
166-
// GitFetch: refs/heads/master
167177
// GitCommit: 1cbb5cf49b4c53bd5a986abf7a1afeb9a80eac1e
168178
// Directory: 4.4
169179
}

manifest/rfc2822.go

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"io"
77
"regexp"
8+
"sort"
89
"strings"
910

1011
"github.com/docker-library/go-dockerlibrary/pkg/stripper"
@@ -36,11 +37,14 @@ type Manifest2822Entry struct {
3637
GitFetch string
3738
GitCommit string
3839
Directory string
40+
// architecture-specific versions of the above fields are in Paragraph.Values as ARCH-Field, ala s390x-Directory
3941

4042
Constraints []string `delim:"," strip:"\n\r\t "`
4143
}
4244

4345
var DefaultManifestEntry = Manifest2822Entry{
46+
Architectures: []string{"amd64"},
47+
4448
GitFetch: "refs/heads/master",
4549
Directory: ".",
4650
}
@@ -50,6 +54,7 @@ func (entry Manifest2822Entry) Clone() Manifest2822Entry {
5054
entry.Maintainers = append([]string{}, entry.Maintainers...)
5155
entry.Tags = append([]string{}, entry.Tags...)
5256
entry.SharedTags = append([]string{}, entry.SharedTags...)
57+
entry.Architectures = append([]string{}, entry.Architectures...)
5358
entry.Constraints = append([]string{}, entry.Constraints...)
5459
return entry
5560
}
@@ -68,36 +73,44 @@ func (entry Manifest2822Entry) SharedTagsString() string {
6873
return strings.Join(entry.SharedTags, StringSeparator2822)
6974
}
7075

71-
func (entry Manifest2822Entry) ConstraintsString() string {
72-
return strings.Join(entry.Constraints, StringSeparator2822)
73-
}
74-
7576
func (entry Manifest2822Entry) ArchitecturesString() string {
7677
return strings.Join(entry.Architectures, StringSeparator2822)
7778
}
7879

80+
func (entry Manifest2822Entry) ConstraintsString() string {
81+
return strings.Join(entry.Constraints, StringSeparator2822)
82+
}
83+
7984
// if this method returns "true", then a.Tags and b.Tags can safely be combined (for the purposes of building)
8085
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] {
8889
return false
8990
}
9091
}
9192

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()
9394
}
9495

9596
func isArchField(field string) bool {
9697
return strings.HasSuffix(field, "-GitRepo") || strings.HasSuffix(field, "-GitFetch") || strings.HasSuffix(field, "-GitCommit") || strings.HasSuffix(field, "-Directory")
9798
}
9899

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+
99111
// returns a new Entry with any of the values that are equal to the values in "defaults" cleared
100112
func (entry Manifest2822Entry) ClearDefaults(defaults Manifest2822Entry) Manifest2822Entry {
113+
entry = entry.Clone() // make absolutely certain we have a deep clone
101114
if entry.MaintainersString() == defaults.MaintainersString() {
102115
entry.Maintainers = nil
103116
}
@@ -107,6 +120,9 @@ func (entry Manifest2822Entry) ClearDefaults(defaults Manifest2822Entry) Manifes
107120
if entry.SharedTagsString() == defaults.SharedTagsString() {
108121
entry.SharedTags = nil
109122
}
123+
if entry.ArchitecturesString() == defaults.ArchitecturesString() {
124+
entry.Architectures = nil
125+
}
110126
if entry.GitRepo == defaults.GitRepo {
111127
entry.GitRepo = ""
112128
}
@@ -119,17 +135,14 @@ func (entry Manifest2822Entry) ClearDefaults(defaults Manifest2822Entry) Manifes
119135
if entry.Directory == defaults.Directory {
120136
entry.Directory = ""
121137
}
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] {
130140
delete(entry.Paragraph.Values, key)
131141
}
132142
}
143+
if entry.ConstraintsString() == defaults.ConstraintsString() {
144+
entry.Constraints = nil
145+
}
133146
return entry
134147
}
135148

@@ -144,6 +157,9 @@ func (entry Manifest2822Entry) String() string {
144157
if str := entry.SharedTagsString(); str != "" {
145158
ret = append(ret, "SharedTags: "+str)
146159
}
160+
if str := entry.ArchitecturesString(); str != "" {
161+
ret = append(ret, "Architectures: "+str)
162+
}
147163
if str := entry.GitRepo; str != "" {
148164
ret = append(ret, "GitRepo: "+str)
149165
}
@@ -156,17 +172,14 @@ func (entry Manifest2822Entry) String() string {
156172
if str := entry.Directory; str != "" {
157173
ret = append(ret, "Directory: "+str)
158174
}
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+
}
159180
if str := entry.ConstraintsString(); str != "" {
160181
ret = append(ret, "Constraints: "+str)
161182
}
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-
}
170183
return strings.Join(ret, "\n")
171184
}
172185

@@ -186,28 +199,28 @@ func (manifest Manifest2822) String() string {
186199
}
187200

188201
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 != "" {
190203
return val
191204
}
192205
return entry.GitRepo
193206
}
194207

195208
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 != "" {
197210
return val
198211
}
199212
return entry.GitFetch
200213
}
201214

202215
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 != "" {
204217
return val
205218
}
206219
return entry.GitCommit
207220
}
208221

209222
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 != "" {
211224
return val
212225
}
213226
return entry.Directory
@@ -429,6 +442,10 @@ func Parse2822(readerIn io.Reader) (*Manifest2822, error) {
429442
for {
430443
entry := manifest.Global.Clone()
431444

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+
432449
err := decoder.Decode(&entry)
433450
if err == io.EOF {
434451
break
@@ -437,6 +454,13 @@ func Parse2822(readerIn io.Reader) (*Manifest2822, error) {
437454
return nil, err
438455
}
439456

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+
440464
if !GitFetchRegex.MatchString(entry.GitFetch) {
441465
return nil, fmt.Errorf(`Tags %q has invalid GitFetch (must be "refs/heads/..." or "refs/tags/..."): %q`, entry.TagsString(), entry.GitFetch)
442466
}

0 commit comments

Comments
 (0)