Skip to content
This repository has been archived by the owner on Aug 22, 2020. It is now read-only.

Add new "Architectures" field #10

Merged
merged 3 commits into from
Jun 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 31 additions & 9 deletions manifest/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ func Example() {

Maintainers: InfoSiftr <[email protected]> (@infosiftr),
Johan Euphrosine <[email protected]> (@proppy)
GitRepo: https://github.com/docker-library/golang.git
GitFetch: refs/heads/master
GitRepo: https://github.com/docker-library/golang.git
SharedTags: latest
arm64v8-GitRepo: https://github.com/docker-library/golang.git


# hi
Expand All @@ -28,22 +29,34 @@ SharedTags: latest

# Go 1.6
Tags: 1.6.1, 1.6, 1
GitCommit: 0ce80411b9f41e9c3a21fc0a1bffba6ae761825a
arm64v8-GitRepo: https://github.com/docker-library/golang.git
Directory: 1.6
GitCommit: 0ce80411b9f41e9c3a21fc0a1bffba6ae761825a
Constraints: some-random-build-server


# Go 1.5
Tags: 1.5.3
SharedTags: 1.5.3-debian, 1.5-debian
GitCommit: d7e2a8d90a9b8f5dfd5bcd428e0c33b68c40cc19
SharedTags: 1.5.3-debian, 1.5-debian
Directory: 1.5
s390x-GitCommit: b6c460e7cd79b595267870a98013ec3078b490df
i386-GitFetch: refs/heads/i386
ppc64le-Directory: 1.5/ppc64le


Tags: 1.5
SharedTags: 1.5-debian
GitCommit: d7e2a8d90a9b8f5dfd5bcd428e0c33b68c40cc19
Directory: 1.5
s390x-GitCommit: b6c460e7cd79b595267870a98013ec3078b490df
i386-GitFetch: refs/heads/i386
ppc64le-Directory: 1.5/ppc64le

SharedTags: raspbian
GitCommit: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef
Tags: raspbian-s390x
Architectures: s390x


`)))
Expand Down Expand Up @@ -84,26 +97,37 @@ i: g@h j
// Maintainers: InfoSiftr <[email protected]> (@infosiftr), Johan Euphrosine <[email protected]> (@proppy)
// SharedTags: latest
// GitRepo: https://github.com/docker-library/golang.git
// arm64v8-GitRepo: https://github.com/docker-library/golang.git
//
// Tags: 1.6.1, 1.6, 1
// GitCommit: 0ce80411b9f41e9c3a21fc0a1bffba6ae761825a
// Directory: 1.6
// Constraints: some-random-build-server
//
// Tags: 1.5.3, 1.5
// SharedTags: latest, 1.5.3-debian, 1.5-debian
// SharedTags: 1.5.3-debian, 1.5-debian
// GitCommit: d7e2a8d90a9b8f5dfd5bcd428e0c33b68c40cc19
// Directory: 1.5
// i386-GitFetch: refs/heads/i386
// ppc64le-Directory: 1.5/ppc64le
// s390x-GitCommit: b6c460e7cd79b595267870a98013ec3078b490df
//
// Tags: raspbian-s390x
// SharedTags: raspbian
// Architectures: s390x
// GitCommit: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef
//
// Shared Tag Groups:
//
// - latest
// - 1.6.1, 1.6, 1
// - 1.5.3, 1.5
//
// - 1.5.3-debian, 1.5-debian
// - 1.5.3, 1.5
//
// - raspbian
// - raspbian-s390x
//
// -------------
// line-based:
// Maintainers: InfoSiftr <[email protected]> (@infosiftr), John Smith <[email protected]> (@example-jsmith)
Expand Down Expand Up @@ -134,15 +158,14 @@ func ExampleFetch_local() {

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

fmt.Println(man.GetTag(tagName))
fmt.Println(man.GetTag(tagName).ClearDefaults(manifest.DefaultManifestEntry).String())

// Output:
// bash:4.4
//
// Maintainers: Tianon Gravi <[email protected]> (@tianon)
// Tags: 4.4.12, 4.4, 4, latest
// GitRepo: https://github.com/tianon/docker-bash.git
// GitFetch: refs/heads/master
// GitCommit: 1cbb5cf49b4c53bd5a986abf7a1afeb9a80eac1e
// Directory: 4.4
}
Expand All @@ -155,15 +178,14 @@ func ExampleFetch_remote() {

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

fmt.Println(man.GetTag(tagName))
fmt.Println(man.GetTag(tagName).ClearDefaults(manifest.DefaultManifestEntry).String())

// Output:
// bash:4.4
//
// Maintainers: Tianon Gravi <[email protected]> (@tianon)
// Tags: 4.4.12, 4.4, 4, latest
// GitRepo: https://github.com/tianon/docker-bash.git
// GitFetch: refs/heads/master
// GitCommit: 1cbb5cf49b4c53bd5a986abf7a1afeb9a80eac1e
// Directory: 4.4
}
91 changes: 90 additions & 1 deletion manifest/rfc2822.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io"
"regexp"
"sort"
"strings"

"github.com/docker-library/go-dockerlibrary/pkg/stripper"
Expand All @@ -30,15 +31,20 @@ type Manifest2822Entry struct {
Tags []string `delim:"," strip:"\n\r\t "`
SharedTags []string `delim:"," strip:"\n\r\t "`

Architectures []string `delim:"," strip:"\n\r\t "`

GitRepo string
GitFetch string
GitCommit string
Directory string
// architecture-specific versions of the above fields are in Paragraph.Values as ARCH-Field, ala s390x-Directory

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

var DefaultManifestEntry = Manifest2822Entry{
Architectures: []string{"amd64"},

GitFetch: "refs/heads/master",
Directory: ".",
}
Expand All @@ -48,6 +54,7 @@ func (entry Manifest2822Entry) Clone() Manifest2822Entry {
entry.Maintainers = append([]string{}, entry.Maintainers...)
entry.Tags = append([]string{}, entry.Tags...)
entry.SharedTags = append([]string{}, entry.SharedTags...)
entry.Architectures = append([]string{}, entry.Architectures...)
entry.Constraints = append([]string{}, entry.Constraints...)
return entry
}
Expand All @@ -66,17 +73,44 @@ func (entry Manifest2822Entry) SharedTagsString() string {
return strings.Join(entry.SharedTags, StringSeparator2822)
}

func (entry Manifest2822Entry) ArchitecturesString() string {
return strings.Join(entry.Architectures, StringSeparator2822)
}

func (entry Manifest2822Entry) ConstraintsString() string {
return strings.Join(entry.Constraints, StringSeparator2822)
}

// if this method returns "true", then a.Tags and b.Tags can safely be combined (for the purposes of building)
func (a Manifest2822Entry) SameBuildArtifacts(b Manifest2822Entry) bool {
return a.GitRepo == b.GitRepo && a.GitFetch == b.GitFetch && a.GitCommit == b.GitCommit && a.Directory == b.Directory && a.ConstraintsString() == b.ConstraintsString()
// check xxxarch-GitRepo, etc. fields for sameness first
for _, key := range append(a.archFields(), b.archFields()...) {
if a.Paragraph.Values[key] != b.Paragraph.Values[key] {
return false
}
}

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

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

// returns a list of architecture-specific fields in an Entry
func (entry Manifest2822Entry) archFields() []string {
ret := []string{}
for key, val := range entry.Paragraph.Values {
if isArchField(key) && val != "" {
ret = append(ret, key)
}
}
return ret
}

// returns a new Entry with any of the values that are equal to the values in "defaults" cleared
func (entry Manifest2822Entry) ClearDefaults(defaults Manifest2822Entry) Manifest2822Entry {
entry = entry.Clone() // make absolutely certain we have a deep clone
if entry.MaintainersString() == defaults.MaintainersString() {
entry.Maintainers = nil
}
Expand All @@ -86,6 +120,9 @@ func (entry Manifest2822Entry) ClearDefaults(defaults Manifest2822Entry) Manifes
if entry.SharedTagsString() == defaults.SharedTagsString() {
entry.SharedTags = nil
}
if entry.ArchitecturesString() == defaults.ArchitecturesString() {
entry.Architectures = nil
}
if entry.GitRepo == defaults.GitRepo {
entry.GitRepo = ""
}
Expand All @@ -98,6 +135,11 @@ func (entry Manifest2822Entry) ClearDefaults(defaults Manifest2822Entry) Manifes
if entry.Directory == defaults.Directory {
entry.Directory = ""
}
for _, key := range defaults.archFields() {
if defaults.Paragraph.Values[key] == entry.Paragraph.Values[key] {
delete(entry.Paragraph.Values, key)
}
}
if entry.ConstraintsString() == defaults.ConstraintsString() {
entry.Constraints = nil
}
Expand All @@ -115,6 +157,9 @@ func (entry Manifest2822Entry) String() string {
if str := entry.SharedTagsString(); str != "" {
ret = append(ret, "SharedTags: "+str)
}
if str := entry.ArchitecturesString(); str != "" {
ret = append(ret, "Architectures: "+str)
}
if str := entry.GitRepo; str != "" {
ret = append(ret, "GitRepo: "+str)
}
Expand All @@ -127,6 +172,11 @@ func (entry Manifest2822Entry) String() string {
if str := entry.Directory; str != "" {
ret = append(ret, "Directory: "+str)
}
archFields := entry.archFields()
sort.Strings(archFields) // consistent ordering
for _, key := range archFields {
ret = append(ret, key+": "+entry.Paragraph.Values[key])
}
if str := entry.ConstraintsString(); str != "" {
ret = append(ret, "Constraints: "+str)
}
Expand All @@ -148,6 +198,34 @@ func (manifest Manifest2822) String() string {
return strings.Join(ret, "\n\n")
}

func (entry Manifest2822Entry) ArchGitRepo(arch string) string {
if val, ok := entry.Paragraph.Values[arch+"-GitRepo"]; ok && val != "" {
return val
}
return entry.GitRepo
}

func (entry Manifest2822Entry) ArchGitFetch(arch string) string {
if val, ok := entry.Paragraph.Values[arch+"-GitFetch"]; ok && val != "" {
return val
}
return entry.GitFetch
}

func (entry Manifest2822Entry) ArchGitCommit(arch string) string {
if val, ok := entry.Paragraph.Values[arch+"-GitCommit"]; ok && val != "" {
return val
}
return entry.GitCommit
}

func (entry Manifest2822Entry) ArchDirectory(arch string) string {
if val, ok := entry.Paragraph.Values[arch+"-Directory"]; ok && val != "" {
return val
}
return entry.Directory
}

func (entry Manifest2822Entry) HasTag(tag string) bool {
for _, existingTag := range entry.Tags {
if tag == existingTag {
Expand Down Expand Up @@ -364,6 +442,10 @@ func Parse2822(readerIn io.Reader) (*Manifest2822, error) {
for {
entry := manifest.Global.Clone()

// reset Architectures and SharedTags so that they can be either inherited or replaced, not additive
entry.SharedTags = nil
entry.Architectures = nil

err := decoder.Decode(&entry)
if err == io.EOF {
break
Expand All @@ -372,6 +454,13 @@ func Parse2822(readerIn io.Reader) (*Manifest2822, error) {
return nil, err
}

if len(entry.SharedTags) == 0 {
entry.SharedTags = manifest.Global.SharedTags
}
if len(entry.Architectures) == 0 {
entry.Architectures = manifest.Global.Architectures
}

if !GitFetchRegex.MatchString(entry.GitFetch) {
return nil, fmt.Errorf(`Tags %q has invalid GitFetch (must be "refs/heads/..." or "refs/tags/..."): %q`, entry.TagsString(), entry.GitFetch)
}
Expand Down