Repository: appc/spec
Pull request #668 (2016-10-21 16:26:12)

schema/types: translate between appc<->go arch tuples
This commit introduces two helper functions to translate between
appc and golang os/architecture labels.

Closes https://github.com/appc/spec/issues/665


Patch:
diff --git a/schema/types/labels.go b/schema/types/labels.go
index 32d703c..89fa428 100644
--- a/schema/types/labels.go
+++ b/schema/types/labels.go
@@ -35,6 +35,17 @@ type Label struct {
 	Value string       `json:"value"`
 }
 
+// {appc,go}ArchTuple are internal helper types used to translate arch tuple between go and appc
+type appcArchTuple struct {
+	appcOs   string
+	appcArch string
+}
+type goArchTuple struct {
+	goOs         string
+	goArch       string
+	goArchFlavor string
+}
+
 // IsValidOsArch checks if a OS-architecture combination is valid given a map
 // of valid OS-architectures
 func IsValidOSArch(labels map[ACIdentifier]string, validOSArch map[string][]string) error {
@@ -132,3 +143,64 @@ func LabelsFromMap(labelsMap map[ACIdentifier]string) (Labels, error) {
 	}
 	return labels, nil
 }
+
+// ToAppcOSArch translates a Golang arch tuple (OS, architecture, flavor) into
+// an appc arch tuple (OS, architecture)
+func ToAppcOSArch(goOs string, goArch string, goArchFlavor string) (appcOs string, appcArch string, e error) {
+	tabularAppcToGo := map[goArchTuple]appcArchTuple{
+		{"linux", "amd64", ""}:   {"linux", "amd64"},
+		{"linux", "386", ""}:     {"linux", "i386"},
+		{"linux", "arm64", ""}:   {"linux", "aarch64"},
+		{"linux", "arm", ""}:     {"linux", "armv6l"},
+		{"linux", "arm", "6"}:    {"linux", "armv6l"},
+		{"linux", "arm", "7"}:    {"linux", "armv7l"},
+		{"linux", "ppc64", ""}:   {"linux", "ppc64"},
+		{"linux", "ppc64le", ""}: {"linux", "ppc64le"},
+		{"linux", "s390x", ""}:   {"linux", "s390x"},
+
+		{"freebsd", "amd64", ""}: {"freebsd", "amd64"},
+		{"freebsd", "386", ""}:   {"freebsd", "i386"},
+		{"freebsd", "arm", ""}:   {"freebsd", "arm"},
+		{"freebsd", "arm", "5"}:  {"freebsd", "arm"},
+		{"freebsd", "arm", "6"}:  {"freebsd", "arm"},
+		{"freebsd", "arm", "7"}:  {"freebsd", "arm"},
+
+		{"darwin", "amd64", ""}: {"darwin", "x86_64"},
+		{"darwin", "386", ""}:   {"darwin", "i386"},
+	}
+	archTuple, ok := tabularAppcToGo[goArchTuple{goOs, goArch, goArchFlavor}]
+	if !ok {
+		return "", "", fmt.Errorf("unknown arch tuple: %q - %q - %q", goOs, goArch, goArchFlavor)
+	}
+	return archTuple.appcOs, archTuple.appcArch, nil
+}
+
+// ToGoOSArch translates an appc arch tuple (OS, architecture) into
+// a Golang arch tuple (OS, architecture, flavor)
+func ToGoOSArch(appcOs string, appcArch string) (goOs string, goArch string, goArchFlavor string, e error) {
+	tabularGoToAppc := map[appcArchTuple]goArchTuple{
+		// {"linux", "aarch64_be"}: nil,
+		// {"linux", "armv7b"}: nil,
+		{"linux", "aarch64"}: {"linux", "arm64", ""},
+		{"linux", "amd64"}:   {"linux", "amd64", ""},
+		{"linux", "armv6l"}:  {"linux", "arm", "6"},
+		{"linux", "armv7l"}:  {"linux", "arm", "7"},
+		{"linux", "i386"}:    {"linux", "386", ""},
+		{"linux", "ppc64"}:   {"linux", "ppc64", ""},
+		{"linux", "ppc64le"}: {"linux", "ppc64le", ""},
+		{"linux", "s390x"}:   {"linux", "s390x", ""},
+
+		{"freebsd", "amd64"}: {"freebsd", "amd64", ""},
+		{"freebsd", "arm"}:   {"freebsd", "arm", "6"},
+		{"freebsd", "386"}:   {"freebsd", "i386", ""},
+
+		{"darwin", "amd64"}: {"darwin", "x86_64", ""},
+		{"darwin", "386"}:   {"darwin", "i386", ""},
+	}
+
+	archTuple, ok := tabularGoToAppc[appcArchTuple{appcOs, appcArch}]
+	if !ok {
+		return "", "", "", fmt.Errorf("unknown arch tuple: %q - %q", appcOs, appcArch)
+	}
+	return archTuple.goOs, archTuple.goArch, archTuple.goArchFlavor, nil
+}


Test patch:
diff --git a/schema/types/labels_test.go b/schema/types/labels_test.go
index 4aaa037..31da1d8 100644
--- a/schema/types/labels_test.go
+++ b/schema/types/labels_test.go
@@ -22,100 +22,172 @@ import (
 
 func TestLabels(t *testing.T) {
 	tests := []struct {
-		in        string
-		errPrefix string
+		in           string
+		goOS         string
+		goArch       string
+		goArchFlavor string
+		errPrefix    string
 	}{
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "amd64"}]`,
+			"linux",
+			"amd64",
+			"",
 			"",
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "aarch64"}]`,
+			"linux",
+			"arm64",
+			"",
 			"",
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "arm64"}]`,
+			"",
+			"",
+			"",
 			`bad arch "arm64" for linux`,
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "aarch64_be"}]`,
 			"",
+			"",
+			"",
+			"",
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "arm64_be"}]`,
+			"",
+			"",
+			"",
 			`bad arch "arm64_be" for linux`,
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "arm"}]`,
+			"",
+			"",
+			"",
 			`bad arch "arm" for linux`,
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "armv6l"}]`,
+			"linux",
+			"arm",
+			"6",
 			"",
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "armv7l"}]`,
+			"linux",
+			"arm",
+			"7",
 			"",
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "armv7b"}]`,
 			"",
+			"",
+			"",
+			"",
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "ppc64le"}]`,
+			"linux",
+			"ppc64le",
+			"",
 			"",
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "ppc64l"}]`,
+			"",
+			"",
+			"",
 			`bad arch "ppc64l" for linux`,
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "ppc64"}]`,
+			"linux",
+			"ppc64",
+			"",
 			"",
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "ppc64b"}]`,
+			"",
+			"",
+			"",
 			`bad arch "ppc64b" for linux`,
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "ppc64be"}]`,
+			"",
+			"",
+			"",
 			`bad arch "ppc64be" for linux`,
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "s390x"}]`,
-			``,
+			"linux",
+			"s390x",
+			"",
+			"",
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "S390x"}]`,
+			"",
+			"",
+			"",
 			`bad arch "S390x" for linux`,
 		},
 		{
 			`[{"name": "os", "value": "freebsd"}, {"name": "arch", "value": "amd64"}]`,
+			"freebsd",
+			"amd64",
+			"",
 			"",
 		},
 		{
 			`[{"name": "os", "value": "OS/360"}, {"name": "arch", "value": "S/360"}]`,
+			"",
+			"",
+			"",
 			`bad os "OS/360"`,
 		},
 		{
 			`[{"name": "os", "value": "freebsd"}, {"name": "arch", "value": "armv7b"}]`,
+			"",
+			"",
+			"",
 			`bad arch "armv7b" for freebsd`,
 		},
 		{
 			`[{"name": "name"}]`,
+			"",
+			"",
+			"",
 			`invalid label name: "name"`,
 		},
 		{
 			`[{"name": "os", "value": "linux"}, {"name": "os", "value": "freebsd"}]`,
+			"",
+			"",
+			"",
 			`duplicate labels of name "os"`,
 		},
 		{
 			`[{"name": "arch", "value": "amd64"}, {"name": "os", "value": "freebsd"}, {"name": "arch", "value": "x86_64"}]`,
+			"",
+			"",
+			"",
 			`duplicate labels of name "arch"`,
 		},
 		{
 			`[]`,
 			"",
+			"",
+			"",
+			"",
 		},
 	}
 	for i, tt := range tests {
@@ -131,6 +203,21 @@ func TestLabels(t *testing.T) {
 			if tt.errPrefix != "" {
 				t.Errorf("#%d: got no err, expected prefix %#v", i, tt.errPrefix)
 			}
+			jsonOs, _ := l.Get("os")
+			jsonArch, _ := l.Get("arch")
+			os, arch, flavor, _ := ToGoOSArch(jsonOs, jsonArch)
+			if os != tt.goOS {
+				t.Errorf("#%d: got os %q, expected os %q", i, os, tt.goOS)
+
+			}
+			if arch != tt.goArch {
+				t.Errorf("#%d: got arch %q, expected arch %q", i, arch, tt.goArch)
+
+			}
+			if flavor != tt.goArchFlavor {
+				t.Errorf("#%d: got flavor %q, expected flavor %q", i, flavor, tt.goArchFlavor)
+
+			}
 		}
 	}
 }