From 506c4a330d584ae26d3f62011e444855c600688c Mon Sep 17 00:00:00 2001 From: Richard Marshall Date: Mon, 10 Dec 2018 12:41:58 -0800 Subject: [PATCH 001/317] Add projected secret path to transformer config Projected volumes can include values sourced from secrets that might be managed by kustomize. To support this use case this patch updates the name reference transformer configuration to include a field spec for projected secrets. --- .../config/defaultconfig/namereference.go | 4 ++++ pkg/transformers/namereference_test.go | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/pkg/transformers/config/defaultconfig/namereference.go b/pkg/transformers/config/defaultconfig/namereference.go index 2f31a36b4..0b188f867 100644 --- a/pkg/transformers/config/defaultconfig/namereference.go +++ b/pkg/transformers/config/defaultconfig/namereference.go @@ -150,6 +150,8 @@ nameReference: kind: Deployment - path: spec/template/spec/imagePullSecrets/name kind: Deployment + - path: spec/template/spec/volumes/projected/sources/secret/name + kind: Deployment - path: spec/template/spec/volumes/secret/secretName kind: ReplicaSet - path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name @@ -186,6 +188,8 @@ nameReference: kind: StatefulSet - path: spec/template/spec/imagePullSecrets/name kind: StatefulSet + - path: spec/template/spec/volumes/projected/sources/secret/name + kind: StatefulSet - path: spec/template/spec/volumes/secret/secretName kind: Job - path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name diff --git a/pkg/transformers/namereference_test.go b/pkg/transformers/namereference_test.go index b01bde234..6a94588ca 100644 --- a/pkg/transformers/namereference_test.go +++ b/pkg/transformers/namereference_test.go @@ -148,6 +148,9 @@ func TestNameReferenceHappyRun(t *testing.T) { "configMap": map[string]interface{}{ "name": "cm2", }, + "secret": map[string]interface{}{ + "name": "secret1", + }, }, }, "secret": map[string]interface{}{ @@ -184,6 +187,9 @@ func TestNameReferenceHappyRun(t *testing.T) { "configMap": map[string]interface{}{ "name": "cm2", }, + "secret": map[string]interface{}{ + "name": "secret1", + }, }, }, }, @@ -307,6 +313,9 @@ func TestNameReferenceHappyRun(t *testing.T) { "configMap": map[string]interface{}{ "name": "someprefix-cm2-somehash", }, + "secret": map[string]interface{}{ + "name": "someprefix-secret1-somehash", + }, }, }, "secret": map[string]interface{}{ @@ -343,6 +352,9 @@ func TestNameReferenceHappyRun(t *testing.T) { "configMap": map[string]interface{}{ "name": "someprefix-cm2-somehash", }, + "secret": map[string]interface{}{ + "name": "someprefix-secret1-somehash", + }, }, }, }, From 259cecd4b830bc674941ca5e1eef02ea4eb36149 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Mon, 10 Dec 2018 10:50:31 -0800 Subject: [PATCH 002/317] add handling function for remote url hostname --- pkg/loader/gitcloner.go | 91 ++++++++++++++++++---- pkg/loader/gitcloner_test.go | 141 ++++++++++++++++++++++++++++++++--- 2 files changed, 209 insertions(+), 23 deletions(-) diff --git a/pkg/loader/gitcloner.go b/pkg/loader/gitcloner.go index 6171aedb1..98a732a8f 100644 --- a/pkg/loader/gitcloner.go +++ b/pkg/loader/gitcloner.go @@ -21,6 +21,7 @@ import ( "io/ioutil" "os/exec" "path/filepath" + "regexp" "strings" "github.com/pkg/errors" @@ -44,7 +45,8 @@ func isRepoUrl(arg string) bool { strings.HasPrefix(arg, "gh:") || strings.HasPrefix(arg, "github.com") || strings.HasPrefix(arg, "git@github.com:") || - strings.Index(arg, "github.com/") > -1) + strings.Index(arg, "github.com/") > -1 || + isAzureHost(arg) || isAWSHost(arg)) } func makeTmpDir() (string, error) { @@ -61,14 +63,14 @@ func simpleGitCloner(spec string) ( if err != nil { return } - repo, pathInCoDir, gitRef, err := parseGithubUrl(spec) + repo, pathInCoDir, gitRef, err := parseUrl(spec) if err != nil { return } cmd := exec.Command( gitProgram, "clone", - "https://github.com/"+repo+".git", + repo, checkoutDir) var out bytes.Buffer cmd.Stdout = &out @@ -90,27 +92,36 @@ func simpleGitCloner(spec string) ( return checkoutDir, pathInCoDir, nil } +func parseUrl(n string) ( + repo string, path string, gitRef string, err error) { + host, repo, path, gitRef, err := parseGithubUrl(n) + if err != nil { + return + } + if isAzureHost(host) || isAWSHost(host) { + repo = host + repo + return + } + repo = host + repo + ".git" + return +} + const refQuery = "?ref=" // From strings like git@github.com:someOrg/someRepo.git or // https://github.com/someOrg/someRepo?ref=someHash, extract // the parts. func parseGithubUrl(n string) ( - repo string, path string, gitRef string, err error) { - for _, p := range []string{ - // Order matters here. - "git::", "gh:", "https://", "http://", - "git@", "github.com:", "github.com/", "gitlab.com/"} { - if strings.ToLower(n[:len(p)]) == p { - n = n[len(p):] - } - } + host string, repo string, path string, gitRef string, err error) { + host, n = parseHostSpec(n) + host = normalizeGitHostSpec(host) + if strings.HasSuffix(n, ".git") { n = n[0 : len(n)-len(".git")] } i := strings.Index(n, string(filepath.Separator)) if i < 1 { - return "", "", "", errors.New("no separator") + return "", "", "", "", errors.New("no separator") } j := strings.Index(n[i+1:], string(filepath.Separator)) if j >= 0 { @@ -131,3 +142,57 @@ func peelQuery(arg string) (string, string) { } return arg, "" } + +func parseHostSpec(n string) (string, string) { + var host string + for _, p := range []string{ + // Order matters here. + "git::", "gh:", "ssh://", "https://", "http://", + "git@", "github.com:", "github.com/", "gitlab.com/"} { + if strings.ToLower(n[:len(p)]) == p { + n = n[len(p):] + host = host + p + } + } + for _, p := range []string{ + "git-codecommit.[a-z0-9-]*.amazonaws.com/", + "dev.azure.com/", + ".*visualstudio.com/"} { + index := regexp.MustCompile(p).FindStringIndex(n) + if len(index) > 0 { + host = host + n[0:index[len(index)-1]] + n = n[index[len(index)-1]:] + } + } + return host, n +} + +func normalizeGitHostSpec(host string) string { + s := strings.ToLower(host) + if strings.Contains(s, "github.com") { + if strings.Contains(s, "git@") || strings.Contains(s, "ssh:") { + host = "git@github.com:" + } else { + host = "https://github.com/" + } + } + if strings.Contains(s, "gitlab") { + if strings.HasPrefix(s, "git::") { + host = strings.TrimLeft(s, "git::") + } + } + return host +} + +// The format of Azure repo URL is documented +// https://docs.microsoft.com/en-us/azure/devops/repos/git/clone?view=vsts&tabs=visual-studio#clone_url +func isAzureHost(host string) bool { + return strings.Contains(host, "dev.azure.com") || + strings.Contains(host, "visualstudio.com") +} + +// The format of AWS repo URL is documented +// https://docs.aws.amazon.com/codecommit/latest/userguide/regions.html +func isAWSHost(host string) bool { + return strings.Contains(host, "amazonaws.com") +} diff --git a/pkg/loader/gitcloner_test.go b/pkg/loader/gitcloner_test.go index 984c25682..732d074ee 100644 --- a/pkg/loader/gitcloner_test.go +++ b/pkg/loader/gitcloner_test.go @@ -185,20 +185,20 @@ var paths = []string{"README.md", "foo/krusty.txt", ""} var hrefArgs = []string{"someBranch", ""} -var extractFmts = []string{ - "gh:%s", - "GH:%s", - "gitHub.com/%s", - "https://github.com/%s", - "hTTps://github.com/%s", - "git::https://gitlab.com/%s", - "github.com:%s", +var extractFmts = map[string]string{ + "gh:%s": "gh:", + "GH:%s": "gh:", + "gitHub.com/%s": "https://github.com/", + "https://github.com/%s": "https://github.com/", + "hTTps://github.com/%s": "https://github.com/", + "git::https://gitlab.com/%s": "https://gitlab.com/", + "github.com:%s": "https://github.com/", } func TestParseGithubUrl(t *testing.T) { for _, repoName := range repoNames { for _, pathName := range paths { - for _, extractFmt := range extractFmts { + for extractFmt, hostSpec := range extractFmts { for _, hrefArg := range hrefArgs { spec := repoName if len(pathName) > 0 { @@ -212,10 +212,16 @@ func TestParseGithubUrl(t *testing.T) { t.Errorf("Should smell like github arg: %s\n", input) continue } - repo, path, gitRef, err := parseGithubUrl(input) + host, repo, path, gitRef, err := parseGithubUrl(input) if err != nil { t.Errorf("problem %v", err) } + if host != hostSpec { + t.Errorf("\n"+ + " from %s\n"+ + " actual host %s\n"+ + "expected host %s\n", input, host, hostSpec) + } if repo != repoName { t.Errorf("\n"+ " from %s\n"+ @@ -239,3 +245,118 @@ func TestParseGithubUrl(t *testing.T) { } } } + +func TestParseUrl(t *testing.T) { + testcases := []struct { + input string + repo string + path string + ref string + }{ + { + input: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo/somedir", + repo: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo", + path: "somedir", + ref: "", + }, + { + input: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo/somedir?ref=testbranch", + repo: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo", + path: "somedir", + ref: "testbranch", + }, + { + input: "https://fabrikops2.visualstudio.com/someorg/somerepo?ref=master", + repo: "https://fabrikops2.visualstudio.com/someorg/somerepo", + path: "", + ref: "master", + }, + { + input: "http://github.com/someorg/somerepo/somedir", + repo: "https://github.com/someorg/somerepo.git", + path: "somedir", + ref: "", + }, + { + input: "git@github.com:someorg/somerepo/somedir", + repo: "git@github.com:someorg/somerepo.git", + path: "somedir", + ref: "", + }, + } + for _, testcase := range testcases { + repo, path, ref, err := parseUrl(testcase.input) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + if repo != testcase.repo { + t.Errorf("repo expected to be %v, but got %v on %s", testcase.repo, repo, testcase.input) + } + if path != testcase.path { + t.Errorf("path expected to be %v, but got %v on %s", testcase.path, path, testcase.input) + } + if ref != testcase.ref { + t.Errorf("ref expected to be %v, but got %v on %s", testcase.ref, ref, testcase.input) + } + } +} + +func TestIsAzureHost(t *testing.T) { + testcases := []struct { + input string + expect bool + }{ + { + input: "https://git-codecommit.us-east-2.amazonaws.com", + expect: false, + }, + { + input: "ssh://git-codecommit.us-east-2.amazonaws.com", + expect: false, + }, + { + input: "https://fabrikops2.visualstudio.com/", + expect: true, + }, + { + input: "https://dev.azure.com/myorg/myproject/", + expect: true, + }, + } + for _, testcase := range testcases { + actual := isAzureHost(testcase.input) + if actual != testcase.expect { + t.Errorf("IsAzureHost: expected %v, but got %v on %s", testcase.expect, actual, testcase.input) + } + } +} + +func TestIsAWSHost(t *testing.T) { + testcases := []struct { + input string + expect bool + }{ + { + input: "https://git-codecommit.us-east-2.amazonaws.com", + expect: true, + }, + { + input: "ssh://git-codecommit.us-east-2.amazonaws.com", + expect: true, + }, + { + input: "git@github.com:", + expect: false, + }, + { + input: "http://github.com/", + expect: false, + }, + } + for _, testcase := range testcases { + actual := isAWSHost(testcase.input) + if actual != testcase.expect { + t.Errorf("IsAWSHost: expected %v, but got %v on %s", testcase.expect, actual, testcase.input) + } + } +} From 0759136d3f70700650c34bb240a6231a8d0f6fe1 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Wed, 12 Dec 2018 15:23:17 -0800 Subject: [PATCH 003/317] Add enforcement message for apiVersion and kind --- pkg/target/kusttarget.go | 7 +++++++ pkg/types/kustomization.go | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 6219581ca..6c2caf552 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -66,6 +66,13 @@ func NewKustTarget( return nil, err } k.DealWithDeprecatedFields() + msgs, errs := k.EnforceFields() + if len(errs) > 0 { + return nil, fmt.Errorf(strings.Join(errs, "\n")) + } + if len(msgs) > 0 { + log.Printf(strings.Join(msgs, "\n")) + } tConfig, err := makeTransformerConfig(ldr, k.Configurations) if err != nil { return nil, err diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index e1badbc6d..fd3a3acc5 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -21,6 +21,11 @@ import ( "sigs.k8s.io/kustomize/pkg/patch" ) +const ( + KustomizationVersion = "v1" + KustomizationKind = "Kustomization" +) + // TypeMeta copies apimachinery/pkg/apis/meta/v1.TypeMeta type TypeMeta struct { // Kind copies apimachinery/pkg/apis/meta/v1.Typemeta.Kind @@ -146,6 +151,21 @@ func (k *Kustomization) DealWithDeprecatedFields() { } } +func (k *Kustomization) EnforceFields() ([]string, []string) { + var msgs, errs []string + if k.APIVersion == "" { + msgs = append(msgs, "apiVersion is not defined. This will not be allowed in the next release.\nPlease add apiVersion: "+KustomizationVersion) + } else if k.APIVersion != KustomizationVersion { + errs = append(errs, "apiVersion should be "+KustomizationVersion) + } + if k.Kind == "" { + msgs = append(msgs, "kind is not defined. This will not be allowed in the next release.\nPlease add kind: "+KustomizationKind) + } else if k.Kind != KustomizationKind { + errs = append(errs, "kind should be "+KustomizationKind) + } + return msgs, errs +} + // GeneratorArgs contains arguments common to generators. type GeneratorArgs struct { // Namespace for the configmap, optional From 3b9cd6bedd5bad91a910622c9d31a0a2386f74ff Mon Sep 17 00:00:00 2001 From: Andy Repton Date: Thu, 13 Dec 2018 18:26:53 +0100 Subject: [PATCH 004/317] Tiny but noticeable typo fix --- docs/kustomization.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index 9ada50dc2..74cd29794 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -96,7 +96,7 @@ secretGenerator: type: "kubernetes.io/tls" - name: app-tls-namespaced # you can define a namespace to generate secret in, defaults to: "default" - namspace: apps + namespace: apps commands: tls.crt: "cat secret/tls.cert" tls.key: "cat secret/tls.key" From d40f52e9537f7d9613b665e674ea8f3c2fc3fcb6 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Thu, 13 Dec 2018 11:12:51 -0800 Subject: [PATCH 005/317] Reduce size of missing field markers. --- .../expected.yaml | 24 +++++++------- .../testcase-multibases-conflict/test.yaml | 2 +- pkg/gvk/gvk.go | 6 ++-- pkg/gvk/gvk_test.go | 14 ++++---- pkg/resid/resid.go | 8 ++--- pkg/resid/resid_test.go | 32 +++++++++---------- 6 files changed, 43 insertions(+), 43 deletions(-) diff --git a/pkg/commands/build/testdata/testcase-generators-namespace/expected.yaml b/pkg/commands/build/testdata/testcase-generators-namespace/expected.yaml index 803b2a325..1d265fe43 100644 --- a/pkg/commands/build/testdata/testcase-generators-namespace/expected.yaml +++ b/pkg/commands/build/testdata/testcase-generators-namespace/expected.yaml @@ -1,12 +1,4 @@ apiVersion: v1 -data: - altGreeting: Good Morning from default namespace! - enableRisky: "false" -kind: ConfigMap -metadata: - name: the-map-4959m5tm6c ---- -apiVersion: v1 data: altGreeting: Good Morning from non-default namespace! enableRisky: "false" @@ -17,11 +9,11 @@ metadata: --- apiVersion: v1 data: - password.txt: dmVyeSRlY3JldA== -kind: Secret + altGreeting: Good Morning from default namespace! + enableRisky: "false" +kind: ConfigMap metadata: - name: the-secret-cfbmct72tb -type: Opaque + name: the-map-4959m5tm6c --- apiVersion: v1 data: @@ -31,3 +23,11 @@ metadata: name: the-non-default-namespace-secret-255294gd9d namespace: non-default type: Opaque +--- +apiVersion: v1 +data: + password.txt: dmVyeSRlY3JldA== +kind: Secret +metadata: + name: the-secret-cfbmct72tb +type: Opaque diff --git a/pkg/commands/build/testdata/testcase-multibases-conflict/test.yaml b/pkg/commands/build/testdata/testcase-multibases-conflict/test.yaml index bda51d606..334c5f957 100644 --- a/pkg/commands/build/testdata/testcase-multibases-conflict/test.yaml +++ b/pkg/commands/build/testdata/testcase-multibases-conflict/test.yaml @@ -1,4 +1,4 @@ description: multibases with name reference args: [] filename: testdata/testcase-multibases-conflict/combined -expectedError: Multiple matches for name noGroup_v1_ServiceAccount +expectedError: Multiple matches for name ~G_v1_ServiceAccount diff --git a/pkg/gvk/gvk.go b/pkg/gvk/gvk.go index 6ab227995..382f284d1 100644 --- a/pkg/gvk/gvk.go +++ b/pkg/gvk/gvk.go @@ -36,9 +36,9 @@ func FromKind(k string) Gvk { } const ( - noGroup = "noGroup" - noVersion = "noVersion" - noKind = "noKind" + noGroup = "~G" + noVersion = "~V" + noKind = "~K" separator = "_" ) diff --git a/pkg/gvk/gvk_test.go b/pkg/gvk/gvk_test.go index 6e235ed3e..3d2b50c35 100644 --- a/pkg/gvk/gvk_test.go +++ b/pkg/gvk/gvk_test.go @@ -75,13 +75,13 @@ var stringTests = []struct { x Gvk s string }{ - {Gvk{}, "noGroup_noVersion_noKind"}, - {Gvk{Kind: "k"}, "noGroup_noVersion_k"}, - {Gvk{Version: "v"}, "noGroup_v_noKind"}, - {Gvk{Version: "v", Kind: "k"}, "noGroup_v_k"}, - {Gvk{Group: "g"}, "g_noVersion_noKind"}, - {Gvk{Group: "g", Kind: "k"}, "g_noVersion_k"}, - {Gvk{Group: "g", Version: "v"}, "g_v_noKind"}, + {Gvk{}, "~G_~V_~K"}, + {Gvk{Kind: "k"}, "~G_~V_k"}, + {Gvk{Version: "v"}, "~G_v_~K"}, + {Gvk{Version: "v", Kind: "k"}, "~G_v_k"}, + {Gvk{Group: "g"}, "g_~V_~K"}, + {Gvk{Group: "g", Kind: "k"}, "g_~V_k"}, + {Gvk{Group: "g", Version: "v"}, "g_v_~K"}, {Gvk{Group: "g", Version: "v", Kind: "k"}, "g_v_k"}, } diff --git a/pkg/resid/resid.go b/pkg/resid/resid.go index e76f9b887..390fc2514 100644 --- a/pkg/resid/resid.go +++ b/pkg/resid/resid.go @@ -74,10 +74,10 @@ func NewResIdKindOnly(k string, n string) ResId { } const ( - noNamespace = "noNamespace" - noPrefix = "noPrefix" - noName = "noName" - noSuffix = "noSuffix" + noNamespace = "~X" + noPrefix = "~P" + noName = "~N" + noSuffix = "~S" separator = "|" ) diff --git a/pkg/resid/resid_test.go b/pkg/resid/resid_test.go index 53fb431d4..165860b6c 100644 --- a/pkg/resid/resid_test.go +++ b/pkg/resid/resid_test.go @@ -15,26 +15,26 @@ var stringTests = []struct { "g_v_k|ns|p|nm|s"}, {ResId{gvKind: gvk.Gvk{Version: "v", Kind: "k"}, name: "nm", prefix: "p", suffix: "s", namespace: "ns"}, - "noGroup_v_k|ns|p|nm|s"}, + "~G_v_k|ns|p|nm|s"}, {ResId{gvKind: gvk.Gvk{Kind: "k"}, name: "nm", prefix: "p", suffix: "s", namespace: "ns"}, - "noGroup_noVersion_k|ns|p|nm|s"}, + "~G_~V_k|ns|p|nm|s"}, {ResId{gvKind: gvk.Gvk{}, name: "nm", prefix: "p", suffix: "s", namespace: "ns"}, - "noGroup_noVersion_noKind|ns|p|nm|s"}, + "~G_~V_~K|ns|p|nm|s"}, {ResId{gvKind: gvk.Gvk{}, name: "nm", prefix: "p", suffix: "s"}, - "noGroup_noVersion_noKind|noNamespace|p|nm|s"}, + "~G_~V_~K|~X|p|nm|s"}, {ResId{gvKind: gvk.Gvk{}, name: "nm", suffix: "s"}, - "noGroup_noVersion_noKind|noNamespace|noPrefix|nm|s"}, + "~G_~V_~K|~X|~P|nm|s"}, {ResId{gvKind: gvk.Gvk{}, suffix: "s"}, - "noGroup_noVersion_noKind|noNamespace|noPrefix|noName|s"}, + "~G_~V_~K|~X|~P|~N|s"}, {ResId{gvKind: gvk.Gvk{}}, - "noGroup_noVersion_noKind|noNamespace|noPrefix|noName|noSuffix"}, + "~G_~V_~K|~X|~P|~N|~S"}, {ResId{}, - "noGroup_noVersion_noKind|noNamespace|noPrefix|noName|noSuffix"}, + "~G_~V_~K|~X|~P|~N|~S"}, } func TestString(t *testing.T) { @@ -54,26 +54,26 @@ var gvknStringTests = []struct { "g_v_k|nm"}, {ResId{gvKind: gvk.Gvk{Version: "v", Kind: "k"}, name: "nm", prefix: "p", suffix: "s", namespace: "ns"}, - "noGroup_v_k|nm"}, + "~G_v_k|nm"}, {ResId{gvKind: gvk.Gvk{Kind: "k"}, name: "nm", prefix: "p", suffix: "s", namespace: "ns"}, - "noGroup_noVersion_k|nm"}, + "~G_~V_k|nm"}, {ResId{gvKind: gvk.Gvk{}, name: "nm", prefix: "p", suffix: "s", namespace: "ns"}, - "noGroup_noVersion_noKind|nm"}, + "~G_~V_~K|nm"}, {ResId{gvKind: gvk.Gvk{}, name: "nm", prefix: "p", suffix: "s"}, - "noGroup_noVersion_noKind|nm"}, + "~G_~V_~K|nm"}, {ResId{gvKind: gvk.Gvk{}, name: "nm", suffix: "s"}, - "noGroup_noVersion_noKind|nm"}, + "~G_~V_~K|nm"}, {ResId{gvKind: gvk.Gvk{}, suffix: "s"}, - "noGroup_noVersion_noKind|"}, + "~G_~V_~K|"}, {ResId{gvKind: gvk.Gvk{}}, - "noGroup_noVersion_noKind|"}, + "~G_~V_~K|"}, {ResId{}, - "noGroup_noVersion_noKind|"}, + "~G_~V_~K|"}, } func TestGvknString(t *testing.T) { From 986c85e728cd66f2991ba734f4fd9aa1c88052e3 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Thu, 13 Dec 2018 11:38:29 -0800 Subject: [PATCH 006/317] Add subcommand: edit fix --- pkg/commands/edit/all.go | 2 + pkg/commands/edit/fix/fix.go | 62 +++++++++++++++++++++++++++++++ pkg/commands/edit/fix/fix_test.go | 45 ++++++++++++++++++++++ pkg/fs/fakefs.go | 4 +- pkg/types/kustomization.go | 18 ++++++++- 5 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 pkg/commands/edit/fix/fix.go create mode 100644 pkg/commands/edit/fix/fix_test.go diff --git a/pkg/commands/edit/all.go b/pkg/commands/edit/all.go index fd27e38de..7f94e35ed 100644 --- a/pkg/commands/edit/all.go +++ b/pkg/commands/edit/all.go @@ -19,6 +19,7 @@ package edit import ( "github.com/spf13/cobra" "sigs.k8s.io/kustomize/pkg/commands/edit/add" + "sigs.k8s.io/kustomize/pkg/commands/edit/fix" "sigs.k8s.io/kustomize/pkg/commands/edit/set" "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/ifc" @@ -45,6 +46,7 @@ func NewCmdEdit(fsys fs.FileSystem, v ifc.Validator, kf ifc.KunstructuredFactory c.AddCommand( add.NewCmdAdd(fsys, v, kf), set.NewCmdSet(fsys, v), + fix.NewCmdFix(fsys), ) return c } diff --git a/pkg/commands/edit/fix/fix.go b/pkg/commands/edit/fix/fix.go new file mode 100644 index 000000000..fe3241249 --- /dev/null +++ b/pkg/commands/edit/fix/fix.go @@ -0,0 +1,62 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fix + +import ( + "log" + "strings" + + "github.com/spf13/cobra" + "sigs.k8s.io/kustomize/pkg/commands/kustfile" + "sigs.k8s.io/kustomize/pkg/fs" +) + +// NewCmdFix returns an instance of 'fix' subcommand. +func NewCmdFix(fSys fs.FileSystem) *cobra.Command { + cmd := &cobra.Command{ + Use: "fix", + Short: "Fix the missing fields in kustomization file", + Long: "", + Example: ` + # Fix the missing and deprecated fields in kustomization file + kustomize fix + +`, + RunE: func(cmd *cobra.Command, args []string) error { + return RunFix(fSys) + }, + } + return cmd +} + +func RunFix(fSys fs.FileSystem) error { + mf, err := kustfile.NewKustomizationFile(fSys) + if err != nil { + return err + } + + m, err := mf.Read() + if err != nil { + return err + } + msgs := m.DealWithMissingFields() + if len(msgs) > 0 { + log.Printf(strings.Join(msgs, "\n")) + } + + return mf.Write(m) +} diff --git a/pkg/commands/edit/fix/fix_test.go b/pkg/commands/edit/fix/fix_test.go new file mode 100644 index 000000000..e34f34fc6 --- /dev/null +++ b/pkg/commands/edit/fix/fix_test.go @@ -0,0 +1,45 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fix + +import ( + "strings" + "testing" + + "sigs.k8s.io/kustomize/pkg/fs" +) + +func TestFix(t *testing.T) { + fakeFS := fs.MakeFakeFS() + fakeFS.WriteTestKustomizationWith([]byte(`nameprefix: some-prefix-`)) + + cmd := NewCmdFix(fakeFS) + err := cmd.RunE(cmd, nil) + if err != nil { + t.Errorf("unexpected cmd error: %v", err) + } + content, err := fakeFS.ReadTestKustomization() + if err != nil { + t.Errorf("unexpected read error: %v", err) + } + if !strings.Contains(string(content), "apiVersion: ") { + t.Errorf("expected apiVersion in kustomization") + } + if !strings.Contains(string(content), "kind: Kustomization") { + t.Errorf("expected kind in kustomization") + } +} diff --git a/pkg/fs/fakefs.go b/pkg/fs/fakefs.go index 32ef34fa1..dffb96039 100644 --- a/pkg/fs/fakefs.go +++ b/pkg/fs/fakefs.go @@ -40,7 +40,9 @@ func MakeFakeFS() *fakeFs { } // kustomizationContent is used in tests. -const kustomizationContent = `namePrefix: some-prefix +const kustomizationContent = `apiVersion: v1 +kind: Kustomization +namePrefix: some-prefix nameSuffix: some-suffix # Labels to add to all objects and selectors. # These labels would also be used to form the selector for apply --prune diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index fd3a3acc5..157628529 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -151,15 +151,29 @@ func (k *Kustomization) DealWithDeprecatedFields() { } } +// DealWithMissingFields fills the missing fields +func (k *Kustomization) DealWithMissingFields() []string { + var msgs []string + if k.APIVersion == "" { + k.APIVersion = KustomizationVersion + msgs = append(msgs, "Fixed the missing field by adding apiVersion: "+KustomizationVersion) + } + if k.Kind == "" { + k.Kind = KustomizationKind + msgs = append(msgs, "Fixed the missing field by adding apiKind: "+KustomizationKind) + } + return msgs +} + func (k *Kustomization) EnforceFields() ([]string, []string) { var msgs, errs []string if k.APIVersion == "" { - msgs = append(msgs, "apiVersion is not defined. This will not be allowed in the next release.\nPlease add apiVersion: "+KustomizationVersion) + msgs = append(msgs, "apiVersion is not defined. This will not be allowed in the next release.\nPlease run `kustomize edit fix`") } else if k.APIVersion != KustomizationVersion { errs = append(errs, "apiVersion should be "+KustomizationVersion) } if k.Kind == "" { - msgs = append(msgs, "kind is not defined. This will not be allowed in the next release.\nPlease add kind: "+KustomizationKind) + msgs = append(msgs, "kind is not defined. This will not be allowed in the next release.\nPlease run `kustomize edit fix`") } else if k.Kind != KustomizationKind { errs = append(errs, "kind should be "+KustomizationKind) } From e9b19281b27fd1ed3c7f81404543b2c49d3e1d47 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Tue, 11 Dec 2018 09:10:49 -0800 Subject: [PATCH 007/317] Add some resId tests to support refactor. --- pkg/gvk/gvk.go | 19 ++++++++++---- pkg/resid/resid.go | 34 +++++++------------------ pkg/resid/resid_test.go | 38 ++++++++++++++++++++++++++++ pkg/resmap/resmap.go | 4 ++- pkg/target/kusttarget_test.go | 36 +++++++++++++++++++++----- pkg/transformers/prefixsuffixname.go | 29 +++++++++++++++------ 6 files changed, 115 insertions(+), 45 deletions(-) diff --git a/pkg/gvk/gvk.go b/pkg/gvk/gvk.go index 382f284d1..0bc515a35 100644 --- a/pkg/gvk/gvk.go +++ b/pkg/gvk/gvk.go @@ -35,6 +35,7 @@ func FromKind(k string) Gvk { } } +// Values that are brief but meaningful in logs. const ( noGroup = "~G" noVersion = "~V" @@ -113,11 +114,19 @@ func (x Gvk) IsLessThan(o Gvk) bool { // IsSelected returns true if `selector` selects `x`; otherwise, false. // If `selector` and `x` are the same, return true. -// If `selector` is nil, it is considered as a wildcard and always return true. -// e.g. selector CAN select -// . -// selector CANNOT select -// . +// If `selector` is nil, it is considered a wildcard match, returning true. +// If selector fields are empty, they are considered wildcards matching +// anything in the corresponding fields, .g. +// selector +// +// selects +// . +// +// while selector +// +// rejects +// . +// func (x Gvk) IsSelected(selector *Gvk) bool { if selector == nil { return true diff --git a/pkg/resid/resid.go b/pkg/resid/resid.go index 390fc2514..2af7c02a5 100644 --- a/pkg/resid/resid.go +++ b/pkg/resid/resid.go @@ -17,7 +17,6 @@ limitations under the License. package resid import ( - "fmt" "strings" "sigs.k8s.io/kustomize/pkg/gvk" @@ -125,44 +124,29 @@ func (n ResId) Name() string { return n.name } -// NameWithPrefixSuffix returns resource name with prefix and suffix. -func (n ResId) NameWithPrefixSuffix() string { - prefix := strings.Join(n.prefixList(), "") - suffix := strings.Join(n.suffixList(), "") - return fmt.Sprintf("%s%s%s", prefix, n.name, suffix) -} - -// Prefix returns name prefix. -func (n ResId) Prefix() string { - return n.prefix -} - -// Suffix returns name suffix. -func (n ResId) Suffix() string { - return n.suffix -} - // Namespace returns resource namespace. func (n ResId) Namespace() string { return n.namespace } -// CopyWithNewPrefixSuffix make a new copy from current ResId and append a new prefix and suffix +// CopyWithNewPrefixSuffix make a new copy from current ResId +// and append a new prefix and suffix func (n ResId) CopyWithNewPrefixSuffix(p, s string) ResId { - prefix := n.prefix + result := n if p != "" { - prefix = n.concatPrefix(p) + result.prefix = n.concatPrefix(p) } - suffix := n.suffix if s != "" { - suffix = n.concatSuffix(s) + result.suffix = n.concatSuffix(s) } - return ResId{gvKind: n.gvKind, name: n.name, prefix: prefix, suffix: suffix, namespace: n.namespace} + return result } // CopyWithNewNamespace make a new copy from current ResId and set a new namespace func (n ResId) CopyWithNewNamespace(ns string) ResId { - return ResId{gvKind: n.gvKind, name: n.name, prefix: n.prefix, suffix: n.suffix, namespace: ns} + result := n + result.namespace = ns + return result } // HasSameLeftmostPrefix check if two ResIds have the same diff --git a/pkg/resid/resid_test.go b/pkg/resid/resid_test.go index 165860b6c..85bafd447 100644 --- a/pkg/resid/resid_test.go +++ b/pkg/resid/resid_test.go @@ -111,3 +111,41 @@ func TestEquals(t *testing.T) { } } } + +func TestCopyWithNewPrefixSuffix(t *testing.T) { + r1 := ResId{ + gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, + name: "nm", + prefix: "a", + suffix: "b", + namespace: "X"} + r2 := r1.CopyWithNewPrefixSuffix("p-", "-s") + expected := ResId{ + gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, + name: "nm", + prefix: "p-a", + suffix: "b-s", + namespace: "X"} + if !r2.GvknEquals(expected) { + t.Fatalf("%v should equal %v", r2, expected) + } +} + +func TestCopyWithNewNamespace(t *testing.T) { + r1 := ResId{ + gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, + name: "nm", + prefix: "a", + suffix: "b", + namespace: "X"} + r2 := r1.CopyWithNewNamespace("zzz") + expected := ResId{ + gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, + name: "nm", + prefix: "a", + suffix: "b", + namespace: "zzz"} + if !r2.GvknEquals(expected) { + t.Fatalf("%v should equal %v", r2, expected) + } +} diff --git a/pkg/resmap/resmap.go b/pkg/resmap/resmap.go index 68c409063..696c5ec2c 100644 --- a/pkg/resmap/resmap.go +++ b/pkg/resmap/resmap.go @@ -131,7 +131,9 @@ func (m ResMap) FilterBy(inputId resid.ResId) ResMap { } result := ResMap{} for id, res := range m { - if id.Namespace() == inputId.Namespace() && id.HasSameLeftmostPrefix(inputId) && id.HasSameRightmostSuffix(inputId) { + if id.Namespace() == inputId.Namespace() && + id.HasSameLeftmostPrefix(inputId) && + id.HasSameRightmostSuffix(inputId) { result[id] = res } } diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index 9b7e5d39b..8a916a1fe 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -260,17 +260,41 @@ func TestSecretTimeout(t *testing.T) { } } +func findSecret(m resmap.ResMap) *resource.Resource { + for id, res := range m { + if id.Gvk().Kind == "Secret" { + return res + } + } + return nil +} + func TestDisableNameSuffixHash(t *testing.T) { kt := makeKustTarget(t, makeLoader1(t)) - kt.kustomization.GeneratorOptions = &types.GeneratorOptions{DisableNameSuffixHash: true} - actual, err := kt.MakeCustomizedResMap() + + m, err := kt.MakeCustomizedResMap() if err != nil { t.Fatalf("unexpected Resources error %v", err) } + secret := findSecret(m) + if secret == nil { + t.Errorf("Expected to find a Secret") + } + if secret.GetName() != "foo-secret-bar-9btc7bt4kb" { + t.Errorf("unexpected secret resource name: %s", secret.GetName()) + } - for id, r := range actual { - if r.GetName() != id.NameWithPrefixSuffix() { - t.Errorf("unexpected hash was added to %s: %s", id.NameWithPrefixSuffix(), r.GetName()) - } + kt.kustomization.GeneratorOptions = &types.GeneratorOptions{ + DisableNameSuffixHash: true} + m, err = kt.MakeCustomizedResMap() + if err != nil { + t.Fatalf("unexpected Resources error %v", err) + } + secret = findSecret(m) + if secret == nil { + t.Errorf("Expected to find a Secret") + } + if secret.GetName() != "foo-secret-bar" { // No hash at end. + t.Errorf("unexpected secret resource name: %s", secret.GetName()) } } diff --git a/pkg/transformers/prefixsuffixname.go b/pkg/transformers/prefixsuffixname.go index 4dc97aba6..ec3304178 100644 --- a/pkg/transformers/prefixsuffixname.go +++ b/pkg/transformers/prefixsuffixname.go @@ -43,20 +43,26 @@ var prefixSuffixFieldSpecsToSkip = []config.FieldSpec{ }, } -// deprecateNamePrefixSuffixFieldSpec will be moved into prefixSuffixFieldSpecsToSkip in next release +// deprecateNamePrefixSuffixFieldSpec will be moved into +// prefixSuffixFieldSpecsToSkip in next release var deprecateNamePrefixSuffixFieldSpec = config.FieldSpec{ Gvk: gvk.Gvk{Kind: "Namespace"}, } -// NewNamePrefixSuffixTransformer construct a namePrefixSuffixTransformer. -func NewNamePrefixSuffixTransformer(np, ns string, pc []config.FieldSpec) (Transformer, error) { +// NewNamePrefixSuffixTransformer makes a namePrefixSuffixTransformer. +func NewNamePrefixSuffixTransformer( + np, ns string, fieldSpecs []config.FieldSpec) (Transformer, error) { if len(np) == 0 && len(ns) == 0 { return NewNoOpTransformer(), nil } - if pc == nil { + if fieldSpecs == nil { return nil, errors.New("fieldSpecs is not expected to be nil") } - return &namePrefixSuffixTransformer{fieldSpecsToUse: pc, prefix: np, suffix: ns, fieldSpecsToSkip: prefixSuffixFieldSpecsToSkip}, nil + return &namePrefixSuffixTransformer{ + prefix: np, + suffix: ns, + fieldSpecsToUse: fieldSpecs, + fieldSpecsToSkip: prefixSuffixFieldSpecsToSkip}, nil } // Transform prepends the name prefix and appends the name suffix. @@ -81,14 +87,20 @@ func (o *namePrefixSuffixTransformer) Transform(m resmap.ResMap) error { for id := range mf { if id.Gvk().IsSelected(&deprecateNamePrefixSuffixFieldSpec.Gvk) { - log.Println("Adding nameprefix and namesuffix to Namespace resource will be deprecated in next release.") + log.Println( + "Adding prefix and suffix to Namespace " + + "resource will be deprecated in next release.") } objMap := mf[id].Map() for _, path := range o.fieldSpecsToUse { if !id.Gvk().IsSelected(&path.Gvk) { continue } - err := mutateField(objMap, path.PathSlice(), path.CreateIfNotPresent, o.addPrefixSuffix) + err := mutateField( + objMap, + path.PathSlice(), + path.CreateIfNotPresent, + o.addPrefixSuffix) if err != nil { return err } @@ -99,7 +111,8 @@ func (o *namePrefixSuffixTransformer) Transform(m resmap.ResMap) error { return nil } -func (o *namePrefixSuffixTransformer) addPrefixSuffix(in interface{}) (interface{}, error) { +func (o *namePrefixSuffixTransformer) addPrefixSuffix( + in interface{}) (interface{}, error) { s, ok := in.(string) if !ok { return nil, fmt.Errorf("%#v is expected to be %T", in, s) From 352ec695564b901a8197da4ed218dc2f21bb1eaf Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Thu, 13 Dec 2018 15:20:15 -0800 Subject: [PATCH 008/317] Allow directory substrings in cycle check. --- pkg/loader/fileloader.go | 3 ++- pkg/target/kusttarget.go | 2 +- pkg/target/kusttarget_test.go | 38 +++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/pkg/loader/fileloader.go b/pkg/loader/fileloader.go index 9ed39af49..038d8599b 100644 --- a/pkg/loader/fileloader.go +++ b/pkg/loader/fileloader.go @@ -190,8 +190,9 @@ func newGitLoader( // seenBefore tests whether the current or any previously // visited root begins with the given path. func (l *fileLoader) seenBefore(path string) error { + terminated := path + string(filepath.Separator) for _, r := range l.roots { - if strings.HasPrefix(r, path) { + if r == path || strings.HasPrefix(r, terminated) { return fmt.Errorf( "cycle detected: new root '%s' contains previous root '%s'", path, r) diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 6c2caf552..75066d974 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -243,7 +243,7 @@ func (kt *KustTarget) loadCustomizedBases() (resmap.ResMap, *interror.Kustomizat for _, path := range kt.kustomization.Bases { ldr, err := kt.ldr.New(path) if err != nil { - errs.Append(errors.Wrap(err, "couldn't make ldr for "+path)) + errs.Append(errors.Wrap(err, "couldn't make loader for "+path)) continue } target, err := NewKustTarget( diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index 8a916a1fe..9db44abc4 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -18,6 +18,7 @@ package target import ( "encoding/base64" + "path/filepath" "reflect" "strings" "testing" @@ -298,3 +299,40 @@ func TestDisableNameSuffixHash(t *testing.T) { t.Errorf("unexpected secret resource name: %s", secret.GetName()) } } + +func write(t *testing.T, ldr loadertest.FakeLoader, dir string, content string) { + err := ldr.AddFile( + filepath.Join(dir, constants.KustomizationFileName), + []byte(` +apiVersion: v1 +kind: Kustomization +`+content)) + if err != nil { + t.Fatalf("Failed to setup fake loader.") + } +} + +func TestIssue596AllowDirectoriesThatAreSubstringsOfEachOther(t *testing.T) { + ldr := loadertest.NewFakeLoader( + "/app/overlays/aws-sandbox2.us-east-1") + write(t, ldr, "/app/base", "") + write(t, ldr, "/app/overlays/aws", ` +bases: +- ../../base +`) + write(t, ldr, "/app/overlays/aws-nonprod", ` +bases: +- ../aws +`) + write(t, ldr, "/app/overlays/aws-sandbox2.us-east-1", ` +bases: +- ../aws-nonprod +`) + m, err := makeKustTarget(t, ldr).MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + if m == nil { + t.Fatalf("Empty map.") + } +} From 77b44f570a77073662f069b09b8bd8636027c580 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Thu, 13 Dec 2018 16:29:11 -0800 Subject: [PATCH 009/317] Reduce log noise. --- pkg/resmap/factory.go | 2 +- pkg/resmap/resmap.go | 22 ++++++++-------------- pkg/resmap/resmap_test.go | 6 +++--- pkg/target/kusttarget.go | 6 +++--- 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/pkg/resmap/factory.go b/pkg/resmap/factory.go index 9083a37ea..e3d1a6878 100644 --- a/pkg/resmap/factory.go +++ b/pkg/resmap/factory.go @@ -57,7 +57,7 @@ func (rmF *Factory) FromFiles( } result = append(result, res) } - return MergeWithoutOverride(result...) + return MergeWithErrorOnIdCollision(result...) } // newResMapFromBytes decodes a list of objects in byte array format. diff --git a/pkg/resmap/resmap.go b/pkg/resmap/resmap.go index 696c5ec2c..af10df03a 100644 --- a/pkg/resmap/resmap.go +++ b/pkg/resmap/resmap.go @@ -20,7 +20,6 @@ package resmap import ( "bytes" "fmt" - "log" "reflect" "sort" @@ -140,9 +139,10 @@ func (m ResMap) FilterBy(inputId resid.ResId) ResMap { return result } -// MergeWithoutOverride combines multiple ResMap instances, failing on key collision -// and skipping nil maps. In case if all of the maps are nil, an empty ResMap is returned. -func MergeWithoutOverride(maps ...ResMap) (ResMap, error) { +// MergeWithErrorOnIdCollision combines multiple ResMap instances, failing on +// key collision and skipping nil maps. +// If all of the maps are nil, an empty ResMap is returned. +func MergeWithErrorOnIdCollision(maps ...ResMap) (ResMap, error) { result := ResMap{} for _, m := range maps { if m == nil { @@ -164,10 +164,10 @@ func MergeWithoutOverride(maps ...ResMap) (ResMap, error) { // "replace" option in its generation instructions, meaning it is supposed // to replace something from the raw resources list. // If all of the maps are nil, an empty ResMap is returned. -// When looping over the instances to combine them, if a resource id for resource X -// is found to be already in the combined map, then the behavior field for X -// must be BehaviorMerge or BehaviorReplace. If X is not in the map, then it's -// behavior cannot be merge or replace. +// When looping over the instances to combine them, if a resource id for +// resource X is found to be already in the combined map, then the behavior +// field for X must be BehaviorMerge or BehaviorReplace. If X is not in the +// map, then it's behavior cannot be merge or replace. func MergeWithOverride(maps ...ResMap) (ResMap, error) { result := maps[0] if result == nil { @@ -183,18 +183,12 @@ func MergeWithOverride(maps ...ResMap) (ResMap, error) { id = matchedId[0] switch r.Behavior() { case ifc.BehaviorReplace: - log.Printf( - "Replace %v with %v", result[id].Map(), r.Map()) r.Replace(result[id]) result[id] = r result[id].SetBehavior(ifc.BehaviorCreate) case ifc.BehaviorMerge: - log.Printf( - "Merging %v with %v", result[id].Map(), r.Map()) r.Merge(result[id]) result[id] = r - log.Printf( - "Merged object is %v", result[id].Map()) result[id].SetBehavior(ifc.BehaviorCreate) default: return nil, fmt.Errorf("id %#v exists; must merge or replace", id) diff --git a/pkg/resmap/resmap_test.go b/pkg/resmap/resmap_test.go index 1723616a4..14e6a7a45 100644 --- a/pkg/resmap/resmap_test.go +++ b/pkg/resmap/resmap_test.go @@ -410,7 +410,7 @@ func TestMergeWithoutOverride(t *testing.T) { }, }), } - merged, err := MergeWithoutOverride(input...) + merged, err := MergeWithErrorOnIdCollision(input...) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -418,7 +418,7 @@ func TestMergeWithoutOverride(t *testing.T) { t.Fatalf("%#v doesn't equal expected %#v", merged, expected) } input3 := []ResMap{merged, nil} - merged1, err := MergeWithoutOverride(input3...) + merged1, err := MergeWithErrorOnIdCollision(input3...) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -426,7 +426,7 @@ func TestMergeWithoutOverride(t *testing.T) { t.Fatalf("%#v doesn't equal expected %#v", merged1, expected) } input4 := []ResMap{nil, merged} - merged2, err := MergeWithoutOverride(input4...) + merged2, err := MergeWithErrorOnIdCollision(input4...) if err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 6c2caf552..5c336112f 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -218,7 +218,7 @@ func (kt *KustTarget) generateConfigMapsAndSecrets( if err != nil { errs.Append(errors.Wrap(err, "NewResMapFromSecretArgs")) } - return resmap.MergeWithoutOverride(cms, secrets) + return resmap.MergeWithErrorOnIdCollision(cms, secrets) } // Gets Bases and Resources as advertised. @@ -232,7 +232,7 @@ func (kt *KustTarget) loadResMapFromBasesAndResources() (resmap.ResMap, error) { if len(errs.Get()) > 0 { return nil, errs } - return resmap.MergeWithoutOverride(resources, bases) + return resmap.MergeWithErrorOnIdCollision(resources, bases) } // Loop through the Bases of this kustomization recursively loading resources. @@ -261,7 +261,7 @@ func (kt *KustTarget) loadCustomizedBases() (resmap.ResMap, *interror.Kustomizat ldr.Cleanup() list = append(list, resMap) } - result, err := resmap.MergeWithoutOverride(list...) + result, err := resmap.MergeWithErrorOnIdCollision(list...) if err != nil { errs.Append(errors.Wrap(err, "Merge failed")) } From 48e8a3aec3f4d19f540bbde2c766d2d9da652ac0 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Thu, 13 Dec 2018 16:38:39 -0800 Subject: [PATCH 010/317] Fix incorrect use of filepath.Separator --- pkg/loader/gitcloner.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/loader/gitcloner.go b/pkg/loader/gitcloner.go index 98a732a8f..506dfe02b 100644 --- a/pkg/loader/gitcloner.go +++ b/pkg/loader/gitcloner.go @@ -119,11 +119,11 @@ func parseGithubUrl(n string) ( if strings.HasSuffix(n, ".git") { n = n[0 : len(n)-len(".git")] } - i := strings.Index(n, string(filepath.Separator)) + i := strings.Index(n, "/") if i < 1 { return "", "", "", "", errors.New("no separator") } - j := strings.Index(n[i+1:], string(filepath.Separator)) + j := strings.Index(n[i+1:], "/") if j >= 0 { j += i + 1 repo = n[:j] From 8cecccbc886369146b1e863025e036cb2970de67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Ga=C3=9F?= Date: Fri, 14 Dec 2018 14:52:25 +0100 Subject: [PATCH 011/317] Add spec/jobTemplate/metadata/labels to common labels transformer --- .../config/defaultconfig/commonlabels.go | 5 +++++ pkg/transformers/labelsandannotations_test.go | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/pkg/transformers/config/defaultconfig/commonlabels.go b/pkg/transformers/config/defaultconfig/commonlabels.go index 7efd6a54d..66943c1ed 100644 --- a/pkg/transformers/config/defaultconfig/commonlabels.go +++ b/pkg/transformers/config/defaultconfig/commonlabels.go @@ -130,6 +130,11 @@ commonLabels: group: batch kind: CronJob +- path: spec/jobTemplate/metadata/labels + create: true + group: batch + kind: CronJob + - path: spec/jobTemplate/spec/template/metadata/labels create: true group: batch diff --git a/pkg/transformers/labelsandannotations_test.go b/pkg/transformers/labelsandannotations_test.go index 979e25280..5bbaa70b6 100644 --- a/pkg/transformers/labelsandannotations_test.go +++ b/pkg/transformers/labelsandannotations_test.go @@ -355,6 +355,12 @@ func TestLabelsRun(t *testing.T) { "spec": map[string]interface{}{ "schedule": "* 23 * * *", "jobTemplate": map[string]interface{}{ + "metadata": map[string]interface{}{ + "labels": map[string]interface{}{ + "label-key1": "label-value1", + "label-key2": "label-value2", + }, + }, "spec": map[string]interface{}{ "template": map[string]interface{}{ "metadata": map[string]interface{}{ @@ -390,6 +396,12 @@ func TestLabelsRun(t *testing.T) { "spec": map[string]interface{}{ "schedule": "* 23 * * *", "jobTemplate": map[string]interface{}{ + "metadata": map[string]interface{}{ + "labels": map[string]interface{}{ + "label-key1": "label-value1", + "label-key2": "label-value2", + }, + }, "spec": map[string]interface{}{ "selector": map[string]interface{}{ "matchLabels": map[string]interface{}{ From d0e4db74b78f5c6c7e0340c5dfb4236bffd684a7 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Fri, 14 Dec 2018 13:11:04 -0800 Subject: [PATCH 012/317] fix the missing fields in all edit commands --- pkg/commands/kustfile/kustomizationfile.go | 4 ++++ pkg/commands/kustfile/kustomizationfile_test.go | 3 +++ pkg/types/kustomization.go | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pkg/commands/kustfile/kustomizationfile.go b/pkg/commands/kustfile/kustomizationfile.go index cae3488de..abd9cfe0b 100644 --- a/pkg/commands/kustfile/kustomizationfile.go +++ b/pkg/commands/kustfile/kustomizationfile.go @@ -153,6 +153,10 @@ func (mf *kustomizationFile) Read() (*types.Kustomization, error) { return nil, err } k.DealWithDeprecatedFields() + msgs := k.DealWithMissingFields() + if len(msgs) > 0 { + log.Printf(strings.Join(msgs, "\n")) + } err = mf.parseCommentedFields(data) if err != nil { return nil, err diff --git a/pkg/commands/kustfile/kustomizationfile_test.go b/pkg/commands/kustfile/kustomizationfile_test.go index a7e77898a..9cfc89839 100644 --- a/pkg/commands/kustfile/kustomizationfile_test.go +++ b/pkg/commands/kustfile/kustomizationfile_test.go @@ -78,6 +78,7 @@ func TestWriteAndRead(t *testing.T) { if err != nil { t.Fatalf("Couldn't read kustomization file: %v\n", err) } + kustomization.DealWithMissingFields() if !reflect.DeepEqual(kustomization, content) { t.Fatal("Read kustomization is different from written kustomization") } @@ -172,6 +173,8 @@ func TestPreserveComments(t *testing.T) { `# shem qing some comments # This is some comment we should preserve # don't delete it +apiVersion: v1 +kind: Kustomization resources: - pod.yaml - service.yaml diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 157628529..8cbeccaf8 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -160,7 +160,7 @@ func (k *Kustomization) DealWithMissingFields() []string { } if k.Kind == "" { k.Kind = KustomizationKind - msgs = append(msgs, "Fixed the missing field by adding apiKind: "+KustomizationKind) + msgs = append(msgs, "Fixed the missing field by adding kind: "+KustomizationKind) } return msgs } From b6b2fb9c62cc4bdbaa799ce0c16d5a7d6c4583f0 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Fri, 14 Dec 2018 14:44:37 -0800 Subject: [PATCH 013/317] add apiVersiond and kind in tests to reduce test noise --- .../build/testdata/testcase-base-only/in/kustomization.yaml | 2 ++ .../base/myapp/mycomponent/kustomization.yaml | 2 ++ .../base/myapp/mycomponent2/kustomization.yaml | 2 ++ .../testcase-configmaps/overlay/dev/kustomization.yaml | 2 ++ .../overlay/dev/myapp/mycomponent/kustomization.yaml | 2 ++ .../overlay/dev/myapp/mycomponent2/kustomization.yaml | 2 ++ .../build/testdata/testcase-crds/crd/kustomization.yaml | 2 ++ .../testcase-generators-namespace/in/kustomization.yaml | 2 ++ .../testcase-multibases-conflict/base/kustomization.yaml | 2 ++ .../testcase-multibases-conflict/combined/kustomization.yaml | 2 ++ .../overlays/a/kustomization.yaml | 2 ++ .../overlays/b/kustomization.yaml | 2 ++ .../testcase-multibases-nonconflict/base/kustomization.yaml | 2 ++ .../combined/kustomization.yaml | 2 ++ .../overlays/a/kustomization.yaml | 2 ++ .../overlays/b/kustomization.yaml | 2 ++ .../in/overlay/kustomization.yaml | 2 ++ .../in/package/kustomization.yaml | 2 ++ .../in/overlay/kustomization.yaml | 2 ++ .../in/package/kustomization.yaml | 2 ++ .../testcase-single-overlay/in/overlay/kustomization.yaml | 2 ++ .../testcase-single-overlay/in/package/kustomization.yaml | 2 ++ .../testcase-variable-ref-ingress/in/base/kustomization.yaml | 2 ++ .../in/overlay/kustomization.yaml | 2 ++ .../testcase-variable-ref/in/overlay/kustomization.yaml | 2 ++ .../testcase-variable-ref/in/package/kustomization.yaml | 2 ++ .../simple/instances/exampleinstance/kustomization.yaml | 2 ++ pkg/examplelayout/simple/package/kustomization.yaml | 2 ++ pkg/target/kusttarget_test.go | 4 ++++ 29 files changed, 60 insertions(+) diff --git a/pkg/commands/build/testdata/testcase-base-only/in/kustomization.yaml b/pkg/commands/build/testdata/testcase-base-only/in/kustomization.yaml index a968cabb5..f416f4fad 100644 --- a/pkg/commands/build/testdata/testcase-base-only/in/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-base-only/in/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization namePrefix: team-foo- commonLabels: app: mynginx diff --git a/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent/kustomization.yaml index 8b9f791b6..feb3ada5f 100644 --- a/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization namePrefix: p1- configMapGenerator: - name: com1 diff --git a/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent2/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent2/kustomization.yaml index da1615aad..a4041a390 100644 --- a/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent2/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent2/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization namePrefix: p2- configMapGenerator: - name: com2 diff --git a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/kustomization.yaml index 1ccbeefb7..580d08d91 100644 --- a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - myapp/mycomponent - myapp/mycomponent2 diff --git a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent/kustomization.yaml index 0ff7d2083..77569d895 100644 --- a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ../../../../base/myapp/mycomponent configMapGenerator: diff --git a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent2/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent2/kustomization.yaml index 45d1eedd1..76c6468c3 100644 --- a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent2/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent2/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ../../../../base/myapp/mycomponent2 configMapGenerator: diff --git a/pkg/commands/build/testdata/testcase-crds/crd/kustomization.yaml b/pkg/commands/build/testdata/testcase-crds/crd/kustomization.yaml index 98f226de9..3c7934039 100644 --- a/pkg/commands/build/testdata/testcase-crds/crd/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-crds/crd/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization crds: - mycrd.json diff --git a/pkg/commands/build/testdata/testcase-generators-namespace/in/kustomization.yaml b/pkg/commands/build/testdata/testcase-generators-namespace/in/kustomization.yaml index b0a1f76df..a0a2585f9 100644 --- a/pkg/commands/build/testdata/testcase-generators-namespace/in/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-generators-namespace/in/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization configMapGenerator: - name: the-non-default-namespace-map namespace: non-default diff --git a/pkg/commands/build/testdata/testcase-multibases-conflict/base/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-conflict/base/kustomization.yaml index 816593c7a..c2659b3ba 100644 --- a/pkg/commands/build/testdata/testcase-multibases-conflict/base/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multibases-conflict/base/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization resources: - serviceaccount.yaml - rolebinding.yaml diff --git a/pkg/commands/build/testdata/testcase-multibases-conflict/combined/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-conflict/combined/kustomization.yaml index 5d1ecdfc7..baab2a316 100644 --- a/pkg/commands/build/testdata/testcase-multibases-conflict/combined/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multibases-conflict/combined/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ../overlays/a - ../overlays/b diff --git a/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/a/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/a/kustomization.yaml index fb034fc6d..30ea303c2 100644 --- a/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/a/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/a/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ../../base/ diff --git a/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/b/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/b/kustomization.yaml index 899058b14..fe87bd2fa 100644 --- a/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/b/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/b/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ../../base/ diff --git a/pkg/commands/build/testdata/testcase-multibases-nonconflict/base/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-nonconflict/base/kustomization.yaml index 816593c7a..c2659b3ba 100644 --- a/pkg/commands/build/testdata/testcase-multibases-nonconflict/base/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multibases-nonconflict/base/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization resources: - serviceaccount.yaml - rolebinding.yaml diff --git a/pkg/commands/build/testdata/testcase-multibases-nonconflict/combined/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-nonconflict/combined/kustomization.yaml index 5d1ecdfc7..baab2a316 100644 --- a/pkg/commands/build/testdata/testcase-multibases-nonconflict/combined/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multibases-nonconflict/combined/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ../overlays/a - ../overlays/b diff --git a/pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/a/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/a/kustomization.yaml index 5e05f791d..29909bf3f 100644 --- a/pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/a/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/a/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ../../base/ diff --git a/pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/b/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/b/kustomization.yaml index 899058b14..fe87bd2fa 100644 --- a/pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/b/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/b/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ../../base/ diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/kustomization.yaml index 2419b72af..207e52395 100644 --- a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization namePrefix: staging- commonLabels: env: staging diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/kustomization.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/kustomization.yaml index 30603cf68..f269394d3 100644 --- a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization namePrefix: team-foo- commonLabels: app: mynginx diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml index 51e39c216..d0c5a3389 100644 --- a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization namePrefix: staging- commonLabels: env: staging diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/kustomization.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/kustomization.yaml index 30603cf68..f269394d3 100644 --- a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization namePrefix: team-foo- commonLabels: app: mynginx diff --git a/pkg/commands/build/testdata/testcase-single-overlay/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-single-overlay/in/overlay/kustomization.yaml index 7538778f7..876f26406 100644 --- a/pkg/commands/build/testdata/testcase-single-overlay/in/overlay/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-single-overlay/in/overlay/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization namePrefix: staging- commonLabels: env: staging diff --git a/pkg/commands/build/testdata/testcase-single-overlay/in/package/kustomization.yaml b/pkg/commands/build/testdata/testcase-single-overlay/in/package/kustomization.yaml index b84575522..8905b2656 100644 --- a/pkg/commands/build/testdata/testcase-single-overlay/in/package/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-single-overlay/in/package/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization namePrefix: team-foo- commonLabels: app: mynginx diff --git a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/kustomization.yaml b/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/kustomization.yaml index 0e4e618c8..6e96e7a37 100644 --- a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization resources: - deployment.yaml - ingress.yaml diff --git a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/overlay/kustomization.yaml index 942d7c1e5..e544f7d0a 100644 --- a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/overlay/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/overlay/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization nameprefix: kustomized- bases: diff --git a/pkg/commands/build/testdata/testcase-variable-ref/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-variable-ref/in/overlay/kustomization.yaml index 1fccccac8..781f1e4fc 100644 --- a/pkg/commands/build/testdata/testcase-variable-ref/in/overlay/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-variable-ref/in/overlay/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization namePrefix: dev- bases: - ../package diff --git a/pkg/commands/build/testdata/testcase-variable-ref/in/package/kustomization.yaml b/pkg/commands/build/testdata/testcase-variable-ref/in/package/kustomization.yaml index 68fcd77b0..d811d59ca 100644 --- a/pkg/commands/build/testdata/testcase-variable-ref/in/package/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-variable-ref/in/package/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization namePrefix: base- resources: - cockroachdb-statefulset-secure.yaml diff --git a/pkg/examplelayout/simple/instances/exampleinstance/kustomization.yaml b/pkg/examplelayout/simple/instances/exampleinstance/kustomization.yaml index 3741a2b52..f16073490 100644 --- a/pkg/examplelayout/simple/instances/exampleinstance/kustomization.yaml +++ b/pkg/examplelayout/simple/instances/exampleinstance/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization namePrefix: test-infra- commonLabels: app: mungebot diff --git a/pkg/examplelayout/simple/package/kustomization.yaml b/pkg/examplelayout/simple/package/kustomization.yaml index 31fed42c4..82bc52e23 100644 --- a/pkg/examplelayout/simple/package/kustomization.yaml +++ b/pkg/examplelayout/simple/package/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization namePrefix: baseprefix- commonLabels: foo: bar diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index 9db44abc4..3442ec15f 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -38,6 +38,8 @@ import ( const ( kustomizationContent1 = ` +apiVersion: v1 +kind: Kustomization namePrefix: foo- nameSuffix: -bar namespace: ns1 @@ -68,6 +70,8 @@ patchesJson6902: path: jsonpatch.json ` kustomizationContent2 = ` +apiVersion: v1 +kind: Kustomization secretGenerator: - name: secret timeoutSeconds: 1 From 20e37eaf65b9a7c90ac4f6a6a49e670e88f994b3 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Thu, 13 Dec 2018 10:35:03 -0800 Subject: [PATCH 014/317] improve url parsing function in gitcloner --- pkg/loader/gitcloner.go | 19 +++++++++++++++---- pkg/loader/gitcloner_test.go | 14 ++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/pkg/loader/gitcloner.go b/pkg/loader/gitcloner.go index 506dfe02b..01d21d4cd 100644 --- a/pkg/loader/gitcloner.go +++ b/pkg/loader/gitcloner.go @@ -44,7 +44,7 @@ func isRepoUrl(arg string) bool { (strings.HasPrefix(arg, "git::") || strings.HasPrefix(arg, "gh:") || strings.HasPrefix(arg, "github.com") || - strings.HasPrefix(arg, "git@github.com:") || + strings.HasPrefix(arg, "git@") || strings.Index(arg, "github.com/") > -1 || isAzureHost(arg) || isAWSHost(arg)) } @@ -106,7 +106,10 @@ func parseUrl(n string) ( return } -const refQuery = "?ref=" +const ( + refQuery = "?ref=" + gitSuffix = ".git" +) // From strings like git@github.com:someOrg/someRepo.git or // https://github.com/someOrg/someRepo?ref=someHash, extract @@ -116,8 +119,16 @@ func parseGithubUrl(n string) ( host, n = parseHostSpec(n) host = normalizeGitHostSpec(host) - if strings.HasSuffix(n, ".git") { - n = n[0 : len(n)-len(".git")] + if strings.HasSuffix(n, gitSuffix) { + repo = n[0 : len(n)-len(gitSuffix)] + return + } + if strings.Contains(n, gitSuffix) { + index := strings.Index(n, gitSuffix) + repo = n[0:index] + n = n[index+len(gitSuffix):] + path, gitRef = peelQuery(n) + return } i := strings.Index(n, "/") if i < 1 { diff --git a/pkg/loader/gitcloner_test.go b/pkg/loader/gitcloner_test.go index 732d074ee..672cf16a8 100644 --- a/pkg/loader/gitcloner_test.go +++ b/pkg/loader/gitcloner_test.go @@ -52,6 +52,14 @@ func TestIsRepoURL(t *testing.T) { input: "git::https://gitlab.com/org/repo", expected: true, }, + { + input: "git@gitlab2.sqtools.ru:10022/infra/kubernetes/thanos-base.git?ref=v0.1.0", + expected: true, + }, + { + input: "git@bitbucket.org:org/repo.git", + expected: true, + }, { input: "/github.com/org/repo", expected: false, @@ -283,6 +291,12 @@ func TestParseUrl(t *testing.T) { path: "somedir", ref: "", }, + { + input: "git@gitlab2.sqtools.ru:10022/infra/kubernetes/thanos-base.git?ref=v0.1.0", + repo: "git@gitlab2.sqtools.ru:10022/infra/kubernetes/thanos-base.git", + path: "", + ref: "v0.1.0", + }, } for _, testcase := range testcases { repo, path, ref, err := parseUrl(testcase.input) From 11a19906b9caf0376a70c3ece664fff8d5e4e1a3 Mon Sep 17 00:00:00 2001 From: jregan Date: Sun, 16 Dec 2018 09:21:54 -0800 Subject: [PATCH 015/317] Improve name transformer docs. --- pkg/target/kusttarget.go | 65 ++++++++++++++------------ pkg/transformers/namereference.go | 31 ++++++++---- pkg/transformers/namereference_test.go | 18 +++---- 3 files changed, 63 insertions(+), 51 deletions(-) diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 404496f27..6801d3ab1 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package target implements state for the set of all resources being customized. +// Package target implements state for the set of all resources to customize. package target import ( @@ -97,9 +97,10 @@ func unmarshal(y []byte, o interface{}) error { return dec.Decode(o) } -// makeTransformerConfig returns a complete TransformerConfig object from either files -// or the default configs -func makeTransformerConfig(ldr ifc.Loader, paths []string) (*config.TransformerConfig, error) { +// makeTransformerConfig returns a complete TransformerConfig object +// from either files or the default configs +func makeTransformerConfig( + ldr ifc.Loader, paths []string) (*config.TransformerConfig, error) { if paths == nil || len(paths) == 0 { return config.NewFactory(nil).DefaultConfig(), nil } @@ -113,13 +114,7 @@ func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) { if err != nil { return nil, err } - return kt.resolveRefsToGeneratedResources(m) -} - -// resolveRefsToGeneratedResources fixes all name references. -func (kt *KustTarget) resolveRefsToGeneratedResources(m resmap.ResMap) (resmap.ResMap, error) { - if kt.kustomization.GeneratorOptions == nil || - !kt.kustomization.GeneratorOptions.DisableNameSuffixHash { + if kt.shouldAddHashSuffixesToGeneratedResources() { // This effects only generated resources. // It changes only the Name field in the // resource held in the ResMap's value, not @@ -129,25 +124,28 @@ func (kt *KustTarget) resolveRefsToGeneratedResources(m resmap.ResMap) (resmap.R return nil, err } } - var r []transformers.Transformer - t, err := transformers.NewNameReferenceTransformer(kt.tConfig.NameReference) - if err != nil { - return nil, err - } - r = append(r, t) - refVars, err := kt.resolveRefVars(m) + // Given that names have changed (prefixs/suffixes added), + // fix all the back references to those names. + err = transformers.NewNameReferenceTransformer( + kt.tConfig.NameReference).Transform(m) if err != nil { return nil, err } - t = transformers.NewRefVarTransformer(refVars, kt.tConfig.VarReference) - r = append(r, t) - err = transformers.NewMultiTransformer(r).Transform(m) + // With all the back references fixed, it's OK to resolve Vars. + refVars, err := kt.resolveVars(m) if err != nil { return nil, err } - return m, nil + err = transformers.NewRefVarTransformer( + refVars, kt.tConfig.VarReference).Transform(m) + return m, err +} + +func (kt *KustTarget) shouldAddHashSuffixesToGeneratedResources() bool { + return kt.kustomization.GeneratorOptions == nil || + !kt.kustomization.GeneratorOptions.DisableNameSuffixHash } // loadCustomizedResMap loads and customizes resources to build a ResMap. @@ -268,7 +266,7 @@ func (kt *KustTarget) loadCustomizedBases() (resmap.ResMap, *interror.Kustomizat return result, errs } -func (kt *KustTarget) loadBasesAsFlatList() ([]*KustTarget, error) { +func (kt *KustTarget) loadBasesAsKustTargets() ([]*KustTarget, error) { var result []*KustTarget errs := &interror.KustomizationErrors{} for _, path := range kt.kustomization.Bases { @@ -291,8 +289,10 @@ func (kt *KustTarget) loadBasesAsFlatList() ([]*KustTarget, error) { return result, nil } -// newTransformer makes a Transformer that does everything except resolve generated names. -func (kt *KustTarget) newTransformer(patches []*resource.Resource) (transformers.Transformer, error) { +// newTransformer makes a Transformer that does a collection +// of object transformations. +func (kt *KustTarget) newTransformer( + patches []*resource.Resource) (transformers.Transformer, error) { var r []transformers.Transformer t, err := kt.tFactory.MakePatchTransformer(patches, kt.rFactory.RF()) if err != nil { @@ -325,7 +325,10 @@ func (kt *KustTarget) newTransformer(patches []*resource.Resource) (transformers return transformers.NewMultiTransformer(r), nil } -func (kt *KustTarget) resolveRefVars(m resmap.ResMap) (map[string]string, error) { +// resolveVars returns a map of Var names to their final values. +// The values are strings intended for substitution wherever +// the $(var.Name) occurs. +func (kt *KustTarget) resolveVars(m resmap.ResMap) (map[string]string, error) { result := map[string]string{} vars, err := kt.getAllVars() if err != nil { @@ -336,11 +339,11 @@ func (kt *KustTarget) resolveRefVars(m resmap.ResMap) (map[string]string, error) if r, found := m.DemandOneMatchForId(id); found { s, err := r.GetFieldValue(v.FieldRef.FieldPath) if err != nil { - return nil, fmt.Errorf("failed to resolve referred var: %+v", v) + return nil, fmt.Errorf("field path err for var: %+v", v) } result[v.Name] = s } else { - log.Printf("couldn't resolve v: %v", v) + log.Printf("couldn't resolve var: %v", v) } } return result, nil @@ -351,7 +354,7 @@ func (kt *KustTarget) getAllVars() ([]types.Var, error) { var result []types.Var errs := &interror.KustomizationErrors{} - bases, err := kt.loadBasesAsFlatList() + bases, err := kt.loadBasesAsKustTargets() if err != nil { return nil, err } @@ -377,7 +380,9 @@ func (kt *KustTarget) getAllVars() ([]types.Var, error) { } func loadKustFile(ldr ifc.Loader) ([]byte, error) { - for _, kf := range []string{constants.KustomizationFileName, constants.SecondaryKustomizationFileName} { + for _, kf := range []string{ + constants.KustomizationFileName, + constants.SecondaryKustomizationFileName} { content, err := ldr.Load(kf) if err == nil { return content, nil diff --git a/pkg/transformers/namereference.go b/pkg/transformers/namereference.go index 2f65f6848..899813776 100644 --- a/pkg/transformers/namereference.go +++ b/pkg/transformers/namereference.go @@ -17,8 +17,8 @@ limitations under the License. package transformers import ( - "errors" "fmt" + "log" "sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/resmap" @@ -33,18 +33,31 @@ var _ Transformer = &nameReferenceTransformer{} // NewNameReferenceTransformer constructs a nameReferenceTransformer // with a given slice of NameBackReferences. -func NewNameReferenceTransformer( - br []config.NameBackReferences) (Transformer, error) { +func NewNameReferenceTransformer(br []config.NameBackReferences) Transformer { if br == nil { - return nil, errors.New("backrefs not expected to be nil") + log.Fatal("backrefs not expected to be nil") } - return &nameReferenceTransformer{backRefs: br}, nil + return &nameReferenceTransformer{backRefs: br} } -// Transform does the field update according to fieldSpecs. -// The old name is in the key in the map and the new name is in the object -// associated with the key. e.g. if is one of the key-value pair in the map, -// then the old name is k.Name and the new name is v.GetName() +// Transform updates name references in resource A that refer to resource B, +// given that B's name may have changed. +// +// For example, a HorizontalPodAutoscaler (HPA) necessarily refers to a +// Deployment (the thing that the HPA scales). The Deployment name might change +// (e.g. prefix added), and the reference in the HPA has to be fixed. +// +// In the outer loop below, we encounter an HPA. In scanning backrefs, we +// find that HPA refers to a Deployment. So we find all resources in the same +// namespace as the HPA (and with the same prefix and suffix), and look through +// them to find all the Deployments with a resId that has a Name matching the +// field in HPA. For each match, we overwrite the HPA name field with the value +// found in the Deployment's name field (the name in the raw object - the +// modified name - not the unmodified name in the resId). +// +// This assumes that the name stored in a ResId (the ResMap key) isn't modified +// by name transformers. Name transformers should only modify the name in the +// body of the resource object (the value in the ResMap). func (o *nameReferenceTransformer) Transform(m resmap.ResMap) error { // TODO: Too much looping. // Even more hidden loops in FilterBy, diff --git a/pkg/transformers/namereference_test.go b/pkg/transformers/namereference_test.go index 6a94588ca..dc50972a9 100644 --- a/pkg/transformers/namereference_test.go +++ b/pkg/transformers/namereference_test.go @@ -417,11 +417,8 @@ func TestNameReferenceHappyRun(t *testing.T) { }, }, }) - nrt, err := NewNameReferenceTransformer(defaultTransformerConfig.NameReference) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - err = nrt.Transform(m) + nrt := NewNameReferenceTransformer(defaultTransformerConfig.NameReference) + err := nrt.Transform(m) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -483,19 +480,16 @@ func TestNameReferenceUnhappyRun(t *testing.T) { expectedErr: "is expected to be either a string or a []interface{}"}, } - nrt, err := NewNameReferenceTransformer(defaultTransformerConfig.NameReference) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - + nrt := NewNameReferenceTransformer(defaultTransformerConfig.NameReference) for _, test := range tests { - err = nrt.Transform(test.resMap) + err := nrt.Transform(test.resMap) if err == nil { t.Fatalf("expected error to happen") } if !strings.Contains(err.Error(), test.expectedErr) { - t.Fatalf("Incorrect error.\nExpected: %s, but got %v", test.expectedErr, err) + t.Fatalf("Incorrect error.\nExpected: %s, but got %v", + test.expectedErr, err) } } } From 54d6cf70875a6a03534e3a0ac3a2af7ecfbdf775 Mon Sep 17 00:00:00 2001 From: jregan Date: Sun, 16 Dec 2018 09:27:58 -0800 Subject: [PATCH 016/317] Simplify refvar transformer. --- pkg/transformers/refvars.go | 86 ++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/pkg/transformers/refvars.go b/pkg/transformers/refvars.go index fef731a4c..d2a9983af 100644 --- a/pkg/transformers/refvars.go +++ b/pkg/transformers/refvars.go @@ -9,58 +9,54 @@ import ( ) type refvarTransformer struct { - fieldSpecs []config.FieldSpec - vars map[string]string + fieldSpecs []config.FieldSpec + mappingFunc func(string) string } -// NewRefVarTransformer returns a Trasformer that replaces $(VAR) style variables with values. -func NewRefVarTransformer(vars map[string]string, p []config.FieldSpec) Transformer { +// NewRefVarTransformer returns a Transformer that replaces $(VAR) style +// variables with values. +// The fieldSpecs are the places to look for occurrences of $(VAR). +func NewRefVarTransformer( + varMap map[string]string, fs []config.FieldSpec) Transformer { return &refvarTransformer{ - vars: vars, - fieldSpecs: p, + fieldSpecs: fs, + mappingFunc: expansion.MappingFuncFor(varMap), } } -// Transform determines the final values of variables: -// -// 1. Determine the final value of each variable: -// a. If the variable's Value is set, expand the `$(var)` references to other -// variables in the .Value field; the sources of variables are the declared -// variables of the container and the service environment variables -// b. If a source is defined for an environment variable, resolve the source -// 2. Create the container's environment in the order variables are declared -// 3. Add remaining service environment vars -func (rv *refvarTransformer) Transform(resources resmap.ResMap) error { - for resId := range resources { - objMap := resources[resId].Map() - for _, pc := range rv.fieldSpecs { - if !resId.Gvk().IsSelected(&pc.Gvk) { - continue - } - err := mutateField(objMap, pc.PathSlice(), false, func(in interface{}) (interface{}, error) { - var ( - mappingFunc = expansion.MappingFuncFor(rv.vars) - ) - switch vt := in.(type) { - case []interface{}: - var xs []string - for _, a := range in.([]interface{}) { - xs = append(xs, expansion.Expand(a.(string), mappingFunc)) - } - return xs, nil - case interface{}: - s, ok := in.(string) - if !ok { - return nil, fmt.Errorf("%#v is expected to be %T", in, s) - } - runtimeVal := expansion.Expand(s, mappingFunc) - return runtimeVal, nil - default: - return "", fmt.Errorf("invalid type encountered %T", vt) +// replaceVars accepts as 'in' a string, or string array, which can have +// embedded instances of $VAR style variables, e.g. a container command string. +// The function returns the string with the variables expanded to their final +// values. +func (rv *refvarTransformer) replaceVars(in interface{}) (interface{}, error) { + switch vt := in.(type) { + case []interface{}: + var xs []string + for _, a := range in.([]interface{}) { + xs = append(xs, expansion.Expand(a.(string), rv.mappingFunc)) + } + return xs, nil + case interface{}: + s, ok := in.(string) + if !ok { + return nil, fmt.Errorf("%#v is expected to be %T", in, s) + } + return expansion.Expand(s, rv.mappingFunc), nil + default: + return "", fmt.Errorf("invalid type encountered %T", vt) + } +} + +// Transform replaces $(VAR) style variables with values. +func (rv *refvarTransformer) Transform(m resmap.ResMap) error { + for id, res := range m { + for _, fieldSpec := range rv.fieldSpecs { + if id.Gvk().IsSelected(&fieldSpec.Gvk) { + if err := mutateField( + res.Map(), fieldSpec.PathSlice(), + false, rv.replaceVars); err != nil { + return err } - }) - if err != nil { - return err } } } From 29694e5b6a2e6b77bd82b5bcba510284ce7838b9 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Mon, 17 Dec 2018 10:54:51 -0800 Subject: [PATCH 017/317] Add test for secretfactory. --- .../configmapandsecret/secretfactory_test.go | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 k8sdeps/configmapandsecret/secretfactory_test.go diff --git a/k8sdeps/configmapandsecret/secretfactory_test.go b/k8sdeps/configmapandsecret/secretfactory_test.go new file mode 100644 index 000000000..f59c3980f --- /dev/null +++ b/k8sdeps/configmapandsecret/secretfactory_test.go @@ -0,0 +1,114 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package configmapandsecret + +import ( + "strings" + "testing" + + "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/types" +) + +func TestMakeSecretNoCommands(t *testing.T) { + factory := NewSecretFactory(fs.MakeFakeFS(), "/") + args := types.SecretArgs{ + GeneratorArgs: types.GeneratorArgs{Name: "apple"}, + Type: "Opaque", + CommandSources: types.CommandSources{ + Commands: nil, + EnvCommand: "", + }} + s, err := factory.MakeSecret(&args, nil) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if s.ObjectMeta.Name != "apple" { + t.Fatalf("unexpected name: %v", s.ObjectMeta.Name) + } + if len(s.Data) > 0 || len(s.StringData) > 0 { + t.Fatalf("unexpected data: %v", s) + } +} + +func TestMakeSecretNoCommandsBadDir(t *testing.T) { + factory := NewSecretFactory(fs.MakeFakeFS(), "/does/not/exist") + args := types.SecretArgs{ + GeneratorArgs: types.GeneratorArgs{Name: "envConfigMap"}, + Type: "Opaque", + CommandSources: types.CommandSources{ + Commands: nil, + EnvCommand: "", + }} + _, err := factory.MakeSecret(&args, nil) + if err == nil { + t.Fatalf("expected error: %v", err) + } + if !strings.Contains(err.Error(), "not a directory") { + t.Fatalf("unexpected error: %v", err) + } +} + +func TestMakeSecretEmptyCommandMap(t *testing.T) { + factory := NewSecretFactory(fs.MakeFakeFS(), "/") + args := types.SecretArgs{ + GeneratorArgs: types.GeneratorArgs{Name: "envConfigMap"}, + Type: "Opaque", + CommandSources: types.CommandSources{ + // TODO try: map[string]string{"commandName": "bogusCommand bogusArg"}, + Commands: nil, + EnvCommand: "echo beans", + }} + s, err := factory.MakeSecret(&args, nil) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if s == nil { + t.Fatalf("nil result") + } + v, ok := s.Data["beans"] + if !ok { + t.Fatalf("expected beans") + } + if len(v) > 0 { + t.Fatalf("unexpected data") + } +} + +func TestMakeSecretWithCommandMap(t *testing.T) { + factory := NewSecretFactory(fs.MakeFakeFS(), "/") + args := types.SecretArgs{ + GeneratorArgs: types.GeneratorArgs{Name: "envConfigMap"}, + Type: "Opaque", + CommandSources: types.CommandSources{ + Commands: map[string]string{"commandName": "echo beans"}, + }} + s, err := factory.MakeSecret(&args, nil) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if s == nil { + t.Fatalf("nil result") + } + v, ok := s.Data["commandName"] + if !ok { + t.Fatalf("expected something for commandName") + } + if string(v) != "beans\n" { + t.Fatalf("unexpected data: %s", string(v)) + } +} From d4ba22191ae8df07a5edbb2aedcbb8317bad1ddf Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Mon, 17 Dec 2018 10:59:27 -0800 Subject: [PATCH 018/317] Avoid unnecessary shell execution in secretFactory. --- k8sdeps/configmapandsecret/secretfactory.go | 29 ++++++++++--------- .../configmapandsecret/secretfactory_test.go | 8 ++--- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/k8sdeps/configmapandsecret/secretfactory.go b/k8sdeps/configmapandsecret/secretfactory.go index 5ba3bba0c..fd1766fcb 100644 --- a/k8sdeps/configmapandsecret/secretfactory.go +++ b/k8sdeps/configmapandsecret/secretfactory.go @@ -72,22 +72,23 @@ func (f *SecretFactory) MakeSecret(args *types.SecretArgs, options *types.Genera log.Println("SecretArgs.TimeoutSeconds will be deprected in next release. Please use GeneratorOptions.TimeoutSeconds instread.") timeout = time.Duration(*args.TimeoutSeconds) * time.Second } - - pairs, err := f.keyValuesFromEnvFileCommand(args.EnvCommand, timeout, options) - if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf( - "env source file: %s", - args.EnvCommand)) + if args.EnvCommand != "" { + pairs, err := f.keyValuesFromEnvFileCommand(args.EnvCommand, timeout, options) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf( + "env source file: %s", + args.EnvCommand)) + } + all = append(all, pairs...) } - all = append(all, pairs...) - - pairs, err = f.keyValuesFromCommands(args.Commands, timeout, options) - if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf( - "commands %v", args.Commands)) + if len(args.Commands) != 0 { + pairs, err := f.keyValuesFromCommands(args.Commands, timeout, options) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf( + "commands %v", args.Commands)) + } + all = append(all, pairs...) } - all = append(all, pairs...) - for _, kv := range all { err = addKvToSecret(s, kv.key, kv.value) if err != nil { diff --git a/k8sdeps/configmapandsecret/secretfactory_test.go b/k8sdeps/configmapandsecret/secretfactory_test.go index f59c3980f..a2c50870a 100644 --- a/k8sdeps/configmapandsecret/secretfactory_test.go +++ b/k8sdeps/configmapandsecret/secretfactory_test.go @@ -17,7 +17,6 @@ limitations under the License. package configmapandsecret import ( - "strings" "testing" "sigs.k8s.io/kustomize/pkg/fs" @@ -55,11 +54,8 @@ func TestMakeSecretNoCommandsBadDir(t *testing.T) { EnvCommand: "", }} _, err := factory.MakeSecret(&args, nil) - if err == nil { - t.Fatalf("expected error: %v", err) - } - if !strings.Contains(err.Error(), "not a directory") { - t.Fatalf("unexpected error: %v", err) + if err != nil { + t.Fatalf("Unexpected error: %v", err) } } From 243cbae41175f63671a9804c97a626dc3a9368f2 Mon Sep 17 00:00:00 2001 From: jregan Date: Sun, 16 Dec 2018 20:21:42 -0800 Subject: [PATCH 019/317] Convert file system based test to in-memory. --- pkg/commands/build/build_test.go | 4 +- .../testdata/testcase-simple/expected.diff | 154 ------------ .../testdata/testcase-simple/expected.yaml | 135 ---------- .../build/testdata/testcase-simple/test.yaml | 5 - .../exampleinstance/configmap/app-init.ini | 2 - .../exampleinstance/configmap/app.env | 2 - .../deployment/deployment.yaml | 43 ---- .../exampleinstance/kustomization.yaml | 28 --- .../instances/exampleinstance/secret/tls.cert | 12 - .../instances/exampleinstance/secret/tls.key | 9 - .../simple/package/Kube-descriptor.yaml | 14 -- .../simple/package/deployment/deployment.yaml | 21 -- .../simple/package/kustomization.yaml | 10 - .../simple/package/service/service.yaml | 11 - pkg/target/bigger_test.go | 230 ++++++++++++++++++ pkg/target/kusttarget_test.go | 36 ++- 16 files changed, 254 insertions(+), 462 deletions(-) delete mode 100644 pkg/commands/build/testdata/testcase-simple/expected.diff delete mode 100644 pkg/commands/build/testdata/testcase-simple/expected.yaml delete mode 100644 pkg/commands/build/testdata/testcase-simple/test.yaml delete mode 100644 pkg/examplelayout/simple/instances/exampleinstance/configmap/app-init.ini delete mode 100644 pkg/examplelayout/simple/instances/exampleinstance/configmap/app.env delete mode 100644 pkg/examplelayout/simple/instances/exampleinstance/deployment/deployment.yaml delete mode 100644 pkg/examplelayout/simple/instances/exampleinstance/kustomization.yaml delete mode 100644 pkg/examplelayout/simple/instances/exampleinstance/secret/tls.cert delete mode 100644 pkg/examplelayout/simple/instances/exampleinstance/secret/tls.key delete mode 100644 pkg/examplelayout/simple/package/Kube-descriptor.yaml delete mode 100644 pkg/examplelayout/simple/package/deployment/deployment.yaml delete mode 100644 pkg/examplelayout/simple/package/kustomization.yaml delete mode 100644 pkg/examplelayout/simple/package/service/service.yaml create mode 100644 pkg/target/bigger_test.go diff --git a/pkg/commands/build/build_test.go b/pkg/commands/build/build_test.go index 98c2f99d3..ead4f6556 100644 --- a/pkg/commands/build/build_test.go +++ b/pkg/commands/build/build_test.go @@ -99,17 +99,15 @@ func TestBuild(t *testing.T) { return nil }) // sanity check that we found the right folder - if !kustfile.StringInSlice("simple", testcases) { + if !kustfile.StringInSlice("multiple-patches-noconflict", testcases) { t.Fatalf("Error locating testcases") } - for _, testcaseName := range testcases { t.Run(testcaseName, func(t *testing.T) { runBuildTestCase(t, testcaseName, updateKustomizeExpected, fSys) }) } - } func runBuildTestCase(t *testing.T, testcaseName string, updateKustomizeExpected bool, fSys fs.FileSystem) { diff --git a/pkg/commands/build/testdata/testcase-simple/expected.diff b/pkg/commands/build/testdata/testcase-simple/expected.diff deleted file mode 100644 index fcd7ce640..000000000 --- a/pkg/commands/build/testdata/testcase-simple/expected.diff +++ /dev/null @@ -1,154 +0,0 @@ -diff -u -N /tmp/noop/extensions_v1beta1_Deployment_mungebot.yaml /tmp/transformed/extensions_v1beta1_Deployment_mungebot.yaml ---- /tmp/noop/extensions_v1beta1_Deployment_mungebot.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/extensions_v1beta1_Deployment_mungebot.yaml YYYY-MM-DD HH:MM:SS -@@ -3,28 +3,68 @@ - metadata: - annotations: - baseAnno: This is an base annotation -+ note: This is a test annotation - labels: - app: mungebot - foo: bar -- name: baseprefix-mungebot -+ org: kubernetes -+ repo: test-infra -+ name: test-infra-baseprefix-mungebot - spec: -- replicas: 1 -+ replicas: 2 - selector: - matchLabels: -+ app: mungebot - foo: bar -+ org: kubernetes -+ repo: test-infra - template: - metadata: - annotations: - baseAnno: This is an base annotation -+ note: This is a test annotation - labels: - app: mungebot - foo: bar -+ org: kubernetes -+ repo: test-infra - spec: - containers: - - env: -+ - name: FOO -+ valueFrom: -+ configMapKeyRef: -+ key: somekey -+ name: test-infra-app-env-bh449c299k -+ - name: BAR -+ valueFrom: -+ secretKeyRef: -+ key: somekey -+ name: test-infra-app-tls-6hkmhf2224 - - name: foo - value: bar -- image: nginx -+ image: nginx:1.8.0 - name: nginx - ports: - - containerPort: 80 -+ - envFrom: -+ - configMapRef: -+ name: someConfigMap -+ - configMapRef: -+ name: test-infra-app-env-bh449c299k -+ - secretRef: -+ name: test-infra-app-tls-6hkmhf2224 -+ image: busybox -+ name: busybox -+ volumeMounts: -+ - mountPath: /tmp/env -+ name: app-env -+ - mountPath: /tmp/tls -+ name: app-tls -+ volumes: -+ - configMap: -+ name: test-infra-app-env-bh449c299k -+ name: app-env -+ - name: app-tls -+ secret: -+ secretName: test-infra-app-tls-6hkmhf2224 -diff -u -N /tmp/noop/v1_ConfigMap_app-config.yaml /tmp/transformed/v1_ConfigMap_app-config.yaml ---- /tmp/noop/v1_ConfigMap_app-config.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_ConfigMap_app-config.yaml YYYY-MM-DD HH:MM:SS -@@ -0,0 +1,15 @@ -+apiVersion: v1 -+data: -+ app-init.ini: | -+ FOO=bar -+ BAR=baz -+kind: ConfigMap -+metadata: -+ annotations: -+ note: This is a test annotation -+ creationTimestamp: null -+ labels: -+ app: mungebot -+ org: kubernetes -+ repo: test-infra -+ name: test-infra-app-config-hf5424hg8g -diff -u -N /tmp/noop/v1_ConfigMap_app-env.yaml /tmp/transformed/v1_ConfigMap_app-env.yaml ---- /tmp/noop/v1_ConfigMap_app-env.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_ConfigMap_app-env.yaml YYYY-MM-DD HH:MM:SS -@@ -0,0 +1,14 @@ -+apiVersion: v1 -+data: -+ DB_PASSWORD: somepw -+ DB_USERNAME: admin -+kind: ConfigMap -+metadata: -+ annotations: -+ note: This is a test annotation -+ creationTimestamp: null -+ labels: -+ app: mungebot -+ org: kubernetes -+ repo: test-infra -+ name: test-infra-app-env-bh449c299k -diff -u -N /tmp/noop/v1_Secret_app-tls.yaml /tmp/transformed/v1_Secret_app-tls.yaml ---- /tmp/noop/v1_Secret_app-tls.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_Secret_app-tls.yaml YYYY-MM-DD HH:MM:SS -@@ -0,0 +1,15 @@ -+apiVersion: v1 -+data: -+ tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUIwekNDQVgyZ0F3SUJBZ0lKQUkvTTdCWWp3Qit1TUEwR0NTcUdTSWIzRFFFQkJRVUFNRVV4Q3pBSkJnTlYKQkFZVEFrRlZNUk13RVFZRFZRUUlEQXBUYjIxbExWTjBZWFJsTVNFd0h3WURWUVFLREJoSmJuUmxjbTVsZENCWAphV1JuYVhSeklGQjBlU0JNZEdRd0hoY05NVEl3T1RFeU1qRTFNakF5V2hjTk1UVXdPVEV5TWpFMU1qQXlXakJGCk1Rc3dDUVlEVlFRR0V3SkJWVEVUTUJFR0ExVUVDQXdLVTI5dFpTMVRkR0YwWlRFaE1COEdBMVVFQ2d3WVNXNTAKWlhKdVpYUWdWMmxrWjJsMGN5QlFkSGtnVEhSa01Gd3dEUVlKS29aSWh2Y05BUUVCQlFBRFN3QXdTQUpCQU5MSgpoUEhoSVRxUWJQa2xHM2liQ1Z4d0dNUmZwL3Y0WHFoZmRRSGRjVmZIYXA2TlE1V29rLzR4SUErdWkzNS9NbU5hCnJ0TnVDK0JkWjF0TXVWQ1BGWmNDQXdFQUFhTlFNRTR3SFFZRFZSME9CQllFRkp2S3M4UmZKYVhUSDA4VytTR3YKelF5S24wSDhNQjhHQTFVZEl3UVlNQmFBRkp2S3M4UmZKYVhUSDA4VytTR3Z6UXlLbjBIOE1Bd0dBMVVkRXdRRgpNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFEUVFCSmxmZkpIeWJqREd4Uk1xYVJtRGhYMCs2djAyVFVLWnNXCnI1UXVWYnBRaEg2dSswVWdjVzBqcDlRd3B4b1BUTFRXR1hFV0JCQnVyeEZ3aUNCaGtRK1YKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= -+ tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlCT3dJQkFBSkJBTkxKaFBIaElUcVFiUGtsRzNpYkNWeHdHTVJmcC92NFhxaGZkUUhkY1ZmSGFwNk5RNVdvCmsvNHhJQSt1aTM1L01tTmFydE51QytCZFoxdE11VkNQRlpjQ0F3RUFBUUpBRUoyTit6c1IwWG44L1E2dHdhNEcKNk9CMU0xV08rayt6dG5YLzFTdk5lV3U4RDZHSW10dXBMVFlnalpjSHVmeWtqMDlqaUhtakh4OHU4WlpCL28xTgpNUUloQVBXK2V5Wm83YXkzbE16MVYwMVdWak5LSzlRU24xTUpsYjA2aC9MdVl2OUZBaUVBMjVXUGVkS2dWeUNXClNtVXdiUHc4Zm5UY3BxRFdFM3lUTzN2S2NlYnFNU3NDSUJGM1VtVnVlOFlVM2p5YkMzTnh1WHEzd05tMzRSOFQKeFZMSHdEWGgvNk5KQWlFQWwyb0hHR0x6NjRCdUFmaktycXd6N3FNWXI5SENMSWUvWXNvV3Evb2x6U2NDSVFEaQpEMmxXdXNvZTIvbkVxZkRWVldHV2x5Sjd5T21xYVZtL2lOVU45QjJOMmc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= -+kind: Secret -+metadata: -+ annotations: -+ note: This is a test annotation -+ creationTimestamp: null -+ labels: -+ app: mungebot -+ org: kubernetes -+ repo: test-infra -+ name: test-infra-app-tls-6hkmhf2224 -+type: kubernetes.io/tls -diff -u -N /tmp/noop/v1_Service_mungebot-service.yaml /tmp/transformed/v1_Service_mungebot-service.yaml ---- /tmp/noop/v1_Service_mungebot-service.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_Service_mungebot-service.yaml YYYY-MM-DD HH:MM:SS -@@ -3,13 +3,18 @@ - metadata: - annotations: - baseAnno: This is an base annotation -+ note: This is a test annotation - labels: - app: mungebot - foo: bar -- name: baseprefix-mungebot-service -+ org: kubernetes -+ repo: test-infra -+ name: test-infra-baseprefix-mungebot-service - spec: - ports: - - port: 7002 - selector: - app: mungebot - foo: bar -+ org: kubernetes -+ repo: test-infra diff --git a/pkg/commands/build/testdata/testcase-simple/expected.yaml b/pkg/commands/build/testdata/testcase-simple/expected.yaml deleted file mode 100644 index f36471e2e..000000000 --- a/pkg/commands/build/testdata/testcase-simple/expected.yaml +++ /dev/null @@ -1,135 +0,0 @@ -apiVersion: v1 -data: - app-init.ini: | - FOO=bar - BAR=baz -kind: ConfigMap -metadata: - annotations: - note: This is a test annotation - labels: - app: mungebot - org: kubernetes - repo: test-infra - name: test-infra-app-config-hf5424hg8g ---- -apiVersion: v1 -data: - DB_PASSWORD: somepw - DB_USERNAME: admin -kind: ConfigMap -metadata: - annotations: - note: This is a test annotation - labels: - app: mungebot - org: kubernetes - repo: test-infra - name: test-infra-app-env-bh449c299k ---- -apiVersion: v1 -data: - tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUIwekNDQVgyZ0F3SUJBZ0lKQUkvTTdCWWp3Qit1TUEwR0NTcUdTSWIzRFFFQkJRVUFNRVV4Q3pBSkJnTlYKQkFZVEFrRlZNUk13RVFZRFZRUUlEQXBUYjIxbExWTjBZWFJsTVNFd0h3WURWUVFLREJoSmJuUmxjbTVsZENCWAphV1JuYVhSeklGQjBlU0JNZEdRd0hoY05NVEl3T1RFeU1qRTFNakF5V2hjTk1UVXdPVEV5TWpFMU1qQXlXakJGCk1Rc3dDUVlEVlFRR0V3SkJWVEVUTUJFR0ExVUVDQXdLVTI5dFpTMVRkR0YwWlRFaE1COEdBMVVFQ2d3WVNXNTAKWlhKdVpYUWdWMmxrWjJsMGN5QlFkSGtnVEhSa01Gd3dEUVlKS29aSWh2Y05BUUVCQlFBRFN3QXdTQUpCQU5MSgpoUEhoSVRxUWJQa2xHM2liQ1Z4d0dNUmZwL3Y0WHFoZmRRSGRjVmZIYXA2TlE1V29rLzR4SUErdWkzNS9NbU5hCnJ0TnVDK0JkWjF0TXVWQ1BGWmNDQXdFQUFhTlFNRTR3SFFZRFZSME9CQllFRkp2S3M4UmZKYVhUSDA4VytTR3YKelF5S24wSDhNQjhHQTFVZEl3UVlNQmFBRkp2S3M4UmZKYVhUSDA4VytTR3Z6UXlLbjBIOE1Bd0dBMVVkRXdRRgpNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUZCUUFEUVFCSmxmZkpIeWJqREd4Uk1xYVJtRGhYMCs2djAyVFVLWnNXCnI1UXVWYnBRaEg2dSswVWdjVzBqcDlRd3B4b1BUTFRXR1hFV0JCQnVyeEZ3aUNCaGtRK1YKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= - tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlCT3dJQkFBSkJBTkxKaFBIaElUcVFiUGtsRzNpYkNWeHdHTVJmcC92NFhxaGZkUUhkY1ZmSGFwNk5RNVdvCmsvNHhJQSt1aTM1L01tTmFydE51QytCZFoxdE11VkNQRlpjQ0F3RUFBUUpBRUoyTit6c1IwWG44L1E2dHdhNEcKNk9CMU0xV08rayt6dG5YLzFTdk5lV3U4RDZHSW10dXBMVFlnalpjSHVmeWtqMDlqaUhtakh4OHU4WlpCL28xTgpNUUloQVBXK2V5Wm83YXkzbE16MVYwMVdWak5LSzlRU24xTUpsYjA2aC9MdVl2OUZBaUVBMjVXUGVkS2dWeUNXClNtVXdiUHc4Zm5UY3BxRFdFM3lUTzN2S2NlYnFNU3NDSUJGM1VtVnVlOFlVM2p5YkMzTnh1WHEzd05tMzRSOFQKeFZMSHdEWGgvNk5KQWlFQWwyb0hHR0x6NjRCdUFmaktycXd6N3FNWXI5SENMSWUvWXNvV3Evb2x6U2NDSVFEaQpEMmxXdXNvZTIvbkVxZkRWVldHV2x5Sjd5T21xYVZtL2lOVU45QjJOMmc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= -kind: Secret -metadata: - annotations: - note: This is a test annotation - labels: - app: mungebot - org: kubernetes - repo: test-infra - name: test-infra-app-tls-6hkmhf2224 -type: kubernetes.io/tls ---- -apiVersion: v1 -kind: Service -metadata: - annotations: - baseAnno: This is an base annotation - note: This is a test annotation - labels: - app: mungebot - foo: bar - org: kubernetes - repo: test-infra - name: test-infra-baseprefix-mungebot-service -spec: - ports: - - port: 7002 - selector: - app: mungebot - foo: bar - org: kubernetes - repo: test-infra ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - annotations: - baseAnno: This is an base annotation - note: This is a test annotation - labels: - app: mungebot - foo: bar - org: kubernetes - repo: test-infra - name: test-infra-baseprefix-mungebot -spec: - replicas: 2 - selector: - matchLabels: - app: mungebot - foo: bar - org: kubernetes - repo: test-infra - template: - metadata: - annotations: - baseAnno: This is an base annotation - note: This is a test annotation - labels: - app: mungebot - foo: bar - org: kubernetes - repo: test-infra - spec: - containers: - - env: - - name: FOO - valueFrom: - configMapKeyRef: - key: somekey - name: test-infra-app-env-bh449c299k - - name: BAR - valueFrom: - secretKeyRef: - key: somekey - name: test-infra-app-tls-6hkmhf2224 - - name: foo - value: bar - image: nginx:1.8.0 - name: nginx - ports: - - containerPort: 80 - - envFrom: - - configMapRef: - name: someConfigMap - - configMapRef: - name: test-infra-app-env-bh449c299k - - secretRef: - name: test-infra-app-tls-6hkmhf2224 - image: busybox - name: busybox - volumeMounts: - - mountPath: /tmp/env - name: app-env - - mountPath: /tmp/tls - name: app-tls - volumes: - - configMap: - name: test-infra-app-env-bh449c299k - name: app-env - - name: app-tls - secret: - secretName: test-infra-app-tls-6hkmhf2224 diff --git a/pkg/commands/build/testdata/testcase-simple/test.yaml b/pkg/commands/build/testdata/testcase-simple/test.yaml deleted file mode 100644 index 82bc2939e..000000000 --- a/pkg/commands/build/testdata/testcase-simple/test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -description: simple -args: [] -filename: ../../examplelayout/simple/instances/exampleinstance/ -expectedStdout: testdata/testcase-simple/expected.yaml -expectedDiff: testdata/testcase-simple/expected.diff diff --git a/pkg/examplelayout/simple/instances/exampleinstance/configmap/app-init.ini b/pkg/examplelayout/simple/instances/exampleinstance/configmap/app-init.ini deleted file mode 100644 index 8ebb8fcb3..000000000 --- a/pkg/examplelayout/simple/instances/exampleinstance/configmap/app-init.ini +++ /dev/null @@ -1,2 +0,0 @@ -FOO=bar -BAR=baz diff --git a/pkg/examplelayout/simple/instances/exampleinstance/configmap/app.env b/pkg/examplelayout/simple/instances/exampleinstance/configmap/app.env deleted file mode 100644 index c4032090a..000000000 --- a/pkg/examplelayout/simple/instances/exampleinstance/configmap/app.env +++ /dev/null @@ -1,2 +0,0 @@ -DB_USERNAME=admin -DB_PASSWORD=somepw diff --git a/pkg/examplelayout/simple/instances/exampleinstance/deployment/deployment.yaml b/pkg/examplelayout/simple/instances/exampleinstance/deployment/deployment.yaml deleted file mode 100644 index c6a060d55..000000000 --- a/pkg/examplelayout/simple/instances/exampleinstance/deployment/deployment.yaml +++ /dev/null @@ -1,43 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: mungebot -spec: - replicas: 2 - template: - spec: - containers: - - name: nginx - image: nginx:1.7.9 - env: - - name: FOO - valueFrom: - configMapKeyRef: - name: app-env - key: somekey - - name: BAR - valueFrom: - secretKeyRef: - name: app-tls - key: somekey - - name: busybox - image: busybox - envFrom: - - configMapRef: - name: someConfigMap - - configMapRef: - name: app-env - - secretRef: - name: app-tls - volumeMounts: - - mountPath: /tmp/env - name: app-env - - mountPath: /tmp/tls - name: app-tls - volumes: - - configMap: - name: app-env - name: app-env - - secret: - secretName: app-tls - name: app-tls diff --git a/pkg/examplelayout/simple/instances/exampleinstance/kustomization.yaml b/pkg/examplelayout/simple/instances/exampleinstance/kustomization.yaml deleted file mode 100644 index f16073490..000000000 --- a/pkg/examplelayout/simple/instances/exampleinstance/kustomization.yaml +++ /dev/null @@ -1,28 +0,0 @@ -apiVersion: v1 -kind: Kustomization -namePrefix: test-infra- -commonLabels: - app: mungebot - org: kubernetes - repo: test-infra -commonAnnotations: - note: This is a test annotation -bases: -- ../../package/ -patchesStrategicMerge: -- deployment/deployment.yaml -configMapGenerator: -- name: app-env - env: configmap/app.env -- name: app-config - files: - - configmap/app-init.ini -secretGenerator: -- name: app-tls - commands: - tls.crt: "cat secret/tls.cert" - tls.key: "cat secret/tls.key" - type: "kubernetes.io/tls" -imageTags: -- name: nginx - newTag: 1.8.0 diff --git a/pkg/examplelayout/simple/instances/exampleinstance/secret/tls.cert b/pkg/examplelayout/simple/instances/exampleinstance/secret/tls.cert deleted file mode 100644 index 039a9cadf..000000000 --- a/pkg/examplelayout/simple/instances/exampleinstance/secret/tls.cert +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIB0zCCAX2gAwIBAgIJAI/M7BYjwB+uMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQwHhcNMTIwOTEyMjE1MjAyWhcNMTUwOTEyMjE1MjAyWjBF -MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 -ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANLJ -hPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wok/4xIA+ui35/MmNa -rtNuC+BdZ1tMuVCPFZcCAwEAAaNQME4wHQYDVR0OBBYEFJvKs8RfJaXTH08W+SGv -zQyKn0H8MB8GA1UdIwQYMBaAFJvKs8RfJaXTH08W+SGvzQyKn0H8MAwGA1UdEwQF -MAMBAf8wDQYJKoZIhvcNAQEFBQADQQBJlffJHybjDGxRMqaRmDhX0+6v02TUKZsW -r5QuVbpQhH6u+0UgcW0jp9QwpxoPTLTWGXEWBBBurxFwiCBhkQ+V ------END CERTIFICATE----- diff --git a/pkg/examplelayout/simple/instances/exampleinstance/secret/tls.key b/pkg/examplelayout/simple/instances/exampleinstance/secret/tls.key deleted file mode 100644 index a748bb8ae..000000000 --- a/pkg/examplelayout/simple/instances/exampleinstance/secret/tls.key +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo -k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G -6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N -MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW -SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T -xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi -D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g== ------END RSA PRIVATE KEY----- diff --git a/pkg/examplelayout/simple/package/Kube-descriptor.yaml b/pkg/examplelayout/simple/package/Kube-descriptor.yaml deleted file mode 100644 index a26036374..000000000 --- a/pkg/examplelayout/simple/package/Kube-descriptor.yaml +++ /dev/null @@ -1,14 +0,0 @@ -# This example is from https://docs.google.com/document/d/1cLPGweVEYrVqQvBLJg6sxV-TrE5Rm2MNOBA_cxZP2WU/edit#heading=h.dr88tktf0e99 - -# Inspired by https://github.com/kubernetes/helm/blob/master/docs/charts.md -# But Kubernetes API style -apiVersion: manifest.k8s.io/v1alpha1 -kind: Descriptor -metadata: - name: mungebot -description: Mungegithub package -# These are search keywords -keywords: [github, bot, kubernetes] -home: https://github.com/bgrant0607/mungebot-pkg/blob/master/README.md -sources: https://github.com/bgrant0607/mungebot-pkg -icon: https://github.com/bgrant0607/mungebot-pkg/blob/master/icon.png diff --git a/pkg/examplelayout/simple/package/deployment/deployment.yaml b/pkg/examplelayout/simple/package/deployment/deployment.yaml deleted file mode 100644 index 9582b0056..000000000 --- a/pkg/examplelayout/simple/package/deployment/deployment.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: mungebot - labels: - app: mungebot -spec: - replicas: 1 - template: - metadata: - labels: - app: mungebot - spec: - containers: - - name: nginx - image: nginx - env: - - name: foo - value: bar - ports: - - containerPort: 80 diff --git a/pkg/examplelayout/simple/package/kustomization.yaml b/pkg/examplelayout/simple/package/kustomization.yaml deleted file mode 100644 index 82bc52e23..000000000 --- a/pkg/examplelayout/simple/package/kustomization.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v1 -kind: Kustomization -namePrefix: baseprefix- -commonLabels: - foo: bar -commonAnnotations: - baseAnno: This is an base annotation -resources: -- deployment/deployment.yaml -- service/service.yaml diff --git a/pkg/examplelayout/simple/package/service/service.yaml b/pkg/examplelayout/simple/package/service/service.yaml deleted file mode 100644 index e8fb0c806..000000000 --- a/pkg/examplelayout/simple/package/service/service.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: mungebot-service - labels: - app: mungebot -spec: - ports: - - port: 7002 - selector: - app: mungebot diff --git a/pkg/target/bigger_test.go b/pkg/target/bigger_test.go new file mode 100644 index 000000000..728b21c7d --- /dev/null +++ b/pkg/target/bigger_test.go @@ -0,0 +1,230 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "testing" + + "sigs.k8s.io/kustomize/pkg/internal/loadertest" +) + +// TODO(monopole): Add a feature test example covering secret generation. + +// WARNING: These tests use a fake file system, and any attempt to use a +// feature that spawns shells will fail, because said shells expect a working +// directory corresponding to a real directory on disk - see +// these lines in secretfactory.go: +// cmd := exec.CommandContext(ctx, commands[0], commands[1:]...) +// cmd.Dir = f.wd +// Worse, the fake directory might match a real directory on the your system, +// making the failure less obvious (and maybe hurting something if your secret +// generation technique writes data to disk). So no use of secret generation +// in these particular tests. +// To eventually fix this, we could write the data to a real filesystem, and +// clean up after, or use some other trick compatible with exec. + +func writeBase(t *testing.T, ldr loadertest.FakeLoader) { + writeK(t, ldr, "/app/base", ` +namePrefix: baseprefix- +commonLabels: + foo: bar +commonAnnotations: + baseAnno: This is a base annotation +resources: +- deployment/deployment.yaml +- service/service.yaml +`) + writeF(t, ldr, "/app/base/service/service.yaml", ` +apiVersion: v1 +kind: Service +metadata: + name: mungebot-service + labels: + app: mungebot +spec: + ports: + - port: 7002 + selector: + app: mungebot +`) + writeF(t, ldr, "/app/base/deployment/deployment.yaml", ` +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: mungebot + labels: + app: mungebot +spec: + replicas: 1 + template: + metadata: + labels: + app: mungebot + spec: + containers: + - name: nginx + image: nginx + env: + - name: foo + value: bar + ports: + - containerPort: 80 +`) + +} + +func TestBigBase(t *testing.T) { + ldr := loadertest.NewFakeLoader("/app/base") + writeBase(t, ldr) + m, err := makeKustTarget(t, ldr).MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + if m == nil { + t.Fatalf("Empty map.") + } + s, err := m.EncodeAsYaml() + if err != nil { + t.Fatalf("Err: %v", err) + } + expected := `apiVersion: v1 +kind: Service +metadata: + annotations: + baseAnno: This is a base annotation + labels: + app: mungebot + foo: bar + name: baseprefix-mungebot-service +spec: + ports: + - port: 7002 + selector: + app: mungebot + foo: bar +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + annotations: + baseAnno: This is a base annotation + labels: + app: mungebot + foo: bar + name: baseprefix-mungebot +spec: + replicas: 1 + selector: + matchLabels: + foo: bar + template: + metadata: + annotations: + baseAnno: This is a base annotation + labels: + app: mungebot + foo: bar + spec: + containers: + - env: + - name: foo + value: bar + image: nginx + name: nginx + ports: + - containerPort: 80 +` + if string(s) != expected { + t.Fatalf("Actual results:\n%s\nnot equal to expected:\n%s\n", + s, expected) + } +} + +func TestBigOverlay(t *testing.T) { + ldr := loadertest.NewFakeLoader("/app/overlay") + writeBase(t, ldr) + writeK(t, ldr, "/app/overlay", ` +namePrefix: test-infra- +commonLabels: + app: mungebot + org: kubernetes + repo: test-infra +commonAnnotations: + note: This is a test annotation +bases: +- ../base +patchesStrategicMerge: +- deployment/deployment.yaml +configMapGenerator: +- name: app-env + env: configmap/app.env +- name: app-config + files: + - configmap/app-init.ini +imageTags: +- name: nginx + newTag: 1.8.0`) + + writeF(t, ldr, "/app/overlay/configmap/app.env", ` +DB_USERNAME=admin +DB_PASSWORD=somepw +`) + writeF(t, ldr, "/app/overlay/configmap/app-init.ini", ` +FOO=bar +BAR=baz +`) + writeF(t, ldr, "/app/overlay/deployment/deployment.yaml", ` +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: mungebot +spec: + replicas: 2 + template: + spec: + containers: + - name: nginx + image: nginx:1.7.9 + env: + - name: FOO + valueFrom: + configMapKeyRef: + name: app-env + key: somekey + - name: busybox + image: busybox + envFrom: + - configMapRef: + name: someConfigMap + - configMapRef: + name: app-env + volumeMounts: + - mountPath: /tmp/env + name: app-env + volumes: + - configMap: + name: app-env + name: app-env +`) + m, err := makeKustTarget(t, ldr).MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + if m == nil { + t.Fatalf("Empty map.") + } +} diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index 3442ec15f..b8deb6075 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -98,6 +98,13 @@ var rf = resmap.NewFactory(resource.NewFactory( kunstruct.NewKunstructuredFactoryImpl())) func makeKustTarget(t *testing.T, l ifc.Loader) *KustTarget { + // Warning: the following filesystem - a fake - must be rooted at /. + // This fs root is used as the working directory for the shell spawned by + // the secretgenerator, and has nothing to do with the filesystem used + // to load relative paths from the fake filesystem. + // This trick only works for secret generator commands that don't actually + // try to read the file system, because these tests don't write to the + // real "/" directory. See use of exec package in the secretfactory. fakeFs := fs.MakeFakeFS() fakeFs.Mkdir("/") kt, err := NewKustTarget( @@ -245,7 +252,7 @@ func TestResourceNotFound(t *testing.T) { if err == nil { t.Fatalf("Didn't get the expected error for an unknown resource") } - if !strings.Contains(err.Error(), `cannot read file "/testpath/deployment.yaml"`) { + if !strings.Contains(err.Error(), `cannot read file`) { t.Fatalf("unexpected error: %q", err) } } @@ -304,31 +311,34 @@ func TestDisableNameSuffixHash(t *testing.T) { } } -func write(t *testing.T, ldr loadertest.FakeLoader, dir string, content string) { - err := ldr.AddFile( - filepath.Join(dir, constants.KustomizationFileName), - []byte(` +func writeF(t *testing.T, ldr loadertest.FakeLoader, dir string, content string) { + err := ldr.AddFile(dir, []byte(content)) + if err != nil { + t.Fatalf("failed write to %s; %v", dir, err) + } +} + +func writeK( + t *testing.T, ldr loadertest.FakeLoader, dir string, content string) { + writeF(t, ldr, filepath.Join(dir, constants.KustomizationFileName), ` apiVersion: v1 kind: Kustomization -`+content)) - if err != nil { - t.Fatalf("Failed to setup fake loader.") - } +`+content) } func TestIssue596AllowDirectoriesThatAreSubstringsOfEachOther(t *testing.T) { ldr := loadertest.NewFakeLoader( "/app/overlays/aws-sandbox2.us-east-1") - write(t, ldr, "/app/base", "") - write(t, ldr, "/app/overlays/aws", ` + writeK(t, ldr, "/app/base", "") + writeK(t, ldr, "/app/overlays/aws", ` bases: - ../../base `) - write(t, ldr, "/app/overlays/aws-nonprod", ` + writeK(t, ldr, "/app/overlays/aws-nonprod", ` bases: - ../aws `) - write(t, ldr, "/app/overlays/aws-sandbox2.us-east-1", ` + writeK(t, ldr, "/app/overlays/aws-sandbox2.us-east-1", ` bases: - ../aws-nonprod `) From ecb83c6ae14f26391b8341471b81282a0156246a Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Fri, 14 Dec 2018 14:30:59 -0800 Subject: [PATCH 020/317] Add KustTarget.getAllVars Test --- pkg/target/kusttarget_test.go | 170 ++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index b8deb6075..c5601d5c2 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -350,3 +350,173 @@ bases: t.Fatalf("Empty map.") } } + +var someVars = []types.Var{ + { + Name: "AWARD", + ObjRef: types.Target{ + APIVersion: "v7", + Gvk: gvk.Gvk{Kind: "Service"}, + Name: "nobelPrize"}, + FieldRef: types.FieldSelector{FieldPath: "some.arbitrary.path"}, + }, + { + Name: "BIRD", + ObjRef: types.Target{ + APIVersion: "v300", + Gvk: gvk.Gvk{Kind: "Service"}, + Name: "heron"}, + FieldRef: types.FieldSelector{FieldPath: "metadata.name"}, + }, + { + Name: "FRUIT", + ObjRef: types.Target{ + Gvk: gvk.Gvk{Kind: "Service"}, + Name: "apple"}, + FieldRef: types.FieldSelector{FieldPath: "metadata.name"}, + }, + { + Name: "VEGETABLE", + ObjRef: types.Target{ + Gvk: gvk.Gvk{Kind: "Leafy"}, + Name: "kale"}, + FieldRef: types.FieldSelector{FieldPath: "metadata.name"}, + }, +} + +func TestGetAllVarsSimple(t *testing.T) { + ldr := loadertest.NewFakeLoader( + "/app") + write(t, ldr, "/app", ` +vars: + - name: AWARD + objref: + kind: Service + name: nobelPrize + apiVersion: v7 + fieldref: + fieldpath: some.arbitrary.path + - name: BIRD + objref: + kind: Service + name: heron + apiVersion: v300 +`) + vars, err := makeKustTarget(t, ldr).getAllVars() + if err != nil { + t.Fatalf("Err: %v", err) + } + if len(vars) != 2 { + t.Fatalf("unexpected size %d", len(vars)) + } + for i, v := range someVars[:2] { + if !reflect.DeepEqual(vars[i], v) { + t.Fatalf("unexpected var[%d]:\n %v\n %v", i, vars[i], v) + } + } +} + +func TestGetAllVarsNested(t *testing.T) { + ldr := loadertest.NewFakeLoader( + "/app/overlays/o2") + write(t, ldr, "/app/base", ` +vars: + - name: AWARD + objref: + kind: Service + name: nobelPrize + apiVersion: v7 + fieldref: + fieldpath: some.arbitrary.path + - name: BIRD + objref: + kind: Service + name: heron + apiVersion: v300 +`) + write(t, ldr, "/app/overlays/o1", ` +vars: + - name: FRUIT + objref: + kind: Service + name: apple +bases: +- ../../base +`) + write(t, ldr, "/app/overlays/o2", ` +vars: + - name: VEGETABLE + objref: + kind: Leafy + name: kale +bases: +- ../o1 +`) + vars, err := makeKustTarget(t, ldr).getAllVars() + if err != nil { + t.Fatalf("Err: %v", err) + } + if len(vars) != 4 { + t.Fatalf("unexpected size %d", len(vars)) + } + for i, v := range someVars { + if !reflect.DeepEqual(vars[i], v) { + t.Fatalf("unexpected var[%d]:\n %v\n %v", i, vars[i], v) + } + } +} + +// TODO(monopole): Fix #634 +func TestGetAllVarsCollisionsOkay_ReproIssue634(t *testing.T) { + ldr := loadertest.NewFakeLoader( + "/app/overlays/o2") + write(t, ldr, "/app/base", ` +vars: + - name: AWARD + objref: + kind: Service + name: nobelPrize + apiVersion: v7 + fieldref: + fieldpath: some.arbitrary.path + - name: BIRD + objref: + kind: Service + name: heron + apiVersion: v300 +`) + write(t, ldr, "/app/overlays/o1", ` +vars: + - name: AWARD + objref: + kind: Service + name: academy +bases: +- ../../base +`) + write(t, ldr, "/app/overlays/o2", ` +vars: + - name: VEGETABLE + objref: + kind: Leafy + name: kale +bases: +- ../o1 +`) + vars, err := makeKustTarget(t, ldr).getAllVars() + if err != nil { + t.Fatalf("Err: %v", err) + } + if len(vars) != 4 { + t.Fatalf("unexpected size %d", len(vars)) + } + v2 := someVars[2] + v2.Name = "AWARD" + v2.ObjRef.Name = "academy" + expected := []types.Var{someVars[0], someVars[1], v2, someVars[3]} + for i, v := range expected { + if !reflect.DeepEqual(vars[i], v) { + t.Fatalf("unexpected var[%d]:\n %v\n %v", i, vars[i], v) + } + } +} From 0665371590e44692739562a26528bd7864b9c207 Mon Sep 17 00:00:00 2001 From: jregan Date: Sat, 15 Dec 2018 17:35:46 -0800 Subject: [PATCH 021/317] Forbid Var name collisions in a kustomization stack --- pkg/target/kusttarget.go | 111 ++++++++++++++++++++-------------- pkg/target/kusttarget_test.go | 58 +++++++++--------- 2 files changed, 95 insertions(+), 74 deletions(-) diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 6801d3ab1..ed61910b2 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -124,22 +124,17 @@ func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) { return nil, err } } - // Given that names have changed (prefixs/suffixes added), // fix all the back references to those names. - err = transformers.NewNameReferenceTransformer( - kt.tConfig.NameReference).Transform(m) - if err != nil { - return nil, err + if kt.tConfig.NameReference != nil { + err = transformers.NewNameReferenceTransformer( + kt.tConfig.NameReference).Transform(m) + if err != nil { + return nil, err + } } - // With all the back references fixed, it's OK to resolve Vars. - refVars, err := kt.resolveVars(m) - if err != nil { - return nil, err - } - err = transformers.NewRefVarTransformer( - refVars, kt.tConfig.VarReference).Transform(m) + err = kt.doVarReplacement(m) return m, err } @@ -148,6 +143,19 @@ func (kt *KustTarget) shouldAddHashSuffixesToGeneratedResources() bool { !kt.kustomization.GeneratorOptions.DisableNameSuffixHash } +func (kt *KustTarget) doVarReplacement(m resmap.ResMap) error { + vars, err := kt.getAllVars() + if err != nil { + return err + } + varMap, err := kt.resolveVars(m, vars) + if err != nil { + return err + } + return transformers.NewRefVarTransformer( + varMap, kt.tConfig.VarReference).Transform(m) +} + // loadCustomizedResMap loads and customizes resources to build a ResMap. func (kt *KustTarget) loadCustomizedResMap() (resmap.ResMap, error) { errs := &interror.KustomizationErrors{} @@ -235,7 +243,8 @@ func (kt *KustTarget) loadResMapFromBasesAndResources() (resmap.ResMap, error) { // Loop through the Bases of this kustomization recursively loading resources. // Combine into one ResMap, demanding unique Ids for each resource. -func (kt *KustTarget) loadCustomizedBases() (resmap.ResMap, *interror.KustomizationErrors) { +func (kt *KustTarget) loadCustomizedBases() ( + resmap.ResMap, *interror.KustomizationErrors) { var list []resmap.ResMap errs := &interror.KustomizationErrors{} for _, path := range kt.kustomization.Bases { @@ -268,24 +277,18 @@ func (kt *KustTarget) loadCustomizedBases() (resmap.ResMap, *interror.Kustomizat func (kt *KustTarget) loadBasesAsKustTargets() ([]*KustTarget, error) { var result []*KustTarget - errs := &interror.KustomizationErrors{} for _, path := range kt.kustomization.Bases { ldr, err := kt.ldr.New(path) if err != nil { - errs.Append(err) - continue + return nil, err } target, err := NewKustTarget( ldr, kt.fSys, kt.rFactory, kt.tFactory) if err != nil { - errs.Append(err) - continue + return nil, err } result = append(result, target) } - if len(errs.Get()) > 0 { - return nil, errs - } return result, nil } @@ -328,12 +331,9 @@ func (kt *KustTarget) newTransformer( // resolveVars returns a map of Var names to their final values. // The values are strings intended for substitution wherever // the $(var.Name) occurs. -func (kt *KustTarget) resolveVars(m resmap.ResMap) (map[string]string, error) { +func (kt *KustTarget) resolveVars( + m resmap.ResMap, vars map[string]types.Var) (map[string]string, error) { result := map[string]string{} - vars, err := kt.getAllVars() - if err != nil { - return result, err - } for _, v := range vars { id := resid.NewResId(v.ObjRef.GVK(), v.ObjRef.Name) if r, found := m.DemandOneMatchForId(id); found { @@ -349,32 +349,53 @@ func (kt *KustTarget) resolveVars(m resmap.ResMap) (map[string]string, error) { return result, nil } -// getAllVars returns all the "environment" style Var instances defined in the app. -func (kt *KustTarget) getAllVars() ([]types.Var, error) { - var result []types.Var - errs := &interror.KustomizationErrors{} +type ErrVarCollision struct { + name string + path string +} - bases, err := kt.loadBasesAsKustTargets() +func (e ErrVarCollision) Error() string { + return fmt.Sprintf( + "var %s in %s defined in some other kustomization", + e.name, e.path) +} + +// getAllVars returns a map of Var names to Var instances, pulled from +// this kustomization and the kustomizations it depends on. +// An error is returned on Var name collision. +func (kt *KustTarget) getAllVars() (map[string]types.Var, error) { + result, err := kt.getVarsFromBases() if err != nil { return nil, err } - - // TODO: computing vars and resources for bases can be combined - for _, b := range bases { - vars, err := b.getAllVars() - if err != nil { - errs.Append(err) - continue - } - b.ldr.Cleanup() - result = append(result, vars...) - } for _, v := range kt.kustomization.Vars { v.Defaulting() - result = append(result, v) + if _, oops := result[v.Name]; oops { + return nil, ErrVarCollision{v.Name, kt.ldr.Root()} + } + result[v.Name] = v } - if len(errs.Get()) > 0 { - return nil, errs + return result, nil +} + +func (kt *KustTarget) getVarsFromBases() (map[string]types.Var, error) { + targets, err := kt.loadBasesAsKustTargets() + if err != nil { + return nil, err + } + result := make(map[string]types.Var) + for _, subKt := range targets { + vars, err := subKt.getAllVars() + if err != nil { + return nil, err + } + subKt.ldr.Cleanup() + for k, v := range vars { + if _, oops := result[k]; oops { + return nil, ErrVarCollision{v.Name, subKt.ldr.Root()} + } + result[k] = v + } } return result, nil } diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index c5601d5c2..e121b4094 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -20,6 +20,7 @@ import ( "encoding/base64" "path/filepath" "reflect" + "sort" "strings" "testing" @@ -351,6 +352,7 @@ bases: } } +// To simplify tests, these vars specified in alphabetical order. var someVars = []types.Var{ { Name: "AWARD", @@ -387,7 +389,7 @@ var someVars = []types.Var{ func TestGetAllVarsSimple(t *testing.T) { ldr := loadertest.NewFakeLoader( "/app") - write(t, ldr, "/app", ` + writeK(t, ldr, "/app", ` vars: - name: AWARD objref: @@ -409,17 +411,25 @@ vars: if len(vars) != 2 { t.Fatalf("unexpected size %d", len(vars)) } - for i, v := range someVars[:2] { - if !reflect.DeepEqual(vars[i], v) { - t.Fatalf("unexpected var[%d]:\n %v\n %v", i, vars[i], v) + for i, k := range sortedKeys(vars)[:2] { + if !reflect.DeepEqual(vars[k], someVars[i]) { + t.Fatalf("unexpected var[%d]:\n %v\n %v", i, vars[k], someVars[i]) } } } +func sortedKeys(m map[string]types.Var) (result []string) { + for k := range m { + result = append(result, k) + } + sort.Strings(result) + return +} + func TestGetAllVarsNested(t *testing.T) { ldr := loadertest.NewFakeLoader( "/app/overlays/o2") - write(t, ldr, "/app/base", ` + writeK(t, ldr, "/app/base", ` vars: - name: AWARD objref: @@ -434,7 +444,7 @@ vars: name: heron apiVersion: v300 `) - write(t, ldr, "/app/overlays/o1", ` + writeK(t, ldr, "/app/overlays/o1", ` vars: - name: FRUIT objref: @@ -443,7 +453,7 @@ vars: bases: - ../../base `) - write(t, ldr, "/app/overlays/o2", ` + writeK(t, ldr, "/app/overlays/o2", ` vars: - name: VEGETABLE objref: @@ -459,18 +469,17 @@ bases: if len(vars) != 4 { t.Fatalf("unexpected size %d", len(vars)) } - for i, v := range someVars { - if !reflect.DeepEqual(vars[i], v) { - t.Fatalf("unexpected var[%d]:\n %v\n %v", i, vars[i], v) + for i, k := range sortedKeys(vars) { + if !reflect.DeepEqual(vars[k], someVars[i]) { + t.Fatalf("unexpected var[%d]:\n %v\n %v", i, vars[k], someVars[i]) } } } -// TODO(monopole): Fix #634 -func TestGetAllVarsCollisionsOkay_ReproIssue634(t *testing.T) { +func TestVarCollisionsForbidden(t *testing.T) { ldr := loadertest.NewFakeLoader( "/app/overlays/o2") - write(t, ldr, "/app/base", ` + writeK(t, ldr, "/app/base", ` vars: - name: AWARD objref: @@ -485,7 +494,7 @@ vars: name: heron apiVersion: v300 `) - write(t, ldr, "/app/overlays/o1", ` + writeK(t, ldr, "/app/overlays/o1", ` vars: - name: AWARD objref: @@ -494,7 +503,7 @@ vars: bases: - ../../base `) - write(t, ldr, "/app/overlays/o2", ` + writeK(t, ldr, "/app/overlays/o2", ` vars: - name: VEGETABLE objref: @@ -503,20 +512,11 @@ vars: bases: - ../o1 `) - vars, err := makeKustTarget(t, ldr).getAllVars() - if err != nil { - t.Fatalf("Err: %v", err) + _, err := makeKustTarget(t, ldr).getAllVars() + if err == nil { + t.Fatalf("expected var collision") } - if len(vars) != 4 { - t.Fatalf("unexpected size %d", len(vars)) - } - v2 := someVars[2] - v2.Name = "AWARD" - v2.ObjRef.Name = "academy" - expected := []types.Var{someVars[0], someVars[1], v2, someVars[3]} - for i, v := range expected { - if !reflect.DeepEqual(vars[i], v) { - t.Fatalf("unexpected var[%d]:\n %v\n %v", i, vars[i], v) - } + if _, ok := err.(ErrVarCollision); !ok { + t.Fatalf("unexpected error: %v", err) } } From 47a04f2648173b42c8c5296e24389c16ccd682fb Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Tue, 18 Dec 2018 09:50:08 -0800 Subject: [PATCH 022/317] More fully in-memory integration tests. --- .../base/kustomization.yaml | 7 - .../base/rolebinding.yaml | 11 -- .../base/serviceaccount.yaml | 4 - .../combined/kustomization.yaml | 5 - .../overlays/a/kustomization.yaml | 10 -- .../overlays/a/serviceaccount.yaml | 4 - .../overlays/b/kustomization.yaml | 7 - .../testcase-multibases-conflict/test.yaml | 4 - .../base/kustomization.yaml | 7 - .../base/rolebinding.yaml | 11 -- .../base/serviceaccount.yaml | 4 - .../combined/kustomization.yaml | 5 - .../expected.yaml | 33 ---- .../overlays/a/kustomization.yaml | 7 - .../overlays/b/kustomization.yaml | 7 - .../testcase-multibases-nonconflict/test.yaml | 4 - ...r_test.go => baseandoverlaymedium_test.go} | 124 ++++++++++++-- pkg/target/kusttarget_test.go | 97 +++-------- pkg/target/resourceconflict_test.go | 153 ++++++++++++++++++ pkg/target/utils_for_test.go | 131 +++++++++++++++ 20 files changed, 422 insertions(+), 213 deletions(-) delete mode 100644 pkg/commands/build/testdata/testcase-multibases-conflict/base/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-conflict/base/rolebinding.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-conflict/base/serviceaccount.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-conflict/combined/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-conflict/overlays/a/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-conflict/overlays/a/serviceaccount.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-conflict/overlays/b/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-conflict/test.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-nonconflict/base/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-nonconflict/base/rolebinding.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-nonconflict/base/serviceaccount.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-nonconflict/combined/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-nonconflict/expected.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/a/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/b/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multibases-nonconflict/test.yaml rename pkg/target/{bigger_test.go => baseandoverlaymedium_test.go} (67%) create mode 100644 pkg/target/resourceconflict_test.go create mode 100644 pkg/target/utils_for_test.go diff --git a/pkg/commands/build/testdata/testcase-multibases-conflict/base/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-conflict/base/kustomization.yaml deleted file mode 100644 index c2659b3ba..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-conflict/base/kustomization.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: Kustomization -resources: -- serviceaccount.yaml -- rolebinding.yaml -namePrefix: base- -nameSuffix: -suffix diff --git a/pkg/commands/build/testdata/testcase-multibases-conflict/base/rolebinding.yaml b/pkg/commands/build/testdata/testcase-multibases-conflict/base/rolebinding.yaml deleted file mode 100644 index c74e189ce..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-conflict/base/rolebinding.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: RoleBinding -metadata: - name: rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: role -subjects: -- kind: ServiceAccount - name: serviceaccount diff --git a/pkg/commands/build/testdata/testcase-multibases-conflict/base/serviceaccount.yaml b/pkg/commands/build/testdata/testcase-multibases-conflict/base/serviceaccount.yaml deleted file mode 100644 index f1fff56b2..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-conflict/base/serviceaccount.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: serviceaccount diff --git a/pkg/commands/build/testdata/testcase-multibases-conflict/combined/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-conflict/combined/kustomization.yaml deleted file mode 100644 index baab2a316..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-conflict/combined/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -kind: Kustomization -bases: -- ../overlays/a -- ../overlays/b diff --git a/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/a/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/a/kustomization.yaml deleted file mode 100644 index 30ea303c2..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/a/kustomization.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v1 -kind: Kustomization -bases: -- ../../base/ - -namePrefix: a- -nameSuffix: -suffixA - -resources: -- serviceaccount.yaml diff --git a/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/a/serviceaccount.yaml b/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/a/serviceaccount.yaml deleted file mode 100644 index f1fff56b2..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/a/serviceaccount.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: serviceaccount diff --git a/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/b/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/b/kustomization.yaml deleted file mode 100644 index fe87bd2fa..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-conflict/overlays/b/kustomization.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: Kustomization -bases: -- ../../base/ - -namePrefix: b- -nameSuffix: -suffixB diff --git a/pkg/commands/build/testdata/testcase-multibases-conflict/test.yaml b/pkg/commands/build/testdata/testcase-multibases-conflict/test.yaml deleted file mode 100644 index 334c5f957..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-conflict/test.yaml +++ /dev/null @@ -1,4 +0,0 @@ -description: multibases with name reference -args: [] -filename: testdata/testcase-multibases-conflict/combined -expectedError: Multiple matches for name ~G_v1_ServiceAccount diff --git a/pkg/commands/build/testdata/testcase-multibases-nonconflict/base/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-nonconflict/base/kustomization.yaml deleted file mode 100644 index c2659b3ba..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-nonconflict/base/kustomization.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: Kustomization -resources: -- serviceaccount.yaml -- rolebinding.yaml -namePrefix: base- -nameSuffix: -suffix diff --git a/pkg/commands/build/testdata/testcase-multibases-nonconflict/base/rolebinding.yaml b/pkg/commands/build/testdata/testcase-multibases-nonconflict/base/rolebinding.yaml deleted file mode 100644 index c74e189ce..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-nonconflict/base/rolebinding.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: RoleBinding -metadata: - name: rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: role -subjects: -- kind: ServiceAccount - name: serviceaccount diff --git a/pkg/commands/build/testdata/testcase-multibases-nonconflict/base/serviceaccount.yaml b/pkg/commands/build/testdata/testcase-multibases-nonconflict/base/serviceaccount.yaml deleted file mode 100644 index f1fff56b2..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-nonconflict/base/serviceaccount.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: serviceaccount diff --git a/pkg/commands/build/testdata/testcase-multibases-nonconflict/combined/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-nonconflict/combined/kustomization.yaml deleted file mode 100644 index baab2a316..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-nonconflict/combined/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -kind: Kustomization -bases: -- ../overlays/a -- ../overlays/b diff --git a/pkg/commands/build/testdata/testcase-multibases-nonconflict/expected.yaml b/pkg/commands/build/testdata/testcase-multibases-nonconflict/expected.yaml deleted file mode 100644 index f1df1b22c..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-nonconflict/expected.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: a-base-serviceaccount-suffix-suffixA ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: b-base-serviceaccount-suffix-suffixB ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: RoleBinding -metadata: - name: a-base-rolebinding-suffix-suffixA -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: role -subjects: -- kind: ServiceAccount - name: a-base-serviceaccount-suffix-suffixA ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: RoleBinding -metadata: - name: b-base-rolebinding-suffix-suffixB -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: role -subjects: -- kind: ServiceAccount - name: b-base-serviceaccount-suffix-suffixB diff --git a/pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/a/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/a/kustomization.yaml deleted file mode 100644 index 29909bf3f..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/a/kustomization.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: Kustomization -bases: -- ../../base/ - -namePrefix: a- -nameSuffix: -suffixA diff --git a/pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/b/kustomization.yaml b/pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/b/kustomization.yaml deleted file mode 100644 index fe87bd2fa..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-nonconflict/overlays/b/kustomization.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: Kustomization -bases: -- ../../base/ - -namePrefix: b- -nameSuffix: -suffixB diff --git a/pkg/commands/build/testdata/testcase-multibases-nonconflict/test.yaml b/pkg/commands/build/testdata/testcase-multibases-nonconflict/test.yaml deleted file mode 100644 index cbbcc93ba..000000000 --- a/pkg/commands/build/testdata/testcase-multibases-nonconflict/test.yaml +++ /dev/null @@ -1,4 +0,0 @@ -description: multibases with name reference -args: [] -filename: testdata/testcase-multibases-nonconflict/combined -expectedStdout: testdata/testcase-multibases-nonconflict/expected.yaml diff --git a/pkg/target/bigger_test.go b/pkg/target/baseandoverlaymedium_test.go similarity index 67% rename from pkg/target/bigger_test.go rename to pkg/target/baseandoverlaymedium_test.go index 728b21c7d..8469a2f53 100644 --- a/pkg/target/bigger_test.go +++ b/pkg/target/baseandoverlaymedium_test.go @@ -84,7 +84,6 @@ spec: ports: - containerPort: 80 `) - } func TestBigBase(t *testing.T) { @@ -101,7 +100,7 @@ func TestBigBase(t *testing.T) { if err != nil { t.Fatalf("Err: %v", err) } - expected := `apiVersion: v1 + assertExpectedEqualsActual(t, s, `apiVersion: v1 kind: Service metadata: annotations: @@ -147,11 +146,7 @@ spec: name: nginx ports: - containerPort: 80 -` - if string(s) != expected { - t.Fatalf("Actual results:\n%s\nnot equal to expected:\n%s\n", - s, expected) - } +`) } func TestBigOverlay(t *testing.T) { @@ -224,7 +219,118 @@ spec: if err != nil { t.Fatalf("Err: %v", err) } - if m == nil { - t.Fatalf("Empty map.") + s, err := m.EncodeAsYaml() + if err != nil { + t.Fatalf("Unexpected err: %v", err) } + assertExpectedEqualsActual(t, s, `apiVersion: v1 +data: + app-init.ini: |2 + + FOO=bar + BAR=baz +kind: ConfigMap +metadata: + annotations: + note: This is a test annotation + labels: + app: mungebot + org: kubernetes + repo: test-infra + name: test-infra-app-config-fd62mfc87h +--- +apiVersion: v1 +data: + DB_PASSWORD: somepw + DB_USERNAME: admin +kind: ConfigMap +metadata: + annotations: + note: This is a test annotation + labels: + app: mungebot + org: kubernetes + repo: test-infra + name: test-infra-app-env-bh449c299k +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + baseAnno: This is a base annotation + note: This is a test annotation + labels: + app: mungebot + foo: bar + org: kubernetes + repo: test-infra + name: test-infra-baseprefix-mungebot-service +spec: + ports: + - port: 7002 + selector: + app: mungebot + foo: bar + org: kubernetes + repo: test-infra +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + annotations: + baseAnno: This is a base annotation + note: This is a test annotation + labels: + app: mungebot + foo: bar + org: kubernetes + repo: test-infra + name: test-infra-baseprefix-mungebot +spec: + replicas: 2 + selector: + matchLabels: + app: mungebot + foo: bar + org: kubernetes + repo: test-infra + template: + metadata: + annotations: + baseAnno: This is a base annotation + note: This is a test annotation + labels: + app: mungebot + foo: bar + org: kubernetes + repo: test-infra + spec: + containers: + - env: + - name: FOO + valueFrom: + configMapKeyRef: + key: somekey + name: test-infra-app-env-bh449c299k + - name: foo + value: bar + image: nginx:1.8.0 + name: nginx + ports: + - containerPort: 80 + - envFrom: + - configMapRef: + name: someConfigMap + - configMapRef: + name: test-infra-app-env-bh449c299k + image: busybox + name: busybox + volumeMounts: + - mountPath: /tmp/env + name: app-env + volumes: + - configMap: + name: test-infra-app-env-bh449c299k + name: app-env +`) } diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index e121b4094..c80c60815 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -18,16 +18,12 @@ package target import ( "encoding/base64" - "path/filepath" "reflect" "sort" "strings" "testing" "sigs.k8s.io/kustomize/k8sdeps/kunstruct" - "sigs.k8s.io/kustomize/k8sdeps/transformer" - "sigs.k8s.io/kustomize/pkg/constants" - "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/internal/loadertest" @@ -98,53 +94,24 @@ metadata: var rf = resmap.NewFactory(resource.NewFactory( kunstruct.NewKunstructuredFactoryImpl())) -func makeKustTarget(t *testing.T, l ifc.Loader) *KustTarget { - // Warning: the following filesystem - a fake - must be rooted at /. - // This fs root is used as the working directory for the shell spawned by - // the secretgenerator, and has nothing to do with the filesystem used - // to load relative paths from the fake filesystem. - // This trick only works for secret generator commands that don't actually - // try to read the file system, because these tests don't write to the - // real "/" directory. See use of exec package in the secretfactory. - fakeFs := fs.MakeFakeFS() - fakeFs.Mkdir("/") - kt, err := NewKustTarget( - l, fakeFs, rf, transformer.NewFactoryImpl()) - if err != nil { - t.Fatalf("Unexpected construction error %v", err) - } - return kt -} - -func makeLoader1(t *testing.T) ifc.Loader { - ldr := loadertest.NewFakeLoader("/testpath") - err := ldr.AddFile("/testpath/"+constants.KustomizationFileName, []byte(kustomizationContent1)) - if err != nil { - t.Fatalf("Failed to setup fake ldr.") - } - err = ldr.AddFile("/testpath/deployment.yaml", []byte(deploymentContent)) - if err != nil { - t.Fatalf("Failed to setup fake ldr.") - } - err = ldr.AddFile("/testpath/namespace.yaml", []byte(namespaceContent)) - if err != nil { - t.Fatalf("Failed to setup fake ldr.") - } - err = ldr.AddFile("/testpath/jsonpatch.json", []byte(jsonpatchContent)) - if err != nil { - t.Fatalf("Failed to setup fake ldr.") - } - return ldr -} - var deploy = gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"} var cmap = gvk.Gvk{Version: "v1", Kind: "ConfigMap"} var secret = gvk.Gvk{Version: "v1", Kind: "Secret"} var ns = gvk.Gvk{Version: "v1", Kind: "Namespace"} +func makeALoader(t *testing.T) ifc.Loader { + ldr := loadertest.NewFakeLoader("/testpath") + writeK(t, ldr, "/testpath/", kustomizationContent1) + writeF(t, ldr, "/testpath/deployment.yaml", deploymentContent) + writeF(t, ldr, "/testpath/namespace.yaml", namespaceContent) + writeF(t, ldr, "/testpath/jsonpatch.json", jsonpatchContent) + return ldr +} + func TestResources1(t *testing.T) { expected := resmap.ResMap{ - resid.NewResIdWithPrefixSuffixNamespace(deploy, "dply1", "foo-", "-bar", "ns1"): rf.RF().FromMap( + resid.NewResIdWithPrefixSuffixNamespace( + deploy, "dply1", "foo-", "-bar", "ns1"): rf.RF().FromMap( map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -177,7 +144,8 @@ func TestResources1(t *testing.T) { }, }, }), - resid.NewResIdWithPrefixSuffixNamespace(cmap, "literalConfigMap", "foo-", "-bar", "ns1"): rf.RF().FromMap( + resid.NewResIdWithPrefixSuffixNamespace( + cmap, "literalConfigMap", "foo-", "-bar", "ns1"): rf.RF().FromMap( map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -196,7 +164,8 @@ func TestResources1(t *testing.T) { "DB_PASSWORD": "somepw", }, }).SetBehavior(ifc.BehaviorCreate), - resid.NewResIdWithPrefixSuffixNamespace(secret, "secret", "foo-", "-bar", "ns1"): rf.RF().FromMap( + resid.NewResIdWithPrefixSuffixNamespace( + secret, "secret", "foo-", "-bar", "ns1"): rf.RF().FromMap( map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", @@ -216,7 +185,8 @@ func TestResources1(t *testing.T) { "DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")), }, }).SetBehavior(ifc.BehaviorCreate), - resid.NewResIdWithPrefixSuffixNamespace(ns, "ns1", "foo-", "-bar", ""): rf.RF().FromMap( + resid.NewResIdWithPrefixSuffixNamespace( + ns, "ns1", "foo-", "-bar", ""): rf.RF().FromMap( map[string]interface{}{ "apiVersion": "v1", "kind": "Namespace", @@ -232,7 +202,7 @@ func TestResources1(t *testing.T) { }), } actual, err := makeKustTarget( - t, makeLoader1(t)).MakeCustomizedResMap() + t, makeALoader(t)).MakeCustomizedResMap() if err != nil { t.Fatalf("unexpected Resources error %v", err) } @@ -245,11 +215,8 @@ func TestResources1(t *testing.T) { func TestResourceNotFound(t *testing.T) { l := loadertest.NewFakeLoader("/testpath") - err := l.AddFile("/testpath/"+constants.KustomizationFileName, []byte(kustomizationContent1)) - if err != nil { - t.Fatalf("Failed to setup fake ldr.") - } - _, err = makeKustTarget(t, l).MakeCustomizedResMap() + writeK(t, l, "/testpath", kustomizationContent1) + _, err := makeKustTarget(t, l).MakeCustomizedResMap() if err == nil { t.Fatalf("Didn't get the expected error for an unknown resource") } @@ -260,11 +227,8 @@ func TestResourceNotFound(t *testing.T) { func TestSecretTimeout(t *testing.T) { l := loadertest.NewFakeLoader("/testpath") - err := l.AddFile("/testpath/"+constants.KustomizationFileName, []byte(kustomizationContent2)) - if err != nil { - t.Fatalf("Failed to setup fake ldr.") - } - _, err = makeKustTarget(t, l).MakeCustomizedResMap() + writeK(t, l, "/testpath", kustomizationContent2) + _, err := makeKustTarget(t, l).MakeCustomizedResMap() if err == nil { t.Fatalf("Didn't get the expected error for an unknown resource") } @@ -283,7 +247,7 @@ func findSecret(m resmap.ResMap) *resource.Resource { } func TestDisableNameSuffixHash(t *testing.T) { - kt := makeKustTarget(t, makeLoader1(t)) + kt := makeKustTarget(t, makeALoader(t)) m, err := kt.MakeCustomizedResMap() if err != nil { @@ -312,21 +276,6 @@ func TestDisableNameSuffixHash(t *testing.T) { } } -func writeF(t *testing.T, ldr loadertest.FakeLoader, dir string, content string) { - err := ldr.AddFile(dir, []byte(content)) - if err != nil { - t.Fatalf("failed write to %s; %v", dir, err) - } -} - -func writeK( - t *testing.T, ldr loadertest.FakeLoader, dir string, content string) { - writeF(t, ldr, filepath.Join(dir, constants.KustomizationFileName), ` -apiVersion: v1 -kind: Kustomization -`+content) -} - func TestIssue596AllowDirectoriesThatAreSubstringsOfEachOther(t *testing.T) { ldr := loadertest.NewFakeLoader( "/app/overlays/aws-sandbox2.us-east-1") diff --git a/pkg/target/resourceconflict_test.go b/pkg/target/resourceconflict_test.go new file mode 100644 index 000000000..4770366df --- /dev/null +++ b/pkg/target/resourceconflict_test.go @@ -0,0 +1,153 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "strings" + "testing" + + "sigs.k8s.io/kustomize/pkg/internal/loadertest" +) + +func writeCombinedOverlays(t *testing.T, ldr loadertest.FakeLoader) { + // Base + writeK(t, ldr, "/app/base", ` +resources: +- serviceaccount.yaml +- rolebinding.yaml +namePrefix: base- +nameSuffix: -suffix +`) + writeF(t, ldr, "/app/base/rolebinding.yaml", ` +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: role +subjects: +- kind: ServiceAccount + name: serviceaccount +`) + writeF(t, ldr, "/app/base/serviceaccount.yaml", ` +apiVersion: v1 +kind: ServiceAccount +metadata: + name: serviceaccount +`) + + // Mid-level overlays + writeK(t, ldr, "/app/overlays/a", ` +bases: +- ../../base +namePrefix: a- +nameSuffix: -suffixA +`) + writeK(t, ldr, "/app/overlays/b", ` +bases: +- ../../base +namePrefix: b- +nameSuffix: -suffixB +`) + + // Top overlay, combining the mid-level overlays + writeK(t, ldr, "/app/combined", ` +bases: +- ../overlays/a +- ../overlays/b +`) +} + +func TestMultibasesNoConflict(t *testing.T) { + ldr := loadertest.NewFakeLoader("/app/combined") + writeCombinedOverlays(t, ldr) + m, err := makeKustTarget(t, ldr).MakeCustomizedResMap() + if err != nil { + t.Fatalf("Unexpected err: %v", err) + } + s, err := m.EncodeAsYaml() + if err != nil { + t.Fatalf("Unexpected err: %v", err) + } + assertExpectedEqualsActual(t, s, `apiVersion: v1 +kind: ServiceAccount +metadata: + name: a-base-serviceaccount-suffix-suffixA +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: b-base-serviceaccount-suffix-suffixB +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: a-base-rolebinding-suffix-suffixA +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: role +subjects: +- kind: ServiceAccount + name: a-base-serviceaccount-suffix-suffixA +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: b-base-rolebinding-suffix-suffixB +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: role +subjects: +- kind: ServiceAccount + name: b-base-serviceaccount-suffix-suffixB +`) +} + +func TestMultibasesWithConflict(t *testing.T) { + ldr := loadertest.NewFakeLoader("/app/combined") + writeCombinedOverlays(t, ldr) + + writeK(t, ldr, "/app/overlays/a", ` +bases: +- ../../base +namePrefix: a- +nameSuffix: -suffixA +resources: +- serviceaccount.yaml +`) + // Expect an error because this resource in the overlay + // matches a resource in the base. + writeF(t, ldr, "/app/overlays/a/serviceaccount.yaml", ` +apiVersion: v1 +kind: ServiceAccount +metadata: + name: serviceaccount +`) + + _, err := makeKustTarget(t, ldr).MakeCustomizedResMap() + if err == nil { + t.Fatalf("Expected resource conflict.") + } + if !strings.Contains( + err.Error(), "Multiple matches for name ~G_v1_ServiceAccount") { + t.Fatalf("Unexpected err: %v", err) + } +} diff --git a/pkg/target/utils_for_test.go b/pkg/target/utils_for_test.go new file mode 100644 index 000000000..c799f3ad5 --- /dev/null +++ b/pkg/target/utils_for_test.go @@ -0,0 +1,131 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +// A collection of utilities used in target tests. + +import ( + "fmt" + "path/filepath" + "strings" + "testing" + + "sigs.k8s.io/kustomize/k8sdeps/transformer" + "sigs.k8s.io/kustomize/pkg/constants" + "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/internal/loadertest" +) + +func makeKustTarget(t *testing.T, l ifc.Loader) *KustTarget { + // Warning: the following filesystem - a fake - must be rooted at /. + // This fs root is used as the working directory for the shell spawned by + // the secretgenerator, and has nothing to do with the filesystem used + // to load relative paths from the fake filesystem. + // This trick only works for secret generator commands that don't actually + // try to read the file system, because these tests don't write to the + // real "/" directory. See use of exec package in the secretfactory. + fakeFs := fs.MakeFakeFS() + fakeFs.Mkdir("/") + kt, err := NewKustTarget( + l, fakeFs, rf, transformer.NewFactoryImpl()) + if err != nil { + t.Fatalf("Unexpected construction error %v", err) + } + return kt +} + +func writeF( + t *testing.T, ldr loadertest.FakeLoader, dir string, content string) { + err := ldr.AddFile(dir, []byte(content)) + if err != nil { + t.Fatalf("failed write to %s; %v", dir, err) + } +} + +func writeK( + t *testing.T, ldr loadertest.FakeLoader, dir string, content string) { + writeF(t, ldr, filepath.Join(dir, constants.KustomizationFileName), ` +apiVersion: v1 +kind: Kustomization +`+content) +} + +func tabToSpace(input string) string { + var result []string + for _, i := range input { + if i == 9 { + result = append(result, " ") + } else { + result = append(result, string(i)) + } + } + return strings.Join(result, "") +} + +func convertToArray(x string) ([]string, int) { + a := strings.Split(strings.TrimSuffix(x, "\n"), "\n") + maxLen := 0 + for i, v := range a { + z := tabToSpace(v) + if len(z) > maxLen { + maxLen = len(z) + } + a[i] = z + } + return a, maxLen +} + +func hint(a, b string) string { + if a == b { + return " " + } + return "X" +} + +// Pretty printing of file differences. +func assertExpectedEqualsActual(t *testing.T, actual []byte, expected string) { + if expected == string(actual) { + return + } + sE, maxLen := convertToArray(expected) + sA, _ := convertToArray(string(actual)) + format := fmt.Sprintf("%%s %%-%ds %%s\n", maxLen+4) + + limit := 0 + if len(sE) < len(sA) { + limit = len(sE) + } else { + limit = len(sA) + } + + fmt.Printf(format, " ", "EXPECTED", "ACTUAL") + fmt.Printf(format, " ", "--------", "------") + for i := 0; i < limit; i++ { + fmt.Printf(format, hint(sE[i], sA[i]), sE[i], sA[i]) + } + if len(sE) < len(sA) { + for i := len(sE); i < len(sA); i++ { + fmt.Printf(format, "X", "", sA[i]) + } + } else { + for i := len(sA); i < len(sE); i++ { + fmt.Printf(format, "X", sE[i], "") + } + } + t.Fatalf("Expected not equal to actual") +} From 819b2e99d02468c87afdc3da4c736bc69d296aa8 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Tue, 18 Dec 2018 11:00:50 -0800 Subject: [PATCH 023/317] add apiVersion and kind to docs/kustomization.yaml --- docs/kustomization.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index 74cd29794..4cf8a0a84 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -32,6 +32,10 @@ # visible in configuration reviews. # ---------------------------------------------------- +# apiVersion and Kind for current kustomization.yaml +apiVersion: v1 +kind: Kustomization + # Adds namespace to all resources. namespace: my-namespace From 64372a786b33405c9007716d3f79358902749691 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Tue, 18 Dec 2018 11:01:10 -0800 Subject: [PATCH 024/317] add apiVersion and kind to example kustomizations --- examples/helloWorld/kustomization.yaml | 2 ++ examples/ldap/base/kustomization.yaml | 2 ++ examples/ldap/overlays/production/kustomization.yaml | 2 ++ examples/ldap/overlays/staging/kustomization.yaml | 2 ++ examples/multibases/base/kustomization.yaml | 4 +++- examples/multibases/dev/kustomization.yaml | 2 ++ examples/multibases/kustomization.yaml | 2 ++ examples/multibases/production/kustomization.yaml | 2 ++ examples/multibases/staging/kustomization.yaml | 2 ++ examples/springboot/overlays/production/kustomization.yaml | 2 ++ examples/springboot/overlays/staging/kustomization.yaml | 2 ++ examples/transformerconfigs/crd/kustomization.yaml | 2 ++ examples/wordpress/kustomization.yaml | 2 ++ examples/wordpress/mysql/kustomization.yaml | 2 ++ examples/wordpress/wordpress/kustomization.yaml | 2 ++ 15 files changed, 31 insertions(+), 1 deletion(-) diff --git a/examples/helloWorld/kustomization.yaml b/examples/helloWorld/kustomization.yaml index 41965951e..f4e18e6af 100644 --- a/examples/helloWorld/kustomization.yaml +++ b/examples/helloWorld/kustomization.yaml @@ -1,5 +1,7 @@ # Example configuration for the webserver # at https://github.com/monopole/hello +apiVersion: v1 +kind: Kustomization commonLabels: app: hello diff --git a/examples/ldap/base/kustomization.yaml b/examples/ldap/base/kustomization.yaml index 6cd10dfad..c039b6e66 100644 --- a/examples/ldap/base/kustomization.yaml +++ b/examples/ldap/base/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization resources: - deployment.yaml - service.yaml diff --git a/examples/ldap/overlays/production/kustomization.yaml b/examples/ldap/overlays/production/kustomization.yaml index 84a159c96..82217a7d3 100644 --- a/examples/ldap/overlays/production/kustomization.yaml +++ b/examples/ldap/overlays/production/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ../../base patchesStrategicMerge: diff --git a/examples/ldap/overlays/staging/kustomization.yaml b/examples/ldap/overlays/staging/kustomization.yaml index 18bbf920f..0f9e4c258 100644 --- a/examples/ldap/overlays/staging/kustomization.yaml +++ b/examples/ldap/overlays/staging/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ../../base patchesStrategicMerge: diff --git a/examples/multibases/base/kustomization.yaml b/examples/multibases/base/kustomization.yaml index d577d5e5f..2bdaded8f 100644 --- a/examples/multibases/base/kustomization.yaml +++ b/examples/multibases/base/kustomization.yaml @@ -1,2 +1,4 @@ +apiVersion: v1 +kind: Kustomization resources: -- pod.yaml \ No newline at end of file +- pod.yaml diff --git a/examples/multibases/dev/kustomization.yaml b/examples/multibases/dev/kustomization.yaml index d92695ed7..10257a866 100644 --- a/examples/multibases/dev/kustomization.yaml +++ b/examples/multibases/dev/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ./../base diff --git a/examples/multibases/kustomization.yaml b/examples/multibases/kustomization.yaml index 387ca23ae..f658b850a 100644 --- a/examples/multibases/kustomization.yaml +++ b/examples/multibases/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ./dev - ./staging diff --git a/examples/multibases/production/kustomization.yaml b/examples/multibases/production/kustomization.yaml index f6ae0c76d..c2b3b3ead 100644 --- a/examples/multibases/production/kustomization.yaml +++ b/examples/multibases/production/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ./../base diff --git a/examples/multibases/staging/kustomization.yaml b/examples/multibases/staging/kustomization.yaml index 0606f73c9..cd13840c1 100644 --- a/examples/multibases/staging/kustomization.yaml +++ b/examples/multibases/staging/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ./../base diff --git a/examples/springboot/overlays/production/kustomization.yaml b/examples/springboot/overlays/production/kustomization.yaml index c892f877a..baf52ab77 100644 --- a/examples/springboot/overlays/production/kustomization.yaml +++ b/examples/springboot/overlays/production/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ../../base patchesStrategicMerge: diff --git a/examples/springboot/overlays/staging/kustomization.yaml b/examples/springboot/overlays/staging/kustomization.yaml index f2f34a742..538fb1721 100644 --- a/examples/springboot/overlays/staging/kustomization.yaml +++ b/examples/springboot/overlays/staging/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - ../../base namePrefix: staging- diff --git a/examples/transformerconfigs/crd/kustomization.yaml b/examples/transformerconfigs/crd/kustomization.yaml index 04c6ec5ad..0d1ecf3b9 100644 --- a/examples/transformerconfigs/crd/kustomization.yaml +++ b/examples/transformerconfigs/crd/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization resources: - resources.yaml diff --git a/examples/wordpress/kustomization.yaml b/examples/wordpress/kustomization.yaml index cda9e01f0..cc8afc5cd 100644 --- a/examples/wordpress/kustomization.yaml +++ b/examples/wordpress/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization bases: - wordpress - mysql diff --git a/examples/wordpress/mysql/kustomization.yaml b/examples/wordpress/mysql/kustomization.yaml index bc664d1b1..022387f9c 100644 --- a/examples/wordpress/mysql/kustomization.yaml +++ b/examples/wordpress/mysql/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization resources: - deployment.yaml - service.yaml diff --git a/examples/wordpress/wordpress/kustomization.yaml b/examples/wordpress/wordpress/kustomization.yaml index a944d005c..26b0f7980 100644 --- a/examples/wordpress/wordpress/kustomization.yaml +++ b/examples/wordpress/wordpress/kustomization.yaml @@ -1,3 +1,5 @@ +apiVersion: v1 +kind: Kustomization resources: - deployment.yaml - service.yaml From 0d14e8954958db98cd032f71dd653e2bf9af795c Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Tue, 18 Dec 2018 11:22:18 -0800 Subject: [PATCH 025/317] add apiVersion and kind in README.md for examples --- examples/breakfast.md | 6 ++++++ examples/combineConfigs.md | 6 ++++++ examples/configGeneration.md | 4 ++++ examples/generatorOptions.md | 2 ++ examples/helloWorld/README.md | 4 ++++ examples/imageTags.md | 2 ++ examples/jsonpatch.md | 2 ++ examples/multibases/README.md | 10 ++++++++++ examples/remoteBuild.md | 2 ++ examples/wordpress/README.md | 2 ++ 10 files changed, 40 insertions(+) diff --git a/examples/breakfast.md b/examples/breakfast.md index a98fbb408..1c1670dc9 100644 --- a/examples/breakfast.md +++ b/examples/breakfast.md @@ -24,6 +24,8 @@ breakfast. This breakfast has coffee and pancakes: ``` cat <$DEMO_HOME/breakfast/base/kustomization.yaml +apiVersion: v1 +kind: Kustomization resources: - coffee.yaml - pancakes.yaml @@ -69,6 +71,8 @@ likes her coffee hot: mkdir -p $DEMO_HOME/breakfast/overlays/alice cat <$DEMO_HOME/breakfast/overlays/alice/kustomization.yaml +apiVersion: v1 +kind: Kustomization commonLabels: who: alice bases: @@ -92,6 +96,8 @@ And likewise a [variant] for Bob, who wants _five_ pancakes, with strawberries: mkdir -p $DEMO_HOME/breakfast/overlays/bob cat <$DEMO_HOME/breakfast/overlays/bob/kustomization.yaml +apiVersion: v1 +kind: Kustomization commonLabels: who: bob bases: diff --git a/examples/combineConfigs.md b/examples/combineConfigs.md index 86e46d34d..9abd56f2e 100644 --- a/examples/combineConfigs.md +++ b/examples/combineConfigs.md @@ -158,6 +158,8 @@ height=10m EOF cat <$DEMO_HOME/base/kustomization.yaml +apiVersion: v1 +kind: Kustomization configMapGenerator: - name: my-configmap files: @@ -191,6 +193,8 @@ dbpassword=mothersMaidenName EOF cat <$OVERLAYS/development/kustomization.yaml +apiVersion: v1 +kind: Kustomization bases: - ../../base namePrefix: dev- @@ -273,6 +277,8 @@ dbpassword=thisShouldProbablyBeInASecretInstead EOF cat <$OVERLAYS/production/kustomization.yaml +apiVersion: v1 +kind: Kustomization bases: - ../../base namePrefix: prod- diff --git a/examples/configGeneration.md b/examples/configGeneration.md index 7a3750ade..2bc8438a4 100644 --- a/examples/configGeneration.md +++ b/examples/configGeneration.md @@ -39,6 +39,8 @@ curl -s -o "$BASE/#1.yaml" "https://raw.githubusercontent.com\ /{deployment,service}.yaml" cat <<'EOF' >$BASE/kustomization.yaml +apiVersion: v1 +kind: Kustomization commonLabels: app: hello resources: @@ -59,6 +61,8 @@ OVERLAYS=$DEMO_HOME/overlays mkdir -p $OVERLAYS/staging cat <<'EOF' >$OVERLAYS/staging/kustomization.yaml +apiVersion: v1 +kind: Kustomization namePrefix: staging- nameSuffix: -v1 commonLabels: diff --git a/examples/generatorOptions.md b/examples/generatorOptions.md index a9fc3c3c0..d92ce7a3b 100644 --- a/examples/generatorOptions.md +++ b/examples/generatorOptions.md @@ -18,6 +18,8 @@ Create a kustomization and add a ConfigMap generator to it. ``` cat > $DEMO_HOME/kustomization.yaml << EOF +apiVersion: v1 +kind: Kustomization configMapGenerator: - name: my-configmap literals: diff --git a/examples/helloWorld/README.md b/examples/helloWorld/README.md index a812ad9a2..942a8d664 100644 --- a/examples/helloWorld/README.md +++ b/examples/helloWorld/README.md @@ -142,6 +142,8 @@ defining a new name prefix, and some different labels. ``` cat <<'EOF' >$OVERLAYS/staging/kustomization.yaml +apiVersion: v1 +kind: Kustomization namePrefix: staging- commonLabels: variant: staging @@ -183,6 +185,8 @@ with a different name prefix and labels. ``` cat <$OVERLAYS/production/kustomization.yaml +apiVersion: v1 +kind: Kustomization namePrefix: production- commonLabels: variant: production diff --git a/examples/imageTags.md b/examples/imageTags.md index d6a5fe11a..43a725b68 100644 --- a/examples/imageTags.md +++ b/examples/imageTags.md @@ -13,6 +13,8 @@ Make a `kustomization` containing a pod resource ``` cat <$DEMO_HOME/kustomization.yaml +apiVersion: v1 +kind: Kustomization resources: - pod.yaml EOF diff --git a/examples/jsonpatch.md b/examples/jsonpatch.md index 61c00f38f..e861464e5 100644 --- a/examples/jsonpatch.md +++ b/examples/jsonpatch.md @@ -11,6 +11,8 @@ Make a `kustomization` containing an ingress resource. DEMO_HOME=$(mktemp -d) cat <$DEMO_HOME/kustomization.yaml +apiVersion: v1 +kind: Kustomization resources: - ingress.yaml EOF diff --git a/examples/multibases/README.md b/examples/multibases/README.md index ae3d471a4..6a8567721 100644 --- a/examples/multibases/README.md +++ b/examples/multibases/README.md @@ -22,6 +22,8 @@ BASE=$DEMO_HOME/base mkdir $BASE cat <$BASE/kustomization.yaml +apiVersion: v1 +kind: Kustomization resources: - pod.yaml EOF @@ -47,6 +49,8 @@ DEV=$DEMO_HOME/dev mkdir $DEV cat <$DEV/kustomization.yaml +apiVersion: v1 +kind: Kustomization bases: - ./../base namePrefix: dev- @@ -60,6 +64,8 @@ STAG=$DEMO_HOME/staging mkdir $STAG cat <$STAG/kustomization.yaml +apiVersion: v1 +kind: Kustomization bases: - ./../base namePrefix: stag- @@ -73,6 +79,8 @@ PROD=$DEMO_HOME/production mkdir $PROD cat <$PROD/kustomization.yaml +apiVersion: v1 +kind: Kustomization bases: - ./../base namePrefix: prod- @@ -83,6 +91,8 @@ Then define a _Kustomization_ composing three variants together: ``` cat <$DEMO_HOME/kustomization.yaml +apiVersion: v1 +kind: Kustomization bases: - ./dev - ./staging diff --git a/examples/remoteBuild.md b/examples/remoteBuild.md index 747724fca..3800c856a 100644 --- a/examples/remoteBuild.md +++ b/examples/remoteBuild.md @@ -34,6 +34,8 @@ A base can also be specified as a URL: DEMO_HOME=$(mktemp -d) cat <$DEMO_HOME/kustomization.yaml +apiVersion: v1 +kind: Kustomization bases: - github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6 namePrefix: remote- diff --git a/examples/wordpress/README.md b/examples/wordpress/README.md index 2b7a86749..29fd290cb 100644 --- a/examples/wordpress/README.md +++ b/examples/wordpress/README.md @@ -49,6 +49,8 @@ Create a new kustomization with two bases: ``` cat <$DEMO_HOME/kustomization.yaml +apiVersion: v1 +kind: Kustomization bases: - wordpress - mysql From dd17174b35011e53665326ebdecb0b9b9e8442d0 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Tue, 18 Dec 2018 12:51:30 -0800 Subject: [PATCH 026/317] fix typos (#645) --- examples/transformerconfigs/README.md | 2 +- examples/transformerconfigs/crd/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/transformerconfigs/README.md b/examples/transformerconfigs/README.md index 31eff9103..d18f1e518 100644 --- a/examples/transformerconfigs/README.md +++ b/examples/transformerconfigs/README.md @@ -87,7 +87,7 @@ nameReference: (etc.) ``` -## cusotmizing transformer configurations +## customizing transformer configurations Kustomize has a default set of configurations. They can be saved to local directory through `kustomize config save -d`. Kustomize allows modifying those configuration files and using them in kustomization.yaml file. This tutorial shows how to customize those configurations to - [support a CRD type](crd/README.md) diff --git a/examples/transformerconfigs/crd/README.md b/examples/transformerconfigs/crd/README.md index faf903f84..6943c416e 100644 --- a/examples/transformerconfigs/crd/README.md +++ b/examples/transformerconfigs/crd/README.md @@ -17,7 +17,7 @@ Get the default transformer configurations using this command: kustomize config save -d $DEMO_HOME/kustomizeconfig ``` The default configurations are saved -in the directory `$DEMO_HOME/kusotmizeconfig` as several files +in the directory `$DEMO_HOME/kustomizeconfig` as several files > ``` > commonannotations.yaml From 949fd514633ebeb5707047aef0778c771c692f87 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Tue, 18 Dec 2018 17:03:59 -0800 Subject: [PATCH 027/317] Yet another kusttarget test. --- pkg/target/baseandoverlaymedium_test.go | 10 +- pkg/target/baseandoverlaysmall_test.go | 189 ++++++++++++++++++++++++ 2 files changed, 194 insertions(+), 5 deletions(-) create mode 100644 pkg/target/baseandoverlaysmall_test.go diff --git a/pkg/target/baseandoverlaymedium_test.go b/pkg/target/baseandoverlaymedium_test.go index 8469a2f53..61b925d77 100644 --- a/pkg/target/baseandoverlaymedium_test.go +++ b/pkg/target/baseandoverlaymedium_test.go @@ -37,7 +37,7 @@ import ( // To eventually fix this, we could write the data to a real filesystem, and // clean up after, or use some other trick compatible with exec. -func writeBase(t *testing.T, ldr loadertest.FakeLoader) { +func writeMediumBase(t *testing.T, ldr loadertest.FakeLoader) { writeK(t, ldr, "/app/base", ` namePrefix: baseprefix- commonLabels: @@ -86,9 +86,9 @@ spec: `) } -func TestBigBase(t *testing.T) { +func TestMediumBase(t *testing.T) { ldr := loadertest.NewFakeLoader("/app/base") - writeBase(t, ldr) + writeMediumBase(t, ldr) m, err := makeKustTarget(t, ldr).MakeCustomizedResMap() if err != nil { t.Fatalf("Err: %v", err) @@ -149,9 +149,9 @@ spec: `) } -func TestBigOverlay(t *testing.T) { +func TestMediumOverlay(t *testing.T) { ldr := loadertest.NewFakeLoader("/app/overlay") - writeBase(t, ldr) + writeMediumBase(t, ldr) writeK(t, ldr, "/app/overlay", ` namePrefix: test-infra- commonLabels: diff --git a/pkg/target/baseandoverlaysmall_test.go b/pkg/target/baseandoverlaysmall_test.go new file mode 100644 index 000000000..887df4317 --- /dev/null +++ b/pkg/target/baseandoverlaysmall_test.go @@ -0,0 +1,189 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "testing" + + "sigs.k8s.io/kustomize/pkg/internal/loadertest" +) + +func writeSmallBase(t *testing.T, ldr loadertest.FakeLoader) { + writeK(t, ldr, "/app/base", ` +namePrefix: a- +commonLabels: + app: myApp +resources: +- deployment.yaml +- service.yaml +`) + writeF(t, ldr, "/app/base/service.yaml", ` +apiVersion: v1 +kind: Service +metadata: + name: myService +spec: + selector: + backend: bungie + ports: + - port: 7002 +`) + writeF(t, ldr, "/app/base/deployment.yaml", ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: myDeployment +spec: + template: + metadata: + labels: + backend: awesome + spec: + containers: + - name: whatever + image: whatever +`) +} + +func TestSmallBase(t *testing.T) { + ldr := loadertest.NewFakeLoader("/app/base") + writeSmallBase(t, ldr) + m, err := makeKustTarget(t, ldr).MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + if m == nil { + t.Fatalf("Empty map.") + } + s, err := m.EncodeAsYaml() + if err != nil { + t.Fatalf("Err: %v", err) + } + assertExpectedEqualsActual(t, s, `apiVersion: v1 +kind: Service +metadata: + labels: + app: myApp + name: a-myService +spec: + ports: + - port: 7002 + selector: + app: myApp + backend: bungie +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: myApp + name: a-myDeployment +spec: + selector: + matchLabels: + app: myApp + template: + metadata: + labels: + app: myApp + backend: awesome + spec: + containers: + - image: whatever + name: whatever +`) +} + +func TestSmallOverlay(t *testing.T) { + ldr := loadertest.NewFakeLoader("/app/overlay") + writeSmallBase(t, ldr) + writeK(t, ldr, "/app/overlay", ` +namePrefix: b- +commonLabels: + env: prod +bases: +- ../base +patchesStrategicMerge: +- deployment/deployment.yaml +imageTags: +- name: whatever + newTag: 1.8.0`) + + writeF(t, ldr, "/app/overlay/configmap/app.env", ` +DB_USERNAME=admin +DB_PASSWORD=somepw +`) + writeF(t, ldr, "/app/overlay/configmap/app-init.ini", ` +FOO=bar +BAR=baz +`) + writeF(t, ldr, "/app/overlay/deployment/deployment.yaml", ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: myDeployment +spec: + replicas: 1000 +`) + m, err := makeKustTarget(t, ldr).MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + s, err := m.EncodeAsYaml() + if err != nil { + t.Fatalf("Unexpected err: %v", err) + } + assertExpectedEqualsActual(t, s, `apiVersion: v1 +kind: Service +metadata: + labels: + app: myApp + env: prod + name: b-a-myService +spec: + ports: + - port: 7002 + selector: + app: myApp + backend: bungie + env: prod +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: myApp + env: prod + name: b-a-myDeployment +spec: + replicas: 1000 + selector: + matchLabels: + app: myApp + env: prod + template: + metadata: + labels: + app: myApp + backend: awesome + env: prod + spec: + containers: + - image: whatever:1.8.0 + name: whatever +`) +} From 4b25963c93f37b65fea25d51e99bd677a705f9ba Mon Sep 17 00:00:00 2001 From: hyww Date: Fri, 21 Dec 2018 02:08:18 +0800 Subject: [PATCH 028/317] List of strategic merge patches (#637) * support List of strategic merge patches * add test for List of patches * handle List in SliceFromBytes * add test for List of patches with anchor/reference * reorganize kunstruct validate --- k8sdeps/kunstruct/factory.go | 10 ++-- k8sdeps/kunstruct/factory_test.go | 27 ++++++++++ pkg/resource/factory.go | 28 ++++++++++- pkg/resource/factory_test.go | 84 +++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 5 deletions(-) diff --git a/k8sdeps/kunstruct/factory.go b/k8sdeps/kunstruct/factory.go index de058f07c..386789130 100644 --- a/k8sdeps/kunstruct/factory.go +++ b/k8sdeps/kunstruct/factory.go @@ -101,12 +101,16 @@ func (kf *KunstructuredFactoryImpl) Set(fs fs.FileSystem, ldr ifc.Loader) { } // validate validates that u has kind and name +// except for kind `List`, which doesn't require a name func (kf *KunstructuredFactoryImpl) validate(u unstructured.Unstructured) error { + kind := u.GetKind() + if kind == "" { + return fmt.Errorf("missing kind in object %v", u) + } else if kind == "List" { + return nil + } if u.GetName() == "" { return fmt.Errorf("missing metadata.name in object %v", u) } - if u.GetKind() == "" { - return fmt.Errorf("missing kind in object %v", u) - } return nil } diff --git a/k8sdeps/kunstruct/factory_test.go b/k8sdeps/kunstruct/factory_test.go index 24dbb8a25..2ef4acaa9 100644 --- a/k8sdeps/kunstruct/factory_test.go +++ b/k8sdeps/kunstruct/factory_test.go @@ -33,6 +33,15 @@ func TestSliceFromBytes(t *testing.T) { "name": "winnie", }, }) + testList := factory.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "List", + "items": []interface{}{ + testConfigMap.Map(), + testConfigMap.Map(), + }, + }) tests := []struct { name string @@ -112,6 +121,24 @@ metadata: expectedOut: nil, expectedErr: true, }, + { + name: "List", + input: []byte(` +apiVersion: v1 +kind: List +items: +- apiVersion: v1 + kind: ConfigMap + metadata: + name: winnie +- apiVersion: v1 + kind: ConfigMap + metadata: + name: winnie +`), + expectedOut: []ifc.Kunstructured{testList}, + expectedErr: false, + }, } for _, test := range tests { diff --git a/pkg/resource/factory.go b/pkg/resource/factory.go index 2d9da9c66..3c0dbab07 100644 --- a/pkg/resource/factory.go +++ b/pkg/resource/factory.go @@ -17,6 +17,8 @@ limitations under the License. package resource import ( + "encoding/json" + "fmt" "log" "sigs.k8s.io/kustomize/pkg/fs" @@ -78,8 +80,30 @@ func (rf *Factory) SliceFromBytes(in []byte) ([]*Resource, error) { return nil, err } var result []*Resource - for _, u := range kunStructs { - result = append(result, rf.FromKunstructured(u)) + for len(kunStructs) > 0 { + u := kunStructs[0] + kunStructs = kunStructs[1:] + if u.GetKind() == "List" { + items := u.Map()["items"] + itemsSlice, ok := items.([]interface{}) + if !ok { + return nil, fmt.Errorf("items in List is type %T, expected array.", items) + } + for _, item := range itemsSlice { + itemJSON, err := json.Marshal(item) + if err != nil { + return nil, err + } + innerU, err := rf.kf.SliceFromBytes(itemJSON) + if err != nil { + return nil, err + } + // append innerU to kunStructs so nested Lists can be handled + kunStructs = append(kunStructs, innerU...) + } + } else { + result = append(result, rf.FromKunstructured(u)) + } } return result, nil } diff --git a/pkg/resource/factory_test.go b/pkg/resource/factory_test.go index edb999c39..2fb0adeb8 100644 --- a/pkg/resource/factory_test.go +++ b/pkg/resource/factory_test.go @@ -49,10 +49,82 @@ metadata: patch3 := ` WOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOT: woot ` + patchList := patch.StrategicMerge("patch4.yaml") + patch4 := ` +apiVersion: v1 +kind: List +items: +- apiVersion: apps/v1 + kind: Deployment + metadata: + name: pooh +- apiVersion: v1 + kind: ConfigMap + metadata: + name: winnie + namespace: hundred-acre-wood +` + patchList2 := patch.StrategicMerge("patch5.yaml") + patch5 := ` +apiVersion: v1 +kind: List +items: +- apiVersion: apps/v1 + kind: Deployment + metadata: + name: deployment-a + spec: &hostAliases + template: + spec: + hostAliases: + - hostnames: + - a.example.com + ip: 8.8.8.8 +- apiVersion: apps/v1 + kind: Deployment + metadata: + name: deployment-b + spec: + <<: *hostAliases +` + testDeploymentSpec := map[string]interface{}{ + "template": map[string]interface{}{ + "spec": map[string]interface{}{ + "hostAliases": []interface{}{ + map[string]interface{}{ + "hostnames": []interface{}{ + "a.example.com", + }, + "ip": "8.8.8.8", + }, + }, + }, + }, + } + testDeploymentA := factory.FromMap( + map[string]interface{}{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": map[string]interface{}{ + "name": "deployment-a", + }, + "spec": testDeploymentSpec, + }) + testDeploymentB := factory.FromMap( + map[string]interface{}{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": map[string]interface{}{ + "name": "deployment-b", + }, + "spec": testDeploymentSpec, + }) l := loadertest.NewFakeLoader("/") l.AddFile("/"+string(patchGood1), []byte(patch1)) l.AddFile("/"+string(patchGood2), []byte(patch2)) l.AddFile("/"+string(patchBad), []byte(patch3)) + l.AddFile("/"+string(patchList), []byte(patch4)) + l.AddFile("/"+string(patchList2), []byte(patch5)) tests := []struct { name string @@ -78,6 +150,18 @@ WOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOT: woot expectedOut: []*Resource{}, expectedErr: true, }, + { + name: "listOfPatches", + input: []patch.StrategicMerge{patchList}, + expectedOut: []*Resource{testDeployment, testConfigMap}, + expectedErr: false, + }, + { + name: "listWithAnchorReference", + input: []patch.StrategicMerge{patchList2}, + expectedOut: []*Resource{testDeploymentA, testDeploymentB}, + expectedErr: false, + }, } for _, test := range tests { rs, err := factory.SliceFromPatches(l, test.input) From 6f566d7a38cffcbb74a2ca2d762f8fbd65055d44 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Thu, 20 Dec 2018 15:19:39 -0800 Subject: [PATCH 029/317] Revert "add apiVersion and kind to docs and examples" (#653) --- docs/kustomization.yaml | 4 ---- examples/breakfast.md | 6 ------ examples/combineConfigs.md | 6 ------ examples/configGeneration.md | 4 ---- examples/generatorOptions.md | 2 -- examples/helloWorld/README.md | 4 ---- examples/helloWorld/kustomization.yaml | 2 -- examples/imageTags.md | 2 -- examples/jsonpatch.md | 2 -- examples/ldap/base/kustomization.yaml | 2 -- examples/ldap/overlays/production/kustomization.yaml | 2 -- examples/ldap/overlays/staging/kustomization.yaml | 2 -- examples/multibases/README.md | 10 ---------- examples/multibases/base/kustomization.yaml | 4 +--- examples/multibases/dev/kustomization.yaml | 2 -- examples/multibases/kustomization.yaml | 2 -- examples/multibases/production/kustomization.yaml | 2 -- examples/multibases/staging/kustomization.yaml | 2 -- examples/remoteBuild.md | 2 -- .../springboot/overlays/production/kustomization.yaml | 2 -- .../springboot/overlays/staging/kustomization.yaml | 2 -- examples/transformerconfigs/crd/kustomization.yaml | 2 -- examples/wordpress/README.md | 2 -- examples/wordpress/kustomization.yaml | 2 -- examples/wordpress/mysql/kustomization.yaml | 2 -- examples/wordpress/wordpress/kustomization.yaml | 2 -- 26 files changed, 1 insertion(+), 75 deletions(-) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index 4cf8a0a84..74cd29794 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -32,10 +32,6 @@ # visible in configuration reviews. # ---------------------------------------------------- -# apiVersion and Kind for current kustomization.yaml -apiVersion: v1 -kind: Kustomization - # Adds namespace to all resources. namespace: my-namespace diff --git a/examples/breakfast.md b/examples/breakfast.md index 1c1670dc9..a98fbb408 100644 --- a/examples/breakfast.md +++ b/examples/breakfast.md @@ -24,8 +24,6 @@ breakfast. This breakfast has coffee and pancakes: ``` cat <$DEMO_HOME/breakfast/base/kustomization.yaml -apiVersion: v1 -kind: Kustomization resources: - coffee.yaml - pancakes.yaml @@ -71,8 +69,6 @@ likes her coffee hot: mkdir -p $DEMO_HOME/breakfast/overlays/alice cat <$DEMO_HOME/breakfast/overlays/alice/kustomization.yaml -apiVersion: v1 -kind: Kustomization commonLabels: who: alice bases: @@ -96,8 +92,6 @@ And likewise a [variant] for Bob, who wants _five_ pancakes, with strawberries: mkdir -p $DEMO_HOME/breakfast/overlays/bob cat <$DEMO_HOME/breakfast/overlays/bob/kustomization.yaml -apiVersion: v1 -kind: Kustomization commonLabels: who: bob bases: diff --git a/examples/combineConfigs.md b/examples/combineConfigs.md index 9abd56f2e..86e46d34d 100644 --- a/examples/combineConfigs.md +++ b/examples/combineConfigs.md @@ -158,8 +158,6 @@ height=10m EOF cat <$DEMO_HOME/base/kustomization.yaml -apiVersion: v1 -kind: Kustomization configMapGenerator: - name: my-configmap files: @@ -193,8 +191,6 @@ dbpassword=mothersMaidenName EOF cat <$OVERLAYS/development/kustomization.yaml -apiVersion: v1 -kind: Kustomization bases: - ../../base namePrefix: dev- @@ -277,8 +273,6 @@ dbpassword=thisShouldProbablyBeInASecretInstead EOF cat <$OVERLAYS/production/kustomization.yaml -apiVersion: v1 -kind: Kustomization bases: - ../../base namePrefix: prod- diff --git a/examples/configGeneration.md b/examples/configGeneration.md index 2bc8438a4..7a3750ade 100644 --- a/examples/configGeneration.md +++ b/examples/configGeneration.md @@ -39,8 +39,6 @@ curl -s -o "$BASE/#1.yaml" "https://raw.githubusercontent.com\ /{deployment,service}.yaml" cat <<'EOF' >$BASE/kustomization.yaml -apiVersion: v1 -kind: Kustomization commonLabels: app: hello resources: @@ -61,8 +59,6 @@ OVERLAYS=$DEMO_HOME/overlays mkdir -p $OVERLAYS/staging cat <<'EOF' >$OVERLAYS/staging/kustomization.yaml -apiVersion: v1 -kind: Kustomization namePrefix: staging- nameSuffix: -v1 commonLabels: diff --git a/examples/generatorOptions.md b/examples/generatorOptions.md index d92ce7a3b..a9fc3c3c0 100644 --- a/examples/generatorOptions.md +++ b/examples/generatorOptions.md @@ -18,8 +18,6 @@ Create a kustomization and add a ConfigMap generator to it. ``` cat > $DEMO_HOME/kustomization.yaml << EOF -apiVersion: v1 -kind: Kustomization configMapGenerator: - name: my-configmap literals: diff --git a/examples/helloWorld/README.md b/examples/helloWorld/README.md index 942a8d664..a812ad9a2 100644 --- a/examples/helloWorld/README.md +++ b/examples/helloWorld/README.md @@ -142,8 +142,6 @@ defining a new name prefix, and some different labels. ``` cat <<'EOF' >$OVERLAYS/staging/kustomization.yaml -apiVersion: v1 -kind: Kustomization namePrefix: staging- commonLabels: variant: staging @@ -185,8 +183,6 @@ with a different name prefix and labels. ``` cat <$OVERLAYS/production/kustomization.yaml -apiVersion: v1 -kind: Kustomization namePrefix: production- commonLabels: variant: production diff --git a/examples/helloWorld/kustomization.yaml b/examples/helloWorld/kustomization.yaml index f4e18e6af..41965951e 100644 --- a/examples/helloWorld/kustomization.yaml +++ b/examples/helloWorld/kustomization.yaml @@ -1,7 +1,5 @@ # Example configuration for the webserver # at https://github.com/monopole/hello -apiVersion: v1 -kind: Kustomization commonLabels: app: hello diff --git a/examples/imageTags.md b/examples/imageTags.md index 43a725b68..d6a5fe11a 100644 --- a/examples/imageTags.md +++ b/examples/imageTags.md @@ -13,8 +13,6 @@ Make a `kustomization` containing a pod resource ``` cat <$DEMO_HOME/kustomization.yaml -apiVersion: v1 -kind: Kustomization resources: - pod.yaml EOF diff --git a/examples/jsonpatch.md b/examples/jsonpatch.md index e861464e5..61c00f38f 100644 --- a/examples/jsonpatch.md +++ b/examples/jsonpatch.md @@ -11,8 +11,6 @@ Make a `kustomization` containing an ingress resource. DEMO_HOME=$(mktemp -d) cat <$DEMO_HOME/kustomization.yaml -apiVersion: v1 -kind: Kustomization resources: - ingress.yaml EOF diff --git a/examples/ldap/base/kustomization.yaml b/examples/ldap/base/kustomization.yaml index c039b6e66..6cd10dfad 100644 --- a/examples/ldap/base/kustomization.yaml +++ b/examples/ldap/base/kustomization.yaml @@ -1,5 +1,3 @@ -apiVersion: v1 -kind: Kustomization resources: - deployment.yaml - service.yaml diff --git a/examples/ldap/overlays/production/kustomization.yaml b/examples/ldap/overlays/production/kustomization.yaml index 82217a7d3..84a159c96 100644 --- a/examples/ldap/overlays/production/kustomization.yaml +++ b/examples/ldap/overlays/production/kustomization.yaml @@ -1,5 +1,3 @@ -apiVersion: v1 -kind: Kustomization bases: - ../../base patchesStrategicMerge: diff --git a/examples/ldap/overlays/staging/kustomization.yaml b/examples/ldap/overlays/staging/kustomization.yaml index 0f9e4c258..18bbf920f 100644 --- a/examples/ldap/overlays/staging/kustomization.yaml +++ b/examples/ldap/overlays/staging/kustomization.yaml @@ -1,5 +1,3 @@ -apiVersion: v1 -kind: Kustomization bases: - ../../base patchesStrategicMerge: diff --git a/examples/multibases/README.md b/examples/multibases/README.md index 6a8567721..ae3d471a4 100644 --- a/examples/multibases/README.md +++ b/examples/multibases/README.md @@ -22,8 +22,6 @@ BASE=$DEMO_HOME/base mkdir $BASE cat <$BASE/kustomization.yaml -apiVersion: v1 -kind: Kustomization resources: - pod.yaml EOF @@ -49,8 +47,6 @@ DEV=$DEMO_HOME/dev mkdir $DEV cat <$DEV/kustomization.yaml -apiVersion: v1 -kind: Kustomization bases: - ./../base namePrefix: dev- @@ -64,8 +60,6 @@ STAG=$DEMO_HOME/staging mkdir $STAG cat <$STAG/kustomization.yaml -apiVersion: v1 -kind: Kustomization bases: - ./../base namePrefix: stag- @@ -79,8 +73,6 @@ PROD=$DEMO_HOME/production mkdir $PROD cat <$PROD/kustomization.yaml -apiVersion: v1 -kind: Kustomization bases: - ./../base namePrefix: prod- @@ -91,8 +83,6 @@ Then define a _Kustomization_ composing three variants together: ``` cat <$DEMO_HOME/kustomization.yaml -apiVersion: v1 -kind: Kustomization bases: - ./dev - ./staging diff --git a/examples/multibases/base/kustomization.yaml b/examples/multibases/base/kustomization.yaml index 2bdaded8f..d577d5e5f 100644 --- a/examples/multibases/base/kustomization.yaml +++ b/examples/multibases/base/kustomization.yaml @@ -1,4 +1,2 @@ -apiVersion: v1 -kind: Kustomization resources: -- pod.yaml +- pod.yaml \ No newline at end of file diff --git a/examples/multibases/dev/kustomization.yaml b/examples/multibases/dev/kustomization.yaml index 10257a866..d92695ed7 100644 --- a/examples/multibases/dev/kustomization.yaml +++ b/examples/multibases/dev/kustomization.yaml @@ -1,5 +1,3 @@ -apiVersion: v1 -kind: Kustomization bases: - ./../base diff --git a/examples/multibases/kustomization.yaml b/examples/multibases/kustomization.yaml index f658b850a..387ca23ae 100644 --- a/examples/multibases/kustomization.yaml +++ b/examples/multibases/kustomization.yaml @@ -1,5 +1,3 @@ -apiVersion: v1 -kind: Kustomization bases: - ./dev - ./staging diff --git a/examples/multibases/production/kustomization.yaml b/examples/multibases/production/kustomization.yaml index c2b3b3ead..f6ae0c76d 100644 --- a/examples/multibases/production/kustomization.yaml +++ b/examples/multibases/production/kustomization.yaml @@ -1,5 +1,3 @@ -apiVersion: v1 -kind: Kustomization bases: - ./../base diff --git a/examples/multibases/staging/kustomization.yaml b/examples/multibases/staging/kustomization.yaml index cd13840c1..0606f73c9 100644 --- a/examples/multibases/staging/kustomization.yaml +++ b/examples/multibases/staging/kustomization.yaml @@ -1,5 +1,3 @@ -apiVersion: v1 -kind: Kustomization bases: - ./../base diff --git a/examples/remoteBuild.md b/examples/remoteBuild.md index 3800c856a..747724fca 100644 --- a/examples/remoteBuild.md +++ b/examples/remoteBuild.md @@ -34,8 +34,6 @@ A base can also be specified as a URL: DEMO_HOME=$(mktemp -d) cat <$DEMO_HOME/kustomization.yaml -apiVersion: v1 -kind: Kustomization bases: - github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6 namePrefix: remote- diff --git a/examples/springboot/overlays/production/kustomization.yaml b/examples/springboot/overlays/production/kustomization.yaml index baf52ab77..c892f877a 100644 --- a/examples/springboot/overlays/production/kustomization.yaml +++ b/examples/springboot/overlays/production/kustomization.yaml @@ -1,5 +1,3 @@ -apiVersion: v1 -kind: Kustomization bases: - ../../base patchesStrategicMerge: diff --git a/examples/springboot/overlays/staging/kustomization.yaml b/examples/springboot/overlays/staging/kustomization.yaml index 538fb1721..f2f34a742 100644 --- a/examples/springboot/overlays/staging/kustomization.yaml +++ b/examples/springboot/overlays/staging/kustomization.yaml @@ -1,5 +1,3 @@ -apiVersion: v1 -kind: Kustomization bases: - ../../base namePrefix: staging- diff --git a/examples/transformerconfigs/crd/kustomization.yaml b/examples/transformerconfigs/crd/kustomization.yaml index 0d1ecf3b9..04c6ec5ad 100644 --- a/examples/transformerconfigs/crd/kustomization.yaml +++ b/examples/transformerconfigs/crd/kustomization.yaml @@ -1,5 +1,3 @@ -apiVersion: v1 -kind: Kustomization resources: - resources.yaml diff --git a/examples/wordpress/README.md b/examples/wordpress/README.md index 29fd290cb..2b7a86749 100644 --- a/examples/wordpress/README.md +++ b/examples/wordpress/README.md @@ -49,8 +49,6 @@ Create a new kustomization with two bases: ``` cat <$DEMO_HOME/kustomization.yaml -apiVersion: v1 -kind: Kustomization bases: - wordpress - mysql diff --git a/examples/wordpress/kustomization.yaml b/examples/wordpress/kustomization.yaml index cc8afc5cd..cda9e01f0 100644 --- a/examples/wordpress/kustomization.yaml +++ b/examples/wordpress/kustomization.yaml @@ -1,5 +1,3 @@ -apiVersion: v1 -kind: Kustomization bases: - wordpress - mysql diff --git a/examples/wordpress/mysql/kustomization.yaml b/examples/wordpress/mysql/kustomization.yaml index 022387f9c..bc664d1b1 100644 --- a/examples/wordpress/mysql/kustomization.yaml +++ b/examples/wordpress/mysql/kustomization.yaml @@ -1,5 +1,3 @@ -apiVersion: v1 -kind: Kustomization resources: - deployment.yaml - service.yaml diff --git a/examples/wordpress/wordpress/kustomization.yaml b/examples/wordpress/wordpress/kustomization.yaml index 26b0f7980..a944d005c 100644 --- a/examples/wordpress/wordpress/kustomization.yaml +++ b/examples/wordpress/wordpress/kustomization.yaml @@ -1,5 +1,3 @@ -apiVersion: v1 -kind: Kustomization resources: - deployment.yaml - service.yaml From 1cd99ab68e03fa2339f9f576317a46eed0b4c71f Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Thu, 20 Dec 2018 15:32:06 -0800 Subject: [PATCH 030/317] change current version from v1 to v1beta1 --- .../testdata/testcase-base-only/in/kustomization.yaml | 2 +- .../base/myapp/mycomponent/kustomization.yaml | 2 +- .../base/myapp/mycomponent2/kustomization.yaml | 2 +- .../testcase-configmaps/overlay/dev/kustomization.yaml | 2 +- .../overlay/dev/myapp/mycomponent/kustomization.yaml | 2 +- .../overlay/dev/myapp/mycomponent2/kustomization.yaml | 2 +- .../build/testdata/testcase-crds/crd/kustomization.yaml | 2 +- .../testcase-generators-namespace/in/kustomization.yaml | 2 +- .../in/overlay/kustomization.yaml | 2 +- .../in/package/kustomization.yaml | 2 +- .../in/overlay/kustomization.yaml | 2 +- .../in/package/kustomization.yaml | 2 +- .../testcase-single-overlay/in/overlay/kustomization.yaml | 2 +- .../testcase-single-overlay/in/package/kustomization.yaml | 2 +- .../in/base/kustomization.yaml | 2 +- .../in/overlay/kustomization.yaml | 2 +- .../testcase-variable-ref/in/overlay/kustomization.yaml | 2 +- .../testcase-variable-ref/in/package/kustomization.yaml | 2 +- pkg/commands/edit/fix/fix.go | 7 ------- pkg/commands/kustfile/kustomizationfile_test.go | 6 +++--- pkg/fs/fakefs.go | 2 +- pkg/target/kusttarget_test.go | 4 ++-- pkg/target/utils_for_test.go | 2 +- pkg/types/kustomization.go | 2 +- 24 files changed, 26 insertions(+), 33 deletions(-) diff --git a/pkg/commands/build/testdata/testcase-base-only/in/kustomization.yaml b/pkg/commands/build/testdata/testcase-base-only/in/kustomization.yaml index f416f4fad..75bcee92f 100644 --- a/pkg/commands/build/testdata/testcase-base-only/in/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-base-only/in/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization namePrefix: team-foo- commonLabels: diff --git a/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent/kustomization.yaml index feb3ada5f..fe386b14b 100644 --- a/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization namePrefix: p1- configMapGenerator: diff --git a/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent2/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent2/kustomization.yaml index a4041a390..18b0347bb 100644 --- a/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent2/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent2/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization namePrefix: p2- configMapGenerator: diff --git a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/kustomization.yaml index 580d08d91..e34a4767b 100644 --- a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization bases: - myapp/mycomponent diff --git a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent/kustomization.yaml index 77569d895..f14834eab 100644 --- a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization bases: - ../../../../base/myapp/mycomponent diff --git a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent2/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent2/kustomization.yaml index 76c6468c3..f66340c38 100644 --- a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent2/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent2/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization bases: - ../../../../base/myapp/mycomponent2 diff --git a/pkg/commands/build/testdata/testcase-crds/crd/kustomization.yaml b/pkg/commands/build/testdata/testcase-crds/crd/kustomization.yaml index 3c7934039..b5f7ff246 100644 --- a/pkg/commands/build/testdata/testcase-crds/crd/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-crds/crd/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization crds: - mycrd.json diff --git a/pkg/commands/build/testdata/testcase-generators-namespace/in/kustomization.yaml b/pkg/commands/build/testdata/testcase-generators-namespace/in/kustomization.yaml index a0a2585f9..5dc4dba90 100644 --- a/pkg/commands/build/testdata/testcase-generators-namespace/in/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-generators-namespace/in/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization configMapGenerator: - name: the-non-default-namespace-map diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/kustomization.yaml index 207e52395..f153f0692 100644 --- a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization namePrefix: staging- commonLabels: diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/kustomization.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/kustomization.yaml index f269394d3..34b6d11b3 100644 --- a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization namePrefix: team-foo- commonLabels: diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml index d0c5a3389..4fb0c9391 100644 --- a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization namePrefix: staging- commonLabels: diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/kustomization.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/kustomization.yaml index f269394d3..34b6d11b3 100644 --- a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization namePrefix: team-foo- commonLabels: diff --git a/pkg/commands/build/testdata/testcase-single-overlay/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-single-overlay/in/overlay/kustomization.yaml index 876f26406..307752281 100644 --- a/pkg/commands/build/testdata/testcase-single-overlay/in/overlay/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-single-overlay/in/overlay/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization namePrefix: staging- commonLabels: diff --git a/pkg/commands/build/testdata/testcase-single-overlay/in/package/kustomization.yaml b/pkg/commands/build/testdata/testcase-single-overlay/in/package/kustomization.yaml index 8905b2656..5ea5cab5f 100644 --- a/pkg/commands/build/testdata/testcase-single-overlay/in/package/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-single-overlay/in/package/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization namePrefix: team-foo- commonLabels: diff --git a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/kustomization.yaml b/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/kustomization.yaml index 6e96e7a37..403316ec8 100644 --- a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization resources: - deployment.yaml diff --git a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/overlay/kustomization.yaml index e544f7d0a..0ae516e62 100644 --- a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/overlay/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/overlay/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization nameprefix: kustomized- diff --git a/pkg/commands/build/testdata/testcase-variable-ref/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-variable-ref/in/overlay/kustomization.yaml index 781f1e4fc..9d4cc170d 100644 --- a/pkg/commands/build/testdata/testcase-variable-ref/in/overlay/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-variable-ref/in/overlay/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization namePrefix: dev- bases: diff --git a/pkg/commands/build/testdata/testcase-variable-ref/in/package/kustomization.yaml b/pkg/commands/build/testdata/testcase-variable-ref/in/package/kustomization.yaml index d811d59ca..e081ba807 100644 --- a/pkg/commands/build/testdata/testcase-variable-ref/in/package/kustomization.yaml +++ b/pkg/commands/build/testdata/testcase-variable-ref/in/package/kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization namePrefix: base- resources: diff --git a/pkg/commands/edit/fix/fix.go b/pkg/commands/edit/fix/fix.go index fe3241249..e940d6d34 100644 --- a/pkg/commands/edit/fix/fix.go +++ b/pkg/commands/edit/fix/fix.go @@ -17,9 +17,6 @@ limitations under the License. package fix import ( - "log" - "strings" - "github.com/spf13/cobra" "sigs.k8s.io/kustomize/pkg/commands/kustfile" "sigs.k8s.io/kustomize/pkg/fs" @@ -53,10 +50,6 @@ func RunFix(fSys fs.FileSystem) error { if err != nil { return err } - msgs := m.DealWithMissingFields() - if len(msgs) > 0 { - log.Printf(strings.Join(msgs, "\n")) - } return mf.Write(m) } diff --git a/pkg/commands/kustfile/kustomizationfile_test.go b/pkg/commands/kustfile/kustomizationfile_test.go index 9cfc89839..3738baf62 100644 --- a/pkg/commands/kustfile/kustomizationfile_test.go +++ b/pkg/commands/kustfile/kustomizationfile_test.go @@ -173,7 +173,7 @@ func TestPreserveComments(t *testing.T) { `# shem qing some comments # This is some comment we should preserve # don't delete it -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization resources: - pod.yaml @@ -228,7 +228,7 @@ resources: - service.yaml APIVersion: v1beta1 -kind: kustomization.yaml +kind: kustomization # something you may want to keep vars: @@ -266,7 +266,7 @@ resources: - service.yaml apiVersion: v1beta1 -kind: kustomization.yaml +kind: kustomization # something you may want to keep vars: diff --git a/pkg/fs/fakefs.go b/pkg/fs/fakefs.go index dffb96039..a68187908 100644 --- a/pkg/fs/fakefs.go +++ b/pkg/fs/fakefs.go @@ -40,7 +40,7 @@ func MakeFakeFS() *fakeFs { } // kustomizationContent is used in tests. -const kustomizationContent = `apiVersion: v1 +const kustomizationContent = `apiVersion: v1beta1 kind: Kustomization namePrefix: some-prefix nameSuffix: some-suffix diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index c80c60815..416e4fd07 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -35,7 +35,7 @@ import ( const ( kustomizationContent1 = ` -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization namePrefix: foo- nameSuffix: -bar @@ -67,7 +67,7 @@ patchesJson6902: path: jsonpatch.json ` kustomizationContent2 = ` -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization secretGenerator: - name: secret diff --git a/pkg/target/utils_for_test.go b/pkg/target/utils_for_test.go index c799f3ad5..4b3f429c4 100644 --- a/pkg/target/utils_for_test.go +++ b/pkg/target/utils_for_test.go @@ -60,7 +60,7 @@ func writeF( func writeK( t *testing.T, ldr loadertest.FakeLoader, dir string, content string) { writeF(t, ldr, filepath.Join(dir, constants.KustomizationFileName), ` -apiVersion: v1 +apiVersion: v1beta1 kind: Kustomization `+content) } diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 8cbeccaf8..28dff3469 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -22,7 +22,7 @@ import ( ) const ( - KustomizationVersion = "v1" + KustomizationVersion = "v1beta1" KustomizationKind = "Kustomization" ) From 037f898f81955fc586426406fc413304ecc23c2f Mon Sep 17 00:00:00 2001 From: jregan Date: Mon, 24 Dec 2018 10:38:16 -0800 Subject: [PATCH 031/317] Make KustTarget test harness to reduce boilerplate. --- pkg/target/baseandoverlaymedium_test.go | 45 ++++------ pkg/target/baseandoverlaysmall_test.go | 45 ++++------ pkg/target/kusttarget_test.go | 105 +++++++++++------------- pkg/target/resourceconflict_test.go | 38 ++++----- pkg/target/utils_for_test.go | 61 ++++++++++---- 5 files changed, 139 insertions(+), 155 deletions(-) diff --git a/pkg/target/baseandoverlaymedium_test.go b/pkg/target/baseandoverlaymedium_test.go index 61b925d77..e51c92d35 100644 --- a/pkg/target/baseandoverlaymedium_test.go +++ b/pkg/target/baseandoverlaymedium_test.go @@ -18,8 +18,6 @@ package target import ( "testing" - - "sigs.k8s.io/kustomize/pkg/internal/loadertest" ) // TODO(monopole): Add a feature test example covering secret generation. @@ -37,8 +35,8 @@ import ( // To eventually fix this, we could write the data to a real filesystem, and // clean up after, or use some other trick compatible with exec. -func writeMediumBase(t *testing.T, ldr loadertest.FakeLoader) { - writeK(t, ldr, "/app/base", ` +func writeMediumBase(th *KustTestHarness) { + th.writeK("/app/base", ` namePrefix: baseprefix- commonLabels: foo: bar @@ -48,7 +46,7 @@ resources: - deployment/deployment.yaml - service/service.yaml `) - writeF(t, ldr, "/app/base/service/service.yaml", ` + th.writeF("/app/base/service/service.yaml", ` apiVersion: v1 kind: Service metadata: @@ -61,7 +59,7 @@ spec: selector: app: mungebot `) - writeF(t, ldr, "/app/base/deployment/deployment.yaml", ` + th.writeF("/app/base/deployment/deployment.yaml", ` apiVersion: extensions/v1beta1 kind: Deployment metadata: @@ -87,20 +85,13 @@ spec: } func TestMediumBase(t *testing.T) { - ldr := loadertest.NewFakeLoader("/app/base") - writeMediumBase(t, ldr) - m, err := makeKustTarget(t, ldr).MakeCustomizedResMap() + th := NewKustTestHarness(t, "/app/base") + writeMediumBase(th) + m, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { t.Fatalf("Err: %v", err) } - if m == nil { - t.Fatalf("Empty map.") - } - s, err := m.EncodeAsYaml() - if err != nil { - t.Fatalf("Err: %v", err) - } - assertExpectedEqualsActual(t, s, `apiVersion: v1 + th.assertActualEqualsExpected(m, `apiVersion: v1 kind: Service metadata: annotations: @@ -150,9 +141,9 @@ spec: } func TestMediumOverlay(t *testing.T) { - ldr := loadertest.NewFakeLoader("/app/overlay") - writeMediumBase(t, ldr) - writeK(t, ldr, "/app/overlay", ` + th := NewKustTestHarness(t, "/app/overlay") + writeMediumBase(th) + th.writeK("/app/overlay", ` namePrefix: test-infra- commonLabels: app: mungebot @@ -174,15 +165,15 @@ imageTags: - name: nginx newTag: 1.8.0`) - writeF(t, ldr, "/app/overlay/configmap/app.env", ` + th.writeF("/app/overlay/configmap/app.env", ` DB_USERNAME=admin DB_PASSWORD=somepw `) - writeF(t, ldr, "/app/overlay/configmap/app-init.ini", ` + th.writeF("/app/overlay/configmap/app-init.ini", ` FOO=bar BAR=baz `) - writeF(t, ldr, "/app/overlay/deployment/deployment.yaml", ` + th.writeF("/app/overlay/deployment/deployment.yaml", ` apiVersion: extensions/v1beta1 kind: Deployment metadata: @@ -215,15 +206,11 @@ spec: name: app-env name: app-env `) - m, err := makeKustTarget(t, ldr).MakeCustomizedResMap() + m, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { t.Fatalf("Err: %v", err) } - s, err := m.EncodeAsYaml() - if err != nil { - t.Fatalf("Unexpected err: %v", err) - } - assertExpectedEqualsActual(t, s, `apiVersion: v1 + th.assertActualEqualsExpected(m, `apiVersion: v1 data: app-init.ini: |2 diff --git a/pkg/target/baseandoverlaysmall_test.go b/pkg/target/baseandoverlaysmall_test.go index 887df4317..e2bc9d4ac 100644 --- a/pkg/target/baseandoverlaysmall_test.go +++ b/pkg/target/baseandoverlaysmall_test.go @@ -18,12 +18,10 @@ package target import ( "testing" - - "sigs.k8s.io/kustomize/pkg/internal/loadertest" ) -func writeSmallBase(t *testing.T, ldr loadertest.FakeLoader) { - writeK(t, ldr, "/app/base", ` +func writeSmallBase(th *KustTestHarness) { + th.writeK("/app/base", ` namePrefix: a- commonLabels: app: myApp @@ -31,7 +29,7 @@ resources: - deployment.yaml - service.yaml `) - writeF(t, ldr, "/app/base/service.yaml", ` + th.writeF("/app/base/service.yaml", ` apiVersion: v1 kind: Service metadata: @@ -42,7 +40,7 @@ spec: ports: - port: 7002 `) - writeF(t, ldr, "/app/base/deployment.yaml", ` + th.writeF("/app/base/deployment.yaml", ` apiVersion: apps/v1 kind: Deployment metadata: @@ -60,20 +58,13 @@ spec: } func TestSmallBase(t *testing.T) { - ldr := loadertest.NewFakeLoader("/app/base") - writeSmallBase(t, ldr) - m, err := makeKustTarget(t, ldr).MakeCustomizedResMap() + th := NewKustTestHarness(t, "/app/base") + writeSmallBase(th) + m, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { t.Fatalf("Err: %v", err) } - if m == nil { - t.Fatalf("Empty map.") - } - s, err := m.EncodeAsYaml() - if err != nil { - t.Fatalf("Err: %v", err) - } - assertExpectedEqualsActual(t, s, `apiVersion: v1 + th.assertActualEqualsExpected(m, `apiVersion: v1 kind: Service metadata: labels: @@ -109,9 +100,9 @@ spec: } func TestSmallOverlay(t *testing.T) { - ldr := loadertest.NewFakeLoader("/app/overlay") - writeSmallBase(t, ldr) - writeK(t, ldr, "/app/overlay", ` + th := NewKustTestHarness(t, "/app/overlay") + writeSmallBase(th) + th.writeK("/app/overlay", ` namePrefix: b- commonLabels: env: prod @@ -123,15 +114,15 @@ imageTags: - name: whatever newTag: 1.8.0`) - writeF(t, ldr, "/app/overlay/configmap/app.env", ` + th.writeF("/app/overlay/configmap/app.env", ` DB_USERNAME=admin DB_PASSWORD=somepw `) - writeF(t, ldr, "/app/overlay/configmap/app-init.ini", ` + th.writeF("/app/overlay/configmap/app-init.ini", ` FOO=bar BAR=baz `) - writeF(t, ldr, "/app/overlay/deployment/deployment.yaml", ` + th.writeF("/app/overlay/deployment/deployment.yaml", ` apiVersion: apps/v1 kind: Deployment metadata: @@ -139,15 +130,11 @@ metadata: spec: replicas: 1000 `) - m, err := makeKustTarget(t, ldr).MakeCustomizedResMap() + m, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { t.Fatalf("Err: %v", err) } - s, err := m.EncodeAsYaml() - if err != nil { - t.Fatalf("Unexpected err: %v", err) - } - assertExpectedEqualsActual(t, s, `apiVersion: v1 + th.assertActualEqualsExpected(m, `apiVersion: v1 kind: Service metadata: labels: diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index 416e4fd07..31e2b5c0e 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -23,10 +23,8 @@ import ( "strings" "testing" - "sigs.k8s.io/kustomize/k8sdeps/kunstruct" "sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/ifc" - "sigs.k8s.io/kustomize/pkg/internal/loadertest" "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" @@ -91,27 +89,17 @@ metadata: ]` ) -var rf = resmap.NewFactory(resource.NewFactory( - kunstruct.NewKunstructuredFactoryImpl())) - -var deploy = gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"} -var cmap = gvk.Gvk{Version: "v1", Kind: "ConfigMap"} -var secret = gvk.Gvk{Version: "v1", Kind: "Secret"} -var ns = gvk.Gvk{Version: "v1", Kind: "Namespace"} - -func makeALoader(t *testing.T) ifc.Loader { - ldr := loadertest.NewFakeLoader("/testpath") - writeK(t, ldr, "/testpath/", kustomizationContent1) - writeF(t, ldr, "/testpath/deployment.yaml", deploymentContent) - writeF(t, ldr, "/testpath/namespace.yaml", namespaceContent) - writeF(t, ldr, "/testpath/jsonpatch.json", jsonpatchContent) - return ldr -} - func TestResources1(t *testing.T) { + th := NewKustTestHarness(t, "/whatever") + th.writeK("/whatever/", kustomizationContent1) + th.writeF("/whatever/deployment.yaml", deploymentContent) + th.writeF("/whatever/namespace.yaml", namespaceContent) + th.writeF("/whatever/jsonpatch.json", jsonpatchContent) + expected := resmap.ResMap{ resid.NewResIdWithPrefixSuffixNamespace( - deploy, "dply1", "foo-", "-bar", "ns1"): rf.RF().FromMap( + gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"}, + "dply1", "foo-", "-bar", "ns1"): th.fromMap( map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -145,7 +133,8 @@ func TestResources1(t *testing.T) { }, }), resid.NewResIdWithPrefixSuffixNamespace( - cmap, "literalConfigMap", "foo-", "-bar", "ns1"): rf.RF().FromMap( + gvk.Gvk{Version: "v1", Kind: "ConfigMap"}, + "literalConfigMap", "foo-", "-bar", "ns1"): th.fromMap( map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -165,7 +154,8 @@ func TestResources1(t *testing.T) { }, }).SetBehavior(ifc.BehaviorCreate), resid.NewResIdWithPrefixSuffixNamespace( - secret, "secret", "foo-", "-bar", "ns1"): rf.RF().FromMap( + gvk.Gvk{Version: "v1", Kind: "Secret"}, + "secret", "foo-", "-bar", "ns1"): th.fromMap( map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", @@ -186,7 +176,8 @@ func TestResources1(t *testing.T) { }, }).SetBehavior(ifc.BehaviorCreate), resid.NewResIdWithPrefixSuffixNamespace( - ns, "ns1", "foo-", "-bar", ""): rf.RF().FromMap( + gvk.Gvk{Version: "v1", Kind: "Namespace"}, + "ns1", "foo-", "-bar", ""): th.fromMap( map[string]interface{}{ "apiVersion": "v1", "kind": "Namespace", @@ -201,8 +192,7 @@ func TestResources1(t *testing.T) { }, }), } - actual, err := makeKustTarget( - t, makeALoader(t)).MakeCustomizedResMap() + actual, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { t.Fatalf("unexpected Resources error %v", err) } @@ -214,9 +204,9 @@ func TestResources1(t *testing.T) { } func TestResourceNotFound(t *testing.T) { - l := loadertest.NewFakeLoader("/testpath") - writeK(t, l, "/testpath", kustomizationContent1) - _, err := makeKustTarget(t, l).MakeCustomizedResMap() + th := NewKustTestHarness(t, "/whatever") + th.writeK("/whatever", kustomizationContent1) + _, err := th.makeKustTarget().MakeCustomizedResMap() if err == nil { t.Fatalf("Didn't get the expected error for an unknown resource") } @@ -226,9 +216,9 @@ func TestResourceNotFound(t *testing.T) { } func TestSecretTimeout(t *testing.T) { - l := loadertest.NewFakeLoader("/testpath") - writeK(t, l, "/testpath", kustomizationContent2) - _, err := makeKustTarget(t, l).MakeCustomizedResMap() + th := NewKustTestHarness(t, "/whatever") + th.writeK("/whatever", kustomizationContent2) + _, err := th.makeKustTarget().MakeCustomizedResMap() if err == nil { t.Fatalf("Didn't get the expected error for an unknown resource") } @@ -247,8 +237,13 @@ func findSecret(m resmap.ResMap) *resource.Resource { } func TestDisableNameSuffixHash(t *testing.T) { - kt := makeKustTarget(t, makeALoader(t)) + th := NewKustTestHarness(t, "/whatever") + th.writeK("/whatever/", kustomizationContent1) + th.writeF("/whatever/deployment.yaml", deploymentContent) + th.writeF("/whatever/namespace.yaml", namespaceContent) + th.writeF("/whatever/jsonpatch.json", jsonpatchContent) + kt := th.makeKustTarget() m, err := kt.MakeCustomizedResMap() if err != nil { t.Fatalf("unexpected Resources error %v", err) @@ -277,28 +272,25 @@ func TestDisableNameSuffixHash(t *testing.T) { } func TestIssue596AllowDirectoriesThatAreSubstringsOfEachOther(t *testing.T) { - ldr := loadertest.NewFakeLoader( - "/app/overlays/aws-sandbox2.us-east-1") - writeK(t, ldr, "/app/base", "") - writeK(t, ldr, "/app/overlays/aws", ` + th := NewKustTestHarness(t, "/app/overlays/aws-sandbox2.us-east-1") + th.writeK("/app/base", "") + th.writeK("/app/overlays/aws", ` bases: - ../../base `) - writeK(t, ldr, "/app/overlays/aws-nonprod", ` + th.writeK("/app/overlays/aws-nonprod", ` bases: - ../aws `) - writeK(t, ldr, "/app/overlays/aws-sandbox2.us-east-1", ` + th.writeK("/app/overlays/aws-sandbox2.us-east-1", ` bases: - ../aws-nonprod `) - m, err := makeKustTarget(t, ldr).MakeCustomizedResMap() + m, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { t.Fatalf("Err: %v", err) } - if m == nil { - t.Fatalf("Empty map.") - } + th.assertActualEqualsExpected(m, "") } // To simplify tests, these vars specified in alphabetical order. @@ -336,9 +328,8 @@ var someVars = []types.Var{ } func TestGetAllVarsSimple(t *testing.T) { - ldr := loadertest.NewFakeLoader( - "/app") - writeK(t, ldr, "/app", ` + th := NewKustTestHarness(t, "/app") + th.writeK("/app", ` vars: - name: AWARD objref: @@ -353,7 +344,7 @@ vars: name: heron apiVersion: v300 `) - vars, err := makeKustTarget(t, ldr).getAllVars() + vars, err := th.makeKustTarget().getAllVars() if err != nil { t.Fatalf("Err: %v", err) } @@ -376,9 +367,8 @@ func sortedKeys(m map[string]types.Var) (result []string) { } func TestGetAllVarsNested(t *testing.T) { - ldr := loadertest.NewFakeLoader( - "/app/overlays/o2") - writeK(t, ldr, "/app/base", ` + th := NewKustTestHarness(t, "/app/overlays/o2") + th.writeK("/app/base", ` vars: - name: AWARD objref: @@ -393,7 +383,7 @@ vars: name: heron apiVersion: v300 `) - writeK(t, ldr, "/app/overlays/o1", ` + th.writeK("/app/overlays/o1", ` vars: - name: FRUIT objref: @@ -402,7 +392,7 @@ vars: bases: - ../../base `) - writeK(t, ldr, "/app/overlays/o2", ` + th.writeK("/app/overlays/o2", ` vars: - name: VEGETABLE objref: @@ -411,7 +401,7 @@ vars: bases: - ../o1 `) - vars, err := makeKustTarget(t, ldr).getAllVars() + vars, err := th.makeKustTarget().getAllVars() if err != nil { t.Fatalf("Err: %v", err) } @@ -426,9 +416,8 @@ bases: } func TestVarCollisionsForbidden(t *testing.T) { - ldr := loadertest.NewFakeLoader( - "/app/overlays/o2") - writeK(t, ldr, "/app/base", ` + th := NewKustTestHarness(t, "/app/overlays/o2") + th.writeK("/app/base", ` vars: - name: AWARD objref: @@ -443,7 +432,7 @@ vars: name: heron apiVersion: v300 `) - writeK(t, ldr, "/app/overlays/o1", ` + th.writeK("/app/overlays/o1", ` vars: - name: AWARD objref: @@ -452,7 +441,7 @@ vars: bases: - ../../base `) - writeK(t, ldr, "/app/overlays/o2", ` + th.writeK("/app/overlays/o2", ` vars: - name: VEGETABLE objref: @@ -461,7 +450,7 @@ vars: bases: - ../o1 `) - _, err := makeKustTarget(t, ldr).getAllVars() + _, err := th.makeKustTarget().getAllVars() if err == nil { t.Fatalf("expected var collision") } diff --git a/pkg/target/resourceconflict_test.go b/pkg/target/resourceconflict_test.go index 4770366df..0002e0120 100644 --- a/pkg/target/resourceconflict_test.go +++ b/pkg/target/resourceconflict_test.go @@ -19,20 +19,18 @@ package target import ( "strings" "testing" - - "sigs.k8s.io/kustomize/pkg/internal/loadertest" ) -func writeCombinedOverlays(t *testing.T, ldr loadertest.FakeLoader) { +func writeCombinedOverlays(th *KustTestHarness) { // Base - writeK(t, ldr, "/app/base", ` + th.writeK("/app/base", ` resources: - serviceaccount.yaml - rolebinding.yaml namePrefix: base- nameSuffix: -suffix `) - writeF(t, ldr, "/app/base/rolebinding.yaml", ` + th.writeF("/app/base/rolebinding.yaml", ` apiVersion: rbac.authorization.k8s.io/v1beta1 kind: RoleBinding metadata: @@ -45,7 +43,7 @@ subjects: - kind: ServiceAccount name: serviceaccount `) - writeF(t, ldr, "/app/base/serviceaccount.yaml", ` + th.writeF("/app/base/serviceaccount.yaml", ` apiVersion: v1 kind: ServiceAccount metadata: @@ -53,13 +51,13 @@ metadata: `) // Mid-level overlays - writeK(t, ldr, "/app/overlays/a", ` + th.writeK("/app/overlays/a", ` bases: - ../../base namePrefix: a- nameSuffix: -suffixA `) - writeK(t, ldr, "/app/overlays/b", ` + th.writeK("/app/overlays/b", ` bases: - ../../base namePrefix: b- @@ -67,7 +65,7 @@ nameSuffix: -suffixB `) // Top overlay, combining the mid-level overlays - writeK(t, ldr, "/app/combined", ` + th.writeK("/app/combined", ` bases: - ../overlays/a - ../overlays/b @@ -75,17 +73,13 @@ bases: } func TestMultibasesNoConflict(t *testing.T) { - ldr := loadertest.NewFakeLoader("/app/combined") - writeCombinedOverlays(t, ldr) - m, err := makeKustTarget(t, ldr).MakeCustomizedResMap() + th := NewKustTestHarness(t, "/app/combined") + writeCombinedOverlays(th) + m, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { t.Fatalf("Unexpected err: %v", err) } - s, err := m.EncodeAsYaml() - if err != nil { - t.Fatalf("Unexpected err: %v", err) - } - assertExpectedEqualsActual(t, s, `apiVersion: v1 + th.assertActualEqualsExpected(m, `apiVersion: v1 kind: ServiceAccount metadata: name: a-base-serviceaccount-suffix-suffixA @@ -122,10 +116,10 @@ subjects: } func TestMultibasesWithConflict(t *testing.T) { - ldr := loadertest.NewFakeLoader("/app/combined") - writeCombinedOverlays(t, ldr) + th := NewKustTestHarness(t, "/app/combined") + writeCombinedOverlays(th) - writeK(t, ldr, "/app/overlays/a", ` + th.writeK("/app/overlays/a", ` bases: - ../../base namePrefix: a- @@ -135,14 +129,14 @@ resources: `) // Expect an error because this resource in the overlay // matches a resource in the base. - writeF(t, ldr, "/app/overlays/a/serviceaccount.yaml", ` + th.writeF("/app/overlays/a/serviceaccount.yaml", ` apiVersion: v1 kind: ServiceAccount metadata: name: serviceaccount `) - _, err := makeKustTarget(t, ldr).MakeCustomizedResMap() + _, err := th.makeKustTarget().MakeCustomizedResMap() if err == nil { t.Fatalf("Expected resource conflict.") } diff --git a/pkg/target/utils_for_test.go b/pkg/target/utils_for_test.go index 4b3f429c4..4cafbb13e 100644 --- a/pkg/target/utils_for_test.go +++ b/pkg/target/utils_for_test.go @@ -24,14 +24,30 @@ import ( "strings" "testing" + "sigs.k8s.io/kustomize/k8sdeps/kunstruct" "sigs.k8s.io/kustomize/k8sdeps/transformer" "sigs.k8s.io/kustomize/pkg/constants" "sigs.k8s.io/kustomize/pkg/fs" - "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/internal/loadertest" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/resource" ) -func makeKustTarget(t *testing.T, l ifc.Loader) *KustTarget { +type KustTestHarness struct { + t *testing.T + rf *resmap.Factory + ldr loadertest.FakeLoader +} + +func NewKustTestHarness(t *testing.T, path string) *KustTestHarness { + return &KustTestHarness{ + t: t, + rf: resmap.NewFactory(resource.NewFactory( + kunstruct.NewKunstructuredFactoryImpl())), + ldr: loadertest.NewFakeLoader(path)} +} + +func (th *KustTestHarness) makeKustTarget() *KustTarget { // Warning: the following filesystem - a fake - must be rooted at /. // This fs root is used as the working directory for the shell spawned by // the secretgenerator, and has nothing to do with the filesystem used @@ -42,29 +58,31 @@ func makeKustTarget(t *testing.T, l ifc.Loader) *KustTarget { fakeFs := fs.MakeFakeFS() fakeFs.Mkdir("/") kt, err := NewKustTarget( - l, fakeFs, rf, transformer.NewFactoryImpl()) + th.ldr, fakeFs, th.rf, transformer.NewFactoryImpl()) if err != nil { - t.Fatalf("Unexpected construction error %v", err) + th.t.Fatalf("Unexpected construction error %v", err) } return kt } -func writeF( - t *testing.T, ldr loadertest.FakeLoader, dir string, content string) { - err := ldr.AddFile(dir, []byte(content)) +func (th *KustTestHarness) writeF(dir string, content string) { + err := th.ldr.AddFile(dir, []byte(content)) if err != nil { - t.Fatalf("failed write to %s; %v", dir, err) + th.t.Fatalf("failed write to %s; %v", dir, err) } } -func writeK( - t *testing.T, ldr loadertest.FakeLoader, dir string, content string) { - writeF(t, ldr, filepath.Join(dir, constants.KustomizationFileName), ` +func (th *KustTestHarness) writeK(dir string, content string) { + th.writeF(filepath.Join(dir, constants.KustomizationFileName), ` apiVersion: v1beta1 kind: Kustomization `+content) } +func (th *KustTestHarness) fromMap(m map[string]interface{}) *resource.Resource { + return th.rf.RF().FromMap(m) +} + func tabToSpace(input string) string { var result []string for _, i := range input { @@ -98,21 +116,30 @@ func hint(a, b string) string { } // Pretty printing of file differences. -func assertExpectedEqualsActual(t *testing.T, actual []byte, expected string) { - if expected == string(actual) { - return +func (th *KustTestHarness) assertActualEqualsExpected( + m resmap.ResMap, expected string) { + if m == nil { + th.t.Fatalf("Map should not be nil.") } + actual, err := m.EncodeAsYaml() + if err != nil { + th.t.Fatalf("Unexpected err: %v", err) + } + if string(actual) != expected { + th.reportDiffAndFail(actual, expected) + } +} + +func (th *KustTestHarness) reportDiffAndFail(actual []byte, expected string) { sE, maxLen := convertToArray(expected) sA, _ := convertToArray(string(actual)) format := fmt.Sprintf("%%s %%-%ds %%s\n", maxLen+4) - limit := 0 if len(sE) < len(sA) { limit = len(sE) } else { limit = len(sA) } - fmt.Printf(format, " ", "EXPECTED", "ACTUAL") fmt.Printf(format, " ", "--------", "------") for i := 0; i < limit; i++ { @@ -127,5 +154,5 @@ func assertExpectedEqualsActual(t *testing.T, actual []byte, expected string) { fmt.Printf(format, "X", sE[i], "") } } - t.Fatalf("Expected not equal to actual") + th.t.Fatalf("Expected not equal to actual") } From 4583c4a9de4f6b07ae8cc2d9dd46e225b400e2d1 Mon Sep 17 00:00:00 2001 From: jregan Date: Wed, 19 Dec 2018 19:01:56 -0800 Subject: [PATCH 032/317] More custom transform coverage. --- pkg/target/baseandoverlaymedium_test.go | 6 +- pkg/target/baseandoverlaysmall_test.go | 9 +- pkg/target/customconfig_test.go | 341 ++++++++++++++++++++++++ pkg/target/kusttarget.go | 34 ++- pkg/target/kusttarget_test.go | 6 +- pkg/target/resourceconflict_test.go | 3 +- pkg/target/utils_for_test.go | 20 +- 7 files changed, 408 insertions(+), 11 deletions(-) create mode 100644 pkg/target/customconfig_test.go diff --git a/pkg/target/baseandoverlaymedium_test.go b/pkg/target/baseandoverlaymedium_test.go index e51c92d35..0ffd7d2b0 100644 --- a/pkg/target/baseandoverlaymedium_test.go +++ b/pkg/target/baseandoverlaymedium_test.go @@ -91,7 +91,8 @@ func TestMediumBase(t *testing.T) { if err != nil { t.Fatalf("Err: %v", err) } - th.assertActualEqualsExpected(m, `apiVersion: v1 + th.assertActualEqualsExpected(m, ` +apiVersion: v1 kind: Service metadata: annotations: @@ -210,7 +211,8 @@ spec: if err != nil { t.Fatalf("Err: %v", err) } - th.assertActualEqualsExpected(m, `apiVersion: v1 + th.assertActualEqualsExpected(m, ` +apiVersion: v1 data: app-init.ini: |2 diff --git a/pkg/target/baseandoverlaysmall_test.go b/pkg/target/baseandoverlaysmall_test.go index e2bc9d4ac..c38112ce3 100644 --- a/pkg/target/baseandoverlaysmall_test.go +++ b/pkg/target/baseandoverlaysmall_test.go @@ -64,7 +64,8 @@ func TestSmallBase(t *testing.T) { if err != nil { t.Fatalf("Err: %v", err) } - th.assertActualEqualsExpected(m, `apiVersion: v1 + th.assertActualEqualsExpected(m, ` +apiVersion: v1 kind: Service metadata: labels: @@ -112,7 +113,8 @@ patchesStrategicMerge: - deployment/deployment.yaml imageTags: - name: whatever - newTag: 1.8.0`) + newTag: 1.8.0 +`) th.writeF("/app/overlay/configmap/app.env", ` DB_USERNAME=admin @@ -134,7 +136,8 @@ spec: if err != nil { t.Fatalf("Err: %v", err) } - th.assertActualEqualsExpected(m, `apiVersion: v1 + th.assertActualEqualsExpected(m, ` +apiVersion: v1 kind: Service metadata: labels: diff --git a/pkg/target/customconfig_test.go b/pkg/target/customconfig_test.go new file mode 100644 index 000000000..9c0c6b0e3 --- /dev/null +++ b/pkg/target/customconfig_test.go @@ -0,0 +1,341 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "testing" +) + +func makeBaseReferencingCustomConfig(th *KustTestHarness) { + th.writeK("/app/base", ` +namePrefix: x- +commonLabels: + app: myApp +vars: +- name: APRIL_DIET + objref: + kind: Giraffe + name: april + fieldref: + fieldpath: spec.diet +- name: KOKO_DIET + objref: + kind: Gorilla + name: koko + fieldref: + fieldpath: spec.diet +resources: +- giraffes.yaml +- gorilla.yaml +- animalPark.yaml +configurations: +- config/defaults.yaml +- config/custom.yaml +`) + th.writeF("/app/base/giraffes.yaml", ` +kind: Giraffe +metadata: + name: may +spec: + diet: acacia + location: SE +--- +kind: Giraffe +metadata: + name: april +spec: + diet: mimosa + location: NE +`) + th.writeF("/app/base/gorilla.yaml", ` +kind: Gorilla +metadata: + name: koko +spec: + diet: bambooshoots + location: SW +`) + th.writeF("/app/base/animalPark.yaml", ` +kind: AnimalPark +metadata: + name: sandiego +spec: + gorillaRef: + name: koko + giraffeRef: + name: april + food: + - "$(APRIL_DIET)" + - "$(KOKO_DIET)" +`) +} + +func TestCustomConfig(t *testing.T) { + th := NewKustTestHarness(t, "/app/base") + makeBaseReferencingCustomConfig(th) + th.writeDefaultConfigs("/app/base/config/defaults.yaml") + th.writeF("/app/base/config/custom.yaml", ` +nameReference: +- kind: Gorilla + fieldSpecs: + - kind: AnimalPark + path: spec/gorillaRef/name +- kind: Giraffe + fieldSpecs: + - kind: AnimalPark + path: spec/giraffeRef/name +varReference: +- path: spec/food + kind: AnimalPark +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +kind: AnimalPark +metadata: + labels: + app: myApp + name: x-sandiego +spec: + food: + - mimosa + - bambooshoots + giraffeRef: + name: x-april + gorillaRef: + name: x-koko +--- +kind: Giraffe +metadata: + labels: + app: myApp + name: x-april +spec: + diet: mimosa + location: NE +--- +kind: Giraffe +metadata: + labels: + app: myApp + name: x-may +spec: + diet: acacia + location: SE +--- +kind: Gorilla +metadata: + labels: + app: myApp + name: x-koko +spec: + diet: bambooshoots + location: SW +`) +} + +// TODO: this test demonstrates #658 +// The prefix "x-" is applied twice (search for x-x-sandiego), because the +// config from the base isn't properly merged with the config in the overlay. +func TestCustomConfigWithDefaultOverspecification(t *testing.T) { + th := NewKustTestHarness(t, "/app/base") + makeBaseReferencingCustomConfig(th) + th.writeDefaultConfigs("/app/base/config/defaults.yaml") + // Specifying namePrefix here conflicts with (is the same as) + // the defaults written above. + th.writeF("/app/base/config/custom.yaml", ` +namePrefix: +- path: metadata/name +nameReference: +- kind: Gorilla + fieldSpecs: + - kind: AnimalPark + path: spec/gorillaRef/name +- kind: Giraffe + fieldSpecs: + - kind: AnimalPark + path: spec/giraffeRef/name +varReference: +- path: spec/food + kind: AnimalPark +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +kind: AnimalPark +metadata: + labels: + app: myApp + name: x-x-sandiego +spec: + food: + - mimosa + - bambooshoots + giraffeRef: + name: x-x-april + gorillaRef: + name: x-x-koko +--- +kind: Giraffe +metadata: + labels: + app: myApp + name: x-x-april +spec: + diet: mimosa + location: NE +--- +kind: Giraffe +metadata: + labels: + app: myApp + name: x-x-may +spec: + diet: acacia + location: SE +--- +kind: Gorilla +metadata: + labels: + app: myApp + name: x-x-koko +spec: + diet: bambooshoots + location: SW +`) +} + +// TODO: Test demonstrates bug #605. +// The customization supplied in a base isn't available to the overlay. +func TestBug605(t *testing.T) { + th := NewKustTestHarness(t, "/app/overlay") + makeBaseReferencingCustomConfig(th) + th.writeDefaultConfigs("/app/base/config/defaults.yaml") + th.writeF("/app/base/config/custom.yaml", ` +nameReference: +- kind: Gorilla + fieldSpecs: + - kind: AnimalPark + path: spec/gorillaRef/name +- kind: Giraffe + fieldSpecs: + - kind: AnimalPark + path: spec/giraffeRef/name +varReference: +- path: spec/food + kind: AnimalPark +`) + th.writeK("/app/overlay", ` +namePrefix: o- +commonLabels: + movie: planetOfTheApes +patchesStrategicMerge: +- animalPark.yaml +resources: +- ursus.yaml +bases: +- ../base +`) + th.writeF("/app/overlay/ursus.yaml", ` +kind: Gorilla +metadata: + name: ursus +spec: + diet: heston + location: Arizona +`) + // The following replaces the gorillaRef in the AnimalPark. + th.writeF("/app/overlay/animalPark.yaml", ` +kind: AnimalPark +metadata: + name: sandiego +spec: + gorillaRef: + name: ursus +`) + + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + // Problems in the expected result: + // - The variables are not replaced in the "food" fields. + // - The name of the AnimalPark should be x-o-sandiego, since + // AnimalPark appears in the base. + // - The giraffe and gorilla name are incorrect in AnimalPark; + // they should be o-x-april and o-ursus respectively. The + // Gorilla ursus doesn't get an x because it's not in the base. + th.assertActualEqualsExpected(m, ` +kind: AnimalPark +metadata: + labels: + app: myApp + movie: planetOfTheApes + name: o-sandiego +spec: + food: + - $(APRIL_DIET) + - $(KOKO_DIET) + giraffeRef: + name: april + gorillaRef: + name: ursus +--- +kind: Giraffe +metadata: + labels: + app: myApp + movie: planetOfTheApes + name: o-x-april +spec: + diet: mimosa + location: NE +--- +kind: Giraffe +metadata: + labels: + app: myApp + movie: planetOfTheApes + name: o-x-may +spec: + diet: acacia + location: SE +--- +kind: Gorilla +metadata: + labels: + app: myApp + movie: planetOfTheApes + name: o-x-koko +spec: + diet: bambooshoots + location: SW +--- +kind: Gorilla +metadata: + labels: + movie: planetOfTheApes + name: o-ursus +spec: + diet: heston + location: Arizona +`) +} diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index ed61910b2..02a094709 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -97,9 +97,24 @@ func unmarshal(y []byte, o interface{}) error { return dec.Decode(o) } -// makeTransformerConfig returns a complete TransformerConfig object -// from either files or the default configs +// Maybe switch to the false path permanently (desired by #606), +// or expose this as a CLI flag. +const demandExplicitConfig = true + func makeTransformerConfig( + ldr ifc.Loader, paths []string) (*config.TransformerConfig, error) { + if demandExplicitConfig { + return loadConfigFromDiskOrDefaults(ldr, paths) + } + return mergeCustomConfigWithDefaults(ldr, paths) +} + +// loadConfigFromDiskOrDefaults returns a TransformerConfig object +// built from either files or the hardcoded default configs. +// There's no merging, it's one or the other. This is preferred if one +// wants all configuration to be explicit in version control, as +// opposed to relying on a mix of files and hard coded config. +func loadConfigFromDiskOrDefaults( ldr ifc.Loader, paths []string) (*config.TransformerConfig, error) { if paths == nil || len(paths) == 0 { return config.NewFactory(nil).DefaultConfig(), nil @@ -107,6 +122,21 @@ func makeTransformerConfig( return config.NewFactory(ldr).FromFiles(paths) } +// mergeCustomConfigWithDefaults returns a merger of custom config, +// if any, with default config. +func mergeCustomConfigWithDefaults( + ldr ifc.Loader, paths []string) (*config.TransformerConfig, error) { + t1 := config.NewFactory(nil).DefaultConfig() + if len(paths) == 0 { + return t1, nil + } + t2, err := config.NewFactory(ldr).FromFiles(paths) + if err != nil { + return nil, err + } + return t1.Merge(t2), nil +} + // MakeCustomizedResMap creates a ResMap per kustomization instructions. // The Resources in the returned ResMap are fully customized. func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) { diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index 31e2b5c0e..ae4eec49d 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -74,12 +74,14 @@ secretGenerator: USER: "sleep 2" type: Opaque ` - deploymentContent = `apiVersion: apps/v1 + deploymentContent = ` +apiVersion: apps/v1 metadata: name: dply1 kind: Deployment ` - namespaceContent = `apiVersion: v1 + namespaceContent = ` +apiVersion: v1 kind: Namespace metadata: name: ns1 diff --git a/pkg/target/resourceconflict_test.go b/pkg/target/resourceconflict_test.go index 0002e0120..991805a03 100644 --- a/pkg/target/resourceconflict_test.go +++ b/pkg/target/resourceconflict_test.go @@ -79,7 +79,8 @@ func TestMultibasesNoConflict(t *testing.T) { if err != nil { t.Fatalf("Unexpected err: %v", err) } - th.assertActualEqualsExpected(m, `apiVersion: v1 + th.assertActualEqualsExpected(m, ` +apiVersion: v1 kind: ServiceAccount metadata: name: a-base-serviceaccount-suffix-suffixA diff --git a/pkg/target/utils_for_test.go b/pkg/target/utils_for_test.go index 4cafbb13e..d3fedce95 100644 --- a/pkg/target/utils_for_test.go +++ b/pkg/target/utils_for_test.go @@ -21,6 +21,7 @@ package target import ( "fmt" "path/filepath" + "sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig" "strings" "testing" @@ -83,6 +84,18 @@ func (th *KustTestHarness) fromMap(m map[string]interface{}) *resource.Resource return th.rf.RF().FromMap(m) } +func (th *KustTestHarness) writeDefaultConfigs(fName string) { + m := defaultconfig.GetDefaultFieldSpecsAsMap() + var content []byte + for _, tCfg := range m { + content = append(content, []byte(tCfg)...) + } + err := th.ldr.AddFile(fName, content) + if err != nil { + th.t.Fatalf("unable to add file %s", fName) + } +} + func tabToSpace(input string) string { var result []string for _, i := range input { @@ -115,12 +128,16 @@ func hint(a, b string) string { return "X" } -// Pretty printing of file differences. func (th *KustTestHarness) assertActualEqualsExpected( m resmap.ResMap, expected string) { if m == nil { th.t.Fatalf("Map should not be nil.") } + // Ignore leading linefeed in expected value + // to ease readability of tests. + if len(expected) > 0 && expected[0] == 10 { + expected = expected[1:] + } actual, err := m.EncodeAsYaml() if err != nil { th.t.Fatalf("Unexpected err: %v", err) @@ -130,6 +147,7 @@ func (th *KustTestHarness) assertActualEqualsExpected( } } +// Pretty printing of file differences. func (th *KustTestHarness) reportDiffAndFail(actual []byte, expected string) { sE, maxLen := convertToArray(expected) sA, _ := convertToArray(string(actual)) From 95203c58c4ffa9bb8b847eabb4054340e957e0ce Mon Sep 17 00:00:00 2001 From: jregan Date: Fri, 28 Dec 2018 07:35:29 -0800 Subject: [PATCH 033/317] Convert multi-patch test to in-memory. --- pkg/commands/build/build_test.go | 5 - .../in/overlay/deployment-patch1.yaml | 20 -- .../in/overlay/deployment-patch2.yaml | 12 - .../in/overlay/kustomization.yaml | 14 - .../in/package/deployment.yaml | 24 -- .../in/package/kustomization.yaml | 16 - .../in/package/service.yaml | 11 - .../test.yaml | 4 - .../expected.diff | 99 ------ .../expected.yaml | 94 ------ .../in/overlay/kustomization.yaml | 14 - .../in/overlay/patches/deployment-patch1.yaml | 21 -- .../in/overlay/patches/deployment-patch2.yaml | 16 - .../in/package/deployment.yaml | 24 -- .../in/package/kustomization.yaml | 16 - .../in/package/service.yaml | 11 - .../test.yaml | 5 - pkg/target/multiplepatch_test.go | 293 ++++++++++++++++++ pkg/target/utils_for_test.go | 3 + 19 files changed, 296 insertions(+), 406 deletions(-) delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/deployment-patch1.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/deployment-patch2.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/deployment.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/service.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-conflict/test.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-noconflict/expected.diff delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-noconflict/expected.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/patches/deployment-patch1.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/patches/deployment-patch2.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/deployment.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/service.yaml delete mode 100644 pkg/commands/build/testdata/testcase-multiple-patches-noconflict/test.yaml create mode 100644 pkg/target/multiplepatch_test.go diff --git a/pkg/commands/build/build_test.go b/pkg/commands/build/build_test.go index ead4f6556..df332b73b 100644 --- a/pkg/commands/build/build_test.go +++ b/pkg/commands/build/build_test.go @@ -27,7 +27,6 @@ import ( "github.com/ghodss/yaml" "sigs.k8s.io/kustomize/k8sdeps" - "sigs.k8s.io/kustomize/pkg/commands/kustfile" "sigs.k8s.io/kustomize/pkg/constants" "sigs.k8s.io/kustomize/pkg/fs" ) @@ -98,10 +97,6 @@ func TestBuild(t *testing.T) { } return nil }) - // sanity check that we found the right folder - if !kustfile.StringInSlice("multiple-patches-noconflict", testcases) { - t.Fatalf("Error locating testcases") - } for _, testcaseName := range testcases { t.Run(testcaseName, func(t *testing.T) { diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/deployment-patch1.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/deployment-patch1.yaml deleted file mode 100644 index c92c5090e..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/deployment-patch1.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: apps/v1beta2 -kind: Deployment -metadata: - name: nginx -spec: - template: - spec: - containers: - - name: nginx - env: - - name: ENABLE_FEATURE_FOO - value: TRUE - volumes: - - name: nginx-persistent-storage - emptyDir: null - gcePersistentDisk: - pdName: nginx-persistent-storage - - configMap: - name: configmap-in-overlay - name: configmap-in-overlay diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/deployment-patch2.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/deployment-patch2.yaml deleted file mode 100644 index ab0bffbdf..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/deployment-patch2.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: apps/v1beta2 -kind: Deployment -metadata: - name: nginx -spec: - template: - spec: - containers: - - name: nginx - env: - - name: ENABLE_FEATURE_FOO - value: FALSE diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/kustomization.yaml deleted file mode 100644 index f153f0692..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/overlay/kustomization.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -namePrefix: staging- -commonLabels: - env: staging -patchesStrategicMerge: - - deployment-patch2.yaml - - deployment-patch1.yaml -bases: - - ../package/ -configMapGenerator: - - name: configmap-in-overlay - literals: - - hello=world diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/deployment.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/deployment.yaml deleted file mode 100644 index 9f7d3cbb6..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/deployment.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: apps/v1beta2 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx - volumeMounts: - - name: nginx-persistent-storage - mountPath: /tmp/ps - volumes: - - name: nginx-persistent-storage - emptyDir: {} - - configMap: - name: configmap-in-base - name: configmap-in-base diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/kustomization.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/kustomization.yaml deleted file mode 100644 index 34b6d11b3..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/kustomization.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -namePrefix: team-foo- -commonLabels: - app: mynginx - org: example.com - team: foo -commonAnnotations: - note: This is a test annotation -resources: - - deployment.yaml - - service.yaml -configMapGenerator: - - name: configmap-in-base - literals: - - foo=bar diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/service.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/service.yaml deleted file mode 100644 index f6dd86909..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/in/package/service.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: nginx - labels: - app: nginx -spec: - ports: - - port: 80 - selector: - app: nginx diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/test.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-conflict/test.yaml deleted file mode 100644 index a92e7f92d..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-conflict/test.yaml +++ /dev/null @@ -1,4 +0,0 @@ -description: conflict between multiple patches -args: [] -filename: testdata/testcase-multiple-patches-conflict/in/overlay/ -expectedError: conflict diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/expected.diff b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/expected.diff deleted file mode 100644 index c957e263b..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/expected.diff +++ /dev/null @@ -1,99 +0,0 @@ -diff -u -N /tmp/noop/apps_v1beta2_Deployment_nginx.yaml /tmp/transformed/apps_v1beta2_Deployment_nginx.yaml ---- /tmp/noop/apps_v1beta2_Deployment_nginx.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/apps_v1beta2_Deployment_nginx.yaml YYYY-MM-DD HH:MM:SS -@@ -5,13 +5,15 @@ - note: This is a test annotation - labels: - app: mynginx -+ env: staging - org: example.com - team: foo -- name: team-foo-nginx -+ name: staging-team-foo-nginx - spec: - selector: - matchLabels: - app: mynginx -+ env: staging - org: example.com - team: foo - template: -@@ -20,18 +22,30 @@ - note: This is a test annotation - labels: - app: mynginx -+ env: staging - org: example.com - team: foo - spec: - containers: -- - image: nginx -+ - env: -+ - name: ANOTHERENV -+ value: FOO -+ - name: ENVKEY -+ value: ENVVALUE -+ image: nginx:latest - name: nginx - volumeMounts: - - mountPath: /tmp/ps - name: nginx-persistent-storage -+ - image: sidecar -+ name: sidecar - volumes: -- - emptyDir: {} -+ - gcePersistentDisk: -+ pdName: nginx-persistent-storage - name: nginx-persistent-storage - - configMap: -- name: team-foo-configmap-in-base-bbdmdh7m8t -+ name: staging-configmap-in-overlay-k7cbc75tg8 -+ name: configmap-in-overlay -+ - configMap: -+ name: staging-team-foo-configmap-in-base-g7k6gt2889 - name: configmap-in-base -diff -u -N /tmp/noop/v1_ConfigMap_configmap-in-base.yaml /tmp/transformed/v1_ConfigMap_configmap-in-base.yaml ---- /tmp/noop/v1_ConfigMap_configmap-in-base.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_ConfigMap_configmap-in-base.yaml YYYY-MM-DD HH:MM:SS -@@ -8,6 +8,7 @@ - creationTimestamp: null - labels: - app: mynginx -+ env: staging - org: example.com - team: foo -- name: team-foo-configmap-in-base-bbdmdh7m8t -+ name: staging-team-foo-configmap-in-base-g7k6gt2889 -diff -u -N /tmp/noop/v1_ConfigMap_configmap-in-overlay.yaml /tmp/transformed/v1_ConfigMap_configmap-in-overlay.yaml ---- /tmp/noop/v1_ConfigMap_configmap-in-overlay.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_ConfigMap_configmap-in-overlay.yaml YYYY-MM-DD HH:MM:SS -@@ -0,0 +1,9 @@ -+apiVersion: v1 -+data: -+ hello: world -+kind: ConfigMap -+metadata: -+ creationTimestamp: null -+ labels: -+ env: staging -+ name: staging-configmap-in-overlay-k7cbc75tg8 -diff -u -N /tmp/noop/v1_Service_nginx.yaml /tmp/transformed/v1_Service_nginx.yaml ---- /tmp/noop/v1_Service_nginx.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_Service_nginx.yaml YYYY-MM-DD HH:MM:SS -@@ -5,13 +5,15 @@ - note: This is a test annotation - labels: - app: mynginx -+ env: staging - org: example.com - team: foo -- name: team-foo-nginx -+ name: staging-team-foo-nginx - spec: - ports: - - port: 80 - selector: - app: mynginx -+ env: staging - org: example.com - team: foo diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/expected.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/expected.yaml deleted file mode 100644 index 2404ec1c9..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/expected.yaml +++ /dev/null @@ -1,94 +0,0 @@ -apiVersion: v1 -data: - foo: bar -kind: ConfigMap -metadata: - annotations: - note: This is a test annotation - labels: - app: mynginx - env: staging - org: example.com - team: foo - name: staging-team-foo-configmap-in-base-g7k6gt2889 ---- -apiVersion: v1 -data: - hello: world -kind: ConfigMap -metadata: - labels: - env: staging - name: staging-configmap-in-overlay-k7cbc75tg8 ---- -apiVersion: v1 -kind: Service -metadata: - annotations: - note: This is a test annotation - labels: - app: mynginx - env: staging - org: example.com - team: foo - name: staging-team-foo-nginx -spec: - ports: - - port: 80 - selector: - app: mynginx - env: staging - org: example.com - team: foo ---- -apiVersion: apps/v1beta2 -kind: Deployment -metadata: - annotations: - note: This is a test annotation - labels: - app: mynginx - env: staging - org: example.com - team: foo - name: staging-team-foo-nginx -spec: - selector: - matchLabels: - app: mynginx - env: staging - org: example.com - team: foo - template: - metadata: - annotations: - note: This is a test annotation - labels: - app: mynginx - env: staging - org: example.com - team: foo - spec: - containers: - - env: - - name: ANOTHERENV - value: FOO - - name: ENVKEY - value: ENVVALUE - image: nginx:latest - name: nginx - volumeMounts: - - mountPath: /tmp/ps - name: nginx-persistent-storage - - image: sidecar - name: sidecar - volumes: - - gcePersistentDisk: - pdName: nginx-persistent-storage - name: nginx-persistent-storage - - configMap: - name: staging-configmap-in-overlay-k7cbc75tg8 - name: configmap-in-overlay - - configMap: - name: staging-team-foo-configmap-in-base-g7k6gt2889 - name: configmap-in-base diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml deleted file mode 100644 index 4fb0c9391..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/kustomization.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -namePrefix: staging- -commonLabels: - env: staging -patchesStrategicMerge: - - patches/deployment-patch1.yaml - - patches/deployment-patch2.yaml -bases: - - ../package/ -configMapGenerator: - - name: configmap-in-overlay - literals: - - hello=world diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/patches/deployment-patch1.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/patches/deployment-patch1.yaml deleted file mode 100644 index 444e05b22..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/patches/deployment-patch1.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: apps/v1beta2 -kind: Deployment -metadata: - name: nginx -spec: - template: - spec: - containers: - - name: nginx - image: nginx:latest - env: - - name: ENVKEY - value: ENVVALUE - volumes: - - name: nginx-persistent-storage - emptyDir: null - gcePersistentDisk: - pdName: nginx-persistent-storage - - configMap: - name: configmap-in-overlay - name: configmap-in-overlay diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/patches/deployment-patch2.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/patches/deployment-patch2.yaml deleted file mode 100644 index f4006d1c7..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/overlay/patches/deployment-patch2.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: apps/v1beta2 -kind: Deployment -metadata: - name: nginx -spec: - template: - spec: - containers: - - name: nginx - env: - - name: ANOTHERENV - value: FOO - - name: sidecar - image: sidecar - volumes: - - name: nginx-persistent-storage diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/deployment.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/deployment.yaml deleted file mode 100644 index 9f7d3cbb6..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/deployment.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: apps/v1beta2 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx - volumeMounts: - - name: nginx-persistent-storage - mountPath: /tmp/ps - volumes: - - name: nginx-persistent-storage - emptyDir: {} - - configMap: - name: configmap-in-base - name: configmap-in-base diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/kustomization.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/kustomization.yaml deleted file mode 100644 index 34b6d11b3..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/kustomization.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -namePrefix: team-foo- -commonLabels: - app: mynginx - org: example.com - team: foo -commonAnnotations: - note: This is a test annotation -resources: - - deployment.yaml - - service.yaml -configMapGenerator: - - name: configmap-in-base - literals: - - foo=bar diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/service.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/service.yaml deleted file mode 100644 index f6dd86909..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/in/package/service.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: nginx - labels: - app: nginx -spec: - ports: - - port: 80 - selector: - app: nginx diff --git a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/test.yaml b/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/test.yaml deleted file mode 100644 index 0b9aaf1b5..000000000 --- a/pkg/commands/build/testdata/testcase-multiple-patches-noconflict/test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -description: multiple patches no conflict -args: [] -filename: testdata/testcase-multiple-patches-noconflict/in/overlay/ -expectedStdout: testdata/testcase-multiple-patches-noconflict/expected.yaml -expectedDiff: testdata/testcase-multiple-patches-noconflict/expected.diff diff --git a/pkg/target/multiplepatch_test.go b/pkg/target/multiplepatch_test.go new file mode 100644 index 000000000..ac4e350c6 --- /dev/null +++ b/pkg/target/multiplepatch_test.go @@ -0,0 +1,293 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "strings" + "testing" +) + +func makeCommonFileForMultiplePatchTest(th *KustTestHarness) { + th.writeK("/app/base", ` +apiVersion: v1beta1 +kind: Kustomization +namePrefix: team-foo- +commonLabels: + app: mynginx + org: example.com + team: foo +commonAnnotations: + note: This is a test annotation +resources: + - deployment.yaml + - service.yaml +configMapGenerator: + - name: configmap-in-base + literals: + - foo=bar +`) + th.writeF("/app/base/deployment.yaml", ` +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: nginx + labels: + app: nginx +spec: + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx + volumeMounts: + - name: nginx-persistent-storage + mountPath: /tmp/ps + volumes: + - name: nginx-persistent-storage + emptyDir: {} + - configMap: + name: configmap-in-base + name: configmap-in-base +`) + th.writeF("/app/base/service.yaml", ` +apiVersion: v1 +kind: Service +metadata: + name: nginx + labels: + app: nginx +spec: + ports: + - port: 80 + selector: + app: nginx +`) + th.writeK("/app/overlay/staging", ` +apiVersion: v1beta1 +kind: Kustomization +namePrefix: staging- +commonLabels: + env: staging +patchesStrategicMerge: + - deployment-patch1.yaml + - deployment-patch2.yaml +bases: + - ../../base +configMapGenerator: + - name: configmap-in-overlay + literals: + - hello=world +`) +} + +func TestMultiplePatchesNoConflict(t *testing.T) { + th := NewKustTestHarness(t, "/app/overlay/staging") + makeCommonFileForMultiplePatchTest(th) + th.writeF("/app/overlay/staging/deployment-patch1.yaml", ` +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: nginx +spec: + template: + spec: + containers: + - name: nginx + image: nginx:latest + env: + - name: ENVKEY + value: ENVVALUE + volumes: + - name: nginx-persistent-storage + emptyDir: null + gcePersistentDisk: + pdName: nginx-persistent-storage + - configMap: + name: configmap-in-overlay + name: configmap-in-overlay +`) + th.writeF("/app/overlay/staging/deployment-patch2.yaml", ` +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: nginx +spec: + template: + spec: + containers: + - name: nginx + env: + - name: ANOTHERENV + value: FOO + - name: sidecar + image: sidecar + volumes: + - name: nginx-persistent-storage +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + foo: bar +kind: ConfigMap +metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + env: staging + org: example.com + team: foo + name: staging-team-foo-configmap-in-base-g7k6gt2889 +--- +apiVersion: v1 +data: + hello: world +kind: ConfigMap +metadata: + labels: + env: staging + name: staging-configmap-in-overlay-k7cbc75tg8 +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + env: staging + org: example.com + team: foo + name: staging-team-foo-nginx +spec: + ports: + - port: 80 + selector: + app: mynginx + env: staging + org: example.com + team: foo +--- +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + env: staging + org: example.com + team: foo + name: staging-team-foo-nginx +spec: + selector: + matchLabels: + app: mynginx + env: staging + org: example.com + team: foo + template: + metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + env: staging + org: example.com + team: foo + spec: + containers: + - env: + - name: ANOTHERENV + value: FOO + - name: ENVKEY + value: ENVVALUE + image: nginx:latest + name: nginx + volumeMounts: + - mountPath: /tmp/ps + name: nginx-persistent-storage + - image: sidecar + name: sidecar + volumes: + - gcePersistentDisk: + pdName: nginx-persistent-storage + name: nginx-persistent-storage + - configMap: + name: staging-configmap-in-overlay-k7cbc75tg8 + name: configmap-in-overlay + - configMap: + name: staging-team-foo-configmap-in-base-g7k6gt2889 + name: configmap-in-base +`) +} + +func TestMultiplePatchesWithConflict(t *testing.T) { + th := NewKustTestHarness(t, "/app/overlay/staging") + makeCommonFileForMultiplePatchTest(th) + th.writeF("/app/overlay/staging/deployment-patch1.yaml", ` +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: nginx +spec: + template: + spec: + containers: + - name: nginx + env: + - name: ENABLE_FEATURE_FOO + value: TRUE + volumes: + - name: nginx-persistent-storage + emptyDir: null + gcePersistentDisk: + pdName: nginx-persistent-storage + - configMap: + name: configmap-in-overlay + name: configmap-in-overlay +`) + th.writeF("/app/overlay/staging/deployment-patch2.yaml", ` +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: nginx +spec: + template: + spec: + containers: + - name: nginx + env: + - name: ENABLE_FEATURE_FOO + value: FALSE +`) + _, err := th.makeKustTarget().MakeCustomizedResMap() + if err == nil { + t.Fatalf("expected conflict") + } + if !strings.Contains( + err.Error(), "conflict between ") { + t.Fatalf("Unexpected err: %v", err) + } +} diff --git a/pkg/target/utils_for_test.go b/pkg/target/utils_for_test.go index d3fedce95..8aebc4f8e 100644 --- a/pkg/target/utils_for_test.go +++ b/pkg/target/utils_for_test.go @@ -151,6 +151,9 @@ func (th *KustTestHarness) assertActualEqualsExpected( func (th *KustTestHarness) reportDiffAndFail(actual []byte, expected string) { sE, maxLen := convertToArray(expected) sA, _ := convertToArray(string(actual)) + fmt.Println("-- ACTUAL -----------------") + fmt.Println(string(actual)) + fmt.Println("---------------------------") format := fmt.Sprintf("%%s %%-%ds %%s\n", maxLen+4) limit := 0 if len(sE) < len(sA) { From 8b76799dd968586f8938ace0b3f67920453e1898 Mon Sep 17 00:00:00 2001 From: jregan Date: Fri, 28 Dec 2018 08:04:34 -0800 Subject: [PATCH 034/317] Convert variable tests to in-memory. --- .../expected.yaml | 53 -- .../in/base/deployment.yaml | 21 - .../in/base/ingress.yaml | 18 - .../in/base/kustomization.yaml | 15 - .../in/base/service.yaml | 12 - .../in/overlay/kustomization.yaml | 6 - .../testcase-variable-ref-ingress/test.yaml | 4 - .../testcase-variable-ref/expected.diff | 186 ----- .../testcase-variable-ref/expected.yaml | 235 ------ .../in/overlay/kustomization.yaml | 6 - .../cockroachdb-statefulset-secure.yaml | 235 ------ .../in/package/cronjob.yaml | 21 - .../in/package/kustomization.yaml | 41 - .../testdata/testcase-variable-ref/test.yaml | 5 - pkg/target/utils_for_test.go | 6 +- pkg/target/variableref_test.go | 725 ++++++++++++++++++ 16 files changed, 728 insertions(+), 861 deletions(-) delete mode 100644 pkg/commands/build/testdata/testcase-variable-ref-ingress/expected.yaml delete mode 100644 pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/deployment.yaml delete mode 100644 pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/ingress.yaml delete mode 100644 pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/service.yaml delete mode 100644 pkg/commands/build/testdata/testcase-variable-ref-ingress/in/overlay/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-variable-ref-ingress/test.yaml delete mode 100644 pkg/commands/build/testdata/testcase-variable-ref/expected.diff delete mode 100644 pkg/commands/build/testdata/testcase-variable-ref/expected.yaml delete mode 100644 pkg/commands/build/testdata/testcase-variable-ref/in/overlay/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-variable-ref/in/package/cockroachdb-statefulset-secure.yaml delete mode 100644 pkg/commands/build/testdata/testcase-variable-ref/in/package/cronjob.yaml delete mode 100644 pkg/commands/build/testdata/testcase-variable-ref/in/package/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-variable-ref/test.yaml create mode 100644 pkg/target/variableref_test.go diff --git a/pkg/commands/build/testdata/testcase-variable-ref-ingress/expected.yaml b/pkg/commands/build/testdata/testcase-variable-ref-ingress/expected.yaml deleted file mode 100644 index 4bbd29393..000000000 --- a/pkg/commands/build/testdata/testcase-variable-ref-ingress/expected.yaml +++ /dev/null @@ -1,53 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/component: nginx - name: kustomized-nginx -spec: - ports: - - name: http - port: 80 - protocol: TCP - targetPort: http ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/component: nginx - name: kustomized-nginx -spec: - selector: - matchLabels: - app.kubernetes.io/component: nginx - template: - metadata: - labels: - app.kubernetes.io/component: nginx - spec: - containers: - - image: nginx:1.15.7-alpine - name: nginx - ports: - - containerPort: 80 - name: http ---- -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - labels: - app.kubernetes.io/component: nginx - name: kustomized-nginx -spec: - rules: - - host: kustomized-nginx.example.com - http: - paths: - - backend: - serviceName: kustomized-nginx - servicePort: 80 - path: / - tls: - - hosts: - - kustomized-nginx.example.com diff --git a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/deployment.yaml b/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/deployment.yaml deleted file mode 100644 index 469300ac4..000000000 --- a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/deployment.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx - labels: - app.kubernetes.io/component: nginx -spec: - selector: - matchLabels: - app.kubernetes.io/component: nginx - template: - metadata: - labels: - app.kubernetes.io/component: nginx - spec: - containers: - - name: nginx - image: nginx:1.15.7-alpine - ports: - - name: http - containerPort: 80 diff --git a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/ingress.yaml b/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/ingress.yaml deleted file mode 100644 index 733be9803..000000000 --- a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/ingress.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: nginx - labels: - app.kubernetes.io/component: nginx -spec: - rules: - - host: $(DEPLOYMENT_NAME).example.com - http: - paths: - - backend: - serviceName: nginx - servicePort: 80 - path: / - tls: - - hosts: - - $(DEPLOYMENT_NAME).example.com diff --git a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/kustomization.yaml b/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/kustomization.yaml deleted file mode 100644 index 403316ec8..000000000 --- a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/kustomization.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -resources: -- deployment.yaml -- ingress.yaml -- service.yaml - -vars: -- name: DEPLOYMENT_NAME - objref: - apiVersion: apps/v1 - kind: Deployment - name: nginx - fieldref: - fieldpath: metadata.name diff --git a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/service.yaml b/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/service.yaml deleted file mode 100644 index 6d426d9e6..000000000 --- a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/base/service.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: nginx - labels: - app.kubernetes.io/component: nginx -spec: - ports: - - name: http - port: 80 - protocol: TCP - targetPort: http diff --git a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/overlay/kustomization.yaml deleted file mode 100644 index 0ae516e62..000000000 --- a/pkg/commands/build/testdata/testcase-variable-ref-ingress/in/overlay/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -nameprefix: kustomized- - -bases: -- ../base diff --git a/pkg/commands/build/testdata/testcase-variable-ref-ingress/test.yaml b/pkg/commands/build/testdata/testcase-variable-ref-ingress/test.yaml deleted file mode 100644 index 89ddf6a76..000000000 --- a/pkg/commands/build/testdata/testcase-variable-ref-ingress/test.yaml +++ /dev/null @@ -1,4 +0,0 @@ -description: variable reference and substitution for ingress resources -args: [] -filename: testdata/testcase-variable-ref-ingress/in/overlay/ -expectedStdout: testdata/testcase-variable-ref-ingress/expected.yaml diff --git a/pkg/commands/build/testdata/testcase-variable-ref/expected.diff b/pkg/commands/build/testdata/testcase-variable-ref/expected.diff deleted file mode 100644 index 76ec67755..000000000 --- a/pkg/commands/build/testdata/testcase-variable-ref/expected.diff +++ /dev/null @@ -1,186 +0,0 @@ -diff -u -N /tmp/noop/apps_v1beta1_StatefulSet_cockroachdb.yaml /tmp/transformed/apps_v1beta1_StatefulSet_cockroachdb.yaml ---- /tmp/noop/apps_v1beta1_StatefulSet_cockroachdb.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/apps_v1beta1_StatefulSet_cockroachdb.yaml YYYY-MM-DD HH:MM:SS -@@ -1,10 +1,10 @@ - apiVersion: apps/v1beta1 - kind: StatefulSet - metadata: -- name: base-cockroachdb -+ name: dev-base-cockroachdb - spec: - replicas: 3 -- serviceName: base-cockroachdb -+ serviceName: dev-base-cockroachdb - template: - metadata: - labels: -@@ -27,7 +27,7 @@ - - /bin/bash - - -ecx - - exec /cockroach/cockroach start --logtostderr --certs-dir /cockroach/cockroach-certs -- --host $(hostname -f) --http-host 0.0.0.0 --join base-cockroachdb-0.base-cockroachdb,base-cockroachdb-1.base-cockroachdb,base-cockroachdb-2.base-cockroachdb -+ --host $(hostname -f) --http-host 0.0.0.0 --join dev-base-cockroachdb-0.dev-base-cockroachdb,dev-base-cockroachdb-1.dev-base-cockroachdb,dev-base-cockroachdb-2.dev-base-cockroachdb - --cache 25% --max-sql-memory 25% - image: cockroachdb/cockroach:v1.1.5 - imagePullPolicy: IfNotPresent -@@ -48,7 +48,7 @@ - - -ecx - - /request-cert -namespace=${POD_NAMESPACE} -certs-dir=/cockroach-certs -type=node - -addresses=localhost,127.0.0.1,${POD_IP},$(hostname -f),$(hostname -f|cut -- -f 1-2 -d '.'),base-cockroachdb-public -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt -+ -f 1-2 -d '.'),dev-base-cockroachdb-public -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt - env: - - name: POD_IP - valueFrom: -@@ -64,7 +64,7 @@ - volumeMounts: - - mountPath: /cockroach-certs - name: certs -- serviceAccountName: base-cockroachdb -+ serviceAccountName: dev-base-cockroachdb - terminationGracePeriodSeconds: 60 - volumes: - - name: datadir -diff -u -N /tmp/noop/batch_v1beta1_CronJob_cronjob-example.yaml /tmp/transformed/batch_v1beta1_CronJob_cronjob-example.yaml ---- /tmp/noop/batch_v1beta1_CronJob_cronjob-example.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/batch_v1beta1_CronJob_cronjob-example.yaml YYYY-MM-DD HH:MM:SS -@@ -1,7 +1,7 @@ - apiVersion: batch/v1beta1 - kind: CronJob - metadata: -- name: base-cronjob-example -+ name: dev-base-cronjob-example - spec: - concurrencyPolicy: Forbid - jobTemplate: -@@ -11,11 +11,11 @@ - containers: - - command: - - echo -- - base-cockroachdb -- - base-test-config-map-259876d7fg -+ - dev-base-cockroachdb -+ - dev-base-test-config-map-b2g2dmd64b - env: - - name: CDB_PUBLIC_SVC -- value: base-cockroachdb-public -+ value: dev-base-cockroachdb-public - image: cockroachdb/cockroach:v1.1.5 - name: cronjob-example - schedule: '*/1 * * * *' -diff -u -N /tmp/noop/policy_v1beta1_PodDisruptionBudget_cockroachdb-budget.yaml /tmp/transformed/policy_v1beta1_PodDisruptionBudget_cockroachdb-budget.yaml ---- /tmp/noop/policy_v1beta1_PodDisruptionBudget_cockroachdb-budget.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/policy_v1beta1_PodDisruptionBudget_cockroachdb-budget.yaml YYYY-MM-DD HH:MM:SS -@@ -3,7 +3,7 @@ - metadata: - labels: - app: cockroachdb -- name: base-cockroachdb-budget -+ name: dev-base-cockroachdb-budget - spec: - maxUnavailable: 1 - selector: -diff -u -N /tmp/noop/rbac.authorization.k8s.io_v1beta1_ClusterRoleBinding_cockroachdb.yaml /tmp/transformed/rbac.authorization.k8s.io_v1beta1_ClusterRoleBinding_cockroachdb.yaml ---- /tmp/noop/rbac.authorization.k8s.io_v1beta1_ClusterRoleBinding_cockroachdb.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/rbac.authorization.k8s.io_v1beta1_ClusterRoleBinding_cockroachdb.yaml YYYY-MM-DD HH:MM:SS -@@ -3,12 +3,12 @@ - metadata: - labels: - app: cockroachdb -- name: base-cockroachdb -+ name: dev-base-cockroachdb - roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole -- name: base-cockroachdb -+ name: dev-base-cockroachdb - subjects: - - kind: ServiceAccount -- name: base-cockroachdb -+ name: dev-base-cockroachdb - namespace: default -diff -u -N /tmp/noop/rbac.authorization.k8s.io_v1beta1_ClusterRole_cockroachdb.yaml /tmp/transformed/rbac.authorization.k8s.io_v1beta1_ClusterRole_cockroachdb.yaml ---- /tmp/noop/rbac.authorization.k8s.io_v1beta1_ClusterRole_cockroachdb.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/rbac.authorization.k8s.io_v1beta1_ClusterRole_cockroachdb.yaml YYYY-MM-DD HH:MM:SS -@@ -3,7 +3,7 @@ - metadata: - labels: - app: cockroachdb -- name: base-cockroachdb -+ name: dev-base-cockroachdb - rules: - - apiGroups: - - certificates.k8s.io -diff -u -N /tmp/noop/rbac.authorization.k8s.io_v1beta1_RoleBinding_cockroachdb.yaml /tmp/transformed/rbac.authorization.k8s.io_v1beta1_RoleBinding_cockroachdb.yaml ---- /tmp/noop/rbac.authorization.k8s.io_v1beta1_RoleBinding_cockroachdb.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/rbac.authorization.k8s.io_v1beta1_RoleBinding_cockroachdb.yaml YYYY-MM-DD HH:MM:SS -@@ -3,12 +3,12 @@ - metadata: - labels: - app: cockroachdb -- name: base-cockroachdb -+ name: dev-base-cockroachdb - roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role -- name: base-cockroachdb -+ name: dev-base-cockroachdb - subjects: - - kind: ServiceAccount -- name: base-cockroachdb -+ name: dev-base-cockroachdb - namespace: default -diff -u -N /tmp/noop/rbac.authorization.k8s.io_v1beta1_Role_cockroachdb.yaml /tmp/transformed/rbac.authorization.k8s.io_v1beta1_Role_cockroachdb.yaml ---- /tmp/noop/rbac.authorization.k8s.io_v1beta1_Role_cockroachdb.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/rbac.authorization.k8s.io_v1beta1_Role_cockroachdb.yaml YYYY-MM-DD HH:MM:SS -@@ -3,7 +3,7 @@ - metadata: - labels: - app: cockroachdb -- name: base-cockroachdb -+ name: dev-base-cockroachdb - rules: - - apiGroups: - - "" -diff -u -N /tmp/noop/v1_ConfigMap_test-config-map.yaml /tmp/transformed/v1_ConfigMap_test-config-map.yaml ---- /tmp/noop/v1_ConfigMap_test-config-map.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_ConfigMap_test-config-map.yaml YYYY-MM-DD HH:MM:SS -@@ -5,4 +5,4 @@ - kind: ConfigMap - metadata: - creationTimestamp: null -- name: base-test-config-map-259876d7fg -+ name: dev-base-test-config-map-b2g2dmd64b -diff -u -N /tmp/noop/v1_ServiceAccount_cockroachdb.yaml /tmp/transformed/v1_ServiceAccount_cockroachdb.yaml ---- /tmp/noop/v1_ServiceAccount_cockroachdb.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_ServiceAccount_cockroachdb.yaml YYYY-MM-DD HH:MM:SS -@@ -3,4 +3,4 @@ - metadata: - labels: - app: cockroachdb -- name: base-cockroachdb -+ name: dev-base-cockroachdb -diff -u -N /tmp/noop/v1_Service_cockroachdb-public.yaml /tmp/transformed/v1_Service_cockroachdb-public.yaml ---- /tmp/noop/v1_Service_cockroachdb-public.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_Service_cockroachdb-public.yaml YYYY-MM-DD HH:MM:SS -@@ -3,7 +3,7 @@ - metadata: - labels: - app: cockroachdb -- name: base-cockroachdb-public -+ name: dev-base-cockroachdb-public - spec: - ports: - - name: grpc -diff -u -N /tmp/noop/v1_Service_cockroachdb.yaml /tmp/transformed/v1_Service_cockroachdb.yaml ---- /tmp/noop/v1_Service_cockroachdb.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_Service_cockroachdb.yaml YYYY-MM-DD HH:MM:SS -@@ -8,7 +8,7 @@ - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" - labels: - app: cockroachdb -- name: base-cockroachdb -+ name: dev-base-cockroachdb - spec: - clusterIP: None - ports: diff --git a/pkg/commands/build/testdata/testcase-variable-ref/expected.yaml b/pkg/commands/build/testdata/testcase-variable-ref/expected.yaml deleted file mode 100644 index ab030bf5b..000000000 --- a/pkg/commands/build/testdata/testcase-variable-ref/expected.yaml +++ /dev/null @@ -1,235 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app: cockroachdb - name: dev-base-cockroachdb ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: Role -metadata: - labels: - app: cockroachdb - name: dev-base-cockroachdb -rules: -- apiGroups: - - "" - resources: - - secrets - verbs: - - create - - get ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRole -metadata: - labels: - app: cockroachdb - name: dev-base-cockroachdb -rules: -- apiGroups: - - certificates.k8s.io - resources: - - certificatesigningrequests - verbs: - - create - - get - - watch ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: RoleBinding -metadata: - labels: - app: cockroachdb - name: dev-base-cockroachdb -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: dev-base-cockroachdb -subjects: -- kind: ServiceAccount - name: dev-base-cockroachdb - namespace: default ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRoleBinding -metadata: - labels: - app: cockroachdb - name: dev-base-cockroachdb -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: dev-base-cockroachdb -subjects: -- kind: ServiceAccount - name: dev-base-cockroachdb - namespace: default ---- -apiVersion: v1 -data: - baz: qux - foo: bar -kind: ConfigMap -metadata: - name: dev-base-test-config-map-b2g2dmd64b ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app: cockroachdb - name: dev-base-cockroachdb-public -spec: - ports: - - name: grpc - port: 26257 - targetPort: 26257 - - name: http - port: 8080 - targetPort: 8080 - selector: - app: cockroachdb ---- -apiVersion: v1 -kind: Service -metadata: - annotations: - prometheus.io/path: _status/vars - prometheus.io/port: "8080" - prometheus.io/scrape: "true" - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" - labels: - app: cockroachdb - name: dev-base-cockroachdb -spec: - clusterIP: None - ports: - - name: grpc - port: 26257 - targetPort: 26257 - - name: http - port: 8080 - targetPort: 8080 - selector: - app: cockroachdb ---- -apiVersion: apps/v1beta1 -kind: StatefulSet -metadata: - name: dev-base-cockroachdb -spec: - replicas: 3 - serviceName: dev-base-cockroachdb - template: - metadata: - labels: - app: cockroachdb - spec: - affinity: - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - podAffinityTerm: - labelSelector: - matchExpressions: - - key: app - operator: In - values: - - cockroachdb - topologyKey: kubernetes.io/hostname - weight: 100 - containers: - - command: - - /bin/bash - - -ecx - - exec /cockroach/cockroach start --logtostderr --certs-dir /cockroach/cockroach-certs - --host $(hostname -f) --http-host 0.0.0.0 --join dev-base-cockroachdb-0.dev-base-cockroachdb,dev-base-cockroachdb-1.dev-base-cockroachdb,dev-base-cockroachdb-2.dev-base-cockroachdb - --cache 25% --max-sql-memory 25% - image: cockroachdb/cockroach:v1.1.5 - imagePullPolicy: IfNotPresent - name: cockroachdb - ports: - - containerPort: 26257 - name: grpc - - containerPort: 8080 - name: http - volumeMounts: - - mountPath: /cockroach/cockroach-data - name: datadir - - mountPath: /cockroach/cockroach-certs - name: certs - initContainers: - - command: - - /bin/ash - - -ecx - - /request-cert -namespace=${POD_NAMESPACE} -certs-dir=/cockroach-certs -type=node - -addresses=localhost,127.0.0.1,${POD_IP},$(hostname -f),$(hostname -f|cut - -f 1-2 -d '.'),dev-base-cockroachdb-public -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt - env: - - name: POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - image: cockroachdb/cockroach-k8s-request-cert:0.2 - imagePullPolicy: IfNotPresent - name: init-certs - volumeMounts: - - mountPath: /cockroach-certs - name: certs - serviceAccountName: dev-base-cockroachdb - terminationGracePeriodSeconds: 60 - volumes: - - name: datadir - persistentVolumeClaim: - claimName: datadir - - emptyDir: {} - name: certs - updateStrategy: - type: RollingUpdate - volumeClaimTemplates: - - metadata: - name: datadir - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi ---- -apiVersion: batch/v1beta1 -kind: CronJob -metadata: - name: dev-base-cronjob-example -spec: - concurrencyPolicy: Forbid - jobTemplate: - spec: - template: - spec: - containers: - - command: - - echo - - dev-base-cockroachdb - - dev-base-test-config-map-b2g2dmd64b - env: - - name: CDB_PUBLIC_SVC - value: dev-base-cockroachdb-public - image: cockroachdb/cockroach:v1.1.5 - name: cronjob-example - schedule: '*/1 * * * *' ---- -apiVersion: policy/v1beta1 -kind: PodDisruptionBudget -metadata: - labels: - app: cockroachdb - name: dev-base-cockroachdb-budget -spec: - maxUnavailable: 1 - selector: - matchLabels: - app: cockroachdb diff --git a/pkg/commands/build/testdata/testcase-variable-ref/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-variable-ref/in/overlay/kustomization.yaml deleted file mode 100644 index 9d4cc170d..000000000 --- a/pkg/commands/build/testdata/testcase-variable-ref/in/overlay/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -namePrefix: dev- -bases: -- ../package - diff --git a/pkg/commands/build/testdata/testcase-variable-ref/in/package/cockroachdb-statefulset-secure.yaml b/pkg/commands/build/testdata/testcase-variable-ref/in/package/cockroachdb-statefulset-secure.yaml deleted file mode 100644 index 5feb4a669..000000000 --- a/pkg/commands/build/testdata/testcase-variable-ref/in/package/cockroachdb-statefulset-secure.yaml +++ /dev/null @@ -1,235 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: cockroachdb - labels: - app: cockroachdb ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: Role -metadata: - name: cockroachdb - labels: - app: cockroachdb -rules: -- apiGroups: - - "" - resources: - - secrets - verbs: - - create - - get ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRole -metadata: - name: cockroachdb - labels: - app: cockroachdb -rules: -- apiGroups: - - certificates.k8s.io - resources: - - certificatesigningrequests - verbs: - - create - - get - - watch ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: RoleBinding -metadata: - name: cockroachdb - labels: - app: cockroachdb -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: cockroachdb -subjects: -- kind: ServiceAccount - name: cockroachdb - namespace: default ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRoleBinding -metadata: - name: cockroachdb - labels: - app: cockroachdb -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: cockroachdb -subjects: -- kind: ServiceAccount - name: cockroachdb - namespace: default ---- -apiVersion: v1 -kind: Service -metadata: - # This service is meant to be used by clients of the database. It exposes a ClusterIP that will - # automatically load balance connections to the different database pods. - name: cockroachdb-public - labels: - app: cockroachdb -spec: - ports: - # The main port, served by gRPC, serves Postgres-flavor SQL, internode - # traffic and the cli. - - port: 26257 - targetPort: 26257 - name: grpc - # The secondary port serves the UI as well as health and debug endpoints. - - port: 8080 - targetPort: 8080 - name: http - selector: - app: cockroachdb ---- -apiVersion: v1 -kind: Service -metadata: - # This service only exists to create DNS entries for each pod in the stateful - # set such that they can resolve each other's IP addresses. It does not - # create a load-balanced ClusterIP and should not be used directly by clients - # in most circumstances. - name: cockroachdb - labels: - app: cockroachdb - annotations: - # This is needed to make the peer-finder work properly and to help avoid - # edge cases where instance 0 comes up after losing its data and needs to - # decide whether it should create a new cluster or try to join an existing - # one. If it creates a new cluster when it should have joined an existing - # one, we'd end up with two separate clusters listening at the same service - # endpoint, which would be very bad. - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" - # Enable automatic monitoring of all instances when Prometheus is running in the cluster. - prometheus.io/scrape: "true" - prometheus.io/path: "_status/vars" - prometheus.io/port: "8080" -spec: - ports: - - port: 26257 - targetPort: 26257 - name: grpc - - port: 8080 - targetPort: 8080 - name: http - clusterIP: None - selector: - app: cockroachdb ---- -apiVersion: policy/v1beta1 -kind: PodDisruptionBudget -metadata: - name: cockroachdb-budget - labels: - app: cockroachdb -spec: - selector: - matchLabels: - app: cockroachdb - maxUnavailable: 1 ---- -apiVersion: apps/v1beta1 -kind: StatefulSet -metadata: - name: cockroachdb -spec: - serviceName: "cockroachdb" - replicas: 3 - template: - metadata: - labels: - app: cockroachdb - spec: - serviceAccountName: cockroachdb - # Init containers are run only once in the lifetime of a pod, before - # it's started up for the first time. It has to exit successfully - # before the pod's main containers are allowed to start. - initContainers: - # The init-certs container sends a certificate signing request to the - # kubernetes cluster. - # You can see pending requests using: kubectl get csr - # CSRs can be approved using: kubectl certificate approve - # - # All addresses used to contact a node must be specified in the --addresses arg. - # - # In addition to the node certificate and key, the init-certs entrypoint will symlink - # the cluster CA to the certs directory. - - name: init-certs - image: cockroachdb/cockroach-k8s-request-cert:0.2 - imagePullPolicy: IfNotPresent - command: - - "/bin/ash" - - "-ecx" - - "/request-cert -namespace=${POD_NAMESPACE} -certs-dir=/cockroach-certs -type=node -addresses=localhost,127.0.0.1,${POD_IP},$(hostname -f),$(hostname -f|cut -f 1-2 -d '.'),$(CDB_PUBLIC_SVC) -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" - env: - - name: POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - volumeMounts: - - name: certs - mountPath: /cockroach-certs - - affinity: - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - podAffinityTerm: - labelSelector: - matchExpressions: - - key: app - operator: In - values: - - cockroachdb - topologyKey: kubernetes.io/hostname - containers: - - name: cockroachdb - image: cockroachdb/cockroach:v1.1.5 - imagePullPolicy: IfNotPresent - ports: - - containerPort: 26257 - name: grpc - - containerPort: 8080 - name: http - volumeMounts: - - name: datadir - mountPath: /cockroach/cockroach-data - - name: certs - mountPath: /cockroach/cockroach-certs - command: - - "/bin/bash" - - "-ecx" - # The use of qualified `hostname -f` is crucial: - # Other nodes aren't able to look up the unqualified hostname. - # Once 2.0 is out, we should be able to switch from --host to --advertise-host to make port-forwarding work to the main port. - - "exec /cockroach/cockroach start --logtostderr --certs-dir /cockroach/cockroach-certs --host $(hostname -f) --http-host 0.0.0.0 --join $(CDB_STATEFULSET_NAME)-0.$(CDB_STATEFULSET_SVC),$(CDB_STATEFULSET_NAME)-1.$(CDB_STATEFULSET_SVC),$(CDB_STATEFULSET_NAME)-2.$(CDB_STATEFULSET_SVC) --cache 25% --max-sql-memory 25%" - # No pre-stop hook is required, a SIGTERM plus some time is all that's - # needed for graceful shutdown of a node. - terminationGracePeriodSeconds: 60 - volumes: - - name: datadir - persistentVolumeClaim: - claimName: datadir - - name: certs - emptyDir: {} - updateStrategy: - type: RollingUpdate - volumeClaimTemplates: - - metadata: - name: datadir - spec: - accessModes: - - "ReadWriteOnce" - resources: - requests: - storage: 1Gi diff --git a/pkg/commands/build/testdata/testcase-variable-ref/in/package/cronjob.yaml b/pkg/commands/build/testdata/testcase-variable-ref/in/package/cronjob.yaml deleted file mode 100644 index 64615c251..000000000 --- a/pkg/commands/build/testdata/testcase-variable-ref/in/package/cronjob.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: batch/v1beta1 -kind: CronJob -metadata: - name: cronjob-example -spec: - schedule: "*/1 * * * *" - concurrencyPolicy: Forbid - jobTemplate: - spec: - template: - spec: - containers: - - name: cronjob-example - image: cockroachdb/cockroach:v1.1.5 - command: - - echo - - "$(CDB_STATEFULSET_NAME)" - - "$(TEST_CONFIG_MAP)" - env: - - name: CDB_PUBLIC_SVC - value: "$(CDB_PUBLIC_SVC)" diff --git a/pkg/commands/build/testdata/testcase-variable-ref/in/package/kustomization.yaml b/pkg/commands/build/testdata/testcase-variable-ref/in/package/kustomization.yaml deleted file mode 100644 index e081ba807..000000000 --- a/pkg/commands/build/testdata/testcase-variable-ref/in/package/kustomization.yaml +++ /dev/null @@ -1,41 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -namePrefix: base- -resources: - - cockroachdb-statefulset-secure.yaml - - cronjob.yaml -configMapGenerator: -- name: test-config-map - literals: - - foo=bar - - baz=qux -vars: - - name: CDB_PUBLIC_SVC - objref: - kind: Service - name: cockroachdb-public - apiVersion: v1 - fieldref: - fieldpath: metadata.name - - name: CDB_STATEFULSET_NAME - objref: - kind: StatefulSet - name: cockroachdb - apiVersion: apps/v1beta1 - fieldref: - fieldpath: metadata.name - - name: CDB_STATEFULSET_SVC - objref: - kind: Service - name: cockroachdb - apiVersion: v1 - fieldref: - fieldpath: metadata.name - - - name: TEST_CONFIG_MAP - objref: - kind: ConfigMap - name: test-config-map - apiVersion: v1 - fieldref: - fieldpath: metadata.name diff --git a/pkg/commands/build/testdata/testcase-variable-ref/test.yaml b/pkg/commands/build/testdata/testcase-variable-ref/test.yaml deleted file mode 100644 index 0c94b121e..000000000 --- a/pkg/commands/build/testdata/testcase-variable-ref/test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -description: variable reference and substitution -args: [] -filename: testdata/testcase-variable-ref/in/overlay/ -expectedStdout: testdata/testcase-variable-ref/expected.yaml -expectedDiff: testdata/testcase-variable-ref/expected.diff diff --git a/pkg/target/utils_for_test.go b/pkg/target/utils_for_test.go index 8aebc4f8e..97f17b5e3 100644 --- a/pkg/target/utils_for_test.go +++ b/pkg/target/utils_for_test.go @@ -151,9 +151,9 @@ func (th *KustTestHarness) assertActualEqualsExpected( func (th *KustTestHarness) reportDiffAndFail(actual []byte, expected string) { sE, maxLen := convertToArray(expected) sA, _ := convertToArray(string(actual)) - fmt.Println("-- ACTUAL -----------------") - fmt.Println(string(actual)) - fmt.Println("---------------------------") + fmt.Println("===== ACTUAL BEGIN ========================================") + fmt.Print(string(actual)) + fmt.Println("===== ACTUAL END ==========================================") format := fmt.Sprintf("%%s %%-%ds %%s\n", maxLen+4) limit := 0 if len(sE) < len(sA) { diff --git a/pkg/target/variableref_test.go b/pkg/target/variableref_test.go new file mode 100644 index 000000000..f923a026a --- /dev/null +++ b/pkg/target/variableref_test.go @@ -0,0 +1,725 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "testing" +) + +func TestVariableRef(t *testing.T) { + th := NewKustTestHarness(t, "/app/overlay/staging") + th.writeK("/app/base", ` +apiVersion: v1beta1 +kind: Kustomization +namePrefix: base- +resources: + - cockroachdb-statefulset-secure.yaml + - cronjob.yaml +configMapGenerator: +- name: test-config-map + literals: + - foo=bar + - baz=qux +vars: + - name: CDB_PUBLIC_SVC + objref: + kind: Service + name: cockroachdb-public + apiVersion: v1 + fieldref: + fieldpath: metadata.name + - name: CDB_STATEFULSET_NAME + objref: + kind: StatefulSet + name: cockroachdb + apiVersion: apps/v1beta1 + fieldref: + fieldpath: metadata.name + - name: CDB_STATEFULSET_SVC + objref: + kind: Service + name: cockroachdb + apiVersion: v1 + fieldref: + fieldpath: metadata.name + + - name: TEST_CONFIG_MAP + objref: + kind: ConfigMap + name: test-config-map + apiVersion: v1 + fieldref: + fieldpath: metadata.name`) + th.writeF("/app/base/cronjob.yaml", ` +apiVersion: batch/v1beta1 +kind: CronJob +metadata: + name: cronjob-example +spec: + schedule: "*/1 * * * *" + concurrencyPolicy: Forbid + jobTemplate: + spec: + template: + spec: + containers: + - name: cronjob-example + image: cockroachdb/cockroach:v1.1.5 + command: + - echo + - "$(CDB_STATEFULSET_NAME)" + - "$(TEST_CONFIG_MAP)" + env: + - name: CDB_PUBLIC_SVC + value: "$(CDB_PUBLIC_SVC)" +`) + th.writeF("/app/base/cockroachdb-statefulset-secure.yaml", ` +apiVersion: v1 +kind: ServiceAccount +metadata: + name: cockroachdb + labels: + app: cockroachdb +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: cockroachdb + labels: + app: cockroachdb +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - get +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: cockroachdb + labels: + app: cockroachdb +rules: +- apiGroups: + - certificates.k8s.io + resources: + - certificatesigningrequests + verbs: + - create + - get + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: cockroachdb + labels: + app: cockroachdb +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: cockroachdb +subjects: +- kind: ServiceAccount + name: cockroachdb + namespace: default +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: cockroachdb + labels: + app: cockroachdb +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cockroachdb +subjects: +- kind: ServiceAccount + name: cockroachdb + namespace: default +--- +apiVersion: v1 +kind: Service +metadata: + # This service is meant to be used by clients of the database. It exposes a ClusterIP that will + # automatically load balance connections to the different database pods. + name: cockroachdb-public + labels: + app: cockroachdb +spec: + ports: + # The main port, served by gRPC, serves Postgres-flavor SQL, internode + # traffic and the cli. + - port: 26257 + targetPort: 26257 + name: grpc + # The secondary port serves the UI as well as health and debug endpoints. + - port: 8080 + targetPort: 8080 + name: http + selector: + app: cockroachdb +--- +apiVersion: v1 +kind: Service +metadata: + name: cockroachdb + labels: + app: cockroachdb + annotations: + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" + # Enable automatic monitoring of all instances when Prometheus is running in the cluster. + prometheus.io/scrape: "true" + prometheus.io/path: "_status/vars" + prometheus.io/port: "8080" +spec: + ports: + - port: 26257 + targetPort: 26257 + name: grpc + - port: 8080 + targetPort: 8080 + name: http + clusterIP: None + selector: + app: cockroachdb +--- +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: cockroachdb-budget + labels: + app: cockroachdb +spec: + selector: + matchLabels: + app: cockroachdb + maxUnavailable: 1 +--- +apiVersion: apps/v1beta1 +kind: StatefulSet +metadata: + name: cockroachdb +spec: + serviceName: "cockroachdb" + replicas: 3 + template: + metadata: + labels: + app: cockroachdb + spec: + serviceAccountName: cockroachdb + # Init containers are run only once in the lifetime of a pod, before + # it's started up for the first time. It has to exit successfully + # before the pod's main containers are allowed to start. + initContainers: + # The init-certs container sends a certificate signing request to the + # kubernetes cluster. + # You can see pending requests using: kubectl get csr + # CSRs can be approved using: kubectl certificate approve + # + # All addresses used to contact a node must be specified in the --addresses arg. + # + # In addition to the node certificate and key, the init-certs entrypoint will symlink + # the cluster CA to the certs directory. + - name: init-certs + image: cockroachdb/cockroach-k8s-request-cert:0.2 + imagePullPolicy: IfNotPresent + command: + - "/bin/ash" + - "-ecx" + - "/request-cert" + - -namespace=${POD_NAMESPACE} + - -certs-dir=/cockroach-certs + - -type=node + - -addresses=localhost,127.0.0.1,${POD_IP},$(hostname -f),$(hostname -f|cut -f 1-2 -d '.'),$(CDB_PUBLIC_SVC) + - -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - name: certs + mountPath: /cockroach-certs + + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - cockroachdb + topologyKey: kubernetes.io/hostname + containers: + - name: cockroachdb + image: cockroachdb/cockroach:v1.1.5 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 26257 + name: grpc + - containerPort: 8080 + name: http + volumeMounts: + - name: datadir + mountPath: /cockroach/cockroach-data + - name: certs + mountPath: /cockroach/cockroach-certs + command: + - "/bin/bash" + - "-ecx" + - "exec /cockroach/cockroach start --logtostderr" + - --certs-dir /cockroach/cockroach-certs + - --host $(hostname -f) + - --http-host 0.0.0.0 + - --join $(CDB_STATEFULSET_NAME)-0.$(CDB_STATEFULSET_SVC),$(CDB_STATEFULSET_NAME)-1.$(CDB_STATEFULSET_SVC),$(CDB_STATEFULSET_NAME)-2.$(CDB_STATEFULSET_SVC) + - --cache 25% + - --max-sql-memory 25% + # No pre-stop hook is required, a SIGTERM plus some time is all that's + # needed for graceful shutdown of a node. + terminationGracePeriodSeconds: 60 + volumes: + - name: datadir + persistentVolumeClaim: + claimName: datadir + - name: certs + emptyDir: {} + updateStrategy: + type: RollingUpdate + volumeClaimTemplates: + - metadata: + name: datadir + spec: + accessModes: + - "ReadWriteOnce" + resources: + requests: + storage: 1Gi +`) + th.writeK("/app/overlay/staging", ` +apiVersion: v1beta1 +kind: Kustomization +namePrefix: dev- +bases: +- ../../base +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: cockroachdb + name: dev-base-cockroachdb +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + labels: + app: cockroachdb + name: dev-base-cockroachdb +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - get +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + labels: + app: cockroachdb + name: dev-base-cockroachdb +rules: +- apiGroups: + - certificates.k8s.io + resources: + - certificatesigningrequests + verbs: + - create + - get + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + labels: + app: cockroachdb + name: dev-base-cockroachdb +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: dev-base-cockroachdb +subjects: +- kind: ServiceAccount + name: dev-base-cockroachdb + namespace: default +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + labels: + app: cockroachdb + name: dev-base-cockroachdb +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: dev-base-cockroachdb +subjects: +- kind: ServiceAccount + name: dev-base-cockroachdb + namespace: default +--- +apiVersion: v1 +data: + baz: qux + foo: bar +kind: ConfigMap +metadata: + name: dev-base-test-config-map-b2g2dmd64b +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: cockroachdb + name: dev-base-cockroachdb-public +spec: + ports: + - name: grpc + port: 26257 + targetPort: 26257 + - name: http + port: 8080 + targetPort: 8080 + selector: + app: cockroachdb +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + prometheus.io/path: _status/vars + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" + labels: + app: cockroachdb + name: dev-base-cockroachdb +spec: + clusterIP: None + ports: + - name: grpc + port: 26257 + targetPort: 26257 + - name: http + port: 8080 + targetPort: 8080 + selector: + app: cockroachdb +--- +apiVersion: apps/v1beta1 +kind: StatefulSet +metadata: + name: dev-base-cockroachdb +spec: + replicas: 3 + serviceName: dev-base-cockroachdb + template: + metadata: + labels: + app: cockroachdb + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - cockroachdb + topologyKey: kubernetes.io/hostname + weight: 100 + containers: + - command: + - /bin/bash + - -ecx + - exec /cockroach/cockroach start --logtostderr + - --certs-dir /cockroach/cockroach-certs + - --host $(hostname -f) + - --http-host 0.0.0.0 + - --join dev-base-cockroachdb-0.dev-base-cockroachdb,dev-base-cockroachdb-1.dev-base-cockroachdb,dev-base-cockroachdb-2.dev-base-cockroachdb + - --cache 25% + - --max-sql-memory 25% + image: cockroachdb/cockroach:v1.1.5 + imagePullPolicy: IfNotPresent + name: cockroachdb + ports: + - containerPort: 26257 + name: grpc + - containerPort: 8080 + name: http + volumeMounts: + - mountPath: /cockroach/cockroach-data + name: datadir + - mountPath: /cockroach/cockroach-certs + name: certs + initContainers: + - command: + - /bin/ash + - -ecx + - /request-cert + - -namespace=${POD_NAMESPACE} + - -certs-dir=/cockroach-certs + - -type=node + - -addresses=localhost,127.0.0.1,${POD_IP},$(hostname -f),$(hostname -f|cut + -f 1-2 -d '.'),dev-base-cockroachdb-public + - -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: cockroachdb/cockroach-k8s-request-cert:0.2 + imagePullPolicy: IfNotPresent + name: init-certs + volumeMounts: + - mountPath: /cockroach-certs + name: certs + serviceAccountName: dev-base-cockroachdb + terminationGracePeriodSeconds: 60 + volumes: + - name: datadir + persistentVolumeClaim: + claimName: datadir + - emptyDir: {} + name: certs + updateStrategy: + type: RollingUpdate + volumeClaimTemplates: + - metadata: + name: datadir + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi +--- +apiVersion: batch/v1beta1 +kind: CronJob +metadata: + name: dev-base-cronjob-example +spec: + concurrencyPolicy: Forbid + jobTemplate: + spec: + template: + spec: + containers: + - command: + - echo + - dev-base-cockroachdb + - dev-base-test-config-map-b2g2dmd64b + env: + - name: CDB_PUBLIC_SVC + value: dev-base-cockroachdb-public + image: cockroachdb/cockroach:v1.1.5 + name: cronjob-example + schedule: '*/1 * * * *' +--- +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + labels: + app: cockroachdb + name: dev-base-cockroachdb-budget +spec: + maxUnavailable: 1 + selector: + matchLabels: + app: cockroachdb +`) +} + +func TestVariableRefIngress(t *testing.T) { + th := NewKustTestHarness(t, "/app/overlay") + th.writeK("/app/base", ` +apiVersion: v1beta1 +kind: Kustomization +resources: +- deployment.yaml +- ingress.yaml +- service.yaml + +vars: +- name: DEPLOYMENT_NAME + objref: + apiVersion: apps/v1 + kind: Deployment + name: nginx + fieldref: + fieldpath: metadata.name +`) + th.writeF("/app/base/deployment.yaml", ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx + labels: + app.kubernetes.io/component: nginx +spec: + selector: + matchLabels: + app.kubernetes.io/component: nginx + template: + metadata: + labels: + app.kubernetes.io/component: nginx + spec: + containers: + - name: nginx + image: nginx:1.15.7-alpine + ports: + - name: http + containerPort: 80 +`) + th.writeF("/app/base/ingress.yaml", ` +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: nginx + labels: + app.kubernetes.io/component: nginx +spec: + rules: + - host: $(DEPLOYMENT_NAME).example.com + http: + paths: + - backend: + serviceName: nginx + servicePort: 80 + path: / + tls: + - hosts: + - $(DEPLOYMENT_NAME).example.com +`) + th.writeF("/app/base/service.yaml", ` +apiVersion: v1 +kind: Service +metadata: + name: nginx + labels: + app.kubernetes.io/component: nginx +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: http +`) + th.writeK("/app/overlay", ` +apiVersion: v1beta1 +kind: Kustomization +nameprefix: kustomized- +bases: +- ../base +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: nginx + name: kustomized-nginx +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: http +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: nginx + name: kustomized-nginx +spec: + selector: + matchLabels: + app.kubernetes.io/component: nginx + template: + metadata: + labels: + app.kubernetes.io/component: nginx + spec: + containers: + - image: nginx:1.15.7-alpine + name: nginx + ports: + - containerPort: 80 + name: http +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + labels: + app.kubernetes.io/component: nginx + name: kustomized-nginx +spec: + rules: + - host: kustomized-nginx.example.com + http: + paths: + - backend: + serviceName: kustomized-nginx + servicePort: 80 + path: / + tls: + - hosts: + - kustomized-nginx.example.com +`) +} From 9dcbee1d4844c5b0a73ae2834a6dc2cf2db74a6b Mon Sep 17 00:00:00 2001 From: jregan Date: Fri, 28 Dec 2018 09:09:26 -0800 Subject: [PATCH 035/317] Convert generator merge and replace tests to in-memory. --- .../testdata/testcase-base-only/expected.diff | 85 ---- .../testdata/testcase-base-only/expected.yaml | 71 --- .../testcase-base-only/in/kustomization.yaml | 13 - .../in/resources/deployment.yaml | 15 - .../in/resources/networkpolicy.yaml | 13 - .../in/resources/service.yaml | 11 - .../testdata/testcase-base-only/test.yaml | 5 - .../testcase-single-overlay/expected.diff | 128 ----- .../testcase-single-overlay/expected.yaml | 105 ---- .../in/overlay/deployment.yaml | 15 - .../in/overlay/kustomization.yaml | 23 - .../in/package/deployment.yaml | 24 - .../in/package/kustomization.yaml | 21 - .../in/package/service.yaml | 11 - .../testcase-single-overlay/test.yaml | 5 - pkg/target/generatormergeandreplace_test.go | 479 ++++++++++++++++++ 16 files changed, 479 insertions(+), 545 deletions(-) delete mode 100644 pkg/commands/build/testdata/testcase-base-only/expected.diff delete mode 100644 pkg/commands/build/testdata/testcase-base-only/expected.yaml delete mode 100644 pkg/commands/build/testdata/testcase-base-only/in/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-base-only/in/resources/deployment.yaml delete mode 100644 pkg/commands/build/testdata/testcase-base-only/in/resources/networkpolicy.yaml delete mode 100644 pkg/commands/build/testdata/testcase-base-only/in/resources/service.yaml delete mode 100644 pkg/commands/build/testdata/testcase-base-only/test.yaml delete mode 100644 pkg/commands/build/testdata/testcase-single-overlay/expected.diff delete mode 100644 pkg/commands/build/testdata/testcase-single-overlay/expected.yaml delete mode 100644 pkg/commands/build/testdata/testcase-single-overlay/in/overlay/deployment.yaml delete mode 100644 pkg/commands/build/testdata/testcase-single-overlay/in/overlay/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-single-overlay/in/package/deployment.yaml delete mode 100644 pkg/commands/build/testdata/testcase-single-overlay/in/package/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-single-overlay/in/package/service.yaml delete mode 100644 pkg/commands/build/testdata/testcase-single-overlay/test.yaml create mode 100644 pkg/target/generatormergeandreplace_test.go diff --git a/pkg/commands/build/testdata/testcase-base-only/expected.diff b/pkg/commands/build/testdata/testcase-base-only/expected.diff deleted file mode 100644 index 5dba387e1..000000000 --- a/pkg/commands/build/testdata/testcase-base-only/expected.diff +++ /dev/null @@ -1,85 +0,0 @@ -diff -u -N /tmp/noop/apps_v1beta2_Deployment_nginx.yaml /tmp/transformed/apps_v1beta2_Deployment_nginx.yaml ---- /tmp/noop/apps_v1beta2_Deployment_nginx.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/apps_v1beta2_Deployment_nginx.yaml YYYY-MM-DD HH:MM:SS -@@ -1,14 +1,27 @@ - apiVersion: apps/v1beta2 - kind: Deployment - metadata: -+ annotations: -+ note: This is a test annotation - labels: -- app: nginx -- name: nginx -+ app: mynginx -+ org: example.com -+ team: foo -+ name: team-foo-nginx - spec: -+ selector: -+ matchLabels: -+ app: mynginx -+ org: example.com -+ team: foo - template: - metadata: -+ annotations: -+ note: This is a test annotation - labels: -- app: nginx -+ app: mynginx -+ org: example.com -+ team: foo - spec: - containers: - - image: nginx -diff -u -N /tmp/noop/networking.k8s.io_v1_NetworkPolicy_nginx.yaml /tmp/transformed/networking.k8s.io_v1_NetworkPolicy_nginx.yaml ---- /tmp/noop/networking.k8s.io_v1_NetworkPolicy_nginx.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/networking.k8s.io_v1_NetworkPolicy_nginx.yaml YYYY-MM-DD HH:MM:SS -@@ -1,13 +1,21 @@ - apiVersion: networking.k8s.io/v1 - kind: NetworkPolicy - metadata: -- name: nginx -+ annotations: -+ note: This is a test annotation -+ labels: -+ app: mynginx -+ org: example.com -+ team: foo -+ name: team-foo-nginx - spec: - ingress: - - from: - - podSelector: - matchLabels: -- app: nginx -+ app: mynginx -+ org: example.com -+ team: foo - podSelector: - matchExpressions: - - key: app -diff -u -N /tmp/noop/v1_Service_nginx.yaml /tmp/transformed/v1_Service_nginx.yaml ---- /tmp/noop/v1_Service_nginx.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_Service_nginx.yaml YYYY-MM-DD HH:MM:SS -@@ -1,11 +1,17 @@ - apiVersion: v1 - kind: Service - metadata: -+ annotations: -+ note: This is a test annotation - labels: -- app: nginx -- name: nginx -+ app: mynginx -+ org: example.com -+ team: foo -+ name: team-foo-nginx - spec: - ports: - - port: 80 - selector: -- app: nginx -+ app: mynginx -+ org: example.com -+ team: foo diff --git a/pkg/commands/build/testdata/testcase-base-only/expected.yaml b/pkg/commands/build/testdata/testcase-base-only/expected.yaml deleted file mode 100644 index 966cec3a2..000000000 --- a/pkg/commands/build/testdata/testcase-base-only/expected.yaml +++ /dev/null @@ -1,71 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - note: This is a test annotation - labels: - app: mynginx - org: example.com - team: foo - name: team-foo-nginx -spec: - ports: - - port: 80 - selector: - app: mynginx - org: example.com - team: foo ---- -apiVersion: apps/v1beta2 -kind: Deployment -metadata: - annotations: - note: This is a test annotation - labels: - app: mynginx - org: example.com - team: foo - name: team-foo-nginx -spec: - selector: - matchLabels: - app: mynginx - org: example.com - team: foo - template: - metadata: - annotations: - note: This is a test annotation - labels: - app: mynginx - org: example.com - team: foo - spec: - containers: - - image: nginx - name: nginx ---- -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - annotations: - note: This is a test annotation - labels: - app: mynginx - org: example.com - team: foo - name: team-foo-nginx -spec: - ingress: - - from: - - podSelector: - matchLabels: - app: mynginx - org: example.com - team: foo - podSelector: - matchExpressions: - - key: app - operator: In - values: - - test diff --git a/pkg/commands/build/testdata/testcase-base-only/in/kustomization.yaml b/pkg/commands/build/testdata/testcase-base-only/in/kustomization.yaml deleted file mode 100644 index 75bcee92f..000000000 --- a/pkg/commands/build/testdata/testcase-base-only/in/kustomization.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -namePrefix: team-foo- -commonLabels: - app: mynginx - org: example.com - team: foo -commonAnnotations: - note: This is a test annotation -resources: - - resources/deployment.yaml - - resources/networkpolicy.yaml - - resources/service.yaml diff --git a/pkg/commands/build/testdata/testcase-base-only/in/resources/deployment.yaml b/pkg/commands/build/testdata/testcase-base-only/in/resources/deployment.yaml deleted file mode 100644 index 722bf87ce..000000000 --- a/pkg/commands/build/testdata/testcase-base-only/in/resources/deployment.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: apps/v1beta2 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx diff --git a/pkg/commands/build/testdata/testcase-base-only/in/resources/networkpolicy.yaml b/pkg/commands/build/testdata/testcase-base-only/in/resources/networkpolicy.yaml deleted file mode 100644 index 213801ce1..000000000 --- a/pkg/commands/build/testdata/testcase-base-only/in/resources/networkpolicy.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: nginx -spec: - podSelector: - matchExpressions: - - {key: app, operator: In, values: [test]} - ingress: - - from: - - podSelector: - matchLabels: - app: nginx diff --git a/pkg/commands/build/testdata/testcase-base-only/in/resources/service.yaml b/pkg/commands/build/testdata/testcase-base-only/in/resources/service.yaml deleted file mode 100644 index f6dd86909..000000000 --- a/pkg/commands/build/testdata/testcase-base-only/in/resources/service.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: nginx - labels: - app: nginx -spec: - ports: - - port: 80 - selector: - app: nginx diff --git a/pkg/commands/build/testdata/testcase-base-only/test.yaml b/pkg/commands/build/testdata/testcase-base-only/test.yaml deleted file mode 100644 index 61d6d0a07..000000000 --- a/pkg/commands/build/testdata/testcase-base-only/test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -description: base only -args: [] -filename: testdata/testcase-base-only/in -expectedStdout: testdata/testcase-base-only/expected.yaml -expectedDiff: testdata/testcase-base-only/expected.diff diff --git a/pkg/commands/build/testdata/testcase-single-overlay/expected.diff b/pkg/commands/build/testdata/testcase-single-overlay/expected.diff deleted file mode 100644 index d27e1da5f..000000000 --- a/pkg/commands/build/testdata/testcase-single-overlay/expected.diff +++ /dev/null @@ -1,128 +0,0 @@ -diff -u -N /tmp/noop/apps_v1beta2_Deployment_nginx.yaml /tmp/transformed/apps_v1beta2_Deployment_nginx.yaml ---- /tmp/noop/apps_v1beta2_Deployment_nginx.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/apps_v1beta2_Deployment_nginx.yaml YYYY-MM-DD HH:MM:SS -@@ -5,23 +5,26 @@ - note: This is a test annotation - labels: - app: mynginx -+ env: staging - org: example.com -- team: foo -- name: team-foo-nginx -+ team: override-foo -+ name: staging-team-foo-nginx - spec: - selector: - matchLabels: - app: mynginx -+ env: staging - org: example.com -- team: foo -+ team: override-foo - template: - metadata: - annotations: - note: This is a test annotation - labels: - app: mynginx -+ env: staging - org: example.com -- team: foo -+ team: override-foo - spec: - containers: - - image: nginx -@@ -30,8 +33,12 @@ - - mountPath: /tmp/ps - name: nginx-persistent-storage - volumes: -- - emptyDir: {} -+ - gcePersistentDisk: -+ pdName: nginx-persistent-storage - name: nginx-persistent-storage - - configMap: -- name: team-foo-configmap-in-base-bbdmdh7m8t -+ name: staging-configmap-in-overlay-k7cbc75tg8 -+ name: configmap-in-overlay -+ - configMap: -+ name: staging-team-foo-configmap-in-base-gh9d7t85gb - name: configmap-in-base -diff -u -N /tmp/noop/v1_ConfigMap_configmap-in-base.yaml /tmp/transformed/v1_ConfigMap_configmap-in-base.yaml ---- /tmp/noop/v1_ConfigMap_configmap-in-base.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_ConfigMap_configmap-in-base.yaml YYYY-MM-DD HH:MM:SS -@@ -1,6 +1,6 @@ - apiVersion: v1 - data: -- foo: bar -+ foo: override-bar - kind: ConfigMap - metadata: - annotations: -@@ -8,6 +8,7 @@ - creationTimestamp: null - labels: - app: mynginx -+ env: staging - org: example.com -- team: foo -- name: team-foo-configmap-in-base-bbdmdh7m8t -+ team: override-foo -+ name: staging-team-foo-configmap-in-base-gh9d7t85gb -diff -u -N /tmp/noop/v1_ConfigMap_configmap-in-overlay.yaml /tmp/transformed/v1_ConfigMap_configmap-in-overlay.yaml ---- /tmp/noop/v1_ConfigMap_configmap-in-overlay.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_ConfigMap_configmap-in-overlay.yaml YYYY-MM-DD HH:MM:SS -@@ -0,0 +1,10 @@ -+apiVersion: v1 -+data: -+ hello: world -+kind: ConfigMap -+metadata: -+ creationTimestamp: null -+ labels: -+ env: staging -+ team: override-foo -+ name: staging-configmap-in-overlay-k7cbc75tg8 -diff -u -N /tmp/noop/v1_Secret_secret-in-base.yaml /tmp/transformed/v1_Secret_secret-in-base.yaml ---- /tmp/noop/v1_Secret_secret-in-base.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_Secret_secret-in-base.yaml YYYY-MM-DD HH:MM:SS -@@ -1,6 +1,7 @@ - apiVersion: v1 - data: - password: c29tZXB3 -+ proxy: aGFwcm94eQ== - username: YWRtaW4= - kind: Secret - metadata: -@@ -9,7 +10,8 @@ - creationTimestamp: null - labels: - app: mynginx -+ env: staging - org: example.com -- team: foo -- name: team-foo-secret-in-base-tkm7hhtf8d -+ team: override-foo -+ name: staging-team-foo-secret-in-base-c8db7gk2m2 - type: Opaque -diff -u -N /tmp/noop/v1_Service_nginx.yaml /tmp/transformed/v1_Service_nginx.yaml ---- /tmp/noop/v1_Service_nginx.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_Service_nginx.yaml YYYY-MM-DD HH:MM:SS -@@ -5,13 +5,15 @@ - note: This is a test annotation - labels: - app: mynginx -+ env: staging - org: example.com -- team: foo -- name: team-foo-nginx -+ team: override-foo -+ name: staging-team-foo-nginx - spec: - ports: - - port: 80 - selector: - app: mynginx -+ env: staging - org: example.com -- team: foo -+ team: override-foo diff --git a/pkg/commands/build/testdata/testcase-single-overlay/expected.yaml b/pkg/commands/build/testdata/testcase-single-overlay/expected.yaml deleted file mode 100644 index 9a6fcac31..000000000 --- a/pkg/commands/build/testdata/testcase-single-overlay/expected.yaml +++ /dev/null @@ -1,105 +0,0 @@ -apiVersion: v1 -data: - foo: override-bar -kind: ConfigMap -metadata: - annotations: - note: This is a test annotation - labels: - app: mynginx - env: staging - org: example.com - team: override-foo - name: staging-team-foo-configmap-in-base-gh9d7t85gb ---- -apiVersion: v1 -data: - hello: world -kind: ConfigMap -metadata: - labels: - env: staging - team: override-foo - name: staging-configmap-in-overlay-k7cbc75tg8 ---- -apiVersion: v1 -data: - password: c29tZXB3 - proxy: aGFwcm94eQ== - username: YWRtaW4= -kind: Secret -metadata: - annotations: - note: This is a test annotation - labels: - app: mynginx - env: staging - org: example.com - team: override-foo - name: staging-team-foo-secret-in-base-c8db7gk2m2 -type: Opaque ---- -apiVersion: v1 -kind: Service -metadata: - annotations: - note: This is a test annotation - labels: - app: mynginx - env: staging - org: example.com - team: override-foo - name: staging-team-foo-nginx -spec: - ports: - - port: 80 - selector: - app: mynginx - env: staging - org: example.com - team: override-foo ---- -apiVersion: apps/v1beta2 -kind: Deployment -metadata: - annotations: - note: This is a test annotation - labels: - app: mynginx - env: staging - org: example.com - team: override-foo - name: staging-team-foo-nginx -spec: - selector: - matchLabels: - app: mynginx - env: staging - org: example.com - team: override-foo - template: - metadata: - annotations: - note: This is a test annotation - labels: - app: mynginx - env: staging - org: example.com - team: override-foo - spec: - containers: - - image: nginx - name: nginx - volumeMounts: - - mountPath: /tmp/ps - name: nginx-persistent-storage - volumes: - - gcePersistentDisk: - pdName: nginx-persistent-storage - name: nginx-persistent-storage - - configMap: - name: staging-configmap-in-overlay-k7cbc75tg8 - name: configmap-in-overlay - - configMap: - name: staging-team-foo-configmap-in-base-gh9d7t85gb - name: configmap-in-base diff --git a/pkg/commands/build/testdata/testcase-single-overlay/in/overlay/deployment.yaml b/pkg/commands/build/testdata/testcase-single-overlay/in/overlay/deployment.yaml deleted file mode 100644 index ae8bc1280..000000000 --- a/pkg/commands/build/testdata/testcase-single-overlay/in/overlay/deployment.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: apps/v1beta2 -kind: Deployment -metadata: - name: nginx -spec: - template: - spec: - volumes: - - name: nginx-persistent-storage - emptyDir: null - gcePersistentDisk: - pdName: nginx-persistent-storage - - configMap: - name: configmap-in-overlay - name: configmap-in-overlay diff --git a/pkg/commands/build/testdata/testcase-single-overlay/in/overlay/kustomization.yaml b/pkg/commands/build/testdata/testcase-single-overlay/in/overlay/kustomization.yaml deleted file mode 100644 index 307752281..000000000 --- a/pkg/commands/build/testdata/testcase-single-overlay/in/overlay/kustomization.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -namePrefix: staging- -commonLabels: - env: staging - team: override-foo -patchesStrategicMerge: - - deployment.yaml -bases: - - ../package/ -configMapGenerator: - - name: configmap-in-overlay - literals: - - hello=world - - name: configmap-in-base - behavior: replace - literals: - - foo=override-bar -secretGenerator: -- name: secret-in-base - behavior: merge - commands: - proxy: "printf haproxy" diff --git a/pkg/commands/build/testdata/testcase-single-overlay/in/package/deployment.yaml b/pkg/commands/build/testdata/testcase-single-overlay/in/package/deployment.yaml deleted file mode 100644 index 9f7d3cbb6..000000000 --- a/pkg/commands/build/testdata/testcase-single-overlay/in/package/deployment.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: apps/v1beta2 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx - volumeMounts: - - name: nginx-persistent-storage - mountPath: /tmp/ps - volumes: - - name: nginx-persistent-storage - emptyDir: {} - - configMap: - name: configmap-in-base - name: configmap-in-base diff --git a/pkg/commands/build/testdata/testcase-single-overlay/in/package/kustomization.yaml b/pkg/commands/build/testdata/testcase-single-overlay/in/package/kustomization.yaml deleted file mode 100644 index 5ea5cab5f..000000000 --- a/pkg/commands/build/testdata/testcase-single-overlay/in/package/kustomization.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -namePrefix: team-foo- -commonLabels: - app: mynginx - org: example.com - team: foo -commonAnnotations: - note: This is a test annotation -resources: - - deployment.yaml - - service.yaml -configMapGenerator: - - name: configmap-in-base - literals: - - foo=bar -secretGenerator: -- name: secret-in-base - commands: - username: "printf admin" - password: "printf somepw" diff --git a/pkg/commands/build/testdata/testcase-single-overlay/in/package/service.yaml b/pkg/commands/build/testdata/testcase-single-overlay/in/package/service.yaml deleted file mode 100644 index f6dd86909..000000000 --- a/pkg/commands/build/testdata/testcase-single-overlay/in/package/service.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: nginx - labels: - app: nginx -spec: - ports: - - port: 80 - selector: - app: nginx diff --git a/pkg/commands/build/testdata/testcase-single-overlay/test.yaml b/pkg/commands/build/testdata/testcase-single-overlay/test.yaml deleted file mode 100644 index 1af80f52c..000000000 --- a/pkg/commands/build/testdata/testcase-single-overlay/test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -description: single overlay -args: [] -filename: testdata/testcase-single-overlay/in/overlay/ -expectedStdout: testdata/testcase-single-overlay/expected.yaml -expectedDiff: testdata/testcase-single-overlay/expected.diff diff --git a/pkg/target/generatormergeandreplace_test.go b/pkg/target/generatormergeandreplace_test.go new file mode 100644 index 000000000..365b41006 --- /dev/null +++ b/pkg/target/generatormergeandreplace_test.go @@ -0,0 +1,479 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "testing" +) + +func TestSimpleBase(t *testing.T) { + th := NewKustTestHarness(t, "/app/base") + th.writeK("/app/base", ` +apiVersion: v1beta1 +kind: Kustomization +namePrefix: team-foo- +commonLabels: + app: mynginx + org: example.com + team: foo +commonAnnotations: + note: This is a test annotation +resources: + - deployment.yaml + - networkpolicy.yaml + - service.yaml +`) + th.writeF("/app/base/service.yaml", ` +apiVersion: v1 +kind: Service +metadata: + name: nginx + labels: + app: nginx +spec: + ports: + - port: 80 + selector: + app: nginx +`) + th.writeF("/app/base/networkpolicy.yaml", ` +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: nginx +spec: + podSelector: + matchExpressions: + - {key: app, operator: In, values: [test]} + ingress: + - from: + - podSelector: + matchLabels: + app: nginx +`) + th.writeF("/app/base/deployment.yaml", ` +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: nginx + labels: + app: nginx +spec: + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +kind: Service +metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + org: example.com + team: foo + name: team-foo-nginx +spec: + ports: + - port: 80 + selector: + app: mynginx + org: example.com + team: foo +--- +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + org: example.com + team: foo + name: team-foo-nginx +spec: + selector: + matchLabels: + app: mynginx + org: example.com + team: foo + template: + metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + org: example.com + team: foo + spec: + containers: + - image: nginx + name: nginx +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + org: example.com + team: foo + name: team-foo-nginx +spec: + ingress: + - from: + - podSelector: + matchLabels: + app: mynginx + org: example.com + team: foo + podSelector: + matchExpressions: + - key: app + operator: In + values: + - test +`) +} + +func makeBaseWithGenerators(th *KustTestHarness) { + th.writeK("/app", ` +apiVersion: v1beta1 +kind: Kustomization +namePrefix: team-foo- +commonLabels: + app: mynginx + org: example.com + team: foo +commonAnnotations: + note: This is a test annotation +resources: + - deployment.yaml + - service.yaml +configMapGenerator: + - name: configmap-in-base + literals: + - foo=bar +secretGenerator: +- name: secret-in-base + commands: + username: "printf admin" + password: "printf somepw" +`) + th.writeF("/app/deployment.yaml", ` +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: nginx + labels: + app: nginx +spec: + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx + volumeMounts: + - name: nginx-persistent-storage + mountPath: /tmp/ps + volumes: + - name: nginx-persistent-storage + emptyDir: {} + - configMap: + name: configmap-in-base + name: configmap-in-base +`) + th.writeF("/app/service.yaml", ` +apiVersion: v1 +kind: Service +metadata: + name: nginx + labels: + app: nginx +spec: + ports: + - port: 80 + selector: + app: nginx +`) +} + +func TestBaseWithGeneratorsAlone(t *testing.T) { + th := NewKustTestHarness(t, "/app") + makeBaseWithGenerators(th) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + foo: bar +kind: ConfigMap +metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + org: example.com + team: foo + name: team-foo-configmap-in-base-bbdmdh7m8t +--- +apiVersion: v1 +data: + password: c29tZXB3 + username: YWRtaW4= +kind: Secret +metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + org: example.com + team: foo + name: team-foo-secret-in-base-tkm7hhtf8d +type: Opaque +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + org: example.com + team: foo + name: team-foo-nginx +spec: + ports: + - port: 80 + selector: + app: mynginx + org: example.com + team: foo +--- +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + org: example.com + team: foo + name: team-foo-nginx +spec: + selector: + matchLabels: + app: mynginx + org: example.com + team: foo + template: + metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + org: example.com + team: foo + spec: + containers: + - image: nginx + name: nginx + volumeMounts: + - mountPath: /tmp/ps + name: nginx-persistent-storage + volumes: + - emptyDir: {} + name: nginx-persistent-storage + - configMap: + name: team-foo-configmap-in-base-bbdmdh7m8t + name: configmap-in-base +`) +} + +func TestMergeAndReplaceGenerators(t *testing.T) { + th := NewKustTestHarness(t, "/overlay") + makeBaseWithGenerators(th) + th.writeF("/overlay/deployment.yaml", ` +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: nginx +spec: + template: + spec: + volumes: + - name: nginx-persistent-storage + emptyDir: null + gcePersistentDisk: + pdName: nginx-persistent-storage + - configMap: + name: configmap-in-overlay + name: configmap-in-overlay +`) + th.writeK("/overlay", ` +apiVersion: v1beta1 +kind: Kustomization +namePrefix: staging- +commonLabels: + env: staging + team: override-foo +patchesStrategicMerge: + - deployment.yaml +bases: + - ../app +configMapGenerator: + - name: configmap-in-overlay + literals: + - hello=world + - name: configmap-in-base + behavior: replace + literals: + - foo=override-bar +secretGenerator: +- name: secret-in-base + behavior: merge + commands: + proxy: "printf haproxy" +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + foo: override-bar +kind: ConfigMap +metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + env: staging + org: example.com + team: override-foo + name: staging-team-foo-configmap-in-base-gh9d7t85gb +--- +apiVersion: v1 +data: + hello: world +kind: ConfigMap +metadata: + labels: + env: staging + team: override-foo + name: staging-configmap-in-overlay-k7cbc75tg8 +--- +apiVersion: v1 +data: + password: c29tZXB3 + proxy: aGFwcm94eQ== + username: YWRtaW4= +kind: Secret +metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + env: staging + org: example.com + team: override-foo + name: staging-team-foo-secret-in-base-c8db7gk2m2 +type: Opaque +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + env: staging + org: example.com + team: override-foo + name: staging-team-foo-nginx +spec: + ports: + - port: 80 + selector: + app: mynginx + env: staging + org: example.com + team: override-foo +--- +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + env: staging + org: example.com + team: override-foo + name: staging-team-foo-nginx +spec: + selector: + matchLabels: + app: mynginx + env: staging + org: example.com + team: override-foo + template: + metadata: + annotations: + note: This is a test annotation + labels: + app: mynginx + env: staging + org: example.com + team: override-foo + spec: + containers: + - image: nginx + name: nginx + volumeMounts: + - mountPath: /tmp/ps + name: nginx-persistent-storage + volumes: + - gcePersistentDisk: + pdName: nginx-persistent-storage + name: nginx-persistent-storage + - configMap: + name: staging-configmap-in-overlay-k7cbc75tg8 + name: configmap-in-overlay + - configMap: + name: staging-team-foo-configmap-in-base-gh9d7t85gb + name: configmap-in-base +`) +} From 8c994725cb2e62371dc69bc2d81eebe22e78d2d2 Mon Sep 17 00:00:00 2001 From: jregan Date: Sat, 29 Dec 2018 08:19:37 -0800 Subject: [PATCH 036/317] Check for config merge conflicts and duplication. --- pkg/gvk/gvk.go | 16 +-- pkg/resource/factory.go | 2 +- pkg/target/customconfig_test.go | 15 +- pkg/target/kusttarget.go | 7 +- pkg/transformers/config/factory.go | 5 +- pkg/transformers/config/factorycrd.go | 32 ++++- pkg/transformers/config/fieldspec.go | 46 +++++- pkg/transformers/config/fieldspec_test.go | 134 ++++++++++++++++++ pkg/transformers/config/namebackreferences.go | 23 +-- .../config/namebackreferences_test.go | 10 +- pkg/transformers/config/transformerconfig.go | 69 ++++++--- .../config/transformerconfig_test.go | 35 ++++- 12 files changed, 325 insertions(+), 69 deletions(-) diff --git a/pkg/gvk/gvk.go b/pkg/gvk/gvk.go index 0bc515a35..00e44f7ea 100644 --- a/pkg/gvk/gvk.go +++ b/pkg/gvk/gvk.go @@ -116,16 +116,16 @@ func (x Gvk) IsLessThan(o Gvk) bool { // If `selector` and `x` are the same, return true. // If `selector` is nil, it is considered a wildcard match, returning true. // If selector fields are empty, they are considered wildcards matching -// anything in the corresponding fields, .g. -// selector -// -// selects -// . +// anything in the corresponding fields, e.g. // -// while selector +// this item: +// +// +// is selected by +// +// +// but rejected by // -// rejects -// . // func (x Gvk) IsSelected(selector *Gvk) bool { if selector == nil { diff --git a/pkg/resource/factory.go b/pkg/resource/factory.go index 3c0dbab07..2f287ecbd 100644 --- a/pkg/resource/factory.go +++ b/pkg/resource/factory.go @@ -87,7 +87,7 @@ func (rf *Factory) SliceFromBytes(in []byte) ([]*Resource, error) { items := u.Map()["items"] itemsSlice, ok := items.([]interface{}) if !ok { - return nil, fmt.Errorf("items in List is type %T, expected array.", items) + return nil, fmt.Errorf("items in List is type %T, expected array", items) } for _, item := range itemsSlice { itemJSON, err := json.Marshal(item) diff --git a/pkg/target/customconfig_test.go b/pkg/target/customconfig_test.go index 9c0c6b0e3..a2f0cde56 100644 --- a/pkg/target/customconfig_test.go +++ b/pkg/target/customconfig_test.go @@ -150,9 +150,6 @@ spec: `) } -// TODO: this test demonstrates #658 -// The prefix "x-" is applied twice (search for x-x-sandiego), because the -// config from the base isn't properly merged with the config in the overlay. func TestCustomConfigWithDefaultOverspecification(t *testing.T) { th := NewKustTestHarness(t, "/app/base") makeBaseReferencingCustomConfig(th) @@ -184,21 +181,21 @@ kind: AnimalPark metadata: labels: app: myApp - name: x-x-sandiego + name: x-sandiego spec: food: - mimosa - bambooshoots giraffeRef: - name: x-x-april + name: x-april gorillaRef: - name: x-x-koko + name: x-koko --- kind: Giraffe metadata: labels: app: myApp - name: x-x-april + name: x-april spec: diet: mimosa location: NE @@ -207,7 +204,7 @@ kind: Giraffe metadata: labels: app: myApp - name: x-x-may + name: x-may spec: diet: acacia location: SE @@ -216,7 +213,7 @@ kind: Gorilla metadata: labels: app: myApp - name: x-x-koko + name: x-koko spec: diet: bambooshoots location: SW diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 02a094709..ac315006a 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -134,7 +134,7 @@ func mergeCustomConfigWithDefaults( if err != nil { return nil, err } - return t1.Merge(t2), nil + return t1.Merge(t2) } // MakeCustomizedResMap creates a ResMap per kustomization instructions. @@ -194,10 +194,13 @@ func (kt *KustTarget) loadCustomizedResMap() (resmap.ResMap, error) { errs.Append(errors.Wrap(err, "loadResMapFromBasesAndResources")) } crdTc, err := config.NewFactory(kt.ldr).LoadCRDs(kt.kustomization.Crds) - kt.tConfig = kt.tConfig.Merge(crdTc) if err != nil { errs.Append(errors.Wrap(err, "LoadCRDs")) } + kt.tConfig, err = kt.tConfig.Merge(crdTc) + if err != nil { + errs.Append(errors.Wrap(err, "merge CRDs")) + } resMap, err := kt.generateConfigMapsAndSecrets(errs) if err != nil { errs.Append(errors.Wrap(err, "generateConfigMapsAndSecrets")) diff --git a/pkg/transformers/config/factory.go b/pkg/transformers/config/factory.go index 0bf842c64..644fbcae6 100644 --- a/pkg/transformers/config/factory.go +++ b/pkg/transformers/config/factory.go @@ -53,7 +53,10 @@ func (tf *Factory) FromFiles( if err != nil { return nil, err } - result = result.Merge(t) + result, err = result.Merge(t) + if err != nil { + return nil, err + } } return result, nil } diff --git a/pkg/transformers/config/factorycrd.go b/pkg/transformers/config/factorycrd.go index 0742ab5db..24e0d5614 100644 --- a/pkg/transformers/config/factorycrd.go +++ b/pkg/transformers/config/factorycrd.go @@ -33,7 +33,10 @@ func (tf *Factory) LoadCRDs(paths []string) (*TransformerConfig, error) { if err != nil { return nil, err } - tc = tc.Merge(otherTc) + tc, err = tc.Merge(otherTc) + if err != nil { + return nil, err + } } return tc, nil } @@ -63,7 +66,10 @@ func (tf *Factory) loadCRD(path string) (*TransformerConfig, error) { if err != nil { return result, err } - result = result.Merge(tc) + result, err = result.Merge(tc) + if err != nil { + return result, err + } } return result, nil @@ -92,7 +98,7 @@ func getCRDs(types map[string]common.OpenAPIDefinition) map[string]gvk.Gvk { func loadCrdIntoConfig( types map[string]common.OpenAPIDefinition, atype string, crd string, in gvk.Gvk, - path []string, config *TransformerConfig) error { + path []string, config *TransformerConfig) (err error) { if _, ok := types[crd]; !ok { return nil } @@ -100,33 +106,42 @@ func loadCrdIntoConfig( for propname, property := range types[atype].Schema.SchemaProps.Properties { _, annotate := property.Extensions.GetString(Annotation) if annotate { - config.AddAnnotationFieldSpec( + err = config.AddAnnotationFieldSpec( FieldSpec{ CreateIfNotPresent: false, Gvk: in, Path: strings.Join(append(path, propname), "/"), }, ) + if err != nil { + return err + } } _, label := property.Extensions.GetString(LabelSelector) if label { - config.AddLabelFieldSpec( + err = config.AddLabelFieldSpec( FieldSpec{ CreateIfNotPresent: false, Gvk: in, Path: strings.Join(append(path, propname), "/"), }, ) + if err != nil { + return err + } } _, identity := property.Extensions.GetString(Identity) if identity { - config.AddPrefixFieldSpec( + err = config.AddPrefixFieldSpec( FieldSpec{ CreateIfNotPresent: false, Gvk: in, Path: strings.Join(append(path, propname), "/"), }, ) + if err != nil { + return err + } } version, ok := property.Extensions.GetString(Version) if ok { @@ -136,7 +151,7 @@ func loadCrdIntoConfig( if !ok { nameKey = "name" } - config.AddNamereferenceFieldSpec(NameBackReferences{ + err = config.AddNamereferenceFieldSpec(NameBackReferences{ Gvk: gvk.Gvk{Kind: kind, Version: version}, FieldSpecs: []FieldSpec{ { @@ -146,6 +161,9 @@ func loadCrdIntoConfig( }, }, }) + if err != nil { + return err + } } } diff --git a/pkg/transformers/config/fieldspec.go b/pkg/transformers/config/fieldspec.go index 7f759d2a0..5b0f6ee33 100644 --- a/pkg/transformers/config/fieldspec.go +++ b/pkg/transformers/config/fieldspec.go @@ -57,6 +57,11 @@ func (fs FieldSpec) String() string { "%s:%v:%s", fs.Gvk.String(), fs.CreateIfNotPresent, fs.Path) } +// If true, the primary key is the same, but other fields might not be. +func (fs FieldSpec) effectivelyEquals(other FieldSpec) bool { + return fs.IsSelected(&other.Gvk) && fs.Path == other.Path +} + // PathSlice converts the path string to a slice of strings, // separated by a '/'. Forward slash can be contained in a // fieldname. such as ingress.kubernetes.io/auth-secret in @@ -76,7 +81,6 @@ func (fs FieldSpec) PathSlice() []string { if !strings.Contains(fs.Path, escapedForwardSlash) { return strings.Split(fs.Path, "/") } - s := strings.Replace(fs.Path, escapedForwardSlash, tempSlashReplacement, -1) paths := strings.Split(s, "/") var result []string @@ -93,3 +97,43 @@ func (s fsSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s fsSlice) Less(i, j int) bool { return s[i].Gvk.IsLessThan(s[j].Gvk) } + +// mergeAll merges the argument into this, returning the result. +// Items already present are ignored. +// Items that conflict (primary key matches, but remain data differs) +// result in an error. +func (s fsSlice) mergeAll(incoming fsSlice) (result fsSlice, err error) { + result = s + for _, x := range incoming { + result, err = result.mergeOne(x) + if err != nil { + return nil, err + } + } + return result, nil +} + +// mergeOne merges the argument into this, returning the result. +// If the item's primary key is already present, and there are no +// conflicts, it is ignored (we don't want duplicates). +// If there is a conflict, the merge fails. +func (s fsSlice) mergeOne(x FieldSpec) (fsSlice, error) { + i := s.index(x) + if i > -1 { + // It's already there. + if s[i].CreateIfNotPresent != x.CreateIfNotPresent { + return nil, fmt.Errorf("conflicting fieldspecs") + } + return s, nil + } + return append(s, x), nil +} + +func (s fsSlice) index(fs FieldSpec) int { + for i, x := range s { + if x.effectivelyEquals(fs) { + return i + } + } + return -1 +} diff --git a/pkg/transformers/config/fieldspec_test.go b/pkg/transformers/config/fieldspec_test.go index 47366317d..7279e0abe 100644 --- a/pkg/transformers/config/fieldspec_test.go +++ b/pkg/transformers/config/fieldspec_test.go @@ -17,8 +17,12 @@ limitations under the License. package config import ( + "fmt" "reflect" + "strings" "testing" + + "sigs.k8s.io/kustomize/pkg/gvk" ) func TestPathSlice(t *testing.T) { @@ -44,3 +48,133 @@ func TestPathSlice(t *testing.T) { } } } + +var mergeTests = []struct { + name string + original fsSlice + incoming fsSlice + err error + result fsSlice +}{ + { + "normal", + fsSlice{ + { + Path: "whatever", + Gvk: gvk.Gvk{Group: "apple"}, + CreateIfNotPresent: false, + }, + { + Path: "whatever", + Gvk: gvk.Gvk{Group: "pear"}, + CreateIfNotPresent: false, + }, + }, + fsSlice{ + { + Path: "home", + Gvk: gvk.Gvk{Group: "beans"}, + CreateIfNotPresent: false, + }, + }, + nil, + fsSlice{ + { + Path: "whatever", + Gvk: gvk.Gvk{Group: "apple"}, + CreateIfNotPresent: false, + }, + { + Path: "whatever", + Gvk: gvk.Gvk{Group: "pear"}, + CreateIfNotPresent: false, + }, + { + Path: "home", + Gvk: gvk.Gvk{Group: "beans"}, + CreateIfNotPresent: false, + }, + }, + }, + { + "ignore copy", + fsSlice{ + { + Path: "whatever", + Gvk: gvk.Gvk{Group: "apple"}, + CreateIfNotPresent: false, + }, + { + Path: "whatever", + Gvk: gvk.Gvk{Group: "pear"}, + CreateIfNotPresent: false, + }, + }, + fsSlice{ + { + Path: "whatever", + Gvk: gvk.Gvk{Group: "apple"}, + CreateIfNotPresent: false, + }, + }, + nil, + fsSlice{ + { + Path: "whatever", + Gvk: gvk.Gvk{Group: "apple"}, + CreateIfNotPresent: false, + }, + { + Path: "whatever", + Gvk: gvk.Gvk{Group: "pear"}, + CreateIfNotPresent: false, + }, + }, + }, + { + "error on conflict", + fsSlice{ + { + Path: "whatever", + Gvk: gvk.Gvk{Group: "apple"}, + CreateIfNotPresent: false, + }, + { + Path: "whatever", + Gvk: gvk.Gvk{Group: "pear"}, + CreateIfNotPresent: false, + }, + }, + fsSlice{ + { + Path: "whatever", + Gvk: gvk.Gvk{Group: "apple"}, + CreateIfNotPresent: true, + }, + }, + fmt.Errorf("hey"), + fsSlice{}, + }, +} + +func TestFsSlice_MergeAll(t *testing.T) { + for _, item := range mergeTests { + result, err := item.original.mergeAll(item.incoming) + if item.err == nil { + if err != nil { + t.Fatalf("test %s: unexpected err %v", item.name, err) + } + if !reflect.DeepEqual(item.result, result) { + t.Fatalf("test %s: expected: %v\n but got: %v\n", + item.name, item.result, result) + } + } else { + if err == nil { + t.Fatalf("test %s: expected err: %v", item.name, err) + } + if !strings.Contains(err.Error(), "conflicting fieldspecs") { + t.Fatalf("test %s: unexpected err: %v", item.name, err) + } + } + } +} diff --git a/pkg/transformers/config/namebackreferences.go b/pkg/transformers/config/namebackreferences.go index d0a6e8d1e..172e4b3ca 100644 --- a/pkg/transformers/config/namebackreferences.go +++ b/pkg/transformers/config/namebackreferences.go @@ -52,7 +52,7 @@ import ( // } type NameBackReferences struct { gvk.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"` - FieldSpecs []FieldSpec `json:"FieldSpecs,omitempty" yaml:"FieldSpecs,omitempty"` + FieldSpecs fsSlice `json:"FieldSpecs,omitempty" yaml:"FieldSpecs,omitempty"` } func (n NameBackReferences) String() string { @@ -72,20 +72,27 @@ func (s nbrSlice) Less(i, j int) bool { return s[i].Gvk.IsLessThan(s[j].Gvk) } -func (s nbrSlice) mergeAll(o nbrSlice) nbrSlice { - result := s +func (s nbrSlice) mergeAll(o nbrSlice) (result nbrSlice, err error) { + result = s for _, r := range o { - result = result.mergeOne(r) + result, err = result.mergeOne(r) + if err != nil { + return nil, err + } } - return result + return result, nil } -func (s nbrSlice) mergeOne(other NameBackReferences) nbrSlice { +func (s nbrSlice) mergeOne(other NameBackReferences) (nbrSlice, error) { var result nbrSlice + var err error found := false for _, c := range s { if c.Gvk.Equals(other.Gvk) { - c.FieldSpecs = append(c.FieldSpecs, other.FieldSpecs...) + c.FieldSpecs, err = c.FieldSpecs.mergeAll(other.FieldSpecs) + if err != nil { + return nil, err + } found = true } result = append(result, c) @@ -94,5 +101,5 @@ func (s nbrSlice) mergeOne(other NameBackReferences) nbrSlice { if !found { result = append(result, other) } - return result + return result, nil } diff --git a/pkg/transformers/config/namebackreferences_test.go b/pkg/transformers/config/namebackreferences_test.go index 59eb07761..a872a74d9 100644 --- a/pkg/transformers/config/namebackreferences_test.go +++ b/pkg/transformers/config/namebackreferences_test.go @@ -89,17 +89,19 @@ func TestMergeAll(t *testing.T) { Gvk: gvk.Gvk{ Kind: "ConfigMap", }, - // Current behavior allows repeats of FieldSpec - FieldSpecs: append(fsSlice1, fsSlice1...), + FieldSpecs: fsSlice1, }, { Gvk: gvk.Gvk{ Kind: "Secret", }, - FieldSpecs: append(fsSlice2, fsSlice2...), + FieldSpecs: fsSlice2, }, } - actual := nbrsSlice1.mergeAll(nbrsSlice2) + actual, err := nbrsSlice1.mergeAll(nbrsSlice2) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } if !reflect.DeepEqual(actual, expected) { t.Fatalf("expected\n %v\n but got\n %v\n", expected, actual) } diff --git a/pkg/transformers/config/transformerconfig.go b/pkg/transformers/config/transformerconfig.go index 5de589e19..6d9e6d2e4 100644 --- a/pkg/transformers/config/transformerconfig.go +++ b/pkg/transformers/config/transformerconfig.go @@ -44,43 +44,70 @@ func (t *TransformerConfig) sortFields() { } // AddPrefixFieldSpec adds a FieldSpec to NamePrefix -func (t *TransformerConfig) AddPrefixFieldSpec(fs FieldSpec) { - t.NamePrefix = append(t.NamePrefix, fs) +func (t *TransformerConfig) AddPrefixFieldSpec(fs FieldSpec) (err error) { + t.NamePrefix, err = t.NamePrefix.mergeOne(fs) + return err } // AddSuffixFieldSpec adds a FieldSpec to NameSuffix -func (t *TransformerConfig) AddSuffixFieldSpec(fs FieldSpec) { - t.NameSuffix = append([]FieldSpec{fs}, t.NameSuffix...) +func (t *TransformerConfig) AddSuffixFieldSpec(fs FieldSpec) (err error) { + t.NameSuffix, err = t.NameSuffix.mergeOne(fs) + return err } // AddLabelFieldSpec adds a FieldSpec to CommonLabels -func (t *TransformerConfig) AddLabelFieldSpec(fs FieldSpec) { - t.CommonLabels = append(t.CommonLabels, fs) +func (t *TransformerConfig) AddLabelFieldSpec(fs FieldSpec) (err error) { + t.CommonLabels, err = t.CommonLabels.mergeOne(fs) + return err } // AddAnnotationFieldSpec adds a FieldSpec to CommonAnnotations -func (t *TransformerConfig) AddAnnotationFieldSpec(fs FieldSpec) { - t.CommonAnnotations = append(t.CommonAnnotations, fs) +func (t *TransformerConfig) AddAnnotationFieldSpec(fs FieldSpec) (err error) { + t.CommonAnnotations, err = t.CommonAnnotations.mergeOne(fs) + return err } // AddNamereferenceFieldSpec adds a NameBackReferences to NameReference -func (t *TransformerConfig) AddNamereferenceFieldSpec(nbrs NameBackReferences) { - t.NameReference = t.NameReference.mergeOne(nbrs) +func (t *TransformerConfig) AddNamereferenceFieldSpec(nbrs NameBackReferences) (err error) { + t.NameReference, err = t.NameReference.mergeOne(nbrs) + return err } // Merge merges two TransformerConfigs objects into a new TransformerConfig object -func (t *TransformerConfig) Merge(input *TransformerConfig) *TransformerConfig { +func (t *TransformerConfig) Merge(input *TransformerConfig) ( + merged *TransformerConfig, err error) { if input == nil { - return t + return t, nil + } + merged = &TransformerConfig{} + merged.NamePrefix, err = t.NamePrefix.mergeAll(input.NamePrefix) + if err != nil { + return nil, err + } + merged.NameSuffix, err = t.NameSuffix.mergeAll(input.NameSuffix) + if err != nil { + return nil, err + } + merged.NameSpace, err = t.NameSpace.mergeAll(input.NameSpace) + if err != nil { + return nil, err + } + merged.CommonAnnotations, err = t.CommonAnnotations.mergeAll(input.CommonAnnotations) + if err != nil { + return nil, err + } + merged.CommonLabels, err = t.CommonLabels.mergeAll(input.CommonLabels) + if err != nil { + return nil, err + } + merged.VarReference, err = t.VarReference.mergeAll(input.VarReference) + if err != nil { + return nil, err + } + merged.NameReference, err = t.NameReference.mergeAll(input.NameReference) + if err != nil { + return nil, err } - merged := &TransformerConfig{} - merged.NamePrefix = append(t.NamePrefix, input.NamePrefix...) - merged.NameSuffix = append(input.NameSuffix, t.NameSuffix...) - merged.NameSpace = append(t.NameSpace, input.NameSpace...) - merged.CommonAnnotations = append(t.CommonAnnotations, input.CommonAnnotations...) - merged.CommonLabels = append(t.CommonLabels, input.CommonLabels...) - merged.VarReference = append(t.VarReference, input.VarReference...) - merged.NameReference = t.NameReference.mergeAll(input.NameReference) merged.sortFields() - return merged + return merged, nil } diff --git a/pkg/transformers/config/transformerconfig_test.go b/pkg/transformers/config/transformerconfig_test.go index a12fa6e38..40d8b05e4 100644 --- a/pkg/transformers/config/transformerconfig_test.go +++ b/pkg/transformers/config/transformerconfig_test.go @@ -42,7 +42,10 @@ func TestAddNamereferenceFieldSpec(t *testing.T) { }, } - cfg.AddNamereferenceFieldSpec(nbrs) + err := cfg.AddNamereferenceFieldSpec(nbrs) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } if len(cfg.NameReference) != 1 { t.Fatal("failed to add namereference FieldSpec") } @@ -57,19 +60,31 @@ func TestAddFieldSpecs(t *testing.T) { CreateIfNotPresent: true, } - cfg.AddPrefixFieldSpec(fieldSpec) + err := cfg.AddPrefixFieldSpec(fieldSpec) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } if len(cfg.NamePrefix) != 1 { t.Fatalf("failed to add nameprefix FieldSpec") } - cfg.AddSuffixFieldSpec(fieldSpec) + err = cfg.AddSuffixFieldSpec(fieldSpec) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } if len(cfg.NameSuffix) != 1 { t.Fatalf("failed to add namesuffix FieldSpec") } - cfg.AddLabelFieldSpec(fieldSpec) + err = cfg.AddLabelFieldSpec(fieldSpec) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } if len(cfg.CommonLabels) != 1 { t.Fatalf("failed to add nameprefix FieldSpec") } - cfg.AddAnnotationFieldSpec(fieldSpec) + err = cfg.AddAnnotationFieldSpec(fieldSpec) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } if len(cfg.CommonAnnotations) != 1 { t.Fatalf("failed to add nameprefix FieldSpec") } @@ -128,7 +143,10 @@ func TestMerge(t *testing.T) { cfgb.AddPrefixFieldSpec(fieldSpecs[1]) cfga.AddSuffixFieldSpec(fieldSpecs[1]) - actual := cfga.Merge(cfgb) + actual, err := cfga.Merge(cfgb) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } if len(actual.NamePrefix) != 2 { t.Fatal("merge failed for namePrefix FieldSpec") @@ -154,7 +172,10 @@ func TestMerge(t *testing.T) { t.Fatalf("expected: %v\n but got: %v\n", expected, actual) } - actual = cfga.Merge(nil) + actual, err = cfga.Merge(nil) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } if !reflect.DeepEqual(actual, cfga) { t.Fatalf("expected: %v\n but got: %v\n", cfga, actual) } From a838b8542605e6298945ef79a4b9f5cb5d65d8e7 Mon Sep 17 00:00:00 2001 From: jregan Date: Sat, 29 Dec 2018 14:09:42 -0800 Subject: [PATCH 037/317] Convert CRD tests to in-memory. --- .../build/testdata/testcase-crds/crd/bee.yaml | 6 - .../testcase-crds/crd/kustomization.yaml | 11 -- .../testdata/testcase-crds/crd/mykind.yaml | 9 - .../testdata/testcase-crds/crd/secret.yaml | 6 - .../testdata/testcase-crds/expected.diff | 36 ---- .../testdata/testcase-crds/expected.yaml | 23 --- .../build/testdata/testcase-crds/test.yaml | 5 - .../crd/mycrd.json => target/crd_test.go} | 170 +++++++++++++++++- 8 files changed, 161 insertions(+), 105 deletions(-) delete mode 100644 pkg/commands/build/testdata/testcase-crds/crd/bee.yaml delete mode 100644 pkg/commands/build/testdata/testcase-crds/crd/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-crds/crd/mykind.yaml delete mode 100644 pkg/commands/build/testdata/testcase-crds/crd/secret.yaml delete mode 100644 pkg/commands/build/testdata/testcase-crds/expected.diff delete mode 100644 pkg/commands/build/testdata/testcase-crds/expected.yaml delete mode 100644 pkg/commands/build/testdata/testcase-crds/test.yaml rename pkg/{commands/build/testdata/testcase-crds/crd/mycrd.json => target/crd_test.go} (61%) diff --git a/pkg/commands/build/testdata/testcase-crds/crd/bee.yaml b/pkg/commands/build/testdata/testcase-crds/crd/bee.yaml deleted file mode 100644 index 28cc9bd9e..000000000 --- a/pkg/commands/build/testdata/testcase-crds/crd/bee.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v1beta1 -kind: Bee -metadata: - name: bee -spec: - action: fly diff --git a/pkg/commands/build/testdata/testcase-crds/crd/kustomization.yaml b/pkg/commands/build/testdata/testcase-crds/crd/kustomization.yaml deleted file mode 100644 index b5f7ff246..000000000 --- a/pkg/commands/build/testdata/testcase-crds/crd/kustomization.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -crds: -- mycrd.json - -resources: -- secret.yaml -- mykind.yaml -- bee.yaml - -namePrefix: test- \ No newline at end of file diff --git a/pkg/commands/build/testdata/testcase-crds/crd/mykind.yaml b/pkg/commands/build/testdata/testcase-crds/crd/mykind.yaml deleted file mode 100644 index 0a644daa6..000000000 --- a/pkg/commands/build/testdata/testcase-crds/crd/mykind.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: jingfang.example.com/v1beta1 -kind: MyKind -metadata: - name: mykind -spec: - secretRef: - name: crdsecret - beeRef: - name: bee diff --git a/pkg/commands/build/testdata/testcase-crds/crd/secret.yaml b/pkg/commands/build/testdata/testcase-crds/crd/secret.yaml deleted file mode 100644 index 9126dd868..000000000 --- a/pkg/commands/build/testdata/testcase-crds/crd/secret.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: crdsecret -data: - PATH: YmJiYmJiYmIK diff --git a/pkg/commands/build/testdata/testcase-crds/expected.diff b/pkg/commands/build/testdata/testcase-crds/expected.diff deleted file mode 100644 index ed2cf5559..000000000 --- a/pkg/commands/build/testdata/testcase-crds/expected.diff +++ /dev/null @@ -1,36 +0,0 @@ -diff -u -N /tmp/noop/jingfang.example.com_v1beta1_MyKind_mykind.yaml /tmp/transformed/jingfang.example.com_v1beta1_MyKind_mykind.yaml ---- /tmp/noop/jingfang.example.com_v1beta1_MyKind_mykind.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/jingfang.example.com_v1beta1_MyKind_mykind.yaml YYYY-MM-DD HH:MM:SS -@@ -1,9 +1,9 @@ - apiVersion: jingfang.example.com/v1beta1 - kind: MyKind - metadata: -- name: mykind -+ name: test-mykind - spec: - beeRef: -- name: bee -+ name: test-bee - secretRef: -- name: crdsecret -+ name: test-crdsecret -diff -u -N /tmp/noop/v1beta1_Bee_bee.yaml /tmp/transformed/v1beta1_Bee_bee.yaml ---- /tmp/noop/v1beta1_Bee_bee.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1beta1_Bee_bee.yaml YYYY-MM-DD HH:MM:SS -@@ -1,6 +1,6 @@ - apiVersion: v1beta1 - kind: Bee - metadata: -- name: bee -+ name: test-bee - spec: - action: fly -diff -u -N /tmp/noop/v1_Secret_crdsecret.yaml /tmp/transformed/v1_Secret_crdsecret.yaml ---- /tmp/noop/v1_Secret_crdsecret.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_Secret_crdsecret.yaml YYYY-MM-DD HH:MM:SS -@@ -3,4 +3,4 @@ - PATH: YmJiYmJiYmIK - kind: Secret - metadata: -- name: crdsecret -+ name: test-crdsecret diff --git a/pkg/commands/build/testdata/testcase-crds/expected.yaml b/pkg/commands/build/testdata/testcase-crds/expected.yaml deleted file mode 100644 index 8116db1e6..000000000 --- a/pkg/commands/build/testdata/testcase-crds/expected.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: v1 -data: - PATH: YmJiYmJiYmIK -kind: Secret -metadata: - name: test-crdsecret ---- -apiVersion: jingfang.example.com/v1beta1 -kind: MyKind -metadata: - name: test-mykind -spec: - beeRef: - name: test-bee - secretRef: - name: test-crdsecret ---- -apiVersion: v1beta1 -kind: Bee -metadata: - name: test-bee -spec: - action: fly diff --git a/pkg/commands/build/testdata/testcase-crds/test.yaml b/pkg/commands/build/testdata/testcase-crds/test.yaml deleted file mode 100644 index c85121c60..000000000 --- a/pkg/commands/build/testdata/testcase-crds/test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -description: name reference in CRDs -args: [] -filename: testdata/testcase-crds/crd -expectedStdout: testdata/testcase-crds/expected.yaml -expectedDiff: testdata/testcase-crds/expected.diff diff --git a/pkg/commands/build/testdata/testcase-crds/crd/mycrd.json b/pkg/target/crd_test.go similarity index 61% rename from pkg/commands/build/testdata/testcase-crds/crd/mycrd.json rename to pkg/target/crd_test.go index afe38882d..68e79b2a7 100644 --- a/pkg/commands/build/testdata/testcase-crds/crd/mycrd.json +++ b/pkg/target/crd_test.go @@ -1,14 +1,78 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "testing" +) + +func writeBaseWithCrd(th *KustTestHarness) { + th.writeK("/app/base", ` +apiVersion: v1beta1 +kind: Kustomization +crds: +- mycrd.json + +resources: +- secret.yaml +- mykind.yaml +- bee.yaml + +namePrefix: x- +`) + th.writeF("/app/base/bee.yaml", ` +apiVersion: v1beta1 +kind: Bee +metadata: + name: bee +spec: + action: fly +`) + th.writeF("/app/base/mykind.yaml", ` +apiVersion: jingfang.example.com/v1beta1 +kind: MyKind +metadata: + name: mykind +spec: + secretRef: + name: crdsecret + beeRef: + name: bee +`) + th.writeF("/app/base/secret.yaml", ` +apiVersion: v1 +kind: Secret +metadata: + name: crdsecret +data: + PATH: yellowBrickRoad +`) + th.writeF("/app/base/mycrd.json", ` { "github.com/example/pkg/apis/jingfang/v1beta1.Bee": { "Schema": { "description": "Bee", "properties": { "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources", + "description": "APIVersion defines the versioned schema of this representation of an object.", "type": "string" }, "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds", + "description": "Kind is a string value representing the REST resource this object represents.", "type": "string" }, "metadata": { @@ -35,7 +99,7 @@ ], "properties": { "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources", + "description": "APIVersion defines the versioned schema of this representation of an object.", "type": "string" }, "items": { @@ -45,7 +109,7 @@ } }, "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds", + "description": "Kind is a string value representing the REST resource this object represents.", "type": "string" }, "metadata": { @@ -85,11 +149,11 @@ "description": "MyKind", "properties": { "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources", + "description": "APIVersion defines the versioned schema of this representation of an object.", "type": "string" }, "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds", + "description": "Kind is a string value representing the REST resource this object represents.", "type": "string" }, "metadata": { @@ -116,7 +180,7 @@ ], "properties": { "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources", + "description": "APIVersion defines the versioned schema of this representation of an object.", "type": "string" }, "items": { @@ -126,7 +190,7 @@ } }, "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds", + "description": "Kind is a string value representing the REST resource this object represents.", "type": "string" }, "metadata": { @@ -149,7 +213,7 @@ "$ref": "github.com/example/pkg/apis/jingfang/v1beta1.BeeObjectReference" }, "secretRef": { - "description": "If defined, we use this secret for configuring the MYSQL_ROOT_PASSWORD If it is not set we generate a secret dynamically", + "description": "If defined, use this secret for configuring the MYSQL_ROOT_PASSWORD", "x-kubernetes-object-ref-api-version": "v1", "x-kubernetes-object-ref-kind": "Secret", "$ref": "k8s.io/api/core/v1.LocalObjectReference" @@ -168,3 +232,91 @@ "Dependencies": [] } } +`) +} + +func TestCrdBase(t *testing.T) { + th := NewKustTestHarness(t, "/app/base") + writeBaseWithCrd(th) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + PATH: yellowBrickRoad +kind: Secret +metadata: + name: x-crdsecret +--- +apiVersion: jingfang.example.com/v1beta1 +kind: MyKind +metadata: + name: x-mykind +spec: + beeRef: + name: x-bee + secretRef: + name: x-crdsecret +--- +apiVersion: v1beta1 +kind: Bee +metadata: + name: x-bee +spec: + action: fly +`) +} + +func TestCrdWithOverlay(t *testing.T) { + th := NewKustTestHarness(t, "/app/overlay") + writeBaseWithCrd(th) + th.writeK("/app/overlay", ` +apiVersion: v1beta1 +kind: Kustomization +namePrefix: prod- +bases: +- ../base +patchesStrategicMerge: +- bee.yaml +`) + th.writeF("/app/overlay/bee.yaml", ` +apiVersion: v1beta1 +kind: Bee +metadata: + name: bee +spec: + action: makehoney +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + // TODO(#605): Some output here is wrong due to #605 + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + PATH: yellowBrickRoad +kind: Secret +metadata: + name: prod-x-crdsecret +--- +apiVersion: jingfang.example.com/v1beta1 +kind: MyKind +metadata: + name: prod-x-mykind +spec: + beeRef: + name: bee + secretRef: + name: crdsecret +--- +apiVersion: v1beta1 +kind: Bee +metadata: + name: prod-bee +spec: + action: makehoney +`) +} From b7e1f8da72cedd2bcb91a5c7aabe4dd79830cf47 Mon Sep 17 00:00:00 2001 From: jregan Date: Sat, 29 Dec 2018 14:51:59 -0800 Subject: [PATCH 038/317] Convert configmap tests to in-memory. --- .../base/myapp/mycomponent/kustomization.yaml | 8 -- .../myapp/mycomponent2/kustomization.yaml | 8 -- .../testcase-configmaps/expected.diff | 16 --- .../testcase-configmaps/expected.yaml | 19 ---- .../overlay/dev/kustomization.yaml | 11 -- .../dev/myapp/mycomponent/kustomization.yaml | 9 -- .../dev/myapp/mycomponent2/kustomization.yaml | 9 -- .../testdata/testcase-configmaps/test.yaml | 5 - pkg/target/configmaps_test.go | 105 ++++++++++++++++++ 9 files changed, 105 insertions(+), 85 deletions(-) delete mode 100644 pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent2/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-configmaps/expected.diff delete mode 100644 pkg/commands/build/testdata/testcase-configmaps/expected.yaml delete mode 100644 pkg/commands/build/testdata/testcase-configmaps/overlay/dev/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent2/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-configmaps/test.yaml create mode 100644 pkg/target/configmaps_test.go diff --git a/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent/kustomization.yaml deleted file mode 100644 index fe386b14b..000000000 --- a/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent/kustomization.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -namePrefix: p1- -configMapGenerator: -- name: com1 - behavior: create - literals: - - from=base diff --git a/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent2/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent2/kustomization.yaml deleted file mode 100644 index 18b0347bb..000000000 --- a/pkg/commands/build/testdata/testcase-configmaps/base/myapp/mycomponent2/kustomization.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -namePrefix: p2- -configMapGenerator: -- name: com2 - behavior: create - literals: - - from=base diff --git a/pkg/commands/build/testdata/testcase-configmaps/expected.diff b/pkg/commands/build/testdata/testcase-configmaps/expected.diff deleted file mode 100644 index 7803718cb..000000000 --- a/pkg/commands/build/testdata/testcase-configmaps/expected.diff +++ /dev/null @@ -1,16 +0,0 @@ -diff -u -N /tmp/noop/v1_ConfigMap_com1.yaml /tmp/transformed/v1_ConfigMap_com1.yaml ---- /tmp/noop/v1_ConfigMap_com1.yaml YYYY-MM-DD HH:MM:SS -+++ /tmp/transformed/v1_ConfigMap_com1.yaml YYYY-MM-DD HH:MM:SS -@@ -1,9 +1,11 @@ - apiVersion: v1 - data: -+ baz: qux -+ foo: bar - from: overlay - kind: ConfigMap - metadata: - annotations: {} - creationTimestamp: null - labels: {} -- name: p1-com1-cmdb776d5b -+ name: p1-com1-dhbbm922gd diff --git a/pkg/commands/build/testdata/testcase-configmaps/expected.yaml b/pkg/commands/build/testdata/testcase-configmaps/expected.yaml deleted file mode 100644 index 59656f4ee..000000000 --- a/pkg/commands/build/testdata/testcase-configmaps/expected.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v1 -data: - baz: qux - foo: bar - from: overlay -kind: ConfigMap -metadata: - annotations: {} - labels: {} - name: p1-com1-dhbbm922gd ---- -apiVersion: v1 -data: - from: overlay -kind: ConfigMap -metadata: - annotations: {} - labels: {} - name: p2-com2-c4b8md75k9 diff --git a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/kustomization.yaml deleted file mode 100644 index e34a4767b..000000000 --- a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/kustomization.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -bases: -- myapp/mycomponent -- myapp/mycomponent2 -configMapGenerator: -- name: com1 - behavior: merge - literals: - - foo=bar - - baz=qux \ No newline at end of file diff --git a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent/kustomization.yaml deleted file mode 100644 index f14834eab..000000000 --- a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent/kustomization.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -bases: -- ../../../../base/myapp/mycomponent -configMapGenerator: -- name: com1 - behavior: merge - literals: - - from=overlay diff --git a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent2/kustomization.yaml b/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent2/kustomization.yaml deleted file mode 100644 index f66340c38..000000000 --- a/pkg/commands/build/testdata/testcase-configmaps/overlay/dev/myapp/mycomponent2/kustomization.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -bases: -- ../../../../base/myapp/mycomponent2 -configMapGenerator: -- name: com2 - behavior: merge - literals: - - from=overlay diff --git a/pkg/commands/build/testdata/testcase-configmaps/test.yaml b/pkg/commands/build/testdata/testcase-configmaps/test.yaml deleted file mode 100644 index 633d415a7..000000000 --- a/pkg/commands/build/testdata/testcase-configmaps/test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -description: configmap generator overlay -args: [] -filename: testdata/testcase-configmaps/overlay/dev -expectedStdout: testdata/testcase-configmaps/expected.yaml -expectedDiff: testdata/testcase-configmaps/expected.diff diff --git a/pkg/target/configmaps_test.go b/pkg/target/configmaps_test.go new file mode 100644 index 000000000..4de2ae326 --- /dev/null +++ b/pkg/target/configmaps_test.go @@ -0,0 +1,105 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "testing" +) + +func TestGenerator1(t *testing.T) { + th := NewKustTestHarness(t, "/app/overlay") + th.writeK("/app/base1", ` +apiVersion: v1beta1 +kind: Kustomization +namePrefix: p1- +configMapGenerator: +- name: com1 + behavior: create + literals: + - from=base +`) + th.writeK("/app/base2", ` +apiVersion: v1beta1 +kind: Kustomization +namePrefix: p2- +configMapGenerator: +- name: com2 + behavior: create + literals: + - from=base +`) + th.writeK("/app/overlay/o1", ` +apiVersion: v1beta1 +kind: Kustomization +bases: +- ../../base1 +configMapGenerator: +- name: com1 + behavior: merge + literals: + - from=overlay +`) + th.writeK("/app/overlay/o2", ` +apiVersion: v1beta1 +kind: Kustomization +bases: +- ../../base2 +configMapGenerator: +- name: com2 + behavior: merge + literals: + - from=overlay +`) + th.writeK("/app/overlay", ` +apiVersion: v1beta1 +kind: Kustomization +bases: +- o1 +- o2 +configMapGenerator: +- name: com1 + behavior: merge + literals: + - foo=bar + - baz=qux +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + baz: qux + foo: bar + from: overlay +kind: ConfigMap +metadata: + annotations: {} + labels: {} + name: p1-com1-dhbbm922gd +--- +apiVersion: v1 +data: + from: overlay +kind: ConfigMap +metadata: + annotations: {} + labels: {} + name: p2-com2-c4b8md75k9 +`) +} From b16a7364fda64e0365be14d2950b78d528a53024 Mon Sep 17 00:00:00 2001 From: jregan Date: Sat, 29 Dec 2018 15:03:26 -0800 Subject: [PATCH 039/317] Convert namespaced generators to in-memory. --- .../expected.yaml | 33 ------- .../in/kustomization.yaml | 21 ----- .../in/password.txt | 1 - .../testcase-generators-namespace/test.yaml | 4 - pkg/target/namespacedgenerators_test.go | 87 +++++++++++++++++++ 5 files changed, 87 insertions(+), 59 deletions(-) delete mode 100644 pkg/commands/build/testdata/testcase-generators-namespace/expected.yaml delete mode 100644 pkg/commands/build/testdata/testcase-generators-namespace/in/kustomization.yaml delete mode 100644 pkg/commands/build/testdata/testcase-generators-namespace/in/password.txt delete mode 100644 pkg/commands/build/testdata/testcase-generators-namespace/test.yaml create mode 100644 pkg/target/namespacedgenerators_test.go diff --git a/pkg/commands/build/testdata/testcase-generators-namespace/expected.yaml b/pkg/commands/build/testdata/testcase-generators-namespace/expected.yaml deleted file mode 100644 index 1d265fe43..000000000 --- a/pkg/commands/build/testdata/testcase-generators-namespace/expected.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: v1 -data: - altGreeting: Good Morning from non-default namespace! - enableRisky: "false" -kind: ConfigMap -metadata: - name: the-non-default-namespace-map-b6h49k7mt8 - namespace: non-default ---- -apiVersion: v1 -data: - altGreeting: Good Morning from default namespace! - enableRisky: "false" -kind: ConfigMap -metadata: - name: the-map-4959m5tm6c ---- -apiVersion: v1 -data: - password.txt: dmVyeSRlY3JldA== -kind: Secret -metadata: - name: the-non-default-namespace-secret-255294gd9d - namespace: non-default -type: Opaque ---- -apiVersion: v1 -data: - password.txt: dmVyeSRlY3JldA== -kind: Secret -metadata: - name: the-secret-cfbmct72tb -type: Opaque diff --git a/pkg/commands/build/testdata/testcase-generators-namespace/in/kustomization.yaml b/pkg/commands/build/testdata/testcase-generators-namespace/in/kustomization.yaml deleted file mode 100644 index 5dc4dba90..000000000 --- a/pkg/commands/build/testdata/testcase-generators-namespace/in/kustomization.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: v1beta1 -kind: Kustomization -configMapGenerator: -- name: the-non-default-namespace-map - namespace: non-default - literals: - - altGreeting=Good Morning from non-default namespace! - - enableRisky="false" -- name: the-map - literals: - - altGreeting=Good Morning from default namespace! - - enableRisky="false" - -secretGenerator: -- name: the-non-default-namespace-secret - namespace: non-default - commands: - password.txt: "cat password.txt" -- name: the-secret - commands: - password.txt: "cat password.txt" \ No newline at end of file diff --git a/pkg/commands/build/testdata/testcase-generators-namespace/in/password.txt b/pkg/commands/build/testdata/testcase-generators-namespace/in/password.txt deleted file mode 100644 index 0ceb1fc32..000000000 --- a/pkg/commands/build/testdata/testcase-generators-namespace/in/password.txt +++ /dev/null @@ -1 +0,0 @@ -very$ecret \ No newline at end of file diff --git a/pkg/commands/build/testdata/testcase-generators-namespace/test.yaml b/pkg/commands/build/testdata/testcase-generators-namespace/test.yaml deleted file mode 100644 index bf13f64b6..000000000 --- a/pkg/commands/build/testdata/testcase-generators-namespace/test.yaml +++ /dev/null @@ -1,4 +0,0 @@ -description: generators-namespace -args: [] -filename: testdata/testcase-generators-namespace/in -expectedStdout: testdata/testcase-generators-namespace/expected.yaml diff --git a/pkg/target/namespacedgenerators_test.go b/pkg/target/namespacedgenerators_test.go new file mode 100644 index 000000000..61d3cd2db --- /dev/null +++ b/pkg/target/namespacedgenerators_test.go @@ -0,0 +1,87 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "testing" +) + +func TestNamespacedGenerator(t *testing.T) { + th := NewKustTestHarness(t, "/app") + th.writeK("/app", ` +apiVersion: v1beta1 +kind: Kustomization +configMapGenerator: +- name: the-non-default-namespace-map + namespace: non-default + literals: + - altGreeting=Good Morning from non-default namespace! + - enableRisky="false" +- name: the-map + literals: + - altGreeting=Good Morning from default namespace! + - enableRisky="false" + +secretGenerator: +- name: the-non-default-namespace-secret + namespace: non-default + commands: + password.txt: "echo verySecret" +- name: the-secret + commands: + password.txt: "echo anotherSecret" +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + altGreeting: Good Morning from non-default namespace! + enableRisky: "false" +kind: ConfigMap +metadata: + name: the-non-default-namespace-map-b6h49k7mt8 + namespace: non-default +--- +apiVersion: v1 +data: + altGreeting: Good Morning from default namespace! + enableRisky: "false" +kind: ConfigMap +metadata: + name: the-map-4959m5tm6c +--- +apiVersion: v1 +data: + password.txt: dmVyeVNlY3JldAo= +kind: Secret +metadata: + name: the-non-default-namespace-secret-9fgdmbbk5c + namespace: non-default +type: Opaque +--- +apiVersion: v1 +data: + password.txt: YW5vdGhlclNlY3JldAo= +kind: Secret +metadata: + name: the-secret-7dd8hcgfhk +type: Opaque +`) +} From d98afdc229c58181ba3f81828a85ac333cdea0c4 Mon Sep 17 00:00:00 2001 From: jregan Date: Sat, 29 Dec 2018 15:12:09 -0800 Subject: [PATCH 040/317] Delete deprecated file-based build test code. --- pkg/commands/build/build_test.go | 96 -------------------------------- 1 file changed, 96 deletions(-) diff --git a/pkg/commands/build/build_test.go b/pkg/commands/build/build_test.go index df332b73b..3c7c4b089 100644 --- a/pkg/commands/build/build_test.go +++ b/pkg/commands/build/build_test.go @@ -17,29 +17,11 @@ limitations under the License. package build import ( - "bytes" - "io/ioutil" - "os" - "path/filepath" - "reflect" - "strings" "testing" - "github.com/ghodss/yaml" - "sigs.k8s.io/kustomize/k8sdeps" "sigs.k8s.io/kustomize/pkg/constants" - "sigs.k8s.io/kustomize/pkg/fs" ) -type buildTestCase struct { - Description string `yaml:"description"` - Args []string `yaml:"args"` - Filename string `yaml:"filename"` - // path to the file that contains the expected output - ExpectedStdout string `yaml:"expectedStdout"` - ExpectedError string `yaml:"expectedError"` -} - func TestBuildValidate(t *testing.T) { var cases = []struct { name string @@ -74,81 +56,3 @@ func TestBuildValidate(t *testing.T) { } } } - -func TestBuild(t *testing.T) { - const updateEnvVar = "UPDATE_KUSTOMIZE_EXPECTED_DATA" - updateKustomizeExpected := os.Getenv(updateEnvVar) == "true" - fSys := fs.MakeRealFS() - - var testcases []string - filepath.Walk("testdata", func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if path == "testdata" { - return nil - } - name := filepath.Base(path) - if info.IsDir() { - if strings.HasPrefix(name, "testcase-") { - testcases = append(testcases, strings.TrimPrefix(name, "testcase-")) - } - return filepath.SkipDir - } - return nil - }) - for _, testcaseName := range testcases { - t.Run(testcaseName, - func(t *testing.T) { - runBuildTestCase(t, testcaseName, updateKustomizeExpected, fSys) - }) - } -} - -func runBuildTestCase(t *testing.T, testcaseName string, updateKustomizeExpected bool, fSys fs.FileSystem) { - name := testcaseName - testcase := buildTestCase{} - testcaseDir := filepath.Join("testdata", "testcase-"+name) - testcaseData, err := ioutil.ReadFile(filepath.Join(testcaseDir, "test.yaml")) - if err != nil { - t.Fatalf("%s: %v", name, err) - } - if err := yaml.Unmarshal(testcaseData, &testcase); err != nil { - t.Fatalf("%s: %v", name, err) - } - - ops := &buildOptions{ - kustomizationPath: testcase.Filename, - } - buf := bytes.NewBuffer([]byte{}) - f := k8sdeps.NewFactory() - err = ops.RunBuild( - buf, fSys, - f.ResmapF, - f.TransformerF) - switch { - case err != nil && len(testcase.ExpectedError) == 0: - t.Errorf("unexpected error: %v", err) - case err != nil && len(testcase.ExpectedError) != 0: - if !strings.Contains(err.Error(), testcase.ExpectedError) { - t.Errorf("expected error to contain %q but got: %v", testcase.ExpectedError, err) - } - return - case err == nil && len(testcase.ExpectedError) != 0: - t.Errorf("unexpected no error") - } - - actualBytes := buf.Bytes() - if !updateKustomizeExpected { - expectedBytes, err := ioutil.ReadFile(testcase.ExpectedStdout) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if !reflect.DeepEqual(actualBytes, expectedBytes) { - t.Errorf("\n**** Actual:\n\n%s\n\n**** doesn't equal expected:\n\n%s\n\n", actualBytes, expectedBytes) - } - } else { - ioutil.WriteFile(testcase.ExpectedStdout, actualBytes, 0644) - } - -} From 93ad371400624b67df62685af0c4c1c9ae3f305e Mon Sep 17 00:00:00 2001 From: jregan Date: Sun, 30 Dec 2018 07:40:30 -0800 Subject: [PATCH 041/317] Fix some comments and format nits. --- pkg/target/customconfig_test.go | 3 ++- pkg/target/kusttarget.go | 5 +++-- pkg/transformers/config/transformerconfig.go | 9 ++++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/pkg/target/customconfig_test.go b/pkg/target/customconfig_test.go index a2f0cde56..f965f3789 100644 --- a/pkg/target/customconfig_test.go +++ b/pkg/target/customconfig_test.go @@ -155,7 +155,8 @@ func TestCustomConfigWithDefaultOverspecification(t *testing.T) { makeBaseReferencingCustomConfig(th) th.writeDefaultConfigs("/app/base/config/defaults.yaml") // Specifying namePrefix here conflicts with (is the same as) - // the defaults written above. + // the defaults written above. This is intentional in the + // test to assure duplicate config doesn't cause problems. th.writeF("/app/base/config/custom.yaml", ` namePrefix: - path: metadata/name diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index ac315006a..f42449b29 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -97,8 +97,9 @@ func unmarshal(y []byte, o interface{}) error { return dec.Decode(o) } -// Maybe switch to the false path permanently (desired by #606), -// or expose this as a CLI flag. +// TODO(#6060) Maybe switch to the false path permanently +// (desired by #606), or expose this as a new customization +// directive. const demandExplicitConfig = true func makeTransformerConfig( diff --git a/pkg/transformers/config/transformerconfig.go b/pkg/transformers/config/transformerconfig.go index 6d9e6d2e4..641e9301c 100644 --- a/pkg/transformers/config/transformerconfig.go +++ b/pkg/transformers/config/transformerconfig.go @@ -68,12 +68,14 @@ func (t *TransformerConfig) AddAnnotationFieldSpec(fs FieldSpec) (err error) { } // AddNamereferenceFieldSpec adds a NameBackReferences to NameReference -func (t *TransformerConfig) AddNamereferenceFieldSpec(nbrs NameBackReferences) (err error) { +func (t *TransformerConfig) AddNamereferenceFieldSpec( + nbrs NameBackReferences) (err error) { t.NameReference, err = t.NameReference.mergeOne(nbrs) return err } -// Merge merges two TransformerConfigs objects into a new TransformerConfig object +// Merge merges two TransformerConfigs objects into +// a new TransformerConfig object func (t *TransformerConfig) Merge(input *TransformerConfig) ( merged *TransformerConfig, err error) { if input == nil { @@ -92,7 +94,8 @@ func (t *TransformerConfig) Merge(input *TransformerConfig) ( if err != nil { return nil, err } - merged.CommonAnnotations, err = t.CommonAnnotations.mergeAll(input.CommonAnnotations) + merged.CommonAnnotations, err = t.CommonAnnotations.mergeAll( + input.CommonAnnotations) if err != nil { return nil, err } From 50a8b2785466c79079f7411542a760340818b33f Mon Sep 17 00:00:00 2001 From: jregan Date: Mon, 31 Dec 2018 11:24:41 -0800 Subject: [PATCH 042/317] Introduce ResAccumulator. --- pkg/target/baseandoverlaymedium_test.go | 3 + pkg/target/baseandoverlaysmall_test.go | 3 + pkg/target/crd_test.go | 6 +- pkg/target/customconfig_test.go | 21 +- pkg/target/kusttarget.go | 269 ++++++++---------------- pkg/target/kusttarget_test.go | 38 ++-- pkg/target/resaccumulator.go | 134 ++++++++++++ pkg/target/resaccumulator_test.go | 132 ++++++++++++ pkg/types/var.go | 70 +++++- pkg/types/var_test.go | 77 ++++++- 10 files changed, 522 insertions(+), 231 deletions(-) create mode 100644 pkg/target/resaccumulator.go create mode 100644 pkg/target/resaccumulator_test.go diff --git a/pkg/target/baseandoverlaymedium_test.go b/pkg/target/baseandoverlaymedium_test.go index 0ffd7d2b0..fe2bf19bb 100644 --- a/pkg/target/baseandoverlaymedium_test.go +++ b/pkg/target/baseandoverlaymedium_test.go @@ -211,6 +211,9 @@ spec: if err != nil { t.Fatalf("Err: %v", err) } + // TODO(#669): The name of the patched Deployment is + // test-infra-baseprefix-mungebot, retaining the base + // prefix (example of correct behavior). th.assertActualEqualsExpected(m, ` apiVersion: v1 data: diff --git a/pkg/target/baseandoverlaysmall_test.go b/pkg/target/baseandoverlaysmall_test.go index c38112ce3..a8c72b7e6 100644 --- a/pkg/target/baseandoverlaysmall_test.go +++ b/pkg/target/baseandoverlaysmall_test.go @@ -136,6 +136,9 @@ spec: if err != nil { t.Fatalf("Err: %v", err) } + // TODO(#669): The name of the patched Deployment is + // b-a-myDeployment, retaining the base prefix + // (example of correct behavior). th.assertActualEqualsExpected(m, ` apiVersion: v1 kind: Service diff --git a/pkg/target/crd_test.go b/pkg/target/crd_test.go index 68e79b2a7..f6d955134 100644 --- a/pkg/target/crd_test.go +++ b/pkg/target/crd_test.go @@ -293,7 +293,7 @@ spec: if err != nil { t.Fatalf("Err: %v", err) } - // TODO(#605): Some output here is wrong due to #605 + // TODO(#669): Bee's name should be "prod-x-bee", not "prod-bee". th.assertActualEqualsExpected(m, ` apiVersion: v1 data: @@ -308,9 +308,9 @@ metadata: name: prod-x-mykind spec: beeRef: - name: bee + name: prod-bee secretRef: - name: crdsecret + name: prod-x-crdsecret --- apiVersion: v1beta1 kind: Bee diff --git a/pkg/target/customconfig_test.go b/pkg/target/customconfig_test.go index f965f3789..daf616681 100644 --- a/pkg/target/customconfig_test.go +++ b/pkg/target/customconfig_test.go @@ -221,9 +221,7 @@ spec: `) } -// TODO: Test demonstrates bug #605. -// The customization supplied in a base isn't available to the overlay. -func TestBug605(t *testing.T) { +func TestFixedBug605_BaseCustomizationAvailableInOverlay(t *testing.T) { th := NewKustTestHarness(t, "/app/overlay") makeBaseReferencingCustomConfig(th) th.writeDefaultConfigs("/app/base/config/defaults.yaml") @@ -274,13 +272,8 @@ spec: if err != nil { t.Fatalf("Err: %v", err) } - // Problems in the expected result: - // - The variables are not replaced in the "food" fields. - // - The name of the AnimalPark should be x-o-sandiego, since - // AnimalPark appears in the base. - // - The giraffe and gorilla name are incorrect in AnimalPark; - // they should be o-x-april and o-ursus respectively. The - // Gorilla ursus doesn't get an x because it's not in the base. + // TODO(#669): The name of AnimalPark should be x-o-sandiego, + // not o-sandiego, since AnimalPark appears in the base. th.assertActualEqualsExpected(m, ` kind: AnimalPark metadata: @@ -290,12 +283,12 @@ metadata: name: o-sandiego spec: food: - - $(APRIL_DIET) - - $(KOKO_DIET) + - mimosa + - bambooshoots giraffeRef: - name: april + name: o-x-april gorillaRef: - name: ursus + name: o-ursus --- kind: Giraffe metadata: diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index f42449b29..d79791682 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -32,7 +32,6 @@ import ( "sigs.k8s.io/kustomize/pkg/ifc/transformer" interror "sigs.k8s.io/kustomize/pkg/internal/error" patchtransformer "sigs.k8s.io/kustomize/pkg/patch/transformer" - "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" "sigs.k8s.io/kustomize/pkg/transformers" @@ -46,7 +45,6 @@ type KustTarget struct { ldr ifc.Loader fSys fs.FileSystem rFactory *resmap.Factory - tConfig *config.TransformerConfig tFactory transformer.Factory } @@ -73,16 +71,11 @@ func NewKustTarget( if len(msgs) > 0 { log.Printf(strings.Join(msgs, "\n")) } - tConfig, err := makeTransformerConfig(ldr, k.Configurations) - if err != nil { - return nil, err - } return &KustTarget{ kustomization: &k, ldr: ldr, fSys: fSys, rFactory: rFactory, - tConfig: tConfig, tFactory: tFactory, }, nil } @@ -141,7 +134,7 @@ func mergeCustomConfigWithDefaults( // MakeCustomizedResMap creates a ResMap per kustomization instructions. // The Resources in the returned ResMap are fully customized. func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) { - m, err := kt.loadCustomizedResMap() + ra, err := kt.accumulateTarget() if err != nil { return nil, err } @@ -150,23 +143,20 @@ func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) { // It changes only the Name field in the // resource held in the ResMap's value, not // the Name in the key in the ResMap. - err := kt.tFactory.MakeHashTransformer().Transform(m) + err := ra.Transform(kt.tFactory.MakeHashTransformer()) if err != nil { return nil, err } } // Given that names have changed (prefixs/suffixes added), // fix all the back references to those names. - if kt.tConfig.NameReference != nil { - err = transformers.NewNameReferenceTransformer( - kt.tConfig.NameReference).Transform(m) - if err != nil { - return nil, err - } + err = ra.FixBackReferences() + if err != nil { + return nil, err } // With all the back references fixed, it's OK to resolve Vars. - err = kt.doVarReplacement(m) - return m, err + err = ra.ResolveVars() + return ra.ResMap(), err } func (kt *KustTarget) shouldAddHashSuffixesToGeneratedResources() bool { @@ -174,31 +164,46 @@ func (kt *KustTarget) shouldAddHashSuffixesToGeneratedResources() bool { !kt.kustomization.GeneratorOptions.DisableNameSuffixHash } -func (kt *KustTarget) doVarReplacement(m resmap.ResMap) error { - vars, err := kt.getAllVars() - if err != nil { - return err - } - varMap, err := kt.resolveVars(m, vars) - if err != nil { - return err - } - return transformers.NewRefVarTransformer( - varMap, kt.tConfig.VarReference).Transform(m) -} - -// loadCustomizedResMap loads and customizes resources to build a ResMap. -func (kt *KustTarget) loadCustomizedResMap() (resmap.ResMap, error) { +// accumulateTarget returns a new ResAccumulator, +// holding customized resources and the data/rules used +// to do so. The name back references and vars are +// not yet fixed. +func (kt *KustTarget) accumulateTarget() ( + ra *ResAccumulator, err error) { + // TODO(monopole): Get rid of the KustomizationErrors accumulator. + // It's not consistently used, and complicates tests. errs := &interror.KustomizationErrors{} - result, err := kt.loadResMapFromBasesAndResources() + ra, errs = kt.accumulateBases() + resources, err := kt.rFactory.FromFiles( + kt.ldr, kt.kustomization.Resources) if err != nil { - errs.Append(errors.Wrap(err, "loadResMapFromBasesAndResources")) + errs.Append(errors.Wrap(err, "rawResources failed to read Resources")) + } + if len(errs.Get()) > 0 { + return ra, errs + } + err = ra.MergeResourcesWithErrorOnIdCollision(resources) + if err != nil { + errs.Append(errors.Wrap(err, "MergeResourcesWithErrorOnIdCollision")) + } + tConfig, err := makeTransformerConfig( + kt.ldr, kt.kustomization.Configurations) + if err != nil { + return nil, err + } + err = ra.MergeConfig(tConfig) + if err != nil { + errs.Append(errors.Wrap(err, "MergeConfig")) + } + err = ra.MergeVars(kt.kustomization.Vars) + if err != nil { + errs.Append(errors.Wrap(err, "MergeVars")) } crdTc, err := config.NewFactory(kt.ldr).LoadCRDs(kt.kustomization.Crds) if err != nil { errs.Append(errors.Wrap(err, "LoadCRDs")) } - kt.tConfig, err = kt.tConfig.Merge(crdTc) + err = ra.MergeConfig(crdTc) if err != nil { errs.Append(errors.Wrap(err, "merge CRDs")) } @@ -206,11 +211,10 @@ func (kt *KustTarget) loadCustomizedResMap() (resmap.ResMap, error) { if err != nil { errs.Append(errors.Wrap(err, "generateConfigMapsAndSecrets")) } - result, err = resmap.MergeWithOverride(result, resMap) + err = ra.MergeResourcesWithOverride(resMap) if err != nil { return nil, err } - patches, err := kt.rFactory.RF().SliceFromPatches( kt.ldr, kt.kustomization.PatchesStrategicMerge) if err != nil { @@ -219,30 +223,15 @@ func (kt *KustTarget) loadCustomizedResMap() (resmap.ResMap, error) { if len(errs.Get()) > 0 { return nil, errs } - - var r []transformers.Transformer - t, err := kt.newTransformer(patches) + t, err := kt.newTransformer(patches, ra.tConfig) if err != nil { return nil, err } - r = append(r, t) - t, err = patchtransformer.NewPatchJson6902Factory(kt.ldr). - MakePatchJson6902Transformer(kt.kustomization.PatchesJson6902) + err = ra.Transform(t) if err != nil { return nil, err } - r = append(r, t) - t, err = transformers.NewImageTagTransformer(kt.kustomization.ImageTags) - if err != nil { - return nil, err - } - r = append(r, t) - - err = transformers.NewMultiTransformer(r).Transform(result) - if err != nil { - return nil, err - } - return result, nil + return ra, nil } func (kt *KustTarget) generateConfigMapsAndSecrets( @@ -261,75 +250,48 @@ func (kt *KustTarget) generateConfigMapsAndSecrets( return resmap.MergeWithErrorOnIdCollision(cms, secrets) } -// Gets Bases and Resources as advertised. -func (kt *KustTarget) loadResMapFromBasesAndResources() (resmap.ResMap, error) { - bases, errs := kt.loadCustomizedBases() - resources, err := kt.rFactory.FromFiles( - kt.ldr, kt.kustomization.Resources) - if err != nil { - errs.Append(errors.Wrap(err, "rawResources failed to read Resources")) - } - if len(errs.Get()) > 0 { - return nil, errs - } - return resmap.MergeWithErrorOnIdCollision(resources, bases) -} +// accumulateBases returns a new ResAccumulator +// holding customized resources and the data/rules +// used to customized them from only the _bases_ +// of this KustTarget. +func (kt *KustTarget) accumulateBases() ( + ra *ResAccumulator, errs *interror.KustomizationErrors) { + errs = &interror.KustomizationErrors{} + ra = MakeEmptyAccumulator() -// Loop through the Bases of this kustomization recursively loading resources. -// Combine into one ResMap, demanding unique Ids for each resource. -func (kt *KustTarget) loadCustomizedBases() ( - resmap.ResMap, *interror.KustomizationErrors) { - var list []resmap.ResMap - errs := &interror.KustomizationErrors{} for _, path := range kt.kustomization.Bases { ldr, err := kt.ldr.New(path) if err != nil { errs.Append(errors.Wrap(err, "couldn't make loader for "+path)) continue } - target, err := NewKustTarget( - ldr, kt.fSys, - kt.rFactory, kt.tFactory) - if err != nil { - errs.Append(errors.Wrap(err, "couldn't make target for "+path)) - continue - } - resMap, err := target.loadCustomizedResMap() - if err != nil { - errs.Append(errors.Wrap(err, "SemiResources")) - continue - } - ldr.Cleanup() - list = append(list, resMap) - } - result, err := resmap.MergeWithErrorOnIdCollision(list...) - if err != nil { - errs.Append(errors.Wrap(err, "Merge failed")) - } - return result, errs -} - -func (kt *KustTarget) loadBasesAsKustTargets() ([]*KustTarget, error) { - var result []*KustTarget - for _, path := range kt.kustomization.Bases { - ldr, err := kt.ldr.New(path) - if err != nil { - return nil, err - } - target, err := NewKustTarget( + subKt, err := NewKustTarget( ldr, kt.fSys, kt.rFactory, kt.tFactory) if err != nil { - return nil, err + errs.Append(errors.Wrap(err, "couldn't make target for "+path)) + ldr.Cleanup() + continue } - result = append(result, target) + subRa, err := subKt.accumulateTarget() + if err != nil { + errs.Append(errors.Wrap(err, "accumulateTarget")) + ldr.Cleanup() + continue + } + err = ra.MergeAccumulator(subRa) + if err != nil { + errs.Append(errors.Wrap(err, path)) + } + ldr.Cleanup() } - return result, nil + return ra, errs } // newTransformer makes a Transformer that does a collection // of object transformations. func (kt *KustTarget) newTransformer( - patches []*resource.Resource) (transformers.Transformer, error) { + patches []*resource.Resource, tConfig *config.TransformerConfig) ( + transformers.Transformer, error) { var r []transformers.Transformer t, err := kt.tFactory.MakePatchTransformer(patches, kt.rFactory.RF()) if err != nil { @@ -337,24 +299,35 @@ func (kt *KustTarget) newTransformer( } r = append(r, t) r = append(r, transformers.NewNamespaceTransformer( - string(kt.kustomization.Namespace), kt.tConfig.NameSpace)) + string(kt.kustomization.Namespace), tConfig.NameSpace)) t, err = transformers.NewNamePrefixSuffixTransformer( string(kt.kustomization.NamePrefix), string(kt.kustomization.NameSuffix), - kt.tConfig.NamePrefix, + tConfig.NamePrefix, ) if err != nil { return nil, err } r = append(r, t) t, err = transformers.NewLabelsMapTransformer( - kt.kustomization.CommonLabels, kt.tConfig.CommonLabels) + kt.kustomization.CommonLabels, tConfig.CommonLabels) if err != nil { return nil, err } r = append(r, t) t, err = transformers.NewAnnotationsMapTransformer( - kt.kustomization.CommonAnnotations, kt.tConfig.CommonAnnotations) + kt.kustomization.CommonAnnotations, tConfig.CommonAnnotations) + if err != nil { + return nil, err + } + r = append(r, t) + t, err = patchtransformer.NewPatchJson6902Factory(kt.ldr). + MakePatchJson6902Transformer(kt.kustomization.PatchesJson6902) + if err != nil { + return nil, err + } + r = append(r, t) + t, err = transformers.NewImageTagTransformer(kt.kustomization.ImageTags) if err != nil { return nil, err } @@ -362,78 +335,6 @@ func (kt *KustTarget) newTransformer( return transformers.NewMultiTransformer(r), nil } -// resolveVars returns a map of Var names to their final values. -// The values are strings intended for substitution wherever -// the $(var.Name) occurs. -func (kt *KustTarget) resolveVars( - m resmap.ResMap, vars map[string]types.Var) (map[string]string, error) { - result := map[string]string{} - for _, v := range vars { - id := resid.NewResId(v.ObjRef.GVK(), v.ObjRef.Name) - if r, found := m.DemandOneMatchForId(id); found { - s, err := r.GetFieldValue(v.FieldRef.FieldPath) - if err != nil { - return nil, fmt.Errorf("field path err for var: %+v", v) - } - result[v.Name] = s - } else { - log.Printf("couldn't resolve var: %v", v) - } - } - return result, nil -} - -type ErrVarCollision struct { - name string - path string -} - -func (e ErrVarCollision) Error() string { - return fmt.Sprintf( - "var %s in %s defined in some other kustomization", - e.name, e.path) -} - -// getAllVars returns a map of Var names to Var instances, pulled from -// this kustomization and the kustomizations it depends on. -// An error is returned on Var name collision. -func (kt *KustTarget) getAllVars() (map[string]types.Var, error) { - result, err := kt.getVarsFromBases() - if err != nil { - return nil, err - } - for _, v := range kt.kustomization.Vars { - v.Defaulting() - if _, oops := result[v.Name]; oops { - return nil, ErrVarCollision{v.Name, kt.ldr.Root()} - } - result[v.Name] = v - } - return result, nil -} - -func (kt *KustTarget) getVarsFromBases() (map[string]types.Var, error) { - targets, err := kt.loadBasesAsKustTargets() - if err != nil { - return nil, err - } - result := make(map[string]types.Var) - for _, subKt := range targets { - vars, err := subKt.getAllVars() - if err != nil { - return nil, err - } - subKt.ldr.Cleanup() - for k, v := range vars { - if _, oops := result[k]; oops { - return nil, ErrVarCollision{v.Name, subKt.ldr.Root()} - } - result[k] = v - } - } - return result, nil -} - func loadKustFile(ldr ifc.Loader) ([]byte, error) { for _, kf := range []string{ constants.KustomizationFileName, diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index ae4eec49d..b23dafef1 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -18,8 +18,8 @@ package target import ( "encoding/base64" + "fmt" "reflect" - "sort" "strings" "testing" @@ -346,28 +346,21 @@ vars: name: heron apiVersion: v300 `) - vars, err := th.makeKustTarget().getAllVars() + ra, err := th.makeKustTarget().accumulateTarget() if err != nil { t.Fatalf("Err: %v", err) } + vars := ra.varSet.Set() if len(vars) != 2 { t.Fatalf("unexpected size %d", len(vars)) } - for i, k := range sortedKeys(vars)[:2] { - if !reflect.DeepEqual(vars[k], someVars[i]) { - t.Fatalf("unexpected var[%d]:\n %v\n %v", i, vars[k], someVars[i]) + for i := range vars[:2] { + if !reflect.DeepEqual(vars[i], someVars[i]) { + t.Fatalf("unexpected var[%d]:\n %v\n %v", i, vars[i], someVars[i]) } } } -func sortedKeys(m map[string]types.Var) (result []string) { - for k := range m { - result = append(result, k) - } - sort.Strings(result) - return -} - func TestGetAllVarsNested(t *testing.T) { th := NewKustTestHarness(t, "/app/overlays/o2") th.writeK("/app/base", ` @@ -403,16 +396,20 @@ vars: bases: - ../o1 `) - vars, err := th.makeKustTarget().getAllVars() + ra, err := th.makeKustTarget().accumulateTarget() if err != nil { t.Fatalf("Err: %v", err) } + vars := ra.varSet.Set() if len(vars) != 4 { - t.Fatalf("unexpected size %d", len(vars)) + for i, v := range vars { + fmt.Printf("%v: %v\n", i, v) + } + t.Fatalf("expected 4 vars, got %d", len(vars)) } - for i, k := range sortedKeys(vars) { - if !reflect.DeepEqual(vars[k], someVars[i]) { - t.Fatalf("unexpected var[%d]:\n %v\n %v", i, vars[k], someVars[i]) + for i := range vars { + if !reflect.DeepEqual(vars[i], someVars[i]) { + t.Fatalf("unexpected var[%d]:\n %v\n %v", i, vars[i], someVars[i]) } } } @@ -452,11 +449,12 @@ vars: bases: - ../o1 `) - _, err := th.makeKustTarget().getAllVars() + _, err := th.makeKustTarget().accumulateTarget() if err == nil { t.Fatalf("expected var collision") } - if _, ok := err.(ErrVarCollision); !ok { + if !strings.Contains(err.Error(), + "var AWARD already encountered") { t.Fatalf("unexpected error: %v", err) } } diff --git a/pkg/target/resaccumulator.go b/pkg/target/resaccumulator.go new file mode 100644 index 000000000..41e448b8d --- /dev/null +++ b/pkg/target/resaccumulator.go @@ -0,0 +1,134 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "fmt" + "log" + "sigs.k8s.io/kustomize/pkg/resid" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/transformers" + "sigs.k8s.io/kustomize/pkg/transformers/config" + "sigs.k8s.io/kustomize/pkg/types" +) + +// ResAccumulator accumulates resources and the rules +// used to customize those resources. +// TODO(monopole): Move to "accumulator" package and make members private. +// This will make a better separation between KustTarget, which should +// be mainly concerned with data loading, and this class, which could +// become the home of all transformation data and logic. +type ResAccumulator struct { + resMap resmap.ResMap + tConfig *config.TransformerConfig + varSet types.VarSet +} + +func MakeEmptyAccumulator() *ResAccumulator { + ra := &ResAccumulator{} + ra.resMap = make(resmap.ResMap) + ra.tConfig = &config.TransformerConfig{} + ra.varSet = types.VarSet{} + return ra +} + +// ResMap returns a copy of the internal resMap. +func (ra *ResAccumulator) ResMap() resmap.ResMap { + result := make(resmap.ResMap) + for k, v := range ra.resMap { + result[k] = v + } + return result +} + +func (ra *ResAccumulator) MergeResourcesWithErrorOnIdCollision( + resources resmap.ResMap) (err error) { + ra.resMap, err = resmap.MergeWithErrorOnIdCollision( + resources, ra.resMap) + return err +} + +func (ra *ResAccumulator) MergeResourcesWithOverride( + resources resmap.ResMap) (err error) { + ra.resMap, err = resmap.MergeWithOverride( + ra.resMap, resources) + return err +} + +func (ra *ResAccumulator) MergeConfig( + tConfig *config.TransformerConfig) (err error) { + ra.tConfig, err = ra.tConfig.Merge(tConfig) + return err +} + +func (ra *ResAccumulator) MergeVars(incoming []types.Var) error { + return ra.varSet.MergeSlice(incoming) +} + +func (ra *ResAccumulator) MergeAccumulator(other *ResAccumulator) (err error) { + err = ra.MergeResourcesWithErrorOnIdCollision(other.resMap) + if err != nil { + return err + } + err = ra.MergeConfig(other.tConfig) + if err != nil { + return err + } + return ra.varSet.MergeSet(&other.varSet) +} + +// makeVarReplacementMap returns a map of Var names to +// their final values. The values are strings intended +// for substitution wherever the $(var.Name) occurs. +func (ra *ResAccumulator) makeVarReplacementMap() (map[string]string, error) { + result := map[string]string{} + for _, v := range ra.varSet.Set() { + id := resid.NewResId(v.ObjRef.GVK(), v.ObjRef.Name) + if r, found := ra.resMap.DemandOneMatchForId(id); found { + s, err := r.GetFieldValue(v.FieldRef.FieldPath) + if err != nil { + return nil, fmt.Errorf("field path err for var: %+v", v) + } + result[v.Name] = s + } else { + // Should this be an error? + log.Printf("var %v defined but not used", v) + } + } + return result, nil +} + +func (ra *ResAccumulator) Transform(t transformers.Transformer) error { + return t.Transform(ra.resMap) +} + +func (ra *ResAccumulator) ResolveVars() error { + replacementMap, err := ra.makeVarReplacementMap() + if err != nil { + return err + } + return ra.Transform(transformers.NewRefVarTransformer( + replacementMap, ra.tConfig.VarReference)) +} + +func (ra *ResAccumulator) FixBackReferences() (err error) { + if ra.tConfig.NameReference == nil { + return nil + } + return ra.Transform(transformers.NewNameReferenceTransformer( + ra.tConfig.NameReference)) +} diff --git a/pkg/target/resaccumulator_test.go b/pkg/target/resaccumulator_test.go new file mode 100644 index 000000000..0d7c7036f --- /dev/null +++ b/pkg/target/resaccumulator_test.go @@ -0,0 +1,132 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "strings" + "testing" + + "sigs.k8s.io/kustomize/k8sdeps/kunstruct" + "sigs.k8s.io/kustomize/pkg/gvk" + "sigs.k8s.io/kustomize/pkg/resid" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/resource" + "sigs.k8s.io/kustomize/pkg/transformers/config" + "sigs.k8s.io/kustomize/pkg/types" +) + +func TestResolveVars(t *testing.T) { + ra := MakeEmptyAccumulator() + err := ra.MergeConfig(config.NewFactory(nil).DefaultConfig()) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + rf := resource.NewFactory( + kunstruct.NewKunstructuredFactoryImpl()) + ra.MergeResourcesWithErrorOnIdCollision(resmap.ResMap{ + resid.NewResId( + gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"}, + "deploy1"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": map[string]interface{}{ + "name": "deploy1", + }, + "spec": map[string]interface{}{ + "template": map[string]interface{}{ + "spec": map[string]interface{}{ + "containers": []interface{}{ + map[string]interface{}{ + "command": []interface{}{ + "myserver", + "--somebackendService $(FOO)", + "--yetAnother $(BAR)", + }, + }, + }, + }, + }, + }, + }), + resid.NewResId( + gvk.Gvk{Version: "v1", Kind: "Service"}, + "backendOne"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "Service", + "metadata": map[string]interface{}{ + "name": "backendOne", + }, + }), + resid.NewResId( + gvk.Gvk{Version: "v1", Kind: "Service"}, + "backendTwo"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "Service", + "metadata": map[string]interface{}{ + "name": "backendTwo", + }, + }), + }) + err = ra.MergeVars([]types.Var{ + { + Name: "FOO", + ObjRef: types.Target{ + Gvk: gvk.Gvk{Version: "v1", Kind: "Service"}, + Name: "backendOne"}, + }, { + Name: "BAR", + ObjRef: types.Target{ + Gvk: gvk.Gvk{Version: "v1", Kind: "Service"}, + Name: "backendTwo"}, + }, + }) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + err = ra.ResolveVars() + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + c := getCommand(find("deploy1", ra.ResMap())) + if c != "myserver --somebackendService backendOne --yetAnother backendTwo" { + t.Fatalf("unexpected command: %s", c) + } +} + +func find(name string, resMap resmap.ResMap) *resource.Resource { + for k, v := range resMap { + if k.Name() == name { + return v + } + } + return nil +} + +// Assumes arg is a deployment, returns the command of first container. +func getCommand(r *resource.Resource) string { + var m map[string]interface{} + var c []interface{} + m, _ = r.Map()["spec"].(map[string]interface{}) + m, _ = m["template"].(map[string]interface{}) + m, _ = m["spec"].(map[string]interface{}) + c, _ = m["containers"].([]interface{}) + m, _ = c[0].(map[string]interface{}) + return strings.Join(m["command"].([]string), " ") +} diff --git a/pkg/types/var.go b/pkg/types/var.go index cda2c2f55..4be30078b 100644 --- a/pkg/types/var.go +++ b/pkg/types/var.go @@ -17,11 +17,15 @@ limitations under the License. package types import ( + "fmt" + "sort" "strings" "sigs.k8s.io/kustomize/pkg/gvk" ) +const defaultFieldPath = "metadata.name" + // Var represents a variable whose value will be sourced // from a field in a Kubernetes object. type Var struct { @@ -38,7 +42,7 @@ type Var struct { // FieldRef refers to the field of the object referred to by // ObjRef whose value will be extracted for use in // replacing $(FOO). - // If unspecified, this defaults to fieldPath: metadata.name + // If unspecified, this defaults to fieldPath: $defaultFieldPath FieldRef FieldSelector `json:"fieldref,omitempty" yaml:"fieldref,omitempty"` } @@ -52,20 +56,76 @@ type Target struct { Name string `json:"name" yaml:"name"` } -// FieldSelector contains the fieldPath to an object field, such as metadata.name +// FieldSelector contains the fieldPath to an object field. // This struct is added to keep the backward compatibility of using ObjectFieldSelector // for Var.FieldRef type FieldSelector struct { FieldPath string `json:"fieldPath,omitempty" yaml:"fieldPath,omitempty"` } -// Defaulting sets reference to field used by default. -func (v *Var) Defaulting() { +// defaulting sets reference to field used by default. +func (v *Var) defaulting() { if v.FieldRef.FieldPath == "" { - v.FieldRef.FieldPath = "metadata.name" + v.FieldRef.FieldPath = defaultFieldPath } } +// VarSet is a slice of Vars where no var.Name is repeated. +type VarSet struct { + set []Var +} + +// Set returns the var set. +func (vs *VarSet) Set() []Var { + return vs.set +} + +// MergeSet absorbs other vars with error on name collision. +func (vs *VarSet) MergeSet(incoming *VarSet) error { + return vs.MergeSlice(incoming.set) +} + +// MergeSlice absorbs other vars with error on name collision. +// Empty fields in incoming vars are defaulted. +func (vs *VarSet) MergeSlice(incoming []Var) error { + for _, v := range incoming { + if vs.Contains(v) { + return fmt.Errorf( + "var %s already encountered", v.Name) + } + v.defaulting() + vs.insert(v) + } + return nil +} + +func (vs *VarSet) insert(v Var) { + index := sort.Search( + len(vs.set), + func(i int) bool { return vs.set[i].Name > v.Name }) + // make room + vs.set = append(vs.set, Var{}) + // shift right at index. + // copy will not increase size of destination. + copy(vs.set[index+1:], vs.set[index:]) + vs.set[index] = v +} + +// Contains is true if the set has the other var. +func (vs *VarSet) Contains(other Var) bool { + return vs.Get(other.Name) != nil +} + +// Get returns the var with the given name, else nil. +func (vs *VarSet) Get(name string) *Var { + for _, v := range vs.set { + if v.Name == name { + return &v + } + } + return nil +} + // GVK returns the Gvk object in Target func (t *Target) GVK() gvk.Gvk { if t.APIVersion == "" { diff --git a/pkg/types/var_test.go b/pkg/types/var_test.go index ee2b7205a..f48c5e1cf 100644 --- a/pkg/types/var_test.go +++ b/pkg/types/var_test.go @@ -17,10 +17,12 @@ limitations under the License. package types import ( - "gopkg.in/yaml.v2" "reflect" - "sigs.k8s.io/kustomize/pkg/gvk" + "strings" "testing" + + "gopkg.in/yaml.v2" + "sigs.k8s.io/kustomize/pkg/gvk" ) func TestGVK(t *testing.T) { @@ -79,8 +81,73 @@ func TestDefaulting(t *testing.T) { Name: "my-secret", }, } - v.Defaulting() - if v.FieldRef.FieldPath != "metadata.name" { - t.Fatalf("var defaulting doesn't behave correctly.\n expected metadata.name, but got %v", v.FieldRef.FieldPath) + v.defaulting() + if v.FieldRef.FieldPath != defaultFieldPath { + t.Fatalf("expected %s, got %v", + defaultFieldPath, v.FieldRef.FieldPath) + } +} + +func TestVarSet(t *testing.T) { + set := &VarSet{} + vars := []Var{ + { + Name: "SHELLVARS", + ObjRef: Target{ + APIVersion: "v7", + Gvk: gvk.Gvk{Kind: "ConfigMap"}, + Name: "bash"}, + }, + { + Name: "BACKEND", + ObjRef: Target{ + APIVersion: "v7", + Gvk: gvk.Gvk{Kind: "Deployment"}, + Name: "myTiredBackend"}, + }, + { + Name: "AWARD", + ObjRef: Target{ + APIVersion: "v7", + Gvk: gvk.Gvk{Kind: "Service"}, + Name: "nobelPrize"}, + FieldRef: FieldSelector{FieldPath: "some.arbitrary.path"}, + }, + } + err := set.MergeSlice(vars) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + for _, v := range vars { + if !set.Contains(v) { + t.Fatalf("set %v should contain var %v", set.Set(), v) + } + } + set2 := &VarSet{} + err = set2.MergeSet(set) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + err = set2.MergeSlice(vars) + if err == nil { + t.Fatalf("expected err") + } + if !strings.Contains(err.Error(), "var SHELLVARS already encountered") { + t.Fatalf("unexpected err: %v", err) + } + v := set2.Get("BACKEND") + if v == nil { + t.Fatalf("expected var") + } + // Confirm defaulting. + if v.FieldRef.FieldPath != defaultFieldPath { + t.Fatalf("unexpected field path: %v", v.FieldRef.FieldPath) + } + // Confirm sorting. + names := set2.Set() + if names[0].Name != "AWARD" || + names[1].Name != "BACKEND" || + names[2].Name != "SHELLVARS" { + t.Fatalf("unexpected order in : %v", names) } } From 032fffe111145b2cccaf9a0bc628566dc3dd8210 Mon Sep 17 00:00:00 2001 From: jregan Date: Sun, 6 Jan 2019 09:17:53 -0800 Subject: [PATCH 043/317] Drain more code from kusttarget. --- pkg/target/kusttarget.go | 78 ++----- pkg/target/resaccumulator_test.go | 2 +- pkg/transformers/config/constants.go | 42 ---- pkg/transformers/config/factory.go | 59 +++-- pkg/transformers/config/factory_test.go | 35 ++- pkg/transformers/config/factorycrd.go | 203 ++++++++++-------- pkg/transformers/config/factorycrd_test.go | 3 +- pkg/transformers/config/transformerconfig.go | 18 ++ pkg/transformers/labelsandannotations_test.go | 2 +- 9 files changed, 211 insertions(+), 231 deletions(-) delete mode 100644 pkg/transformers/config/constants.go diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index d79791682..b362737f2 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -50,7 +50,8 @@ type KustTarget struct { // NewKustTarget returns a new instance of KustTarget primed with a Loader. func NewKustTarget( - ldr ifc.Loader, fSys fs.FileSystem, + ldr ifc.Loader, + fSys fs.FileSystem, rFactory *resmap.Factory, tFactory transformer.Factory) (*KustTarget, error) { content, err := loadKustFile(ldr) @@ -80,6 +81,21 @@ func NewKustTarget( }, nil } +func loadKustFile(ldr ifc.Loader) ([]byte, error) { + for _, kf := range []string{ + constants.KustomizationFileName, + constants.SecondaryKustomizationFileName} { + content, err := ldr.Load(kf) + if err == nil { + return content, nil + } + if !strings.Contains(err.Error(), "no such file or directory") { + return nil, err + } + } + return nil, fmt.Errorf("no kustomization.yaml file under %s", ldr.Root()) +} + func unmarshal(y []byte, o interface{}) error { j, err := yaml.YAMLToJSON(y) if err != nil { @@ -90,47 +106,6 @@ func unmarshal(y []byte, o interface{}) error { return dec.Decode(o) } -// TODO(#6060) Maybe switch to the false path permanently -// (desired by #606), or expose this as a new customization -// directive. -const demandExplicitConfig = true - -func makeTransformerConfig( - ldr ifc.Loader, paths []string) (*config.TransformerConfig, error) { - if demandExplicitConfig { - return loadConfigFromDiskOrDefaults(ldr, paths) - } - return mergeCustomConfigWithDefaults(ldr, paths) -} - -// loadConfigFromDiskOrDefaults returns a TransformerConfig object -// built from either files or the hardcoded default configs. -// There's no merging, it's one or the other. This is preferred if one -// wants all configuration to be explicit in version control, as -// opposed to relying on a mix of files and hard coded config. -func loadConfigFromDiskOrDefaults( - ldr ifc.Loader, paths []string) (*config.TransformerConfig, error) { - if paths == nil || len(paths) == 0 { - return config.NewFactory(nil).DefaultConfig(), nil - } - return config.NewFactory(ldr).FromFiles(paths) -} - -// mergeCustomConfigWithDefaults returns a merger of custom config, -// if any, with default config. -func mergeCustomConfigWithDefaults( - ldr ifc.Loader, paths []string) (*config.TransformerConfig, error) { - t1 := config.NewFactory(nil).DefaultConfig() - if len(paths) == 0 { - return t1, nil - } - t2, err := config.NewFactory(ldr).FromFiles(paths) - if err != nil { - return nil, err - } - return t1.Merge(t2) -} - // MakeCustomizedResMap creates a ResMap per kustomization instructions. // The Resources in the returned ResMap are fully customized. func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) { @@ -186,7 +161,7 @@ func (kt *KustTarget) accumulateTarget() ( if err != nil { errs.Append(errors.Wrap(err, "MergeResourcesWithErrorOnIdCollision")) } - tConfig, err := makeTransformerConfig( + tConfig, err := config.MakeTransformerConfig( kt.ldr, kt.kustomization.Configurations) if err != nil { return nil, err @@ -199,7 +174,7 @@ func (kt *KustTarget) accumulateTarget() ( if err != nil { errs.Append(errors.Wrap(err, "MergeVars")) } - crdTc, err := config.NewFactory(kt.ldr).LoadCRDs(kt.kustomization.Crds) + crdTc, err := config.LoadConfigFromCRDs(kt.ldr, kt.kustomization.Crds) if err != nil { errs.Append(errors.Wrap(err, "LoadCRDs")) } @@ -334,18 +309,3 @@ func (kt *KustTarget) newTransformer( r = append(r, t) return transformers.NewMultiTransformer(r), nil } - -func loadKustFile(ldr ifc.Loader) ([]byte, error) { - for _, kf := range []string{ - constants.KustomizationFileName, - constants.SecondaryKustomizationFileName} { - content, err := ldr.Load(kf) - if err == nil { - return content, nil - } - if !strings.Contains(err.Error(), "no such file or directory") { - return nil, err - } - } - return nil, fmt.Errorf("no kustomization.yaml file under %s", ldr.Root()) -} diff --git a/pkg/target/resaccumulator_test.go b/pkg/target/resaccumulator_test.go index 0d7c7036f..69ec0b791 100644 --- a/pkg/target/resaccumulator_test.go +++ b/pkg/target/resaccumulator_test.go @@ -31,7 +31,7 @@ import ( func TestResolveVars(t *testing.T) { ra := MakeEmptyAccumulator() - err := ra.MergeConfig(config.NewFactory(nil).DefaultConfig()) + err := ra.MergeConfig(config.MakeDefaultConfig()) if err != nil { t.Fatalf("unexpected err: %v", err) } diff --git a/pkg/transformers/config/constants.go b/pkg/transformers/config/constants.go deleted file mode 100644 index 357b8950f..000000000 --- a/pkg/transformers/config/constants.go +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -// Annotation is to mark a field as annotations. -// "x-kubernetes-annotation": "" -const Annotation = "x-kubernetes-annotation" - -// LabelSelector is to mark a field as LabelSelector -// "x-kubernetes-label-selector": "" -const LabelSelector = "x-kubernetes-label-selector" - -// Identity is to mark a field as Identity -// "x-kubernetes-identity": "" -const Identity = "x-kubernetes-identity" - -// Version marks the type version of an object ref field -// "x-kubernetes-object-ref-api-version": -const Version = "x-kubernetes-object-ref-api-version" - -// Kind marks the type name of an object ref field -// "x-kubernetes-object-ref-kind": -const Kind = "x-kubernetes-object-ref-kind" - -// NameKey marks the field key that refers to an object of an object ref field -// "x-kubernetes-object-ref-name-key": "name" -// default is "name" -const NameKey = "x-kubernetes-object-ref-name-key" diff --git a/pkg/transformers/config/factory.go b/pkg/transformers/config/factory.go index 644fbcae6..9d912dd3c 100644 --- a/pkg/transformers/config/factory.go +++ b/pkg/transformers/config/factory.go @@ -21,7 +21,6 @@ import ( "github.com/ghodss/yaml" "sigs.k8s.io/kustomize/pkg/ifc" - "sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig" ) // Factory makes instances of TransformerConfig. @@ -29,6 +28,48 @@ type Factory struct { ldr ifc.Loader } +// TODO(#6060) Maybe switch to the false path permanently +// (desired by #606), or expose this as a new customization +// directive. +const demandExplicitConfig = true + +func MakeTransformerConfig( + ldr ifc.Loader, paths []string) (*TransformerConfig, error) { + if demandExplicitConfig { + return loadConfigFromDiskOrDefaults(ldr, paths) + } + return mergeCustomConfigWithDefaults(ldr, paths) +} + +// loadConfigFromDiskOrDefaults returns a TransformerConfig object +// built from either files or the hardcoded default configs. +// There's no merging, it's one or the other. This is preferred +// if one wants all configuration to be explicit in version +// control, as opposed to relying on a mix of files and +// hard-coded config. +func loadConfigFromDiskOrDefaults( + ldr ifc.Loader, paths []string) (*TransformerConfig, error) { + if paths == nil || len(paths) == 0 { + return MakeDefaultConfig(), nil + } + return NewFactory(ldr).FromFiles(paths) +} + +// mergeCustomConfigWithDefaults returns a merger of custom config, +// if any, with default config. +func mergeCustomConfigWithDefaults( + ldr ifc.Loader, paths []string) (*TransformerConfig, error) { + t1 := MakeDefaultConfig() + if len(paths) == 0 { + return t1, nil + } + t2, err := NewFactory(ldr).FromFiles(paths) + if err != nil { + return nil, err + } + return t1.Merge(t2) +} + func NewFactory(l ifc.Loader) *Factory { return &Factory{ldr: l} } @@ -71,19 +112,3 @@ func makeTransformerConfigFromBytes(data []byte) (*TransformerConfig, error) { t.sortFields() return &t, nil } - -// EmptyConfig returns an empty TransformerConfig object -func (tf *Factory) EmptyConfig() *TransformerConfig { - return &TransformerConfig{} -} - -// DefaultConfig returns a default TransformerConfig. -// This should never fail, hence the Fatal panic. -func (tf *Factory) DefaultConfig() *TransformerConfig { - c, err := makeTransformerConfigFromBytes( - defaultconfig.GetDefaultFieldSpecs()) - if err != nil { - log.Fatalf("Unable to make default transformconfig: %v", err) - } - return c -} diff --git a/pkg/transformers/config/factory_test.go b/pkg/transformers/config/factory_test.go index 81b79de06..a380af74c 100644 --- a/pkg/transformers/config/factory_test.go +++ b/pkg/transformers/config/factory_test.go @@ -25,21 +25,28 @@ import ( "testing" ) -func TestMakeDefaultTransformerConfig(t *testing.T) { +func TestMakeDefaultConfig(t *testing.T) { // Confirm default can be made without fatal error inside call. - l, _, _ := makeFakeLoaderAndOutput() - _ = NewFactory(l).DefaultConfig() + _ = MakeDefaultConfig() } -func makeFakeLoaderAndOutput() (ifc.Loader, *TransformerConfig, *TransformerConfig) { - transformerConfig := ` +func makeTestLoader(path, content string) ifc.Loader { + fs := fs.MakeFakeFS() + fs.WriteFile(path, []byte(content)) + return loader.NewFileLoaderAtRoot(fs) +} + +func TestFromFiles(t *testing.T) { + path := "/transformerconfig/test/config.yaml" + ldr := makeTestLoader(path, ` namePrefix: - path: nameprefix/path kind: SomeKind -` - fakeFS := fs.MakeFakeFS() - fakeFS.WriteFile("/transformerconfig/test/config.yaml", []byte(transformerConfig)) - ldr := loader.NewFileLoaderAtRoot(fakeFS) +`) + tcfg, err := NewFactory(ldr).FromFiles([]string{"transformerconfig/test/config.yaml"}) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } expected := &TransformerConfig{ NamePrefix: []FieldSpec{ { @@ -48,16 +55,6 @@ namePrefix: }, }, } - return ldr, expected, NewFactory(ldr).DefaultConfig() -} - -func TestMakeTransformerConfigFromFiles(t *testing.T) { - ldr, expected, _ := makeFakeLoaderAndOutput() - tcfg, err := NewFactory(ldr).FromFiles([]string{"transformerconfig/test/config.yaml"}) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if !reflect.DeepEqual(tcfg, expected) { t.Fatalf("expected %v\n but go6t %v\n", expected, tcfg) } diff --git a/pkg/transformers/config/factorycrd.go b/pkg/transformers/config/factorycrd.go index 24e0d5614..8aaa8ee64 100644 --- a/pkg/transformers/config/factorycrd.go +++ b/pkg/transformers/config/factorycrd.go @@ -21,15 +21,29 @@ import ( "strings" "github.com/ghodss/yaml" + "github.com/go-openapi/spec" "k8s.io/kube-openapi/pkg/common" "sigs.k8s.io/kustomize/pkg/gvk" + "sigs.k8s.io/kustomize/pkg/ifc" ) -// LoadCRDs parse CRD schemas from paths into a TransformerConfig -func (tf *Factory) LoadCRDs(paths []string) (*TransformerConfig, error) { - tc := tf.EmptyConfig() +type myProperties map[string]spec.Schema +type nameToApiMap map[string]common.OpenAPIDefinition + +// LoadConfigFromCRDs parse CRD schemas from paths into a TransformerConfig +func LoadConfigFromCRDs( + ldr ifc.Loader, paths []string) (*TransformerConfig, error) { + tc := MakeEmptyConfig() for _, path := range paths { - otherTc, err := tf.loadCRD(path) + content, err := ldr.Load(path) + if err != nil { + return nil, err + } + m, err := makeNameToApiMap(content) + if err != nil { + return nil, err + } + otherTc, err := makeConfigFromApiMap(m) if err != nil { return nil, err } @@ -41,28 +55,24 @@ func (tf *Factory) LoadCRDs(paths []string) (*TransformerConfig, error) { return tc, nil } -func (tf *Factory) loadCRD(path string) (*TransformerConfig, error) { - result := tf.EmptyConfig() - content, err := tf.loader().Load(path) - if err != nil { - return result, err - } - - var types map[string]common.OpenAPIDefinition +func makeNameToApiMap(content []byte) (result nameToApiMap, err error) { if content[0] == '{' { - err = json.Unmarshal(content, &types) + err = json.Unmarshal(content, &result) } else { - err = yaml.Unmarshal(content, &types) - } - if err != nil { - return nil, err + err = yaml.Unmarshal(content, &result) } + return +} - crds := getCRDs(types) - for crd, k := range crds { - tc := tf.EmptyConfig() - err = loadCrdIntoConfig( - types, crd, crd, k, []string{}, tc) +func makeConfigFromApiMap(m nameToApiMap) (*TransformerConfig, error) { + result := MakeEmptyConfig() + for name, api := range m { + if !looksLikeAk8sType(api.Schema.SchemaProps.Properties) { + continue + } + tc := MakeEmptyConfig() + err := loadCrdIntoConfig( + tc, makeGvkFromTypeName(name), m, name, []string{}) if err != nil { return result, err } @@ -71,107 +81,120 @@ func (tf *Factory) loadCRD(path string) (*TransformerConfig, error) { return result, err } } - return result, nil } -// getCRDs get all CRD types -func getCRDs(types map[string]common.OpenAPIDefinition) map[string]gvk.Gvk { - crds := map[string]gvk.Gvk{} - - for typename, t := range types { - properties := t.Schema.SchemaProps.Properties - _, foundKind := properties["kind"] - _, foundAPIVersion := properties["apiVersion"] - _, foundMetadata := properties["metadata"] - if foundKind && foundAPIVersion && foundMetadata { - // TODO: Get Group and Version for CRD from the openAPI definition once - // "x-kubernetes-group-version-kind" is available in CRD - kind := strings.Split(typename, ".")[len(strings.Split(typename, "."))-1] - crds[typename] = gvk.Gvk{Kind: kind} - } - } - return crds +// TODO: Get Group and Version for CRD from the +// openAPI definition once +// "x-kubernetes-group-version-kind" is available in CRD +func makeGvkFromTypeName(n string) gvk.Gvk { + names := strings.Split(n, ".") + kind := names[len(names)-1] + return gvk.Gvk{Kind: kind} } +func looksLikeAk8sType(properties myProperties) bool { + _, ok := properties["kind"] + if !ok { + return false + } + _, ok = properties["apiVersion"] + if !ok { + return false + } + _, ok = properties["metadata"] + if !ok { + return false + } + return true +} + +const ( + // "x-kubernetes-annotation": "" + xAnnotation = "x-kubernetes-annotation" + + // "x-kubernetes-label-selector": "" + xLabelSelector = "x-kubernetes-label-selector" + + // "x-kubernetes-identity": "" + xIdentity = "x-kubernetes-identity" + + // "x-kubernetes-object-ref-api-version": + xVersion = "x-kubernetes-object-ref-api-version" + + // "x-kubernetes-object-ref-kind": + xKind = "x-kubernetes-object-ref-kind" + + // "x-kubernetes-object-ref-name-key": "name" + // default is "name" + xNameKey = "x-kubernetes-object-ref-name-key" +) + // loadCrdIntoConfig loads a CRD spec into a TransformerConfig func loadCrdIntoConfig( - types map[string]common.OpenAPIDefinition, - atype string, crd string, in gvk.Gvk, - path []string, config *TransformerConfig) (err error) { - if _, ok := types[crd]; !ok { + theConfig *TransformerConfig, theGvk gvk.Gvk, theMap nameToApiMap, + typeName string, path []string) (err error) { + api, ok := theMap[typeName] + if !ok { return nil } - - for propname, property := range types[atype].Schema.SchemaProps.Properties { - _, annotate := property.Extensions.GetString(Annotation) + for propName, property := range api.Schema.SchemaProps.Properties { + _, annotate := property.Extensions.GetString(xAnnotation) if annotate { - err = config.AddAnnotationFieldSpec( - FieldSpec{ - CreateIfNotPresent: false, - Gvk: in, - Path: strings.Join(append(path, propname), "/"), - }, - ) + err = theConfig.AddAnnotationFieldSpec( + makeFs(theGvk, append(path, propName))) if err != nil { - return err + return } } - _, label := property.Extensions.GetString(LabelSelector) + _, label := property.Extensions.GetString(xLabelSelector) if label { - err = config.AddLabelFieldSpec( - FieldSpec{ - CreateIfNotPresent: false, - Gvk: in, - Path: strings.Join(append(path, propname), "/"), - }, - ) + err = theConfig.AddLabelFieldSpec( + makeFs(theGvk, append(path, propName))) if err != nil { - return err + return } } - _, identity := property.Extensions.GetString(Identity) + _, identity := property.Extensions.GetString(xIdentity) if identity { - err = config.AddPrefixFieldSpec( - FieldSpec{ - CreateIfNotPresent: false, - Gvk: in, - Path: strings.Join(append(path, propname), "/"), - }, - ) + err = theConfig.AddPrefixFieldSpec( + makeFs(theGvk, append(path, propName))) if err != nil { - return err + return } } - version, ok := property.Extensions.GetString(Version) + version, ok := property.Extensions.GetString(xVersion) if ok { - kind, ok := property.Extensions.GetString(Kind) + kind, ok := property.Extensions.GetString(xKind) if ok { - nameKey, ok := property.Extensions.GetString(NameKey) + nameKey, ok := property.Extensions.GetString(xNameKey) if !ok { nameKey = "name" } - err = config.AddNamereferenceFieldSpec(NameBackReferences{ - Gvk: gvk.Gvk{Kind: kind, Version: version}, - FieldSpecs: []FieldSpec{ - { - CreateIfNotPresent: false, - Gvk: in, - Path: strings.Join(append(path, propname, nameKey), "/"), - }, - }, - }) + err = theConfig.AddNamereferenceFieldSpec( + NameBackReferences{ + Gvk: gvk.Gvk{Kind: kind, Version: version}, + FieldSpecs: []FieldSpec{ + makeFs(theGvk, append(path, propName, nameKey))}, + }) if err != nil { - return err + return } } } - if property.Ref.GetURL() != nil { loadCrdIntoConfig( - types, property.Ref.String(), crd, in, - append(path, propname), config) + theConfig, theGvk, theMap, + property.Ref.String(), append(path, propName)) } } return nil } + +func makeFs(in gvk.Gvk, path []string) FieldSpec { + return FieldSpec{ + CreateIfNotPresent: false, + Gvk: in, + Path: strings.Join(path, "/"), + } +} diff --git a/pkg/transformers/config/factorycrd_test.go b/pkg/transformers/config/factorycrd_test.go index 0065533f4..18ed5d7f3 100644 --- a/pkg/transformers/config/factorycrd_test.go +++ b/pkg/transformers/config/factorycrd_test.go @@ -182,8 +182,7 @@ func TestLoadCRDs(t *testing.T) { NameReference: nbrs, } - actualTc, err := NewFactory(makeLoader(t)).LoadCRDs( - []string{"crd.json"}) + actualTc, err := LoadConfigFromCRDs(makeLoader(t), []string{"crd.json"}) if err != nil { t.Fatalf("unexpected error:%v", err) } diff --git a/pkg/transformers/config/transformerconfig.go b/pkg/transformers/config/transformerconfig.go index 641e9301c..556f0b814 100644 --- a/pkg/transformers/config/transformerconfig.go +++ b/pkg/transformers/config/transformerconfig.go @@ -19,7 +19,10 @@ limitations under the License. package config import ( + "log" "sort" + + "sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig" ) // TransformerConfig holds the data needed to perform transformations. @@ -33,6 +36,21 @@ type TransformerConfig struct { VarReference fsSlice `json:"varReference,omitempty" yaml:"varReference,omitempty"` } +// MakeEmptyConfig returns an empty TransformerConfig object +func MakeEmptyConfig() *TransformerConfig { + return &TransformerConfig{} +} + +// MakeDefaultConfig returns a default TransformerConfig. +func MakeDefaultConfig() *TransformerConfig { + c, err := makeTransformerConfigFromBytes( + defaultconfig.GetDefaultFieldSpecs()) + if err != nil { + log.Fatalf("Unable to make default transformconfig: %v", err) + } + return c +} + // sortFields provides determinism in logging, tests, etc. func (t *TransformerConfig) sortFields() { sort.Sort(t.NamePrefix) diff --git a/pkg/transformers/labelsandannotations_test.go b/pkg/transformers/labelsandannotations_test.go index 5bbaa70b6..5e88be13f 100644 --- a/pkg/transformers/labelsandannotations_test.go +++ b/pkg/transformers/labelsandannotations_test.go @@ -44,7 +44,7 @@ var crb = gvk.Gvk{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "Clus var sa = gvk.Gvk{Version: "v1", Kind: "ServiceAccount"} var ingress = gvk.Gvk{Kind: "Ingress"} var rf = resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl()) -var defaultTransformerConfig = config.NewFactory(nil).DefaultConfig() +var defaultTransformerConfig = config.MakeDefaultConfig() func TestLabelsRun(t *testing.T) { m := resmap.ResMap{ From a5c6938c6591c7311ddd42e7d5b79868cb8117d5 Mon Sep 17 00:00:00 2001 From: Jeff Regan Date: Mon, 7 Jan 2019 13:02:05 -0800 Subject: [PATCH 044/317] Fix link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4f3224240..cc9e29379 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ You can reach the maintainers of this project at: Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct]. -[KEP]: https://github.com/kubernetes/community/blob/master/keps/sig-cli/0008-kustomize.md +[KEP]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/0008-kustomize.md [`make`]: https://www.gnu.org/software/make [`sed`]: https://www.gnu.org/software/sed [applied]: docs/glossary.md#apply From b9ab948ef20d1ad221034ff945e6150e0589854a Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Mon, 7 Jan 2019 13:52:52 -0800 Subject: [PATCH 045/317] make BuildOptions exported --- pkg/commands/build/build.go | 17 +++++++++++++---- pkg/commands/build/build_test.go | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/pkg/commands/build/build.go b/pkg/commands/build/build.go index b306e2620..9a04da800 100644 --- a/pkg/commands/build/build.go +++ b/pkg/commands/build/build.go @@ -29,11 +29,20 @@ import ( "sigs.k8s.io/kustomize/pkg/target" ) -type buildOptions struct { +// BuildOptions contain the options for running a build +type BuildOptions struct { kustomizationPath string outputPath string } +// NewBuildOptions creates a BuildOptions object +func NewBuildOptions(p, o string) *BuildOptions { + return &BuildOptions{ + kustomizationPath: p, + outputPath: o, + } +} + var examples = ` Use the file somedir/kustomization.yaml to generate a set of api resources: build somedir @@ -54,7 +63,7 @@ func NewCmdBuild( out io.Writer, fs fs.FileSystem, rf *resmap.Factory, ptf transformer.Factory) *cobra.Command { - var o buildOptions + var o BuildOptions cmd := &cobra.Command{ Use: "build [path]", @@ -77,7 +86,7 @@ func NewCmdBuild( } // Validate validates build command. -func (o *buildOptions) Validate(args []string) error { +func (o *BuildOptions) Validate(args []string) error { if len(args) > 1 { return errors.New("specify one path to " + constants.KustomizationFileName) } @@ -91,7 +100,7 @@ func (o *buildOptions) Validate(args []string) error { } // RunBuild runs build command. -func (o *buildOptions) RunBuild( +func (o *BuildOptions) RunBuild( out io.Writer, fSys fs.FileSystem, rf *resmap.Factory, ptf transformer.Factory) error { ldr, err := loader.NewLoader(o.kustomizationPath, fSys) diff --git a/pkg/commands/build/build_test.go b/pkg/commands/build/build_test.go index 3c7c4b089..e9f1d3ec8 100644 --- a/pkg/commands/build/build_test.go +++ b/pkg/commands/build/build_test.go @@ -36,7 +36,7 @@ func TestBuildValidate(t *testing.T) { "", "specify one path to " + constants.KustomizationFileName}, } for _, mycase := range cases { - opts := buildOptions{} + opts := BuildOptions{} e := opts.Validate(mycase.args) if len(mycase.erMsg) > 0 { if e == nil { From 94be867a54b4872920a5005671205e7a4263e17f Mon Sep 17 00:00:00 2001 From: Florian Assmus Date: Fri, 11 Jan 2019 13:41:29 +0100 Subject: [PATCH 046/317] Remove git:: prefix for all urls not only GitLab --- pkg/loader/gitcloner.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pkg/loader/gitcloner.go b/pkg/loader/gitcloner.go index 01d21d4cd..7701f68a7 100644 --- a/pkg/loader/gitcloner.go +++ b/pkg/loader/gitcloner.go @@ -187,10 +187,8 @@ func normalizeGitHostSpec(host string) string { host = "https://github.com/" } } - if strings.Contains(s, "gitlab") { - if strings.HasPrefix(s, "git::") { - host = strings.TrimLeft(s, "git::") - } + if strings.HasPrefix(s, "git::") { + host = strings.TrimLeft(s, "git::") } return host } From 60dc3aa09dd15c79caaf23cfa605cea7ca5f8366 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Fri, 11 Jan 2019 11:34:12 -0800 Subject: [PATCH 047/317] Don't force all config to be explicit. --- pkg/transformers/config/factory.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/transformers/config/factory.go b/pkg/transformers/config/factory.go index 9d912dd3c..9def6a6e2 100644 --- a/pkg/transformers/config/factory.go +++ b/pkg/transformers/config/factory.go @@ -28,10 +28,10 @@ type Factory struct { ldr ifc.Loader } -// TODO(#6060) Maybe switch to the false path permanently -// (desired by #606), or expose this as a new customization -// directive. -const demandExplicitConfig = true +// TODO(#606): Setting this to false satisfies the feature +// request in 606. The todo is to delete the non-active +// code path in a subsequent PR. +const demandExplicitConfig = false func MakeTransformerConfig( ldr ifc.Loader, paths []string) (*TransformerConfig, error) { From 78a2884b7980c62aea5cb7d819da5c52a3330476 Mon Sep 17 00:00:00 2001 From: Garrett Rodrigues Date: Mon, 14 Jan 2019 14:06:02 -0800 Subject: [PATCH 048/317] remove myself from maintainers --- OWNERS_ALIASES | 1 - 1 file changed, 1 deletion(-) diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES index 1688ed754..1851d8eb9 100644 --- a/OWNERS_ALIASES +++ b/OWNERS_ALIASES @@ -1,6 +1,5 @@ aliases: kustomize-admins: - - grodrigues3 - monopole - pwittrock kustomize-maintainers: From ea1dd08a8cc43e2169b4d9bf307274779084687a Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Mon, 14 Jan 2019 15:35:03 -0800 Subject: [PATCH 049/317] Small cleanups, no change in exec. --- pkg/fs/fakefs.go | 5 ++++ pkg/fs/fs.go | 1 + pkg/fs/realfs.go | 5 ++++ pkg/loader/fileloader.go | 54 +++++++++++++++++++---------------- pkg/loader/fileloader_test.go | 2 +- 5 files changed, 41 insertions(+), 26 deletions(-) diff --git a/pkg/fs/fakefs.go b/pkg/fs/fakefs.go index a68187908..f38260185 100644 --- a/pkg/fs/fakefs.go +++ b/pkg/fs/fakefs.go @@ -102,6 +102,11 @@ func (fs *fakeFs) Open(name string) (File, error) { return fs.m[name], nil } +// EvalSymlinks does nothing and cannot fail. +func (fs *fakeFs) EvalSymlinks(path string) (string, error) { + return path, nil +} + // Exists returns true if file is known. func (fs *fakeFs) Exists(name string) bool { _, found := fs.m[name] diff --git a/pkg/fs/fs.go b/pkg/fs/fs.go index 6d4d6d229..5d647850a 100644 --- a/pkg/fs/fs.go +++ b/pkg/fs/fs.go @@ -30,6 +30,7 @@ type FileSystem interface { RemoveAll(name string) error Open(name string) (File, error) IsDir(name string) bool + EvalSymlinks(path string) (string, error) Exists(name string) bool Glob(pattern string) ([]string, error) ReadFile(name string) ([]byte, error) diff --git a/pkg/fs/realfs.go b/pkg/fs/realfs.go index 98a647d52..c4fad35c4 100644 --- a/pkg/fs/realfs.go +++ b/pkg/fs/realfs.go @@ -53,6 +53,11 @@ func (realFS) RemoveAll(name string) error { // Open delegates to os.Open. func (realFS) Open(name string) (File, error) { return os.Open(name) } +// EvalSymlinks delegates to filepath.EvalSymlinks. +func (realFS) EvalSymlinks(path string) (string, error) { + return filepath.EvalSymlinks(path) +} + // Exists returns true if os.Stat succeeds. func (realFS) Exists(name string) bool { _, err := os.Stat(name) diff --git a/pkg/loader/fileloader.go b/pkg/loader/fileloader.go index 038d8599b..0d4a210a8 100644 --- a/pkg/loader/fileloader.go +++ b/pkg/loader/fileloader.go @@ -76,8 +76,9 @@ import ( // the kustomization file. // type fileLoader struct { - // Previously visited directories, tracked to - // avoid cycles. The last entry is the current root. + // Previously visited absolute directory paths. + // Tracked to avoid cycles. + // The last entry is the current root. roots []string // File system utilities. fSys fs.FileSystem @@ -94,7 +95,7 @@ func NewFileLoaderAtCwd(fSys fs.FileSystem) *fileLoader { // NewFileLoaderAtRoot returns a loader that loads from "/". func NewFileLoaderAtRoot(fSys fs.FileSystem) *fileLoader { - return newLoaderOrDie(fSys, "/") + return newLoaderOrDie(fSys, string(filepath.Separator)) } // Root returns the absolute path that is prepended to any @@ -120,16 +121,20 @@ func newFileLoaderAt( return nil, fmt.Errorf( "loader root cannot be empty") } - root, err := filepath.Abs(root) + absRoot, err := filepath.Abs(root) if err != nil { return nil, fmt.Errorf( "absolute path error in '%s' : %v", root, err) } - if !fSys.IsDir(root) { - return nil, fmt.Errorf("absolute root dir '%s' does not exist", root) + if err := isPathEqualToOrAbove(absRoot, roots); err != nil { + return nil, err + } + if !fSys.IsDir(absRoot) { + return nil, fmt.Errorf( + "absolute root dir '%s' does not exist", absRoot) } return &fileLoader{ - roots: append(roots, root), + roots: append(roots, absRoot), fSys: fSys, cloner: cloner, cleaner: func() error { return nil }, @@ -138,28 +143,25 @@ func newFileLoaderAt( // New returns a new Loader, rooted relative to current loader, // or rooted in a temp directory holding a git repo clone. -func (l *fileLoader) New(root string) (ifc.Loader, error) { - if root == "" { +func (l *fileLoader) New(path string) (ifc.Loader, error) { + if path == "" { return nil, fmt.Errorf("new root cannot be empty") } - if isRepoUrl(root) { - if err := l.seenBefore(root); err != nil { + if isRepoUrl(path) { + // This works well enough for purpose at hand to detect + // previously visited URLs and thus avoid cycles. + if err := isPathEqualToOrAbove(path, l.roots); err != nil { return nil, err } - return newGitLoader(root, l.fSys, l.roots, l.cloner) + return newGitLoader(path, l.fSys, l.roots, l.cloner) } - if filepath.IsAbs(root) { - return nil, fmt.Errorf("new root '%s' cannot be absolute", root) + if filepath.IsAbs(path) { + return nil, fmt.Errorf("new root '%s' cannot be absolute", path) } - // Get absolute path to squeeze out "..", ".", etc. - // to facilitate the seenBefore test. - absRoot, err := filepath.Abs(filepath.Join(l.Root(), root)) + absRoot, err := filepath.Abs(filepath.Join(l.Root(), path)) if err != nil { return nil, fmt.Errorf( - "problem joining '%s' to '%s': %v", l.Root(), root, err) - } - if err := l.seenBefore(absRoot); err != nil { - return nil, err + "problem joining '%s' to '%s': %v", l.Root(), path, err) } return newFileLoaderAt(absRoot, l.fSys, l.roots, l.cloner) } @@ -187,11 +189,13 @@ func newGitLoader( }, nil } -// seenBefore tests whether the current or any previously -// visited root begins with the given path. -func (l *fileLoader) seenBefore(path string) error { +// isPathEqualToOrAbove tests whether the 1st argument, +// viewed as a path to a directory, is equal to or above +// any of the paths in the 2nd argument. It's assumed +// that all paths are cleaned, delinkified and absolute. +func isPathEqualToOrAbove(path string, roots []string) error { terminated := path + string(filepath.Separator) - for _, r := range l.roots { + for _, r := range roots { if r == path || strings.HasPrefix(r, terminated) { return fmt.Errorf( "cycle detected: new root '%s' contains previous root '%s'", diff --git a/pkg/loader/fileloader_test.go b/pkg/loader/fileloader_test.go index 7f23a2d65..202abd221 100644 --- a/pkg/loader/fileloader_test.go +++ b/pkg/loader/fileloader_test.go @@ -64,7 +64,7 @@ func TestLoaderLoad(t *testing.T) { for _, x := range testCases { b, err := l1.Load(x.path) if err != nil { - t.Fatalf("unexpected load error %v", err) + t.Fatalf("unexpected load error: %v", err) } if !reflect.DeepEqual([]byte(x.expectedContent), b) { t.Fatalf("in load expected %s, but got %s", x.expectedContent, b) From 38f0ca9f033410757707d2c9266aa980c1397a95 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Mon, 14 Jan 2019 15:44:22 -0800 Subject: [PATCH 050/317] Allow namespaced object to refer cluster level object --- pkg/resmap/resmap.go | 2 +- pkg/transformers/namereference_test.go | 61 ++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/pkg/resmap/resmap.go b/pkg/resmap/resmap.go index af10df03a..4ee304b30 100644 --- a/pkg/resmap/resmap.go +++ b/pkg/resmap/resmap.go @@ -130,7 +130,7 @@ func (m ResMap) FilterBy(inputId resid.ResId) ResMap { } result := ResMap{} for id, res := range m { - if id.Namespace() == inputId.Namespace() && + if id.Gvk().IsClusterKind() || id.Namespace() == inputId.Namespace() && id.HasSameLeftmostPrefix(inputId) && id.HasSameRightmostSuffix(inputId) { result[id] = res diff --git a/pkg/transformers/namereference_test.go b/pkg/transformers/namereference_test.go index dc50972a9..4cdeab011 100644 --- a/pkg/transformers/namereference_test.go +++ b/pkg/transformers/namereference_test.go @@ -493,3 +493,64 @@ func TestNameReferenceUnhappyRun(t *testing.T) { } } } + +func TestNameReferencePersistentVolumeHappyRun(t *testing.T) { + rf := resource.NewFactory( + kunstruct.NewKunstructuredFactoryImpl()) + m := resmap.ResMap{ + resid.NewResId(pv, "volume1"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "PersistentVolume", + "metadata": map[string]interface{}{ + "name": "someprefix-volume1", + }, + }), + + resid.NewResId(pvc, "claim1"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "PersistentVolumeClaim", + "metadata": map[string]interface{}{ + "name": "someprefix-claim1", + "namespace": "some-namespace", + }, + "spec": map[string]interface{}{ + "volumeName": "volume1", + }, + }), + } + + expected := resmap.ResMap{ + resid.NewResId(pv, "volume1"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "PersistentVolume", + "metadata": map[string]interface{}{ + "name": "someprefix-volume1", + }, + }), + + resid.NewResId(pvc, "claim1"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "PersistentVolumeClaim", + "metadata": map[string]interface{}{ + "name": "someprefix-claim1", + "namespace": "some-namespace", + }, + "spec": map[string]interface{}{ + "volumeName": "someprefix-volume1", + }, + }), + } + nrt := NewNameReferenceTransformer(defaultTransformerConfig.NameReference) + err := nrt.Transform(m) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if !reflect.DeepEqual(m, expected) { + err = expected.ErrorIfNotEqual(m) + t.Fatalf("actual doesn't match expected: %v", err) + } +} From 176ad74a1cfc24b5d8dd84d659812237d775c599 Mon Sep 17 00:00:00 2001 From: Florian Assmus Date: Tue, 15 Jan 2019 22:53:36 +0100 Subject: [PATCH 051/317] Add unit test for additional git url patterns --- pkg/loader/gitcloner.go | 19 +++++++++++-------- pkg/loader/gitcloner_test.go | 29 ++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/pkg/loader/gitcloner.go b/pkg/loader/gitcloner.go index 7701f68a7..56adc5770 100644 --- a/pkg/loader/gitcloner.go +++ b/pkg/loader/gitcloner.go @@ -43,6 +43,7 @@ func isRepoUrl(arg string) bool { return !filepath.IsAbs(arg) && (strings.HasPrefix(arg, "git::") || strings.HasPrefix(arg, "gh:") || + strings.HasPrefix(arg, "ssh:") || strings.HasPrefix(arg, "github.com") || strings.HasPrefix(arg, "git@") || strings.Index(arg, "github.com/") > -1 || @@ -159,20 +160,22 @@ func parseHostSpec(n string) (string, string) { for _, p := range []string{ // Order matters here. "git::", "gh:", "ssh://", "https://", "http://", - "git@", "github.com:", "github.com/", "gitlab.com/"} { + "git@", "github.com:", "github.com/"} { if strings.ToLower(n[:len(p)]) == p { n = n[len(p):] host = host + p } } + + // If host is a http(s) or ssh URL, grab the domain part. for _, p := range []string{ - "git-codecommit.[a-z0-9-]*.amazonaws.com/", - "dev.azure.com/", - ".*visualstudio.com/"} { - index := regexp.MustCompile(p).FindStringIndex(n) - if len(index) > 0 { - host = host + n[0:index[len(index)-1]] - n = n[index[len(index)-1]:] + "ssh://", "https://", "http://"} { + if strings.HasSuffix(strings.ToLower(host), p) { + index := regexp.MustCompile("^(.*?)/").FindStringIndex(n) + if len(index) > 0 { + host = host + n[0:index[len(index)-1]] + n = n[index[len(index)-1]:] + } } } return host, n diff --git a/pkg/loader/gitcloner_test.go b/pkg/loader/gitcloner_test.go index 672cf16a8..4b0b1f386 100644 --- a/pkg/loader/gitcloner_test.go +++ b/pkg/loader/gitcloner_test.go @@ -60,6 +60,18 @@ func TestIsRepoURL(t *testing.T) { input: "git@bitbucket.org:org/repo.git", expected: true, }, + { + input: "git::http://git.example.com/org/repo.git", + expected: true, + }, + { + input: "git::https://git.example.com/org/repo.git", + expected: true, + }, + { + input: "ssh://git.example.com:7999/org/repo.git", + expected: true, + }, { input: "/github.com/org/repo", expected: false, @@ -194,13 +206,16 @@ var paths = []string{"README.md", "foo/krusty.txt", ""} var hrefArgs = []string{"someBranch", ""} var extractFmts = map[string]string{ - "gh:%s": "gh:", - "GH:%s": "gh:", - "gitHub.com/%s": "https://github.com/", - "https://github.com/%s": "https://github.com/", - "hTTps://github.com/%s": "https://github.com/", - "git::https://gitlab.com/%s": "https://gitlab.com/", - "github.com:%s": "https://github.com/", + "gh:%s": "gh:", + "GH:%s": "gh:", + "gitHub.com/%s": "https://github.com/", + "https://github.com/%s": "https://github.com/", + "hTTps://github.com/%s": "https://github.com/", + "git::https://gitlab.com/%s": "https://gitlab.com/", + "github.com:%s": "https://github.com/", + "git::http://git.example.com/%s": "http://git.example.com/", + "git::https://git.example.com/%s": "https://git.example.com/", + "ssh://git.example.com:7999/%s": "ssh://git.example.com:7999/", } func TestParseGithubUrl(t *testing.T) { From 6dd599a983e59f3bc95d9381b2d1ae090eefe8cf Mon Sep 17 00:00:00 2001 From: Nestor Date: Wed, 16 Jan 2019 15:10:45 +0100 Subject: [PATCH 052/317] Add image transformer --- pkg/commands/edit/set/setimagetag.go | 12 +- pkg/image/append.go | 33 ++++ pkg/image/image.go | 34 ++++ pkg/image/imagetag.go | 31 ++++ pkg/target/kusttarget.go | 2 +- pkg/transformers/image.go | 159 ++++++++++++++++++ .../{imagetag_test.go => image_test.go} | 59 ++++++- pkg/transformers/imagetag.go | 126 -------------- pkg/types/kustomization.go | 30 ++-- 9 files changed, 333 insertions(+), 153 deletions(-) create mode 100644 pkg/image/append.go create mode 100644 pkg/image/image.go create mode 100644 pkg/image/imagetag.go create mode 100644 pkg/transformers/image.go rename pkg/transformers/{imagetag_test.go => image_test.go} (72%) delete mode 100644 pkg/transformers/imagetag.go diff --git a/pkg/commands/edit/set/setimagetag.go b/pkg/commands/edit/set/setimagetag.go index 2b216b906..730dc558d 100644 --- a/pkg/commands/edit/set/setimagetag.go +++ b/pkg/commands/edit/set/setimagetag.go @@ -25,11 +25,11 @@ import ( "github.com/spf13/cobra" "sigs.k8s.io/kustomize/pkg/commands/kustfile" "sigs.k8s.io/kustomize/pkg/fs" - "sigs.k8s.io/kustomize/pkg/types" + "sigs.k8s.io/kustomize/pkg/image" ) type setImageTagOptions struct { - imageTagMap map[string]types.ImageTag + imageTagMap map[string]image.Tag } var pattern = regexp.MustCompile("^(.*):([a-zA-Z0-9._-]*)$") @@ -74,11 +74,11 @@ func (o *setImageTagOptions) Validate(args []string) error { return errors.New("no image specified") } - o.imageTagMap = make(map[string]types.ImageTag) + o.imageTagMap = make(map[string]image.Tag) for _, arg := range args { if s := strings.Split(arg, "@"); len(s) > 1 { - o.imageTagMap[s[0]] = types.ImageTag{ + o.imageTagMap[s[0]] = image.Tag{ Name: s[0], Digest: s[1], } @@ -89,7 +89,7 @@ func (o *setImageTagOptions) Validate(args []string) error { if len(s) != 3 { return errors.New("invalid format of imagetag, must specify it as : or @") } - o.imageTagMap[s[1]] = types.ImageTag{ + o.imageTagMap[s[1]] = image.Tag{ Name: s[1], NewTag: s[2], } @@ -116,7 +116,7 @@ func (o *setImageTagOptions) RunSetImageTags(fSys fs.FileSystem) error { o.imageTagMap[it.Name] = it } - var imageTags []types.ImageTag + var imageTags []image.Tag for _, v := range o.imageTagMap { imageTags = append(imageTags, v) } diff --git a/pkg/image/append.go b/pkg/image/append.go new file mode 100644 index 000000000..2edd03d16 --- /dev/null +++ b/pkg/image/append.go @@ -0,0 +1,33 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package image + +// Append appends a slice of type Tag to slice of type Image +func Append(images []Image, tags ...Tag) []Image { + for _, tag := range tags { + images = append(images, toImage(tag)) + } + return images +} + +func toImage(tag Tag) Image { + return Image{ + Name: tag.Name, + NewTag: tag.NewTag, + Digest: tag.Digest, + } +} diff --git a/pkg/image/image.go b/pkg/image/image.go new file mode 100644 index 000000000..189319609 --- /dev/null +++ b/pkg/image/image.go @@ -0,0 +1,34 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package image + +// Image contains an image name, a new name, a new tag or digest, +// which will replace the original name and tag. +type Image struct { + // Name is a tag-less image name. + Name string `json:"name,omitempty" yaml:"name,omitempty"` + + // NewName is the value used to replace the original name. + NewName string `json:"newName,omitempty" yaml:"newName,omitempty"` + + // NewTag is the value used to replace the original tag. + NewTag string `json:"newTag,omitempty" yaml:"newTag,omitempty"` + + // Digest is the value used to replace the original image tag. + // If digest is present NewTag value is ignored. + Digest string `json:"digest,omitempty" yaml:"digest,omitempty"` +} diff --git a/pkg/image/imagetag.go b/pkg/image/imagetag.go new file mode 100644 index 000000000..0a09ce19d --- /dev/null +++ b/pkg/image/imagetag.go @@ -0,0 +1,31 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package image + +// Tag contains an image and a new tag, which will replace the original tag. +// Tag usage is deprecated, instead use ImageTag. +type Tag struct { + // Name is a tag-less image name. + Name string `json:"name,omitempty" yaml:"name,omitempty"` + + // NewTag is the value to use in replacing the original tag. + NewTag string `json:"newTag,omitempty" yaml:"newTag,omitempty"` + + // Digest is the value used to replace the original image tag. + // If digest is present NewTag value is ignored. + Digest string `json:"digest,omitempty" yaml:"digest,omitempty"` +} diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index b362737f2..fadfcee01 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -302,7 +302,7 @@ func (kt *KustTarget) newTransformer( return nil, err } r = append(r, t) - t, err = transformers.NewImageTagTransformer(kt.kustomization.ImageTags) + t, err = transformers.NewImageTransformer(kt.kustomization.Image) if err != nil { return nil, err } diff --git a/pkg/transformers/image.go b/pkg/transformers/image.go new file mode 100644 index 000000000..eed3f0274 --- /dev/null +++ b/pkg/transformers/image.go @@ -0,0 +1,159 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package transformers + +import ( + "regexp" + "strings" + + "sigs.k8s.io/kustomize/pkg/image" + "sigs.k8s.io/kustomize/pkg/resmap" +) + +// imageTransformer replace image names and tags +type imageTransformer struct { + images []image.Image +} + +var _ Transformer = &imageTransformer{} + +// NewImageTransformer constructs an imageTransformer. +func NewImageTransformer(slice []image.Image) (Transformer, error) { + return &imageTransformer{slice}, nil +} + +// Transform finds the matching images and replaces name and/or tag +func (pt *imageTransformer) Transform(resources resmap.ResMap) error { + if len(pt.images) == 0 { + return nil + } + for _, res := range resources { + err := pt.findAndReplaceImage(res.Map()) + if err != nil { + return err + } + } + return nil +} + +/* + findAndReplaceImage replaces the image name and tags inside one object + It searches the object for container session + then loops though all images inside containers session, + finds matched ones and update the image name and tag name +*/ +func (pt *imageTransformer) findAndReplaceImage(obj map[string]interface{}) error { + paths := []string{"containers", "initContainers"} + found := false + for _, path := range paths { + _, found = obj[path] + if found { + err := pt.updateContainers(obj, path) + if err != nil { + return err + } + } + } + if !found { + return pt.findContainers(obj) + } + return nil +} + +func (pt *imageTransformer) updateContainers(obj map[string]interface{}, path string) error { + containers := obj[path].([]interface{}) + for i := range containers { + container := containers[i].(map[string]interface{}) + containerImage, found := container["image"] + if !found { + continue + } + + imageName := containerImage.(string) + for _, image := range pt.images { + if isImageMatched(imageName, image.Name) { + name, tag := split(imageName) + + if image.NewName != "" { + name = image.NewName + } + + if image.NewTag != "" { + tag = ":" + image.NewTag + } + + if image.Digest != "" { + tag = "@" + image.Digest + } + + container["image"] = name + tag + break + } + } + } + return nil +} + +func (pt *imageTransformer) findContainers(obj map[string]interface{}) error { + for key := range obj { + switch typedV := obj[key].(type) { + case map[string]interface{}: + err := pt.findAndReplaceImage(typedV) + if err != nil { + return err + } + case []interface{}: + for i := range typedV { + item := typedV[i] + typedItem, ok := item.(map[string]interface{}) + if ok { + err := pt.findAndReplaceImage(typedItem) + if err != nil { + return err + } + } + } + } + } + return nil +} + +func isImageMatched(s, t string) bool { + // Tag values are limited to [a-zA-Z0-9_.-]. + pattern, _ := regexp.Compile("^" + t + "(:[a-zA-Z0-9_.-]*)?$") + return pattern.MatchString(s) +} + +// split separates and returns the name and tag parts +// from the image string using either colon `:` or at `@` separators. +// Note that the returned tag keeps its separator. +func split(imageName string) (name string, tag string) { + ic := strings.LastIndex(imageName, ":") + ia := strings.LastIndex(imageName, "@") + if ic < 0 && ia < 0 { + return imageName, "" + } + + i := ic + if ic < 0 { + i = ia + } + + name = imageName[:i] + tag = imageName[i:] + return +} diff --git a/pkg/transformers/imagetag_test.go b/pkg/transformers/image_test.go similarity index 72% rename from pkg/transformers/imagetag_test.go rename to pkg/transformers/image_test.go index 179dab248..03ac2c707 100644 --- a/pkg/transformers/imagetag_test.go +++ b/pkg/transformers/image_test.go @@ -22,13 +22,13 @@ import ( "sigs.k8s.io/kustomize/k8sdeps/kunstruct" "sigs.k8s.io/kustomize/pkg/gvk" + "sigs.k8s.io/kustomize/pkg/image" "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" - "sigs.k8s.io/kustomize/pkg/types" ) -func TestImageTagTransformer(t *testing.T) { +func TestImageTransformer(t *testing.T) { var rf = resource.NewFactory( kunstruct.NewKunstructuredFactoryImpl()) @@ -49,6 +49,10 @@ func TestImageTagTransformer(t *testing.T) { "name": "nginx2", "image": "my-nginx:1.8.0", }, + map[string]interface{}{ + "name": "init-alpine", + "image": "alpine:1.8.0", + }, }, "containers": []interface{}{ map[string]interface{}{ @@ -59,6 +63,10 @@ func TestImageTagTransformer(t *testing.T) { "name": "replaced-with-digest", "image": "foobar:1", }, + map[string]interface{}{ + "name": "postgresdb", + "image": "postgres:1.8.0", + }, }, }, }, @@ -98,6 +106,22 @@ func TestImageTagTransformer(t *testing.T) { }, }, }, + "spec3": map[string]interface{}{ + "template": map[string]interface{}{ + "spec": map[string]interface{}{ + "initContainers": []interface{}{ + map[string]interface{}{ + "name": "postgresdb", + "image": "postgres:alpine-9", + }, + map[string]interface{}{ + "name": "init-docker", + "image": "docker:17-git", + }, + }, + }, + }, + }, }), } expected := resmap.ResMap{ @@ -117,6 +141,10 @@ func TestImageTagTransformer(t *testing.T) { "name": "nginx2", "image": "my-nginx:previous", }, + map[string]interface{}{ + "name": "init-alpine", + "image": "myprivaterepohostname:1234/my/cool-alpine:1.8.0", + }, }, "containers": []interface{}{ map[string]interface{}{ @@ -127,6 +155,10 @@ func TestImageTagTransformer(t *testing.T) { "name": "replaced-with-digest", "image": "foobar@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3", }, + map[string]interface{}{ + "name": "postgresdb", + "image": "my-postgres:v3", + }, }, }, }, @@ -166,14 +198,33 @@ func TestImageTagTransformer(t *testing.T) { }, }, }, + "spec3": map[string]interface{}{ + "template": map[string]interface{}{ + "spec": map[string]interface{}{ + "initContainers": []interface{}{ + map[string]interface{}{ + "name": "postgresdb", + "image": "my-postgres:v3", + }, + map[string]interface{}{ + "name": "init-docker", + "image": "my-docker@sha256:25a0d4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3", + }, + }, + }, + }, + }, }), } - it, err := NewImageTagTransformer([]types.ImageTag{ + it, err := NewImageTransformer([]image.Image{ {Name: "nginx", NewTag: "v2"}, {Name: "my-nginx", NewTag: "previous"}, {Name: "myprivaterepohostname:1234/my/image", NewTag: "v1.0.1"}, {Name: "foobar", Digest: "sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"}, + {Name: "alpine", NewName: "myprivaterepohostname:1234/my/cool-alpine"}, + {Name: "postgres", NewName: "my-postgres", NewTag: "v3"}, + {Name: "docker", NewName: "my-docker", Digest: "sha256:25a0d4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"}, }) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -184,6 +235,6 @@ func TestImageTagTransformer(t *testing.T) { } if !reflect.DeepEqual(m, expected) { err = expected.ErrorIfNotEqual(m) - t.Fatalf("actual doesn't match expected: %v", err) + t.Fatalf("actual doesn't match expected: %v. Actual %+v", err, m) } } diff --git a/pkg/transformers/imagetag.go b/pkg/transformers/imagetag.go deleted file mode 100644 index ef1f7c279..000000000 --- a/pkg/transformers/imagetag.go +++ /dev/null @@ -1,126 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package transformers - -import ( - "regexp" - - "sigs.k8s.io/kustomize/pkg/resmap" - "sigs.k8s.io/kustomize/pkg/types" -) - -// imageTagTransformer replace image tags -type imageTagTransformer struct { - imageTags []types.ImageTag -} - -var _ Transformer = &imageTagTransformer{} - -// NewImageTagTransformer constructs a imageTagTransformer. -func NewImageTagTransformer(slice []types.ImageTag) (Transformer, error) { - return &imageTagTransformer{slice}, nil -} - -// Transform finds the matching images and replace the tag -func (pt *imageTagTransformer) Transform(resources resmap.ResMap) error { - if len(pt.imageTags) == 0 { - return nil - } - for _, res := range resources { - err := pt.findAndReplaceTag(res.Map()) - if err != nil { - return err - } - } - return nil -} - -/* - findAndReplaceTag replaces the image tags inside one object - It searches the object for container session - then loops though all images inside containers session, finds matched ones and update the tag name -*/ -func (pt *imageTagTransformer) findAndReplaceTag(obj map[string]interface{}) error { - paths := []string{"containers", "initContainers"} - found := false - for _, path := range paths { - _, found = obj[path] - if found { - err := pt.updateContainers(obj, path) - if err != nil { - return err - } - } - } - if !found { - return pt.findContainers(obj) - } - return nil -} - -func (pt *imageTagTransformer) updateContainers(obj map[string]interface{}, path string) error { - containers := obj[path].([]interface{}) - for i := range containers { - container := containers[i].(map[string]interface{}) - image, found := container["image"] - if !found { - continue - } - for _, imagetag := range pt.imageTags { - if isImageMatched(image.(string), imagetag.Name) { - container["image"] = imagetag.Name + ":" + imagetag.NewTag - - if imagetag.Digest != "" { - container["image"] = imagetag.Name + "@" + imagetag.Digest - } - - break - } - } - } - return nil -} - -func (pt *imageTagTransformer) findContainers(obj map[string]interface{}) error { - for key := range obj { - switch typedV := obj[key].(type) { - case map[string]interface{}: - err := pt.findAndReplaceTag(typedV) - if err != nil { - return err - } - case []interface{}: - for i := range typedV { - item := typedV[i] - typedItem, ok := item.(map[string]interface{}) - if ok { - err := pt.findAndReplaceTag(typedItem) - if err != nil { - return err - } - } - } - } - } - return nil -} - -func isImageMatched(s, t string) bool { - // Tag values are limited to [a-zA-Z0-9_.-]. - pattern, _ := regexp.Compile("^" + t + "(:[a-zA-Z0-9_.-]*)?$") - return pattern.MatchString(s) -} diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 28dff3469..40733d8da 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -18,6 +18,7 @@ limitations under the License. package types import ( + "sigs.k8s.io/kustomize/pkg/image" "sigs.k8s.io/kustomize/pkg/patch" ) @@ -71,10 +72,10 @@ type Kustomization struct { // and http://jsonpatch.com PatchesJson6902 []patch.Json6902 `json:"patchesJson6902,omitempty" yaml:"patchesJson6902,omitempty"` - // ImageTags is a list of (image name, new tag) pairs for simply - // changing a an image tag. This can also be achieved with a + // Image is a list of (image name, new name, new tag or digest) + // for changing image names, tags or digests. This can also be achieved with a // patch, but this operator is simpler to specify. - ImageTags []ImageTag `json:"imageTags,omitempty" yaml:"imageTags,omitempty"` + Image []image.Image `json:"images,omitempty" yaml:"images,omitempty"` // Vars allow things modified by kustomize to be injected into a // container specification. A var is a name (e.g. FOO) associated @@ -134,6 +135,9 @@ type Kustomization struct { // Deprecated. Patches []string `json:"patches,omitempty" yaml:"patches,omitempty"` + + // Deprecated. Use `Image` + ImageTags []image.Tag `json:"imageTags,omitempty" yaml:"imageTags,omitempty"` } // DealWithDeprecatedFields should be called immediately after @@ -149,6 +153,13 @@ func (k *Kustomization) DealWithDeprecatedFields() { k.PatchesStrategicMerge, k.Patches...) k.Patches = []string{} } + + if len(k.ImageTags) > 0 { + // Transform `image.Tag` to `image.Image` + // for backwards compatibility + k.Image = image.Append( + k.Image, k.ImageTags...) + } } // DealWithMissingFields fills the missing fields @@ -261,19 +272,6 @@ type DataSources struct { EnvSource string `json:"env,omitempty" yaml:"env,omitempty"` } -// ImageTag contains an image and a new tag, which will replace the original tag. -type ImageTag struct { - // Name is a tag-less image name. - Name string `json:"name,omitempty" yaml:"name,omitempty"` - - // NewTag is the value to use in replacing the original tag. - NewTag string `json:"newTag,omitempty" yaml:"newTag,omitempty"` - - // Digest is the value used to replace the original image tag. - // If digest is present NewTag value is ignored. - Digest string `json:"digest,omitempty" yaml:"digest,omitempty"` -} - // GeneratorOptions modify behavior of all ConfigMap and Secret generators. type GeneratorOptions struct { // Labels to add to all generated resources. From 14af70d148c73fd3f31879074453b9bdf6473f78 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Fri, 11 Jan 2019 16:55:21 -0800 Subject: [PATCH 053/317] Restrict loading to root or below. --- pkg/loader/fileloader.go | 151 +++++++++++++++++++++++----------- pkg/loader/fileloader_test.go | 104 +++++++++++++++++++++++ 2 files changed, 206 insertions(+), 49 deletions(-) diff --git a/pkg/loader/fileloader.go b/pkg/loader/fileloader.go index 0d4a210a8..2393a723f 100644 --- a/pkg/loader/fileloader.go +++ b/pkg/loader/fileloader.go @@ -26,54 +26,56 @@ import ( "sigs.k8s.io/kustomize/pkg/ifc" ) -// fileLoader loads files, returning an array of bytes. -// It also enforces two kustomization requirements: +// fileLoader is a kustomization's interface to files. // -// 1) relocatable +// The directory in which a kustomization file sits +// is referred to below as the kustomization's root. // -// A kustomization and the resources, bases, -// patches, etc. that it depends on should be -// relocatable, so all path specifications -// must be relative, not absolute. The paths -// are taken relative to the location of the -// kusttomization file. +// An instance of fileLoader has an immutable root, +// and offers a `New` method returning a new loader +// with a new root. // -// 2) acyclic +// A kustomization file refers to two kinds of files: // -// There should be no cycles in overlay to base -// relationships, including no cycles between -// git repositories. +// * supplemental data paths // -// The loader has a notion of a current working directory -// (CWD), called 'root', that is independent of the CWD -// of the process. When `Load` is called with a file path -// argument, the load is done relative to this root, -// not relative to the process CWD. +// `Load` is used to visit these paths. // -// The loader offers a `New` method returning a new loader -// with a new root. The new root can be one of two things, -// a remote git repo URL, or a directory specified relative -// to the current root. In the former case, the remote -// repository is locally cloned, and the new loader is -// rooted on a path in that clone. +// They must terminate in or below the root. // -// Crucially, a root history is used to so that New fails -// if its argument either matches or is a parent of the -// current or any previously used root. +// They hold things like resources, patches, +// data for ConfigMaps, etc. // -// This disallows: +// * bases; other kustomizations // -// * A base that is a git repository that, in turn, -// specifies a base repository seen previously -// in the loading process (a cycle). +// `New` is used to load bases. // -// * An overlay depending on a base positioned at or -// above it. I.e. '../foo' is OK, but '.', '..', -// '../..', etc. are disallowed. Allowing such a -// base has no advantages and encourage cycles, -// particularly if some future change were to -// introduce globbing to file specifications in -// the kustomization file. +// A base can be either a remote git repo URL, or +// a directory specified relative to the current +// root. In the former case, the repo is locally +// cloned, and the new loader is rooted on a path +// in that clone. +// +// As loaders create new loaders, a root history +// is established, and used to disallow: +// +// - A base that is a repository that, in turn, +// specifies a base repository seen previously +// in the loading stack (a cycle). +// +// - An overlay depending on a base positioned at +// or above it. I.e. '../foo' is OK, but '.', +// '..', '../..', etc. are disallowed. Allowing +// such a base has no advantages and encourages +// cycles, particularly if some future change +// were to introduce globbing to file +// specifications in the kustomization file. +// +// These restrictions assure that kustomizations +// are self-contained and relocatable, and impose +// some safety when relying on remote kustomizations, +// e.g. a ConfigMap generator specified to read +// from /etc/passwd will fail. // type fileLoader struct { // Previously visited absolute directory paths. @@ -121,7 +123,7 @@ func newFileLoaderAt( return nil, fmt.Errorf( "loader root cannot be empty") } - absRoot, err := filepath.Abs(root) + absRoot, err := cleanedAbs(root, fSys) if err != nil { return nil, fmt.Errorf( "absolute path error in '%s' : %v", root, err) @@ -141,6 +143,22 @@ func newFileLoaderAt( }, nil } +// cleanedAbs returns a cleaned, absolute path +// with no symbolic links. +func cleanedAbs(path string, fSys fs.FileSystem) (string, error) { + absRoot, err := filepath.Abs(path) + if err != nil { + return "", fmt.Errorf( + "abs path error on '%s' : %v", path, err) + } + deLinked, err := fSys.EvalSymlinks(absRoot) + if err != nil { + return "", fmt.Errorf( + "evalsymlink failure on '%s' : %v", path, err) + } + return deLinked, nil +} + // New returns a new Loader, rooted relative to current loader, // or rooted in a temp directory holding a git repo clone. func (l *fileLoader) New(path string) (ifc.Loader, error) { @@ -158,12 +176,8 @@ func (l *fileLoader) New(path string) (ifc.Loader, error) { if filepath.IsAbs(path) { return nil, fmt.Errorf("new root '%s' cannot be absolute", path) } - absRoot, err := filepath.Abs(filepath.Join(l.Root(), path)) - if err != nil { - return nil, fmt.Errorf( - "problem joining '%s' to '%s': %v", l.Root(), path, err) - } - return newFileLoaderAt(absRoot, l.fSys, l.roots, l.cloner) + return newFileLoaderAt( + filepath.Join(l.Root(), path), l.fSys, l.roots, l.cloner) } // newGitLoader returns a new Loader pinned to a temporary @@ -205,13 +219,52 @@ func isPathEqualToOrAbove(path string, roots []string) error { return nil } -// Load returns content of file at the given relative path. +// Load returns content of file at the given relative path, +// else an error. The path must refer to a file in or +// below the current Root(). func (l *fileLoader) Load(path string) ([]byte, error) { if filepath.IsAbs(path) { - return nil, fmt.Errorf( - "must use relative path; '%s' is absolute", path) + return nil, l.loadOutOfBounds(path) } - return l.fSys.ReadFile(filepath.Join(l.Root(), path)) + path, err := cleanedAbs( + filepath.Join(l.Root(), path), l.fSys) + if err != nil { + return nil, err + } + if !l.isInOrBelowRoot(path) { + return nil, l.loadOutOfBounds(path) + } + return l.fSys.ReadFile(path) +} + +// isInOrBelowRoot is true if the argument is in or +// below Root() from purely a path perspective (no +// check for actual file existence). For this to work, +// both the given argument "path" and l.Root() must +// be cleaned, absolute paths, and l.Root() must be +// a directory. Both conditions enforced elsewhere. +// +// This is tested on linux, but will have trouble +// on other operating systems. As soon as related +// work is completed in the core filepath package, +// this code should be refactored to use it. +// See: +// https://github.com/golang/go/issues/18355 +// https://github.com/golang/dep/issues/296 +// https://github.com/golang/dep/blob/master/internal/fs/fs.go#L33 +// https://codereview.appspot.com/5712045 +func (l *fileLoader) isInOrBelowRoot(path string) bool { + if l.Root() == string(filepath.Separator) { + return true + } + return strings.HasPrefix( + path, l.Root()+string(filepath.Separator)) +} + +func (l *fileLoader) loadOutOfBounds(path string) error { + return fmt.Errorf( + "security; file '%s' is not in or below '%s'", + path, l.Root()) } // Cleanup runs the cleaner. diff --git a/pkg/loader/fileloader_test.go b/pkg/loader/fileloader_test.go index 202abd221..8598ff5b0 100644 --- a/pkg/loader/fileloader_test.go +++ b/pkg/loader/fileloader_test.go @@ -17,11 +17,16 @@ limitations under the License. package loader import ( + "io/ioutil" + "os" + "path" + "path/filepath" "reflect" "strings" "testing" "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/ifc" ) type testData struct { @@ -198,3 +203,102 @@ func TestLoaderMisc(t *testing.T) { t.Fatalf("Expected error") } } + +func TestRestrictedLoadingInRealLoader(t *testing.T) { + // Create a structure like this + // + // /tmp/kustomize-test-SZwCZYjySj + // ├── base + // │ ├── okayData + // │ ├── symLinkToOkayData -> okayData + // │ └── symLinkToForbiddenData -> ../forbiddenData + // └── forbiddenData + // + dir, err := ioutil.TempDir("", "kustomize-test-") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + defer os.RemoveAll(dir) + + fSys := fs.MakeRealFS() + fSys.Mkdir(filepath.Join(dir, "base")) + + contentOk := "hi there, i'm OK data" + fSys.WriteFile( + filepath.Join(dir, "base", "okayData"), []byte(contentOk)) + + contentForbidden := "don't be looking at me" + fSys.WriteFile( + filepath.Join(dir, "forbiddenData"), []byte(contentForbidden)) + + os.Symlink( + filepath.Join(dir, "base", "okayData"), + filepath.Join(dir, "base", "symLinkToOkayData")) + os.Symlink( + filepath.Join(dir, "forbiddenData"), + filepath.Join(dir, "base", "symLinkToForbiddenData")) + + var l ifc.Loader + + l = newLoaderOrDie(fSys, dir) + + // Sanity checks - loading from perspective of "dir". + // Everything works, including reading from a subdirectory. + data, err := l.Load(path.Join("base", "okayData")) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if string(data) != contentOk { + t.Fatalf("unexpected content: %v", data) + } + data, err = l.Load("forbiddenData") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if string(data) != contentForbidden { + t.Fatalf("unexpected content: %v", data) + } + + // Drop in. + l, err = l.New("base") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // Reading okayData works. + data, err = l.Load("okayData") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if string(data) != contentOk { + t.Fatalf("unexpected content: %v", data) + } + + // Reading local symlink to okayData works. + data, err = l.Load("symLinkToOkayData") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if string(data) != contentOk { + t.Fatalf("unexpected content: %v", data) + } + + // Reading symlink to forbiddenData fails. + _, err = l.Load("symLinkToForbiddenData") + if err == nil { + t.Fatalf("expected error") + } + if !strings.Contains(err.Error(), "is not in or below") { + t.Fatalf("unexpected err: %v", err) + } + + // Attempt to read "up" fails, though earlier we were + // able to read this file when root was "..". + _, err = l.Load("../forbiddenData") + if err == nil { + t.Fatalf("expected error") + } + if !strings.Contains(err.Error(), "is not in or below") { + t.Fatalf("unexpected err: %v", err) + } +} From 2fa4a3458924de6c3a1613fb0c69b2f658e6b3c7 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Tue, 15 Jan 2019 15:03:45 -0800 Subject: [PATCH 054/317] replace commands/envcommand by DataSource in SecretGenerator --- docs/kustomization.yaml | 35 +--- examples/combineConfigs.md | 6 +- examples/generatorOptions.md | 2 - k8sdeps/configmapandsecret/secretfactory.go | 103 +++------- .../configmapandsecret/secretfactory_test.go | 179 +++++++++++------- k8sdeps/kunstruct/factory.go | 2 +- pkg/resmap/factory_test.go | 52 +---- pkg/target/generatormergeandreplace_test.go | 10 +- pkg/target/kusttarget_test.go | 28 +-- pkg/target/namespacedgenerators_test.go | 16 +- pkg/types/kustomization.go | 29 +-- 11 files changed, 166 insertions(+), 296 deletions(-) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index 74cd29794..7cc821c7b 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -85,35 +85,23 @@ configMapGenerator: # Each entry in this list results in the creation of # one Secret resource (it's a generator of n secrets). -# A command can do anything to get a secret, -# e.g. prompt the user directly, start a webserver to -# initate an oauth dance, etc. secretGenerator: - name: app-tls - commands: - tls.crt: "cat secret/tls.cert" - tls.key: "cat secret/tls.key" + files: + - secret/tls.cert + - secret/tls.key type: "kubernetes.io/tls" - name: app-tls-namespaced # you can define a namespace to generate secret in, defaults to: "default" namespace: apps - commands: - tls.crt: "cat secret/tls.cert" - tls.key: "cat secret/tls.key" + files: + - tls.crt=catsecret/tls.cert + - tls.key=secret/tls.key type: "kubernetes.io/tls" -- name: downloaded_secret - # timeoutSeconds specifies the number of seconds to - # wait for the commands below. It defaults to 5 seconds. - timeoutSeconds: 30 - commands: - username: "curl -s https://path/to/secrets/username.yaml" - password: "curl -s https://path/to/secrets/password.yaml" - type: Opaque - name: env_file_secret - # envCommand is similar to command but outputs lines of key=val pairs - # i.e. a Docker .env file or a .ini file. - # you can only specify one envCommand per secret. - envCommand: printf \"DB_USERNAME=admin\nDB_PASSWORD=somepw\" + # env is a path to a file to read lines of key=val + # you can only specify one env file per secret. + env: env.txt type: Opaque # generatorOptions modify behavior of all ConfigMap and Secret generators @@ -124,11 +112,6 @@ generatorOptions: # annotations to add to all generated resources annotations: kustomize.generated.resource: somevalue - # timeoutSeconds specifies the timeout for commands - timeoutSeconds: 30 - # shell and arguments to use as a context for commands used in resource - # generation. Default at time of writing: ["sh", "-c"] - shell: ["sh", "-c"] # disableNameSuffixHash is true disables the default behavior of adding a # suffix to the names of generated resources that is a hash of # the resource contents. diff --git a/examples/combineConfigs.md b/examples/combineConfigs.md index 86e46d34d..99090f7e8 100644 --- a/examples/combineConfigs.md +++ b/examples/combineConfigs.md @@ -92,9 +92,9 @@ secret holding them (not covering that here). diff --git a/examples/generatorOptions.md b/examples/generatorOptions.md index a9fc3c3c0..4fff9ac26 100644 --- a/examples/generatorOptions.md +++ b/examples/generatorOptions.md @@ -5,8 +5,6 @@ Kustomize provides options to modify the behavior of ConfigMap and Secret genera - disable appending a content hash suffix to the names of generated resources - adding labels to generated resources - adding annotations to generated resources - - changing shell and arguments for getting data from commands - - changing timeout for executing commands This demo shows how to use these options. First create a workspace. ``` diff --git a/k8sdeps/configmapandsecret/secretfactory.go b/k8sdeps/configmapandsecret/secretfactory.go index fd1766fcb..ab6c67d1c 100644 --- a/k8sdeps/configmapandsecret/secretfactory.go +++ b/k8sdeps/configmapandsecret/secretfactory.go @@ -17,34 +17,26 @@ limitations under the License. package configmapandsecret import ( - "context" "fmt" - "log" - "os/exec" - "path/filepath" "strings" - "time" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/validation" "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/types" ) -const ( - defaultCommandTimeout = 5 * time.Second -) - // SecretFactory makes Secrets. type SecretFactory struct { fSys fs.FileSystem - wd string + ldr ifc.Loader } // NewSecretFactory returns a new SecretFactory. -func NewSecretFactory(fSys fs.FileSystem, wd string) *SecretFactory { - return &SecretFactory{fSys: fSys, wd: wd} +func NewSecretFactory(fSys fs.FileSystem, ldr ifc.Loader) *SecretFactory { + return &SecretFactory{fSys: fSys, ldr: ldr} } func (f *SecretFactory) makeFreshSecret(args *types.SecretArgs) *corev1.Secret { @@ -67,28 +59,28 @@ func (f *SecretFactory) MakeSecret(args *types.SecretArgs, options *types.Genera var err error s := f.makeFreshSecret(args) - timeout := defaultCommandTimeout - if args.TimeoutSeconds != nil { - log.Println("SecretArgs.TimeoutSeconds will be deprected in next release. Please use GeneratorOptions.TimeoutSeconds instread.") - timeout = time.Duration(*args.TimeoutSeconds) * time.Second + pairs, err := keyValuesFromEnvFile(f.ldr, args.EnvSource) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf( + "env source file: %s", + args.EnvSource)) } - if args.EnvCommand != "" { - pairs, err := f.keyValuesFromEnvFileCommand(args.EnvCommand, timeout, options) - if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf( - "env source file: %s", - args.EnvCommand)) - } - all = append(all, pairs...) + all = append(all, pairs...) + + pairs, err = keyValuesFromLiteralSources(args.LiteralSources) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf( + "literal sources %v", args.LiteralSources)) } - if len(args.Commands) != 0 { - pairs, err := f.keyValuesFromCommands(args.Commands, timeout, options) - if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf( - "commands %v", args.Commands)) - } - all = append(all, pairs...) + all = append(all, pairs...) + + pairs, err = keyValuesFromFileSources(f.ldr, args.FileSources) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf( + "file sources: %v", args.FileSources)) } + all = append(all, pairs...) + for _, kv := range all { err = addKvToSecret(s, kv.key, kv.value) if err != nil { @@ -113,52 +105,3 @@ func addKvToSecret(secret *corev1.Secret, keyName, data string) error { secret.Data[keyName] = []byte(data) return nil } - -func (f *SecretFactory) keyValuesFromEnvFileCommand(cmd string, timeout time.Duration, options *types.GeneratorOptions) ([]kvPair, error) { - content, err := f.createSecretKey(cmd, timeout, options) - if err != nil { - return nil, err - } - return keyValuesFromLines(content) -} - -func (f *SecretFactory) keyValuesFromCommands(sources map[string]string, timeout time.Duration, options *types.GeneratorOptions) ([]kvPair, error) { - var kvs []kvPair - for k, cmd := range sources { - content, err := f.createSecretKey(cmd, timeout, options) - if err != nil { - return nil, err - } - kvs = append(kvs, kvPair{key: k, value: string(content)}) - } - return kvs, nil -} - -// Run a command, return its output as the secret. -func (f *SecretFactory) createSecretKey(command string, timeout time.Duration, options *types.GeneratorOptions) ([]byte, error) { - if !f.fSys.IsDir(f.wd) { - f.wd = filepath.Dir(f.wd) - if !f.fSys.IsDir(f.wd) { - return nil, errors.New("not a directory: " + f.wd) - } - } - - if options != nil && options.TimeoutSeconds != nil { - t := time.Duration(*options.TimeoutSeconds) * time.Second - if t > timeout { - timeout = t - } - } - - var commands []string - if options == nil || len(options.Shell) == 0 { - commands = []string{"sh", "-c", command} - } else { - commands = append(options.Shell, command) - } - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - cmd := exec.CommandContext(ctx, commands[0], commands[1:]...) - cmd.Dir = f.wd - return cmd.Output() -} diff --git a/k8sdeps/configmapandsecret/secretfactory_test.go b/k8sdeps/configmapandsecret/secretfactory_test.go index a2c50870a..c299a960d 100644 --- a/k8sdeps/configmapandsecret/secretfactory_test.go +++ b/k8sdeps/configmapandsecret/secretfactory_test.go @@ -17,94 +17,129 @@ limitations under the License. package configmapandsecret import ( + "reflect" "testing" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/loader" "sigs.k8s.io/kustomize/pkg/types" ) -func TestMakeSecretNoCommands(t *testing.T) { - factory := NewSecretFactory(fs.MakeFakeFS(), "/") - args := types.SecretArgs{ - GeneratorArgs: types.GeneratorArgs{Name: "apple"}, - Type: "Opaque", - CommandSources: types.CommandSources{ - Commands: nil, - EnvCommand: "", - }} - s, err := factory.MakeSecret(&args, nil) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if s.ObjectMeta.Name != "apple" { - t.Fatalf("unexpected name: %v", s.ObjectMeta.Name) - } - if len(s.Data) > 0 || len(s.StringData) > 0 { - t.Fatalf("unexpected data: %v", s) +func makeEnvSecret(name string) *corev1.Secret { + return &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Data: map[string][]byte{ + "DB_PASSWORD": []byte("somepw"), + "DB_USERNAME": []byte("admin"), + }, + Type: "Opaque", } } -func TestMakeSecretNoCommandsBadDir(t *testing.T) { - factory := NewSecretFactory(fs.MakeFakeFS(), "/does/not/exist") - args := types.SecretArgs{ - GeneratorArgs: types.GeneratorArgs{Name: "envConfigMap"}, - Type: "Opaque", - CommandSources: types.CommandSources{ - Commands: nil, - EnvCommand: "", - }} - _, err := factory.MakeSecret(&args, nil) - if err != nil { - t.Fatalf("Unexpected error: %v", err) +func makeFileSecret(name string) *corev1.Secret { + return &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Data: map[string][]byte{ + "app-init.ini": []byte(`FOO=bar +BAR=baz +`), + }, + Type: "Opaque", } } -func TestMakeSecretEmptyCommandMap(t *testing.T) { - factory := NewSecretFactory(fs.MakeFakeFS(), "/") - args := types.SecretArgs{ - GeneratorArgs: types.GeneratorArgs{Name: "envConfigMap"}, - Type: "Opaque", - CommandSources: types.CommandSources{ - // TODO try: map[string]string{"commandName": "bogusCommand bogusArg"}, - Commands: nil, - EnvCommand: "echo beans", - }} - s, err := factory.MakeSecret(&args, nil) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if s == nil { - t.Fatalf("nil result") - } - v, ok := s.Data["beans"] - if !ok { - t.Fatalf("expected beans") - } - if len(v) > 0 { - t.Fatalf("unexpected data") +func makeLiteralSecret(name string) *corev1.Secret { + s := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Data: map[string][]byte{ + "a": []byte("x"), + "b": []byte("y"), + }, + Type: "Opaque", } + s.SetLabels(map[string]string{"foo": "bar"}) + return s } -func TestMakeSecretWithCommandMap(t *testing.T) { - factory := NewSecretFactory(fs.MakeFakeFS(), "/") - args := types.SecretArgs{ - GeneratorArgs: types.GeneratorArgs{Name: "envConfigMap"}, - Type: "Opaque", - CommandSources: types.CommandSources{ - Commands: map[string]string{"commandName": "echo beans"}, - }} - s, err := factory.MakeSecret(&args, nil) - if err != nil { - t.Fatalf("unexpected error: %v", err) +func TestConstructSecret(t *testing.T) { + type testCase struct { + description string + input types.SecretArgs + options *types.GeneratorOptions + expected *corev1.Secret } - if s == nil { - t.Fatalf("nil result") + + testCases := []testCase{ + { + description: "construct secret from env", + input: types.SecretArgs{ + GeneratorArgs: types.GeneratorArgs{Name: "envSecret"}, + DataSources: types.DataSources{ + EnvSource: "secret/app.env", + }, + }, + options: nil, + expected: makeEnvSecret("envSecret"), + }, + { + description: "construct secret from file", + input: types.SecretArgs{ + GeneratorArgs: types.GeneratorArgs{Name: "fileSecret"}, + DataSources: types.DataSources{ + FileSources: []string{"secret/app-init.ini"}, + }, + }, + options: nil, + expected: makeFileSecret("fileSecret"), + }, + { + description: "construct secret from literal", + input: types.SecretArgs{ + GeneratorArgs: types.GeneratorArgs{Name: "literalSecret"}, + DataSources: types.DataSources{ + LiteralSources: []string{"a=x", "b=y"}, + }, + }, + options: &types.GeneratorOptions{ + Labels: map[string]string{ + "foo": "bar", + }, + }, + expected: makeLiteralSecret("literalSecret"), + }, } - v, ok := s.Data["commandName"] - if !ok { - t.Fatalf("expected something for commandName") - } - if string(v) != "beans\n" { - t.Fatalf("unexpected data: %s", string(v)) + + fSys := fs.MakeFakeFS() + fSys.WriteFile("/secret/app.env", []byte("DB_USERNAME=admin\nDB_PASSWORD=somepw\n")) + fSys.WriteFile("/secret/app-init.ini", []byte("FOO=bar\nBAR=baz\n")) + f := NewSecretFactory(fSys, loader.NewFileLoaderAtRoot(fSys)) + for _, tc := range testCases { + cm, err := f.MakeSecret(&tc.input, tc.options) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if !reflect.DeepEqual(*cm, *tc.expected) { + t.Fatalf("in testcase: %q updated:\n%#v\ndoesn't match expected:\n%#v\n", tc.description, *cm, tc.expected) + } } } diff --git a/k8sdeps/kunstruct/factory.go b/k8sdeps/kunstruct/factory.go index 386789130..432bf4ee5 100644 --- a/k8sdeps/kunstruct/factory.go +++ b/k8sdeps/kunstruct/factory.go @@ -97,7 +97,7 @@ func (kf *KunstructuredFactoryImpl) MakeSecret(args *types.SecretArgs, options * // Set sets loader, filesystem and workdirectory func (kf *KunstructuredFactoryImpl) Set(fs fs.FileSystem, ldr ifc.Loader) { kf.cmFactory = configmapandsecret.NewConfigMapFactory(fs, ldr) - kf.secretFactory = configmapandsecret.NewSecretFactory(fs, ldr.Root()) + kf.secretFactory = configmapandsecret.NewSecretFactory(fs, ldr) } // validate validates that u has kind and name diff --git a/pkg/resmap/factory_test.go b/pkg/resmap/factory_test.go index 5d41548eb..16daccfc4 100644 --- a/pkg/resmap/factory_test.go +++ b/pkg/resmap/factory_test.go @@ -252,21 +252,14 @@ func TestNewResMapFromSecretArgs(t *testing.T) { secrets := []types.SecretArgs{ { GeneratorArgs: types.GeneratorArgs{Name: "apple"}, - CommandSources: types.CommandSources{ - Commands: map[string]string{ - "DB_USERNAME": "printf admin", - "DB_PASSWORD": "printf somepw", + DataSources: types.DataSources{ + LiteralSources: []string{ + "DB_USERNAME=admin", + "DB_PASSWORD=somepw", }, }, Type: ifc.SecretTypeOpaque, }, - { - GeneratorArgs: types.GeneratorArgs{Name: "peanuts"}, - CommandSources: types.CommandSources{ - EnvCommand: "printf \"DB_USERNAME=admin\nDB_PASSWORD=somepw\"", - }, - Type: ifc.SecretTypeOpaque, - }, } fakeFs := fs.MakeFakeFS() fakeFs.Mkdir(".") @@ -291,45 +284,8 @@ func TestNewResMapFromSecretArgs(t *testing.T) { "DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")), }, }).SetBehavior(ifc.BehaviorCreate), - resid.NewResId(secret, "peanuts"): rf.FromMap( - map[string]interface{}{ - "apiVersion": "v1", - "kind": "Secret", - "metadata": map[string]interface{}{ - "name": "peanuts", - }, - "type": ifc.SecretTypeOpaque, - "data": map[string]interface{}{ - "DB_USERNAME": base64.StdEncoding.EncodeToString([]byte("admin")), - "DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")), - }, - }).SetBehavior(ifc.BehaviorCreate), } if !reflect.DeepEqual(actual, expected) { t.Fatalf("%#v\ndoesn't match expected:\n%#v", actual, expected) } } - -func TestSecretTimeout(t *testing.T) { - timeout := int64(1) - secrets := []types.SecretArgs{ - { - GeneratorArgs: types.GeneratorArgs{Name: "slow"}, - TimeoutSeconds: &timeout, - CommandSources: types.CommandSources{ - Commands: map[string]string{ - "USER": "sleep 2", - }, - }, - Type: ifc.SecretTypeOpaque, - }, - } - fakeFs := fs.MakeFakeFS() - fakeFs.Mkdir(".") - rmF.Set(fakeFs, loader.NewFileLoaderAtRoot(fakeFs)) - _, err := rmF.NewResMapFromSecretArgs(secrets, nil) - - if err == nil { - t.Fatal("didn't get the expected timeout error", err) - } -} diff --git a/pkg/target/generatormergeandreplace_test.go b/pkg/target/generatormergeandreplace_test.go index 365b41006..a08ad37dc 100644 --- a/pkg/target/generatormergeandreplace_test.go +++ b/pkg/target/generatormergeandreplace_test.go @@ -181,9 +181,9 @@ configMapGenerator: - foo=bar secretGenerator: - name: secret-in-base - commands: - username: "printf admin" - password: "printf somepw" + literals: + - username=admin + - password=somepw `) th.writeF("/app/deployment.yaml", ` apiVersion: apps/v1beta2 @@ -362,8 +362,8 @@ configMapGenerator: secretGenerator: - name: secret-in-base behavior: merge - commands: - proxy: "printf haproxy" + literals: + - proxy=haproxy `) m, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index b23dafef1..7d720c666 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -52,9 +52,9 @@ configMapGenerator: - DB_PASSWORD=somepw secretGenerator: - name: secret - commands: - DB_USERNAME: "printf admin" - DB_PASSWORD: "printf somepw" + literals: + - DB_USERNAME=admin + - DB_PASSWORD=somepw type: Opaque patchesJson6902: - target: @@ -63,16 +63,6 @@ patchesJson6902: kind: Deployment name: dply1 path: jsonpatch.json -` - kustomizationContent2 = ` -apiVersion: v1beta1 -kind: Kustomization -secretGenerator: -- name: secret - timeoutSeconds: 1 - commands: - USER: "sleep 2" - type: Opaque ` deploymentContent = ` apiVersion: apps/v1 @@ -217,18 +207,6 @@ func TestResourceNotFound(t *testing.T) { } } -func TestSecretTimeout(t *testing.T) { - th := NewKustTestHarness(t, "/whatever") - th.writeK("/whatever", kustomizationContent2) - _, err := th.makeKustTarget().MakeCustomizedResMap() - if err == nil { - t.Fatalf("Didn't get the expected error for an unknown resource") - } - if !strings.Contains(err.Error(), "killed") { - t.Fatalf("unexpected error: %q", err) - } -} - func findSecret(m resmap.ResMap) *resource.Resource { for id, res := range m { if id.Gvk().Kind == "Secret" { diff --git a/pkg/target/namespacedgenerators_test.go b/pkg/target/namespacedgenerators_test.go index 61d3cd2db..7977d6737 100644 --- a/pkg/target/namespacedgenerators_test.go +++ b/pkg/target/namespacedgenerators_test.go @@ -39,11 +39,11 @@ configMapGenerator: secretGenerator: - name: the-non-default-namespace-secret namespace: non-default - commands: - password.txt: "echo verySecret" + literals: + - password.txt=verySecret - name: the-secret - commands: - password.txt: "echo anotherSecret" + literals: + - password.txt=anotherSecret `) m, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { @@ -69,19 +69,19 @@ metadata: --- apiVersion: v1 data: - password.txt: dmVyeVNlY3JldAo= + password.txt: dmVyeVNlY3JldA== kind: Secret metadata: - name: the-non-default-namespace-secret-9fgdmbbk5c + name: the-non-default-namespace-secret-h8d9hkgtb9 namespace: non-default type: Opaque --- apiVersion: v1 data: - password.txt: YW5vdGhlclNlY3JldAo= + password.txt: YW5vdGhlclNlY3JldA== kind: Secret metadata: - name: the-secret-7dd8hcgfhk + name: the-secret-fgb45h45bh type: Opaque `) } diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 28dff3469..43fb106f7 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -216,26 +216,12 @@ type SecretArgs struct { // This is the same field as the secret type field in v1/Secret: // It can be "Opaque" (default), or "kubernetes.io/tls". // - // If type is "kubernetes.io/tls", then "Commands" must have exactly two + // If type is "kubernetes.io/tls", then "literals" or "files" must have exactly two // keys: "tls.key" and "tls.crt" Type string `json:"type,omitempty" yaml:"type,omitempty"` - // CommandSources for secret. - CommandSources `json:",inline,omitempty" yaml:",inline,omitempty"` - - // Deprecated. - // Replaced by GeneratorOptions.TimeoutSeconds - // TimeoutSeconds specifies the timeout for commands. - TimeoutSeconds *int64 `json:"timeoutSeconds,omitempty" yaml:"timeoutSeconds,omitempty"` -} - -// CommandSources contains some generic sources for secrets. -type CommandSources struct { - // Map of keys to commands to generate the values - Commands map[string]string `json:"commands,omitempty" yaml:"commands,omitempty"` - // EnvCommand to output lines of key=val pairs to create a secret. - // i.e. a Docker .env file or a .ini file. - EnvCommand string `json:"envCommand,omitempty" yaml:"envCommand,omitempty"` + // DataSources for secret. + DataSources `json:",inline,omitempty" yaml:",inline,omitempty"` } // DataSources contains some generic sources for configmaps. @@ -282,15 +268,6 @@ type GeneratorOptions struct { // Annotations to add to all generated resources. Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` - // TimeoutSeconds specifies the timeout for commands, if any, - // used in resource generation. At time of writing, the default - // was specified in configmapandsecret.defaultCommandTimeout. - TimeoutSeconds *int64 `json:"timeoutSeconds,omitempty" yaml:"timeoutSeconds,omitempty"` - - // Shell and arguments to use as a context for commands used in - // resource generation. Default at time of writing: {'sh', '-c'}. - Shell []string `json:"shell,omitempty" yaml:"shell,omitempty"` - // DisableNameSuffixHash if true disables the default behavior of adding a // suffix to the names of generated resources that is a hash of the // resource contents. From f7c34ccb5273c46f7dcf7bcda2690aff5a222bb0 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Wed, 16 Jan 2019 13:33:06 -0800 Subject: [PATCH 055/317] Remove filesystem from ConfigMapGenerator and SecretGenerator --- k8sdeps/configmapandsecret/configmapfactory.go | 9 +++------ k8sdeps/configmapandsecret/configmapfactory_test.go | 2 +- k8sdeps/configmapandsecret/secretfactory.go | 8 +++----- k8sdeps/configmapandsecret/secretfactory_test.go | 2 +- k8sdeps/kunstruct/factory.go | 9 ++++----- pkg/commands/edit/add/configmap.go | 2 +- pkg/ifc/ifc.go | 3 +-- pkg/resmap/factory.go | 7 +++---- pkg/resmap/factory_test.go | 4 ++-- pkg/resource/factory.go | 7 +++---- pkg/target/kusttarget.go | 2 +- 11 files changed, 23 insertions(+), 32 deletions(-) diff --git a/k8sdeps/configmapandsecret/configmapfactory.go b/k8sdeps/configmapandsecret/configmapfactory.go index 71e932f8e..10be41a71 100644 --- a/k8sdeps/configmapandsecret/configmapfactory.go +++ b/k8sdeps/configmapandsecret/configmapfactory.go @@ -26,21 +26,18 @@ import ( "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/validation" - "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/types" ) // ConfigMapFactory makes ConfigMaps. type ConfigMapFactory struct { - fSys fs.FileSystem - ldr ifc.Loader + ldr ifc.Loader } // NewConfigMapFactory returns a new ConfigMapFactory. -func NewConfigMapFactory( - fSys fs.FileSystem, l ifc.Loader) *ConfigMapFactory { - return &ConfigMapFactory{fSys: fSys, ldr: l} +func NewConfigMapFactory(l ifc.Loader) *ConfigMapFactory { + return &ConfigMapFactory{ldr: l} } func (f *ConfigMapFactory) makeFreshConfigMap( diff --git a/k8sdeps/configmapandsecret/configmapfactory_test.go b/k8sdeps/configmapandsecret/configmapfactory_test.go index b3914f5ad..d34a190ab 100644 --- a/k8sdeps/configmapandsecret/configmapfactory_test.go +++ b/k8sdeps/configmapandsecret/configmapfactory_test.go @@ -131,7 +131,7 @@ func TestConstructConfigMap(t *testing.T) { fSys := fs.MakeFakeFS() fSys.WriteFile("/configmap/app.env", []byte("DB_USERNAME=admin\nDB_PASSWORD=somepw\n")) fSys.WriteFile("/configmap/app-init.ini", []byte("FOO=bar\nBAR=baz\n")) - f := NewConfigMapFactory(fSys, loader.NewFileLoaderAtRoot(fSys)) + f := NewConfigMapFactory(loader.NewFileLoaderAtRoot(fSys)) for _, tc := range testCases { cm, err := f.MakeConfigMap(&tc.input, tc.options) if err != nil { diff --git a/k8sdeps/configmapandsecret/secretfactory.go b/k8sdeps/configmapandsecret/secretfactory.go index ab6c67d1c..1303c812c 100644 --- a/k8sdeps/configmapandsecret/secretfactory.go +++ b/k8sdeps/configmapandsecret/secretfactory.go @@ -23,20 +23,18 @@ import ( "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/validation" - "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/types" ) // SecretFactory makes Secrets. type SecretFactory struct { - fSys fs.FileSystem - ldr ifc.Loader + ldr ifc.Loader } // NewSecretFactory returns a new SecretFactory. -func NewSecretFactory(fSys fs.FileSystem, ldr ifc.Loader) *SecretFactory { - return &SecretFactory{fSys: fSys, ldr: ldr} +func NewSecretFactory(ldr ifc.Loader) *SecretFactory { + return &SecretFactory{ldr: ldr} } func (f *SecretFactory) makeFreshSecret(args *types.SecretArgs) *corev1.Secret { diff --git a/k8sdeps/configmapandsecret/secretfactory_test.go b/k8sdeps/configmapandsecret/secretfactory_test.go index c299a960d..e62ea04c4 100644 --- a/k8sdeps/configmapandsecret/secretfactory_test.go +++ b/k8sdeps/configmapandsecret/secretfactory_test.go @@ -132,7 +132,7 @@ func TestConstructSecret(t *testing.T) { fSys := fs.MakeFakeFS() fSys.WriteFile("/secret/app.env", []byte("DB_USERNAME=admin\nDB_PASSWORD=somepw\n")) fSys.WriteFile("/secret/app-init.ini", []byte("FOO=bar\nBAR=baz\n")) - f := NewSecretFactory(fSys, loader.NewFileLoaderAtRoot(fSys)) + f := NewSecretFactory(loader.NewFileLoaderAtRoot(fSys)) for _, tc := range testCases { cm, err := f.MakeSecret(&tc.input, tc.options) if err != nil { diff --git a/k8sdeps/kunstruct/factory.go b/k8sdeps/kunstruct/factory.go index 432bf4ee5..44222408f 100644 --- a/k8sdeps/kunstruct/factory.go +++ b/k8sdeps/kunstruct/factory.go @@ -25,7 +25,6 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/util/yaml" "sigs.k8s.io/kustomize/k8sdeps/configmapandsecret" - "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/types" ) @@ -94,10 +93,10 @@ func (kf *KunstructuredFactoryImpl) MakeSecret(args *types.SecretArgs, options * return NewKunstructuredFromObject(sec) } -// Set sets loader, filesystem and workdirectory -func (kf *KunstructuredFactoryImpl) Set(fs fs.FileSystem, ldr ifc.Loader) { - kf.cmFactory = configmapandsecret.NewConfigMapFactory(fs, ldr) - kf.secretFactory = configmapandsecret.NewSecretFactory(fs, ldr) +// Set sets loader +func (kf *KunstructuredFactoryImpl) Set(ldr ifc.Loader) { + kf.cmFactory = configmapandsecret.NewConfigMapFactory(ldr) + kf.secretFactory = configmapandsecret.NewSecretFactory(ldr) } // validate validates that u has kind and name diff --git a/pkg/commands/edit/add/configmap.go b/pkg/commands/edit/add/configmap.go index 7fc93518f..013967fd4 100644 --- a/pkg/commands/edit/add/configmap.go +++ b/pkg/commands/edit/add/configmap.go @@ -67,7 +67,7 @@ func newCmdAddConfigMap(fSys fs.FileSystem, kf ifc.KunstructuredFactory) *cobra. } // Add the flagsAndArgs map to the kustomization file. - kf.Set(fSys, loader.NewFileLoaderAtCwd(fSys)) + kf.Set(loader.NewFileLoaderAtCwd(fSys)) err = addConfigMap(kustomization, flagsAndArgs, kf) if err != nil { return err diff --git a/pkg/ifc/ifc.go b/pkg/ifc/ifc.go index c4f3dbb26..e6267cae2 100644 --- a/pkg/ifc/ifc.go +++ b/pkg/ifc/ifc.go @@ -18,7 +18,6 @@ limitations under the License. package ifc import ( - "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/types" ) @@ -67,7 +66,7 @@ type KunstructuredFactory interface { FromMap(m map[string]interface{}) Kunstructured MakeConfigMap(args *types.ConfigMapArgs, options *types.GeneratorOptions) (Kunstructured, error) MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (Kunstructured, error) - Set(fs fs.FileSystem, ldr Loader) + Set(ldr Loader) } // See core.v1.SecretTypeOpaque diff --git a/pkg/resmap/factory.go b/pkg/resmap/factory.go index e3d1a6878..9e64dbee4 100644 --- a/pkg/resmap/factory.go +++ b/pkg/resmap/factory.go @@ -20,7 +20,6 @@ import ( "fmt" "github.com/pkg/errors" - "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/ifc" internal "sigs.k8s.io/kustomize/pkg/internal/error" "sigs.k8s.io/kustomize/pkg/resource" @@ -106,9 +105,9 @@ func (rmF *Factory) NewResMapFromSecretArgs(argsList []types.SecretArgs, options return newResMapFromResourceSlice(resources) } -// Set sets the filesystem and loader for the underlying factory -func (rmF *Factory) Set(fs fs.FileSystem, ldr ifc.Loader) { - rmF.resF.Set(fs, ldr) +// Set sets the loader for the underlying factory +func (rmF *Factory) Set(ldr ifc.Loader) { + rmF.resF.Set(ldr) } func newResMapFromResourceSlice(resources []*resource.Resource) (ResMap, error) { diff --git a/pkg/resmap/factory_test.go b/pkg/resmap/factory_test.go index 16daccfc4..ec6af7661 100644 --- a/pkg/resmap/factory_test.go +++ b/pkg/resmap/factory_test.go @@ -231,7 +231,7 @@ BAR=baz // TODO: add testcase for data coming from multiple sources like // files/literal/env etc. } - rmF.Set(fs.MakeFakeFS(), l) + rmF.Set(l) for _, tc := range testCases { if ferr := l.AddFile(tc.filepath, []byte(tc.content)); ferr != nil { t.Fatalf("Error adding fake file: %v\n", ferr) @@ -263,7 +263,7 @@ func TestNewResMapFromSecretArgs(t *testing.T) { } fakeFs := fs.MakeFakeFS() fakeFs.Mkdir(".") - rmF.Set(fakeFs, loader.NewFileLoaderAtRoot(fakeFs)) + rmF.Set(loader.NewFileLoaderAtRoot(fakeFs)) actual, err := rmF.NewResMapFromSecretArgs(secrets, nil) if err != nil { diff --git a/pkg/resource/factory.go b/pkg/resource/factory.go index 2f287ecbd..789b4cafd 100644 --- a/pkg/resource/factory.go +++ b/pkg/resource/factory.go @@ -21,7 +21,6 @@ import ( "fmt" "log" - "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/ifc" internal "sigs.k8s.io/kustomize/pkg/internal/error" "sigs.k8s.io/kustomize/pkg/patch" @@ -108,9 +107,9 @@ func (rf *Factory) SliceFromBytes(in []byte) ([]*Resource, error) { return result, nil } -// Set sets the filesystem and loader for the underlying factory -func (rf *Factory) Set(fs fs.FileSystem, ldr ifc.Loader) { - rf.kf.Set(fs, ldr) +// Set sets the loader for the underlying factory +func (rf *Factory) Set(ldr ifc.Loader) { + rf.kf.Set(ldr) } // MakeConfigMap makes an instance of Resource for ConfigMap diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index b362737f2..d26ccd865 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -211,7 +211,7 @@ func (kt *KustTarget) accumulateTarget() ( func (kt *KustTarget) generateConfigMapsAndSecrets( errs *interror.KustomizationErrors) (resmap.ResMap, error) { - kt.rFactory.Set(kt.fSys, kt.ldr) + kt.rFactory.Set(kt.ldr) cms, err := kt.rFactory.NewResMapFromConfigMapArgs( kt.kustomization.ConfigMapGenerator, kt.kustomization.GeneratorOptions) if err != nil { From 6d56c1750f65b4f648040959313c5004e5c351cb Mon Sep 17 00:00:00 2001 From: Nestor Date: Thu, 17 Jan 2019 15:49:35 +0100 Subject: [PATCH 056/317] fix issues from code review --- pkg/commands/edit/set/setimagetag.go | 10 ++++---- pkg/image/append.go | 6 ++--- pkg/image/image.go | 4 +++- pkg/image/imagetag.go | 8 +++---- pkg/target/kusttarget.go | 2 +- pkg/transformers/image.go | 4 ++-- pkg/transformers/image_test.go | 36 +++++++++++++++++++++------- pkg/types/kustomization.go | 10 ++++---- 8 files changed, 50 insertions(+), 30 deletions(-) diff --git a/pkg/commands/edit/set/setimagetag.go b/pkg/commands/edit/set/setimagetag.go index 730dc558d..43eb4b139 100644 --- a/pkg/commands/edit/set/setimagetag.go +++ b/pkg/commands/edit/set/setimagetag.go @@ -29,7 +29,7 @@ import ( ) type setImageTagOptions struct { - imageTagMap map[string]image.Tag + imageTagMap map[string]image.ImageTag } var pattern = regexp.MustCompile("^(.*):([a-zA-Z0-9._-]*)$") @@ -74,11 +74,11 @@ func (o *setImageTagOptions) Validate(args []string) error { return errors.New("no image specified") } - o.imageTagMap = make(map[string]image.Tag) + o.imageTagMap = make(map[string]image.ImageTag) for _, arg := range args { if s := strings.Split(arg, "@"); len(s) > 1 { - o.imageTagMap[s[0]] = image.Tag{ + o.imageTagMap[s[0]] = image.ImageTag{ Name: s[0], Digest: s[1], } @@ -89,7 +89,7 @@ func (o *setImageTagOptions) Validate(args []string) error { if len(s) != 3 { return errors.New("invalid format of imagetag, must specify it as : or @") } - o.imageTagMap[s[1]] = image.Tag{ + o.imageTagMap[s[1]] = image.ImageTag{ Name: s[1], NewTag: s[2], } @@ -116,7 +116,7 @@ func (o *setImageTagOptions) RunSetImageTags(fSys fs.FileSystem) error { o.imageTagMap[it.Name] = it } - var imageTags []image.Tag + var imageTags []image.ImageTag for _, v := range o.imageTagMap { imageTags = append(imageTags, v) } diff --git a/pkg/image/append.go b/pkg/image/append.go index 2edd03d16..ae479b0f1 100644 --- a/pkg/image/append.go +++ b/pkg/image/append.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2019 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,14 +17,14 @@ limitations under the License. package image // Append appends a slice of type Tag to slice of type Image -func Append(images []Image, tags ...Tag) []Image { +func Append(images []Image, tags ...ImageTag) []Image { for _, tag := range tags { images = append(images, toImage(tag)) } return images } -func toImage(tag Tag) Image { +func toImage(tag ImageTag) Image { return Image{ Name: tag.Name, NewTag: tag.NewTag, diff --git a/pkg/image/image.go b/pkg/image/image.go index 189319609..dbe3b8b17 100644 --- a/pkg/image/image.go +++ b/pkg/image/image.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2019 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,6 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ +// Package image provides struct definitions and libraries +// for image overwriting of names, tags and digest. package image // Image contains an image name, a new name, a new tag or digest, diff --git a/pkg/image/imagetag.go b/pkg/image/imagetag.go index 0a09ce19d..acff10a50 100644 --- a/pkg/image/imagetag.go +++ b/pkg/image/imagetag.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2019 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,9 +16,9 @@ limitations under the License. package image -// Tag contains an image and a new tag, which will replace the original tag. -// Tag usage is deprecated, instead use ImageTag. -type Tag struct { +// ImageTag contains an image and a new tag, which will replace the original tag. +// Deprecated, instead use Image. +type ImageTag struct { // Name is a tag-less image name. Name string `json:"name,omitempty" yaml:"name,omitempty"` diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index fadfcee01..6d8fb1cbc 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -302,7 +302,7 @@ func (kt *KustTarget) newTransformer( return nil, err } r = append(r, t) - t, err = transformers.NewImageTransformer(kt.kustomization.Image) + t, err = transformers.NewImageTransformer(kt.kustomization.Images) if err != nil { return nil, err } diff --git a/pkg/transformers/image.go b/pkg/transformers/image.go index eed3f0274..6dbc94412 100644 --- a/pkg/transformers/image.go +++ b/pkg/transformers/image.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2019 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ func NewImageTransformer(slice []image.Image) (Transformer, error) { return &imageTransformer{slice}, nil } -// Transform finds the matching images and replaces name and/or tag +// Transform finds the matching images and replaces name, tag and/or digest func (pt *imageTransformer) Transform(resources resmap.ResMap) error { if len(pt.images) == 0 { return nil diff --git a/pkg/transformers/image_test.go b/pkg/transformers/image_test.go index 03ac2c707..f1bf18351 100644 --- a/pkg/transformers/image_test.go +++ b/pkg/transformers/image_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2019 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -82,10 +82,6 @@ func TestImageTransformer(t *testing.T) { "name": "nginx1", "image": "nginx", }, - map[string]interface{}{ - "name": "myimage", - "image": "myprivaterepohostname:1234/my/image:latest", - }, }, }, }, @@ -118,6 +114,18 @@ func TestImageTransformer(t *testing.T) { "name": "init-docker", "image": "docker:17-git", }, + map[string]interface{}{ + "name": "myimage", + "image": "myprivaterepohostname:1234/my/image:latest", + }, + map[string]interface{}{ + "name": "my-app", + "image": "my-app-image:v1", + }, + map[string]interface{}{ + "name": "my-cool-app", + "image": "gcr.io:8080/my-project/my-cool-app:latest", + }, }, }, }, @@ -174,10 +182,6 @@ func TestImageTransformer(t *testing.T) { "name": "nginx1", "image": "nginx:v2", }, - map[string]interface{}{ - "name": "myimage", - "image": "myprivaterepohostname:1234/my/image:v1.0.1", - }, }, }, }, @@ -210,6 +214,18 @@ func TestImageTransformer(t *testing.T) { "name": "init-docker", "image": "my-docker@sha256:25a0d4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3", }, + map[string]interface{}{ + "name": "myimage", + "image": "myprivaterepohostname:1234/my/image:v1.0.1", + }, + map[string]interface{}{ + "name": "my-app", + "image": "gcr.io/my-project/my-app-image:v1", + }, + map[string]interface{}{ + "name": "my-cool-app", + "image": "my-cool-app:latest", + }, }, }, }, @@ -223,6 +239,8 @@ func TestImageTransformer(t *testing.T) { {Name: "myprivaterepohostname:1234/my/image", NewTag: "v1.0.1"}, {Name: "foobar", Digest: "sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"}, {Name: "alpine", NewName: "myprivaterepohostname:1234/my/cool-alpine"}, + {Name: "my-app-image", NewName: "gcr.io/my-project/my-app-image"}, + {Name: "gcr.io:8080/my-project/my-cool-app", NewName: "my-cool-app"}, {Name: "postgres", NewName: "my-postgres", NewTag: "v3"}, {Name: "docker", NewName: "my-docker", Digest: "sha256:25a0d4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"}, }) diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 40733d8da..31b3a2147 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -72,10 +72,10 @@ type Kustomization struct { // and http://jsonpatch.com PatchesJson6902 []patch.Json6902 `json:"patchesJson6902,omitempty" yaml:"patchesJson6902,omitempty"` - // Image is a list of (image name, new name, new tag or digest) + // Images is a list of (image name, new name, new tag or digest) // for changing image names, tags or digests. This can also be achieved with a // patch, but this operator is simpler to specify. - Image []image.Image `json:"images,omitempty" yaml:"images,omitempty"` + Images []image.Image `json:"images,omitempty" yaml:"images,omitempty"` // Vars allow things modified by kustomize to be injected into a // container specification. A var is a name (e.g. FOO) associated @@ -137,7 +137,7 @@ type Kustomization struct { Patches []string `json:"patches,omitempty" yaml:"patches,omitempty"` // Deprecated. Use `Image` - ImageTags []image.Tag `json:"imageTags,omitempty" yaml:"imageTags,omitempty"` + ImageTags []image.ImageTag `json:"imageTags,omitempty" yaml:"imageTags,omitempty"` } // DealWithDeprecatedFields should be called immediately after @@ -157,8 +157,8 @@ func (k *Kustomization) DealWithDeprecatedFields() { if len(k.ImageTags) > 0 { // Transform `image.Tag` to `image.Image` // for backwards compatibility - k.Image = image.Append( - k.Image, k.ImageTags...) + k.Images = image.Append( + k.Images, k.ImageTags...) } } From 6616b25d66b9a04c70b6125801f929fb39ae2791 Mon Sep 17 00:00:00 2001 From: Nestor Date: Thu, 17 Jan 2019 16:02:14 +0100 Subject: [PATCH 057/317] fix comment --- pkg/types/kustomization.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 31b3a2147..26c689452 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -155,7 +155,7 @@ func (k *Kustomization) DealWithDeprecatedFields() { } if len(k.ImageTags) > 0 { - // Transform `image.Tag` to `image.Image` + // Transform `ImageTag` to `Image` // for backwards compatibility k.Images = image.Append( k.Images, k.ImageTags...) From d4170797ae239d1dc9f205071686550b2fec31ae Mon Sep 17 00:00:00 2001 From: ryane Date: Tue, 1 Jan 2019 10:40:56 -0500 Subject: [PATCH 058/317] configmap binarydata support --- .../configmapandsecret/configmapfactory.go | 20 ++++++++++++++++--- .../configmapfactory_test.go | 10 ++++++++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/k8sdeps/configmapandsecret/configmapfactory.go b/k8sdeps/configmapandsecret/configmapfactory.go index 10be41a71..c853476f2 100644 --- a/k8sdeps/configmapandsecret/configmapfactory.go +++ b/k8sdeps/configmapandsecret/configmapfactory.go @@ -21,6 +21,7 @@ import ( "fmt" "path" "strings" + "unicode/utf8" "github.com/pkg/errors" "k8s.io/api/core/v1" @@ -48,6 +49,7 @@ func (f *ConfigMapFactory) makeFreshConfigMap( cm.Name = args.Name cm.Namespace = args.Namespace cm.Data = map[string]string{} + cm.BinaryData = map[string][]byte{} return cm } @@ -139,10 +141,22 @@ func addKvToConfigMap(configMap *v1.ConfigMap, keyName, data string) error { if errs := validation.IsConfigMapKey(keyName); len(errs) != 0 { return fmt.Errorf("%q is not a valid key name for a ConfigMap: %s", keyName, strings.Join(errs, ";")) } - if _, entryExists := configMap.Data[keyName]; entryExists { - return fmt.Errorf("cannot add key %s, another key by that name already exists: %v", keyName, configMap.Data) + + keyExistsErrorMsg := "cannot add key %s, another key by that name already exists: %v" + + if utf8.Valid([]byte(data)) { + if _, entryExists := configMap.Data[keyName]; entryExists { + return fmt.Errorf(keyExistsErrorMsg, keyName, configMap.Data) + } + configMap.Data[keyName] = data + return nil } - configMap.Data[keyName] = data + + // binary data + if _, entryExists := configMap.BinaryData[keyName]; entryExists { + return fmt.Errorf(keyExistsErrorMsg, keyName, configMap.BinaryData) + } + configMap.BinaryData[keyName] = []byte(data) return nil } diff --git a/k8sdeps/configmapandsecret/configmapfactory_test.go b/k8sdeps/configmapandsecret/configmapfactory_test.go index d34a190ab..461ad0021 100644 --- a/k8sdeps/configmapandsecret/configmapfactory_test.go +++ b/k8sdeps/configmapandsecret/configmapfactory_test.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -40,6 +40,7 @@ func makeEnvConfigMap(name string) *corev1.ConfigMap { "DB_USERNAME": "admin", "DB_PASSWORD": "somepw", }, + BinaryData: map[string][]byte{}, } } @@ -57,6 +58,9 @@ func makeFileConfigMap(name string) *corev1.ConfigMap { BAR=baz `, }, + BinaryData: map[string][]byte{ + "app.bin": {0xff, 0xfd}, + }, } } @@ -75,6 +79,7 @@ func makeLiteralConfigMap(name string) *corev1.ConfigMap { "c": "Hello World", "d": "true", }, + BinaryData: map[string][]byte{}, } cm.SetLabels(map[string]string{"foo": "bar"}) return cm @@ -105,7 +110,7 @@ func TestConstructConfigMap(t *testing.T) { input: types.ConfigMapArgs{ GeneratorArgs: types.GeneratorArgs{Name: "fileConfigMap"}, DataSources: types.DataSources{ - FileSources: []string{"configmap/app-init.ini"}, + FileSources: []string{"configmap/app-init.ini", "configmap/app.bin"}, }, }, options: nil, @@ -131,6 +136,7 @@ func TestConstructConfigMap(t *testing.T) { fSys := fs.MakeFakeFS() fSys.WriteFile("/configmap/app.env", []byte("DB_USERNAME=admin\nDB_PASSWORD=somepw\n")) fSys.WriteFile("/configmap/app-init.ini", []byte("FOO=bar\nBAR=baz\n")) + fSys.WriteFile("/configmap/app.bin", []byte{0xff, 0xfd}) f := NewConfigMapFactory(loader.NewFileLoaderAtRoot(fSys)) for _, tc := range testCases { cm, err := f.MakeConfigMap(&tc.input, tc.options) From 87411590c5fde9fb288afb6f9825b8e242cd4dfb Mon Sep 17 00:00:00 2001 From: ryane Date: Wed, 16 Jan 2019 14:12:31 -0500 Subject: [PATCH 059/317] configmap binarydata comments and small tweaks the BinaryData map is nil until the generator finds a file with contents that needs injected into the BinaryData field of the configmap --- k8sdeps/configmapandsecret/configmapfactory.go | 8 ++++++-- k8sdeps/configmapandsecret/configmapfactory_test.go | 4 +--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/k8sdeps/configmapandsecret/configmapfactory.go b/k8sdeps/configmapandsecret/configmapfactory.go index c853476f2..f0d8f4962 100644 --- a/k8sdeps/configmapandsecret/configmapfactory.go +++ b/k8sdeps/configmapandsecret/configmapfactory.go @@ -49,7 +49,6 @@ func (f *ConfigMapFactory) makeFreshConfigMap( cm.Name = args.Name cm.Namespace = args.Namespace cm.Data = map[string]string{} - cm.BinaryData = map[string][]byte{} return cm } @@ -144,6 +143,8 @@ func addKvToConfigMap(configMap *v1.ConfigMap, keyName, data string) error { keyExistsErrorMsg := "cannot add key %s, another key by that name already exists: %v" + // If the configmap data contains byte sequences that are all in the UTF-8 + // range, we will write it to .Data if utf8.Valid([]byte(data)) { if _, entryExists := configMap.Data[keyName]; entryExists { return fmt.Errorf(keyExistsErrorMsg, keyName, configMap.Data) @@ -152,7 +153,10 @@ func addKvToConfigMap(configMap *v1.ConfigMap, keyName, data string) error { return nil } - // binary data + // otherwise, it's BinaryData + if configMap.BinaryData == nil { + configMap.BinaryData = map[string][]byte{} + } if _, entryExists := configMap.BinaryData[keyName]; entryExists { return fmt.Errorf(keyExistsErrorMsg, keyName, configMap.BinaryData) } diff --git a/k8sdeps/configmapandsecret/configmapfactory_test.go b/k8sdeps/configmapandsecret/configmapfactory_test.go index 461ad0021..4e00aca55 100644 --- a/k8sdeps/configmapandsecret/configmapfactory_test.go +++ b/k8sdeps/configmapandsecret/configmapfactory_test.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -40,7 +40,6 @@ func makeEnvConfigMap(name string) *corev1.ConfigMap { "DB_USERNAME": "admin", "DB_PASSWORD": "somepw", }, - BinaryData: map[string][]byte{}, } } @@ -79,7 +78,6 @@ func makeLiteralConfigMap(name string) *corev1.ConfigMap { "c": "Hello World", "d": "true", }, - BinaryData: map[string][]byte{}, } cm.SetLabels(map[string]string{"foo": "bar"}) return cm From 78bac973f7be1eba0b4a0ec57f51737c4feffd1f Mon Sep 17 00:00:00 2001 From: jregan Date: Thu, 17 Jan 2019 16:13:23 -0800 Subject: [PATCH 060/317] Add sed-like behavior to the eschewed feature list. --- README.md | 5 +++- docs/eschewedFeatures.md | 54 ++++++++++++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index cc9e29379..426ea9f88 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ patch [kubernetes style] API objects. It's like [`make`], in that what it does is declared in a file, and it's like [`sed`], in that it emits editted text. -This tool is sponsored by [sig-cli] ([KEP]). +This tool is sponsored by [sig-cli] ([KEP]), and +inspired by [DAM]. + [![Build Status](https://travis-ci.org/kubernetes-sigs/kustomize.svg?branch=master)](https://travis-ci.org/kubernetes-sigs/kustomize) [![Go Report Card](https://goreportcard.com/badge/github.com/kubernetes-sigs/kustomize)](https://goreportcard.com/report/github.com/kubernetes-sigs/kustomize) @@ -128,6 +130,7 @@ You can reach the maintainers of this project at: Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct]. +[DAM]: docs/glossary.md#declarative-application-management [KEP]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/0008-kustomize.md [`make`]: https://www.gnu.org/software/make [`sed`]: https://www.gnu.org/software/sed diff --git a/docs/eschewedFeatures.md b/docs/eschewedFeatures.md index 4743b3751..5de3e6c16 100644 --- a/docs/eschewedFeatures.md +++ b/docs/eschewedFeatures.md @@ -31,6 +31,48 @@ what you don't want and commit it to your private fork, then use kustomize on your fork. As often as desired, use _git rebase_ to capture improvements from the upstream base. +## Unstructured edits + +_Structured edits_ are changes controlled by +knowledge of the k8s API, and YAML or JSON syntax. + +Most edits performed by kustomize can be expressed as +[JSON patches] or [SMP patches]. Common edits, like +adding labels or adding a name prefix, get dedicated +shorthand commands. Another class of edits take +data from one specific object's field and use it in +another (e.g. a service object's name found and +copied into a container's command line). + +These edits are designed to create valid output +given valid input, and can provide syntactically +and semantically informed error messages if inputs +are invalid. + +_Unstructured edits_, e.g. a templating approach, +or a command to replace any target string in the +character stream with some other string, aren't +limited by any syntax or object structure. + +Such powerful techniques are eschewed because +- There would be no way to say that a kustomization + was correct without running it and checking + the output. +- Errors in the output would be + disconnected from the edit that caused it. +- They are toil to maintain by a rotating + staff of operators. + +Kustomizations are meant to be sharable and stackable. +Imagine tracing down a problem rooted in a +clever set of stacked regexp replacements +performed by various overlays on some remote base. + +Other tools (sed, jinja, erb, envsubst, helm, ksonnet, +etc.) provide varying degrees of unstructured editting +and/or embedded languages, and can be used instead +of, or in a pipe with, kustomize. + ## Build-time side effects from CLI args or env variables `kustomize` supports the best practice of storing one's @@ -39,7 +81,7 @@ entire configuration in a version control system. Changing `kustomize build` configuration output as a result of additional arguments or flags to `build`, or by consulting shell environment variable values in `build` -code, would violate that goal. +code, would frustrate that goal. `kustomize` insteads offers [kustomization] file `edit` commands. Like any shell command, they can accept @@ -74,12 +116,10 @@ commands that accept globbed arguments, expand them at _edit time_ relative to the local file system, and store the resulting explicit names into the kustomization file. -In this way the resources, patches and bases used at _build time_ -remain explicitly declared in version control. - - -[DAM]: glossary.md#declarative-application-management [base]: glossary.md#base +[DAM]: glossary.md#declarative-application-management +[java import]: https://www.codebyamir.com/blog/pitfalls-java-import-wildcards +[JSON patches]: glossary.md#patchjson6902 [kustomization]: glossary.md#kustomization [OTS workflow]: workflows.md#off-the-shelf-configuration -[java import]: https://www.codebyamir.com/blog/pitfalls-java-import-wildcards +[SMP patches]: glossary.md#patchstrategicmerge From b22e43a4a756b4e355c0321306ef71b1e47e9897 Mon Sep 17 00:00:00 2001 From: Nestor Date: Fri, 18 Jan 2019 10:56:16 +0100 Subject: [PATCH 061/317] add set image command --- pkg/commands/edit/set/all.go | 1 + pkg/commands/edit/set/setimage.go | 186 +++++++++++++++ pkg/commands/edit/set/setimage_test.go | 225 ++++++++++++++++++ pkg/commands/edit/set/setimagetag.go | 4 +- pkg/commands/kustfile/kustomizationfile.go | 1 + .../kustfile/kustomizationfile_test.go | 1 + pkg/types/kustomization.go | 2 + 7 files changed, 419 insertions(+), 1 deletion(-) create mode 100644 pkg/commands/edit/set/setimage.go create mode 100644 pkg/commands/edit/set/setimage_test.go diff --git a/pkg/commands/edit/set/all.go b/pkg/commands/edit/set/all.go index 67321bbe8..ed78b06ff 100644 --- a/pkg/commands/edit/set/all.go +++ b/pkg/commands/edit/set/all.go @@ -43,6 +43,7 @@ func NewCmdSet(fsys fs.FileSystem, v ifc.Validator) *cobra.Command { newCmdSetNameSuffix(fsys), newCmdSetNamespace(fsys, v), newCmdSetImageTag(fsys), + newCmdSetImage(fsys), ) return c } diff --git a/pkg/commands/edit/set/setimage.go b/pkg/commands/edit/set/setimage.go new file mode 100644 index 000000000..cba76575d --- /dev/null +++ b/pkg/commands/edit/set/setimage.go @@ -0,0 +1,186 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package set + +import ( + "errors" + "sort" + "strings" + + "github.com/spf13/cobra" + "sigs.k8s.io/kustomize/pkg/commands/kustfile" + "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/image" +) + +type setImageOptions struct { + imageMap map[string]image.Image +} + +// errors + +var ( + errImageNoArgs = errors.New("no image specified") + errImageInvalidArgs = errors.New(`invalid format of image, use one of the following options: +- =: +- =@ +- : +- @`) +) + +const separator = "=" + +// newCmdSetImage sets the new names, tags or digests for images in the kustomization. +func newCmdSetImage(fsys fs.FileSystem) *cobra.Command { + var o setImageOptions + + cmd := &cobra.Command{ + Use: "image", + Short: `Sets images and their new names, new tags or digests in the kustomization file`, + Example: ` +The command + set image postgres=my-registry/postgres:latest nginx:1.8.0 my-app=my-registry/my-app alpine@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 +will add + +image: +- name: postgres + newName: my-registry/postgres + newTag: latest +- name: nginx + newTag: 1.8.0 +- name: my-app + newName: my-registry/my-app +- digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 + name: alpine + +to the kustomization file if it doesn't exist, +and overwrite the previous ones if the image name exists. + +`, + RunE: func(cmd *cobra.Command, args []string) error { + err := o.Validate(args) + if err != nil { + return err + } + return o.RunSetImage(fsys) + }, + } + return cmd +} + +type overwrite struct { + name string + digest string + tag string +} + +// Validate validates setImage command. +func (o *setImageOptions) Validate(args []string) error { + if len(args) == 0 { + return errImageNoArgs + } + + o.imageMap = make(map[string]image.Image) + + for _, arg := range args { + + img, err := parse(arg) + if err != nil { + return err + } + o.imageMap[img.Name] = img + } + return nil +} + +// RunSetImage runs setImage command. +func (o *setImageOptions) RunSetImage(fSys fs.FileSystem) error { + mf, err := kustfile.NewKustomizationFile(fSys) + if err != nil { + return err + } + m, err := mf.Read() + if err != nil { + return err + } + + // append only new images from ksutomize file + for _, im := range m.Images { + if _, ok := o.imageMap[im.Name]; ok { + continue + } + + o.imageMap[im.Name] = im + } + + var images []image.Image + for _, v := range o.imageMap { + images = append(images, v) + } + + sort.Slice(images, func(i, j int) bool { + return images[i].Name < images[j].Name + }) + + m.Images = images + return mf.Write(m) +} + +func parse(arg string) (image.Image, error) { + + // matches if there is an image name to overwrite + // =<:|@> + if s := strings.Split(arg, separator); len(s) == 2 { + p, err := parseOverwrite(s[1]) + return image.Image{ + Name: s[0], + NewName: p.name, + NewTag: p.tag, + Digest: p.digest, + }, err + } + + // matches only for overwrites + // <:|@> + p, err := parseOverwrite(arg) + return image.Image{ + Name: p.name, + NewTag: p.tag, + Digest: p.digest, + }, err +} + +// parseOverwrite parses the overwrite parameters +// from the given arg into a struct +func parseOverwrite(arg string) (overwrite, error) { + // match @ + if d := strings.Split(arg, "@"); len(d) > 1 { + return overwrite{ + name: d[0], + digest: d[1], + }, nil + } + + // match : + if t := pattern.FindStringSubmatch(arg); len(t) == 3 { + return overwrite{ + name: t[1], + tag: t[2], + }, nil + } + return overwrite{}, errImageInvalidArgs +} diff --git a/pkg/commands/edit/set/setimage_test.go b/pkg/commands/edit/set/setimage_test.go new file mode 100644 index 000000000..e851d4f56 --- /dev/null +++ b/pkg/commands/edit/set/setimage_test.go @@ -0,0 +1,225 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package set + +import ( + "fmt" + "strings" + "testing" + + "sigs.k8s.io/kustomize/pkg/fs" +) + +func TestSetImage(t *testing.T) { + type given struct { + args []string + infileImages []string + } + type expected struct { + fileOutput []string + err error + } + testCases := []struct { + description string + given given + expected expected + }{ + { + given: given{ + args: []string{"image1=my-image1:my-tag"}, + }, + expected: expected{ + fileOutput: []string{ + "images:", + "- name: image1", + " newName: my-image1", + " newTag: my-tag", + }}, + }, + { + given: given{ + args: []string{"image1=my-image1@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"}, + }, + expected: expected{ + fileOutput: []string{ + "images:", + "- digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3", + " name: image1", + " newName: my-image1", + }}, + }, + { + given: given{ + args: []string{"image1:my-tag"}, + }, + expected: expected{ + fileOutput: []string{ + "images:", + "- name: image1", + " newTag: my-tag", + }}, + }, + { + given: given{ + args: []string{"image1@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"}, + }, + expected: expected{ + fileOutput: []string{ + "images:", + "- digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3", + " name: image1", + }}, + }, + { + given: given{ + args: []string{"ngnix=localhost:5000/my-project/ngnix:dev-01"}, + }, + expected: expected{ + fileOutput: []string{ + "images:", + "- name: ngnix", + " newName: localhost:5000/my-project/ngnix", + " newTag: dev-01", + }}, + }, + { + description: "override file", + given: given{ + args: []string{"image1=foo.bar.foo:8800/foo/image1:foo-bar"}, + infileImages: []string{ + "images:", + "- name: image1", + " newName: my-image1", + " newTag: my-tag", + "- name: image2", + " newName: my-image2", + " newTag: my-tag2", + }, + }, + expected: expected{ + fileOutput: []string{ + "images:", + "- name: image1", + " newName: foo.bar.foo:8800/foo/image1", + " newTag: foo-bar", + "- name: image2", + " newName: my-image2", + " newTag: my-tag2", + }}, + }, + { + description: "override new tag and new name with just a new tag", + given: given{ + args: []string{"image1:v1"}, + infileImages: []string{ + "images:", + "- name: image1", + " newTag: my-tag", + }, + }, + expected: expected{ + fileOutput: []string{ + "images:", + "- name: image1", + " newTag: v1", + }}, + }, + { + description: "multiple args with multiple overrides", + given: given{ + args: []string{ + "image1=foo.bar.foo:8800/foo/image1:foo-bar", + "image2=my-image2@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3", + "image3:my-tag", + }, + infileImages: []string{ + "images:", + "- name: image1", + " newName: my-image1", + " newTag: my-tag1", + "- name: image2", + " newName: my-image2", + " newTag: my-tag2", + "- name: image3", + " newTag: my-tag", + }, + }, + expected: expected{ + fileOutput: []string{ + "images:", + "- name: image1", + " newName: foo.bar.foo:8800/foo/image1", + " newTag: foo-bar", + "- digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3", + " name: image2", + " newName: my-image2", + "- name: image3", + " newTag: my-tag", + }}, + }, + { + description: "error: no args", + expected: expected{ + err: errImageNoArgs, + }, + }, + { + description: "error: invalid args", + given: given{ + args: []string{"bad", "args"}, + }, + expected: expected{ + err: errImageInvalidArgs, + }, + }, + } + + for _, tc := range testCases { + t.Run(fmt.Sprintf("%s%v", tc.description, tc.given.args), func(t *testing.T) { + // arrange + fakeFS := fs.MakeFakeFS() + cmd := newCmdSetImage(fakeFS) + + if len(tc.given.infileImages) > 0 { + // write file with infileImages + fakeFS.WriteTestKustomizationWith([]byte(strings.Join(tc.given.infileImages, "\n"))) + } else { + // writes default kustomization file + fakeFS.WriteTestKustomization() + } + + // act + err := cmd.RunE(cmd, tc.given.args) + + // assert + if err != tc.expected.err { + t.Errorf("Unexpedted error from set image command. Actual: %v\nExpected: %v", err, tc.expected.err) + t.FailNow() + } + + content, err := fakeFS.ReadTestKustomization() + if err != nil { + t.Errorf("unexpected read error: %v", err) + t.FailNow() + } + expectedStr := strings.Join(tc.expected.fileOutput, "\n") + if !strings.Contains(string(content), expectedStr) { + t.Errorf("unexpected image in kustomization file. \nActual:\n%s\nExpected:\n%s", content, expectedStr) + } + }) + } +} diff --git a/pkg/commands/edit/set/setimagetag.go b/pkg/commands/edit/set/setimagetag.go index 43eb4b139..41baedbd7 100644 --- a/pkg/commands/edit/set/setimagetag.go +++ b/pkg/commands/edit/set/setimagetag.go @@ -18,6 +18,7 @@ package set import ( "errors" + "log" "regexp" "sort" "strings" @@ -40,7 +41,7 @@ func newCmdSetImageTag(fsys fs.FileSystem) *cobra.Command { cmd := &cobra.Command{ Use: "imagetag", - Short: "Sets images and their new tags or digests in the kustomization file", + Short: "[*** DEPRECATED, use: kustomize edit set image ***] Sets images and their new tags or digests in the kustomization file", Example: ` The command set imagetag nginx:1.8.0 my-app:latest alpine@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 @@ -58,6 +59,7 @@ to the kustomization file if it doesn't exist, and overwrite the previous ones if the image tag exists. `, RunE: func(cmd *cobra.Command, args []string) error { + log.Print("This is a deprecated command, it still works but will be removed in a further release. Use better kustomize edit set image") err := o.Validate(args) if err != nil { return err diff --git a/pkg/commands/kustfile/kustomizationfile.go b/pkg/commands/kustfile/kustomizationfile.go index abd9cfe0b..177ec604f 100644 --- a/pkg/commands/kustfile/kustomizationfile.go +++ b/pkg/commands/kustfile/kustomizationfile.go @@ -66,6 +66,7 @@ func determineFieldOrder() []string { "SecretGenerator", "GeneratorOptions", "Vars", + "Images", "ImageTags", "Configurations", } diff --git a/pkg/commands/kustfile/kustomizationfile_test.go b/pkg/commands/kustfile/kustomizationfile_test.go index 3738baf62..b1b1cc42a 100644 --- a/pkg/commands/kustfile/kustomizationfile_test.go +++ b/pkg/commands/kustfile/kustomizationfile_test.go @@ -44,6 +44,7 @@ func TestFieldOrder(t *testing.T) { "SecretGenerator", "GeneratorOptions", "Vars", + "Images", "ImageTags", "Configurations", } diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 73cb2a3e3..2b4f58963 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -157,6 +157,8 @@ func (k *Kustomization) DealWithDeprecatedFields() { if len(k.ImageTags) > 0 { // Transform `ImageTag` to `Image` // for backwards compatibility + // images are appended first to keep + // higher precedence k.Images = image.Append( k.Images, k.ImageTags...) } From fed8195eb24ce0c8602a12edbfef003cb5b393c9 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Tue, 22 Jan 2019 10:58:36 -0800 Subject: [PATCH 062/317] add apiversion and kind to docs/kustomization.yaml --- docs/kustomization.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index 7cc821c7b..54e27f297 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -28,9 +28,12 @@ # don't exist. # # In practice, fields with no value should simply be -# omitted from kustomize.yaml to reduce the content +# omitted from kustomization.yaml to reduce the content # visible in configuration reviews. # ---------------------------------------------------- +# apiVersion and kind of Kustomization +apiVersion: v1beta1 +kind: Kustomization # Adds namespace to all resources. namespace: my-namespace From d4b90c8f4e51741b598b0a642bb1a323d9b453a1 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Tue, 22 Jan 2019 11:07:32 -0800 Subject: [PATCH 063/317] Add bug writing instructions to README. --- README.md | 74 ++++++++++++++++++++++++++++++++++------ docs/eschewedFeatures.md | 9 +++-- 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 426ea9f88..0efbb13a1 100644 --- a/README.md +++ b/README.md @@ -117,30 +117,87 @@ The YAML can be directly [applied] to a cluster: > kustomize build ~/someApp/overlays/production | kubectl apply -f - > ``` -## Community, discussion, contribution, and support +## Community -Learn how to engage with the Kubernetes community on the [community page]. +### Filing bug reports -You can reach the maintainers of this project at: + +##### A good report specifies + + * the output of `kustomize version`, + * the input (the content of `kustomization.yaml` + and any files it refers to), + * the expected YAML output. + +##### A _great_ report is a bug reproduction test + +Kustomize has a simple test harness in the +[target package] for specifying a kustomization's +input and the expected output. +See this [example of a target test]. + +The pattern is + * call `NewKustTestHarness` + * specify kustomization input data (resources, + patches, etc.) as inline strings, + * call `makeKustTarget().MakeCustomizedResMap()` + * compare the actual output to expected output + +In a bug reproduction test, the expected output string +initially contains the _wrong_ (unexpected) output, +thus unambiguously reproducing the bug. + +Nearby comments should explain what the output +_should_ be, and have a TODO pointing to the related +issue. + +The person who fixes the bug then has a clear +bug reproduction and a test to modify when +the bug is fixed. + +The bug reporter can then see the bug was fixed, +and has permanent regression coverage to prevent +its reintroduction. + +### Feature requests + +Feature requests are welcome. + +Before working on an implementation, please + * Read the [eschewed feature list]. + * File an issue describing + how the new feature would behave + and label it [kind/feature]. + +### Other communication channels - [Slack] - [Mailing List] +- General kubernetes [community page] ### Code of conduct -Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct]. +Participation in the Kubernetes community +is governed by the [Kubernetes Code of Conduct]. -[DAM]: docs/glossary.md#declarative-application-management -[KEP]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/0008-kustomize.md [`make`]: https://www.gnu.org/software/make [`sed`]: https://www.gnu.org/software/sed +[DAM]: docs/glossary.md#declarative-application-management +[KEP]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/0008-kustomize.md +[Kubernetes Code of Conduct]: code-of-conduct.md +[Mailing List]: https://groups.google.com/forum/#!forum/kubernetes-sig-cli +[Slack]: https://kubernetes.slack.com/messages/sig-cli [applied]: docs/glossary.md#apply [base]: docs/glossary.md#base +[community page]: http://kubernetes.io/community/ [declarative configuration]: docs/glossary.md#declarative-application-management +[eschewed feature list]: docs/eschewedFeatures.md +[example of a target test]: https://github.com/kubernetes-sigs/kustomize/blob/master/pkg/target/baseandoverlaysmall_test.go [examples]: examples/README.md [imageBase]: docs/base.jpg [imageOverlay]: docs/overlay.jpg [install]: docs/INSTALL.md +[kind/feature]: https://github.com/kubernetes-sigs/kustomize/labels/kind%2Ffeature [kubernetes style]: docs/glossary.md#kubernetes-style-object [kustomization]: docs/glossary.md#kustomization [overlay]: docs/glossary.md#overlay @@ -149,10 +206,7 @@ Participation in the Kubernetes community is governed by the [Kubernetes Code of [resource]: docs/glossary.md#resource [resources]: docs/glossary.md#resource [sig-cli]: https://github.com/kubernetes/community/blob/master/sig-cli/README.md +[target package]: https://github.com/kubernetes-sigs/kustomize/tree/master/pkg/target [variant]: docs/glossary.md#variant [variants]: docs/glossary.md#variant [workflows]: docs/workflows.md -[community page]: http://kubernetes.io/community/ -[Kubernetes Code of Conduct]: code-of-conduct.md -[Slack]: https://kubernetes.slack.com/messages/sig-cli -[Mailing List]: https://groups.google.com/forum/#!forum/kubernetes-sig-cli diff --git a/docs/eschewedFeatures.md b/docs/eschewedFeatures.md index 5de3e6c16..33e067ad6 100644 --- a/docs/eschewedFeatures.md +++ b/docs/eschewedFeatures.md @@ -1,5 +1,10 @@ # Eschewed Features +The maintainers established this list to +place bounds on the kustomize feature +set. The bounds can be changed with +a consensus on the risks. + For a bigger picture about why kustomize does some things and not others, see the glossary entry for [DAM]. @@ -10,8 +15,8 @@ glossary entry for [DAM]. _compositions_ or _mixins_ - concepts that are widely accepted as a best practice in various programming languages. -To this end, `kustomize` offers various _addition_ directives. One -can add labels, annotations, patches, resources and bases. +To this end, `kustomize` offers various _addition_ directives. +One may add labels, annotations, patches, resources, bases, etc. Corresponding _removal_ directives are not offered. Removal semantics would introduce many possibilities for From 2e6bdd4041e2fdf9b877bc2270512ad29e9afc36 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Tue, 22 Jan 2019 14:08:17 -0800 Subject: [PATCH 064/317] Add more loader tests. --- pkg/loader/fileloader.go | 2 +- pkg/loader/fileloader_test.go | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/pkg/loader/fileloader.go b/pkg/loader/fileloader.go index 2393a723f..9973e4e4b 100644 --- a/pkg/loader/fileloader.go +++ b/pkg/loader/fileloader.go @@ -133,7 +133,7 @@ func newFileLoaderAt( } if !fSys.IsDir(absRoot) { return nil, fmt.Errorf( - "absolute root dir '%s' does not exist", absRoot) + "'%s' does not exist or is not a directory", absRoot) } return &fileLoader{ roots: append(roots, absRoot), diff --git a/pkg/loader/fileloader_test.go b/pkg/loader/fileloader_test.go index 8598ff5b0..bc94c2c09 100644 --- a/pkg/loader/fileloader_test.go +++ b/pkg/loader/fileloader_test.go @@ -61,6 +61,25 @@ func MakeFakeFs(td []testData) fs.FileSystem { return fSys } +func TestNewFileLoaderAt_DemandsDirectory(t *testing.T) { + fSys := MakeFakeFs(testCases) + _, err := newFileLoaderAt("/foo", fSys, []string{}, nil) + if err != nil { + t.Fatalf("Unexpected error - a directory should work.") + } + _, err = newFileLoaderAt("/foo/project", fSys, []string{}, nil) + if err != nil { + t.Fatalf("Unexpected error - a directory should work.") + } + _, err = newFileLoaderAt("/foo/project/fileA.yaml", fSys, []string{}, nil) + if err == nil { + t.Fatalf("Expected error - a file should not work.") + } + if !strings.Contains(err.Error(), "does not exist or is not a directory") { + t.Fatalf("unexpected err: %v", err) + } +} + func TestLoaderLoad(t *testing.T) { l1 := NewFileLoaderAtRoot(MakeFakeFs(testCases)) if "/" != l1.Root() { From d141b2421c94fda408a1a4cd85b6dca0b91b4c66 Mon Sep 17 00:00:00 2001 From: jregan Date: Tue, 22 Jan 2019 18:57:11 -0800 Subject: [PATCH 065/317] DataSources is now common to Secrets and ConfigMaps. --- .../configmapfactory_test.go | 24 ++++++++----- .../configmapandsecret/secretfactory_test.go | 24 ++++++++----- pkg/resmap/factory_test.go | 36 +++++++++++-------- pkg/types/kustomization.go | 9 ++--- 4 files changed, 55 insertions(+), 38 deletions(-) diff --git a/k8sdeps/configmapandsecret/configmapfactory_test.go b/k8sdeps/configmapandsecret/configmapfactory_test.go index 4e00aca55..3524a7bfd 100644 --- a/k8sdeps/configmapandsecret/configmapfactory_test.go +++ b/k8sdeps/configmapandsecret/configmapfactory_test.go @@ -95,9 +95,11 @@ func TestConstructConfigMap(t *testing.T) { { description: "construct config map from env", input: types.ConfigMapArgs{ - GeneratorArgs: types.GeneratorArgs{Name: "envConfigMap"}, - DataSources: types.DataSources{ - EnvSource: "configmap/app.env", + GeneratorArgs: types.GeneratorArgs{ + Name: "envConfigMap", + DataSources: types.DataSources{ + EnvSource: "configmap/app.env", + }, }, }, options: nil, @@ -106,9 +108,11 @@ func TestConstructConfigMap(t *testing.T) { { description: "construct config map from file", input: types.ConfigMapArgs{ - GeneratorArgs: types.GeneratorArgs{Name: "fileConfigMap"}, - DataSources: types.DataSources{ - FileSources: []string{"configmap/app-init.ini", "configmap/app.bin"}, + GeneratorArgs: types.GeneratorArgs{ + Name: "fileConfigMap", + DataSources: types.DataSources{ + FileSources: []string{"configmap/app-init.ini", "configmap/app.bin"}, + }, }, }, options: nil, @@ -117,9 +121,11 @@ func TestConstructConfigMap(t *testing.T) { { description: "construct config map from literal", input: types.ConfigMapArgs{ - GeneratorArgs: types.GeneratorArgs{Name: "literalConfigMap"}, - DataSources: types.DataSources{ - LiteralSources: []string{"a=x", "b=y", "c=\"Hello World\"", "d='true'"}, + GeneratorArgs: types.GeneratorArgs{ + Name: "literalConfigMap", + DataSources: types.DataSources{ + LiteralSources: []string{"a=x", "b=y", "c=\"Hello World\"", "d='true'"}, + }, }, }, options: &types.GeneratorOptions{ diff --git a/k8sdeps/configmapandsecret/secretfactory_test.go b/k8sdeps/configmapandsecret/secretfactory_test.go index e62ea04c4..da405a27f 100644 --- a/k8sdeps/configmapandsecret/secretfactory_test.go +++ b/k8sdeps/configmapandsecret/secretfactory_test.go @@ -93,9 +93,11 @@ func TestConstructSecret(t *testing.T) { { description: "construct secret from env", input: types.SecretArgs{ - GeneratorArgs: types.GeneratorArgs{Name: "envSecret"}, - DataSources: types.DataSources{ - EnvSource: "secret/app.env", + GeneratorArgs: types.GeneratorArgs{ + Name: "envSecret", + DataSources: types.DataSources{ + EnvSource: "secret/app.env", + }, }, }, options: nil, @@ -104,9 +106,11 @@ func TestConstructSecret(t *testing.T) { { description: "construct secret from file", input: types.SecretArgs{ - GeneratorArgs: types.GeneratorArgs{Name: "fileSecret"}, - DataSources: types.DataSources{ - FileSources: []string{"secret/app-init.ini"}, + GeneratorArgs: types.GeneratorArgs{ + Name: "fileSecret", + DataSources: types.DataSources{ + FileSources: []string{"secret/app-init.ini"}, + }, }, }, options: nil, @@ -115,9 +119,11 @@ func TestConstructSecret(t *testing.T) { { description: "construct secret from literal", input: types.SecretArgs{ - GeneratorArgs: types.GeneratorArgs{Name: "literalSecret"}, - DataSources: types.DataSources{ - LiteralSources: []string{"a=x", "b=y"}, + GeneratorArgs: types.GeneratorArgs{ + Name: "literalSecret", + DataSources: types.DataSources{ + LiteralSources: []string{"a=x", "b=y"}, + }, }, }, options: &types.GeneratorOptions{ diff --git a/pkg/resmap/factory_test.go b/pkg/resmap/factory_test.go index ec6af7661..8d4cb0d54 100644 --- a/pkg/resmap/factory_test.go +++ b/pkg/resmap/factory_test.go @@ -151,9 +151,11 @@ func TestNewFromConfigMaps(t *testing.T) { description: "construct config map from env", input: []types.ConfigMapArgs{ { - GeneratorArgs: types.GeneratorArgs{Name: "envConfigMap"}, - DataSources: types.DataSources{ - EnvSource: "app.env", + GeneratorArgs: types.GeneratorArgs{ + Name: "envConfigMap", + DataSources: types.DataSources{ + EnvSource: "app.env", + }, }, }, }, @@ -177,9 +179,11 @@ func TestNewFromConfigMaps(t *testing.T) { { description: "construct config map from file", input: []types.ConfigMapArgs{{ - GeneratorArgs: types.GeneratorArgs{Name: "fileConfigMap"}, - DataSources: types.DataSources{ - FileSources: []string{"app-init.ini"}, + GeneratorArgs: types.GeneratorArgs{ + Name: "fileConfigMap", + DataSources: types.DataSources{ + FileSources: []string{"app-init.ini"}, + }, }, }, }, @@ -205,9 +209,11 @@ BAR=baz description: "construct config map from literal", input: []types.ConfigMapArgs{ { - GeneratorArgs: types.GeneratorArgs{Name: "literalConfigMap"}, - DataSources: types.DataSources{ - LiteralSources: []string{"a=x", "b=y", "c=\"Good Morning\"", "d=\"false\""}, + GeneratorArgs: types.GeneratorArgs{ + Name: "literalConfigMap", + DataSources: types.DataSources{ + LiteralSources: []string{"a=x", "b=y", "c=\"Good Morning\"", "d=\"false\""}, + }, }, }, }, @@ -251,11 +257,13 @@ var secret = gvk.Gvk{Version: "v1", Kind: "Secret"} func TestNewResMapFromSecretArgs(t *testing.T) { secrets := []types.SecretArgs{ { - GeneratorArgs: types.GeneratorArgs{Name: "apple"}, - DataSources: types.DataSources{ - LiteralSources: []string{ - "DB_USERNAME=admin", - "DB_PASSWORD=somepw", + GeneratorArgs: types.GeneratorArgs{ + Name: "apple", + DataSources: types.DataSources{ + LiteralSources: []string{ + "DB_USERNAME=admin", + "DB_PASSWORD=somepw", + }, }, }, Type: ifc.SecretTypeOpaque, diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 73cb2a3e3..069de6c79 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -206,15 +206,15 @@ type GeneratorArgs struct { // 'replace': replace the existing one // 'merge': merge with the existing one Behavior string `json:"behavior,omitempty" yaml:"behavior,omitempty"` + + // DataSources for the generator. + DataSources `json:",inline,omitempty" yaml:",inline,omitempty"` } // ConfigMapArgs contains the metadata of how to generate a configmap. type ConfigMapArgs struct { // GeneratorArgs for the configmap. GeneratorArgs `json:",inline,omitempty" yaml:",inline,omitempty"` - - // DataSources for configmap. - DataSources `json:",inline,omitempty" yaml:",inline,omitempty"` } // SecretArgs contains the metadata of how to generate a secret. @@ -230,9 +230,6 @@ type SecretArgs struct { // If type is "kubernetes.io/tls", then "literals" or "files" must have exactly two // keys: "tls.key" and "tls.crt" Type string `json:"type,omitempty" yaml:"type,omitempty"` - - // DataSources for secret. - DataSources `json:",inline,omitempty" yaml:",inline,omitempty"` } // DataSources contains some generic sources for configmaps. From e49bd3ab1da4576ec518d399a184fd1e4cb38d39 Mon Sep 17 00:00:00 2001 From: Nestor Date: Wed, 23 Jan 2019 07:59:58 +0100 Subject: [PATCH 066/317] improve image command messages --- pkg/commands/edit/set/setimage.go | 26 +++++++++++++++++++------- pkg/commands/edit/set/setimagetag.go | 4 ++-- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/pkg/commands/edit/set/setimage.go b/pkg/commands/edit/set/setimage.go index cba76575d..8454ab0f8 100644 --- a/pkg/commands/edit/set/setimage.go +++ b/pkg/commands/edit/set/setimage.go @@ -38,6 +38,7 @@ var ( errImageInvalidArgs = errors.New(`invalid format of image, use one of the following options: - =: - =@ +- = - : - @`) ) @@ -53,23 +54,34 @@ func newCmdSetImage(fsys fs.FileSystem) *cobra.Command { Short: `Sets images and their new names, new tags or digests in the kustomization file`, Example: ` The command - set image postgres=my-registry/postgres:latest nginx:1.8.0 my-app=my-registry/my-app alpine@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 -will add + set image postgres=eu.gcr.io/my-project/postgres:latest my-app=my-registry/my-app@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 +will add image: - name: postgres - newName: my-registry/postgres + newName: eu.gcr.io/my-project/postgres newTag: latest -- name: nginx - newTag: 1.8.0 -- name: my-app +- digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 + name: my-app newName: my-registry/my-app + +to the kustomization file if it doesn't exist, +and overwrite the previous ones if the image name exists. + +The command + set image node:8.15.0 mysql=mariadb alpine@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 +will add + +image: +- name: node + newTag: 8.15.0 +- name: mysql + newName: mariadb - digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 name: alpine to the kustomization file if it doesn't exist, and overwrite the previous ones if the image name exists. - `, RunE: func(cmd *cobra.Command, args []string) error { err := o.Validate(args) diff --git a/pkg/commands/edit/set/setimagetag.go b/pkg/commands/edit/set/setimagetag.go index 41baedbd7..2c8e5db32 100644 --- a/pkg/commands/edit/set/setimagetag.go +++ b/pkg/commands/edit/set/setimagetag.go @@ -41,7 +41,7 @@ func newCmdSetImageTag(fsys fs.FileSystem) *cobra.Command { cmd := &cobra.Command{ Use: "imagetag", - Short: "[*** DEPRECATED, use: kustomize edit set image ***] Sets images and their new tags or digests in the kustomization file", + Short: "The `imagetag` command is deprecated, instead use `edit set image`.", Example: ` The command set imagetag nginx:1.8.0 my-app:latest alpine@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 @@ -59,7 +59,7 @@ to the kustomization file if it doesn't exist, and overwrite the previous ones if the image tag exists. `, RunE: func(cmd *cobra.Command, args []string) error { - log.Print("This is a deprecated command, it still works but will be removed in a further release. Use better kustomize edit set image") + log.Print(cmd.Short) err := o.Validate(args) if err != nil { return err From 62d096e57d300248fdd8383f4ed5867ee30583f8 Mon Sep 17 00:00:00 2001 From: Nestor Date: Wed, 23 Jan 2019 09:24:59 +0100 Subject: [PATCH 067/317] add 'images' documentation deprecate 'imageTags' documentation --- docs/kustomization.yaml | 34 +++++++++++++++++++++++++++++ examples/README.md | 2 +- examples/{imageTags.md => image.md} | 25 +++++++++++---------- 3 files changed, 48 insertions(+), 13 deletions(-) rename examples/{imageTags.md => image.md} (66%) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index 7cc821c7b..0b966ea1d 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -257,6 +257,40 @@ vars: fieldref: fieldpath: spec.template.spec.restartPolicy +# Images modify the name, tags and/or digest for images without creating patches. +# E.g. Given this kubernetes Deployment fragment: +# ``` +# containers: +# - name: mypostgresdb +# image: postgres:8 +# - name: nginxapp +# image: nginx:1.7.9 +# - name: myapp +# image: my-demo-app:latest +# - name: alpine-app +# image: alpine:3.7 +#``` +# one can change the `image` in the following ways: +# +# - `postgres:8` to `my-registry/my-postgres:v1`, +# - nginx tag `1.7.9` to `1.8.0`, +# - image name `my-demo-app` to `my-app`, +# - alpine's tag `3.7` to a digest value +# +# all with the following *kustomization*: + +images: + - name: postgres + newName: my-registry/my-postgres + newTag: v1 + - name: nginx + newTag: 1.8.0 + - name: my-demo-app + newName: my-app + - name: alpine + digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 + +# ImageTags is deprecated, instead use Image. # ImageTags modify the tags for images without creating patches. # E.g. Given this fragment of a Deployment: # ``` diff --git a/examples/README.md b/examples/README.md index eb259837b..5b94edadb 100644 --- a/examples/README.md +++ b/examples/README.md @@ -37,7 +37,7 @@ go get sigs.k8s.io/kustomize * [vars](wordpress/README.md) - Injecting k8s runtime data into container arguments (e.g. to point wordpress to a SQL service) by vars. - * [image tags](imageTags.md) - Updating image tags without applying a patch. + * [image names and tags](image.md) - Updating image names and tags without applying a patch. * [multibases](multibases/README.md) - Composing three variants (dev, staging, production) with a common base. diff --git a/examples/imageTags.md b/examples/image.md similarity index 66% rename from examples/imageTags.md rename to examples/image.md index d6a5fe11a..a6248c1f3 100644 --- a/examples/imageTags.md +++ b/examples/image.md @@ -1,4 +1,4 @@ -# Demo: change image tags +# Demo: change image names and tags Define a place to work: @@ -42,21 +42,22 @@ EOF ``` The `myapp-pod` resource declares an initContainer and a container, both use the image `busybox:1.29.0`. -The tag `1.29.0` can be changed by adding `imageTags` in `kustomization.yaml`. +The image `busybox` and tag `1.29.0` can be changed by adding `images` in `kustomization.yaml`. -Add `imageTags`: - +Add `images`: + ``` cd $DEMO_HOME -kustomize edit set imagetag busybox:1.29.1 +kustomize edit set image busybox=alpine:3.6 ``` -The `kustomization.yaml` will be added following `imageTags`. +The folowing `images` will be added to `kustomization.yaml`: > ``` -> imageTags: +> images: > - name: busybox -> newTag: 1.29.1 +> newName: alpine +> newTag: 3.6 > ``` Now build this `kustomization` @@ -65,11 +66,11 @@ Now build this `kustomization` kustomize build $DEMO_HOME ``` -Confirm that this replaces _both_ busybox tags: +Confirm that this replaces _both_ busybox images and tags for `alpine:3.6`: - + ``` -test 2 == \ - $(kustomize build $DEMO_HOME | grep busybox:1.29.1 | wc -l); \ +test 2 = \ + $(kustomize build $DEMO_HOME | grep alpine:3.6 | wc -l); \ echo $? ``` From f1b8fdec7fbd7d3b5c2244a9c2b766fcce90af35 Mon Sep 17 00:00:00 2001 From: Thomas Riccardi Date: Wed, 23 Jan 2019 10:49:39 +0100 Subject: [PATCH 068/317] Fix typo in generatorOptions example doc --- examples/generatorOptions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/generatorOptions.md b/examples/generatorOptions.md index 4fff9ac26..fcda27a84 100644 --- a/examples/generatorOptions.md +++ b/examples/generatorOptions.md @@ -8,7 +8,7 @@ Kustomize provides options to modify the behavior of ConfigMap and Secret genera This demo shows how to use these options. First create a workspace. ``` -DEMO_HOME=$(mkdir -d) +DEMO_HOME=$(mktemp -d) ``` Create a kustomization and add a ConfigMap generator to it. From 51bbf57e9559d6128a8dacf6cbf12e2d4dfbb7f5 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Wed, 23 Jan 2019 17:23:29 -0800 Subject: [PATCH 069/317] Tweak documentation on directive. --- docs/kustomization.yaml | 53 ++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index 778130c8c..377d7837c 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -212,11 +212,13 @@ crds: - crds/typeA.yaml - crds/typeB.yaml -# Vars are used to insert values from resources that cannot be referenced -# otherwise. For example if you need to pass a Service's name to the arguments -# or environment variables of a program but without hard coding the actual name -# of the Service you'd insert `$(MY_SERVICE_NAME)` into the value field of the -# env var or into the command or args of the container as shown here: +# Vars are used to capture text from one resource's field +# and insert that text elsewhere. +# +# For example, suppose one specify the name of a k8s Service +# object in a container's command line, and the name of a +# k8s Secret object in a container's environment variable, +# so that the following would work: # ``` # containers: # - image: myimage @@ -226,19 +228,8 @@ crds: # value: $(SOME_SECRET_NAME) # ``` # -# Then you'll add an entry to `vars:` like shown below with the same name -# and a reference to the resource from which to pull the field's value. -# The actual field's path is optional and by default it will use -# `metadata.name`. Currently only string type fields are supported, no integers -# or booleans, etc. Also array access is currently not possible. For example getting -# the image field of container number 2 inside of a pod can currently not be done. +# To do so, add an entry to `vars:` as follows: # -# Not every location of a variable is supported. To see a complete list of locations -# see the file [varreference.go](https://github.com/kubernetes-sigs/kustomize/blob/master/pkg/transformers/config/defaultconfig/varreference.go#L20). -# -# An example of a situation where you'd not use vars is when you'd like to set a -# pod's `serviceAccountName`. In that case you would just reference the ServiceAccount -# by name and Kustomize will resolve it to the eventual name while building the manifests. vars: - name: SOME_SECRET_NAME objref: @@ -259,6 +250,34 @@ vars: apiVersion: apps/v1 fieldref: fieldpath: spec.template.spec.restartPolicy +# +# A var is a tuple of variable name, object reference and field +# reference within that object. That's where the text is found. +# +# The field reference is optional; it defaults to `metadata.name`, +# a normal default, since kustomize is used to generates or +# modify the names of resources. +# +# At time of writing, only string type fields are supported. +# No ints, bools, arrays etc. It's not possible to, say, +# extract the name of the image in container number 2 of +# some pod template. +# +# A variable reference, i.e. the string '$(FOO)', can only +# be placed in particular fields of particular objects as +# specified by kustomize's configuration data. +# +# The default config data for vars is at +# https://github.com/kubernetes-sigs/kustomize/blob/master/pkg/transformers/config/defaultconfig/varreference.go +# Long story short, the default targets are all +# container command args and env value fields. +# +# Vars should _not_ be used for inserting names in places +# where kustomize is already handling that job. E.g., +# a Deployment may reference a ConfigMap by name, and +# if kustomize changes the name of a ConfigMap, it knows +# to change the name reference in the Deployment. + # Images modify the name, tags and/or digest for images without creating patches. # E.g. Given this kubernetes Deployment fragment: From f7a59178a81e3888b9c3eb075debde8611d4e7bb Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Thu, 24 Jan 2019 12:26:59 -0800 Subject: [PATCH 070/317] support different filenames for kustomization file --- pkg/commands/build/build.go | 4 ++-- pkg/commands/build/build_test.go | 2 +- pkg/commands/edit/add/addmetadata.go | 4 ++-- pkg/commands/kustfile/kustomizationfile.go | 22 +++++++++++++----- .../kustfile/kustomizationfile_test.go | 4 ++-- pkg/constants/constants.go | 21 ++++++++--------- pkg/fs/fakefs.go | 4 ++-- pkg/loader/gitcloner_test.go | 2 +- pkg/target/kusttarget.go | 23 +++++++++++-------- pkg/target/utils_for_test.go | 2 +- 10 files changed, 50 insertions(+), 38 deletions(-) diff --git a/pkg/commands/build/build.go b/pkg/commands/build/build.go index 9a04da800..0c3d1e425 100644 --- a/pkg/commands/build/build.go +++ b/pkg/commands/build/build.go @@ -67,7 +67,7 @@ func NewCmdBuild( cmd := &cobra.Command{ Use: "build [path]", - Short: "Print current configuration per contents of " + constants.KustomizationFileName, + Short: "Print current configuration per contents of " + constants.KustomizationFileNames[0], Example: examples, SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) error { @@ -88,7 +88,7 @@ func NewCmdBuild( // Validate validates build command. func (o *BuildOptions) Validate(args []string) error { if len(args) > 1 { - return errors.New("specify one path to " + constants.KustomizationFileName) + return errors.New("specify one path to " + constants.KustomizationFileNames[0]) } if len(args) == 0 { o.kustomizationPath = "./" diff --git a/pkg/commands/build/build_test.go b/pkg/commands/build/build_test.go index e9f1d3ec8..95859e529 100644 --- a/pkg/commands/build/build_test.go +++ b/pkg/commands/build/build_test.go @@ -33,7 +33,7 @@ func TestBuildValidate(t *testing.T) { {"file", []string{"beans"}, "beans", ""}, {"path", []string{"a/b/c"}, "a/b/c", ""}, {"path", []string{"too", "many"}, - "", "specify one path to " + constants.KustomizationFileName}, + "", "specify one path to " + constants.KustomizationFileNames[0]}, } for _, mycase := range cases { opts := BuildOptions{} diff --git a/pkg/commands/edit/add/addmetadata.go b/pkg/commands/edit/add/addmetadata.go index 00daaa617..633c7566a 100644 --- a/pkg/commands/edit/add/addmetadata.go +++ b/pkg/commands/edit/add/addmetadata.go @@ -59,7 +59,7 @@ func newCmdAddAnnotation(fSys fs.FileSystem, v func(map[string]string) error) *c o.mapValidator = v cmd := &cobra.Command{ Use: "annotation", - Short: "Adds one or more commonAnnotations to " + constants.KustomizationFileName, + Short: "Adds one or more commonAnnotations to " + constants.KustomizationFileNames[0], Example: ` add annotation {annotationKey1:annotationValue1},{annotationKey2:annotationValue2}`, RunE: func(cmd *cobra.Command, args []string) error { @@ -76,7 +76,7 @@ func newCmdAddLabel(fSys fs.FileSystem, v func(map[string]string) error) *cobra. o.mapValidator = v cmd := &cobra.Command{ Use: "label", - Short: "Adds one or more commonLabels to " + constants.KustomizationFileName, + Short: "Adds one or more commonLabels to " + constants.KustomizationFileNames[0], Example: ` add label {labelKey1:labelValue1},{labelKey2:labelValue2}`, RunE: func(cmd *cobra.Command, args []string) error { diff --git a/pkg/commands/kustfile/kustomizationfile.go b/pkg/commands/kustfile/kustomizationfile.go index 177ec604f..537a07c09 100644 --- a/pkg/commands/kustfile/kustomizationfile.go +++ b/pkg/commands/kustfile/kustomizationfile.go @@ -129,12 +129,22 @@ func NewKustomizationFile(fSys fs.FileSystem) (*kustomizationFile, error) { // n } func (mf *kustomizationFile) validate() error { - if mf.fSys.Exists(constants.KustomizationFileName) { - mf.path = constants.KustomizationFileName - } else if mf.fSys.Exists(constants.SecondaryKustomizationFileName) { - mf.path = constants.SecondaryKustomizationFileName - } else { - return fmt.Errorf("Missing kustomization file '%s'.\n", constants.KustomizationFileName) + match := 0 + var path []string + for _, kfilename := range constants.KustomizationFileNames { + if mf.fSys.Exists(kfilename) { + match += 1 + path = append(path, kfilename) + } + } + + switch match { + case 0: + return fmt.Errorf("Missing kustomization file '%s'.\n", constants.KustomizationFileNames[0]) + case 1: + mf.path = path[0] + default: + return fmt.Errorf("Found multiple kustomization file: %v\n", path) } if mf.fSys.IsDir(mf.path) { diff --git a/pkg/commands/kustfile/kustomizationfile_test.go b/pkg/commands/kustfile/kustomizationfile_test.go index b1b1cc42a..b50f68ffd 100644 --- a/pkg/commands/kustfile/kustomizationfile_test.go +++ b/pkg/commands/kustfile/kustomizationfile_test.go @@ -159,12 +159,12 @@ configMapGenerator: name: my-configmap ` fakeFS := fs.MakeFakeFS() - fakeFS.WriteFile(constants.SecondaryKustomizationFileName, []byte(kcontent)) + fakeFS.WriteFile(constants.KustomizationFileNames[1], []byte(kcontent)) k, err := NewKustomizationFile(fakeFS) if err != nil { t.Fatalf("Unexpected Error: %v", err) } - if k.path != constants.SecondaryKustomizationFileName { + if k.path != constants.KustomizationFileNames[1] { t.Fatalf("Load incorrect file path %s", k.path) } } diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index d81024afa..0938f1567 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -17,15 +17,12 @@ limitations under the License. // Package constants holds global constants for the kustomize tool. package constants -// KustomizationFileSuffix is expected suffix for KustomizationFileName. -const KustomizationFileSuffix = ".yaml" - -// SecondaryKustomizationFileSuffix is the second expected suffix when KustomizationFileSuffix is not found -const SecondaryKustomizationFileSuffix = ".yml" - -// KustomizationFileName is the Well-Known File Name for a kustomize configuration file. -const KustomizationFileName = "kustomization" + KustomizationFileSuffix - -// SecondaryKustomizationFileName is the secondary File Name for a kustomize configuration file when -// KustomizationFileName is not found -const SecondaryKustomizationFileName = "kustomization" + SecondaryKustomizationFileSuffix +// KustomizationFileNames is a list of filenames that can be recognized and consumbed +// by Kustomize. +// In each directory, Kustomize searches for file with the name in this list. +// Only one match is allowed. +var KustomizationFileNames = [3]string{ + "kustomization.yaml", + "kustomization.yml", + "Kustomization", +} diff --git a/pkg/fs/fakefs.go b/pkg/fs/fakefs.go index f38260185..edb19bc5e 100644 --- a/pkg/fs/fakefs.go +++ b/pkg/fs/fakefs.go @@ -151,7 +151,7 @@ func (fs *fakeFs) ReadFile(name string) ([]byte, error) { } func (fs *fakeFs) ReadTestKustomization() ([]byte, error) { - return fs.ReadFile(constants.KustomizationFileName) + return fs.ReadFile(constants.KustomizationFileNames[0]) } // WriteFile always succeeds and does nothing. @@ -169,7 +169,7 @@ func (fs *fakeFs) WriteTestKustomization() { // WriteTestKustomizationWith writes a standard test file. func (fs *fakeFs) WriteTestKustomizationWith(bytes []byte) { - fs.WriteFile(constants.KustomizationFileName, bytes) + fs.WriteFile(constants.KustomizationFileNames[0], bytes) } func (fs *fakeFs) pathMatch(path, pattern string) bool { diff --git a/pkg/loader/gitcloner_test.go b/pkg/loader/gitcloner_test.go index 4b0b1f386..2c5df4474 100644 --- a/pkg/loader/gitcloner_test.go +++ b/pkg/loader/gitcloner_test.go @@ -162,7 +162,7 @@ func TestGitLoader(t *testing.T) { fSys.MkdirAll(coRoot) fSys.MkdirAll(coRoot + "/" + pathInRepo) fSys.WriteFile( - coRoot+"/"+pathInRepo+"/"+constants.KustomizationFileName, + coRoot+"/"+pathInRepo+"/"+constants.KustomizationFileNames[0], []byte(` whatever `)) diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 2dd0b2f02..3c6bcb0a1 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -82,18 +82,23 @@ func NewKustTarget( } func loadKustFile(ldr ifc.Loader) ([]byte, error) { - for _, kf := range []string{ - constants.KustomizationFileName, - constants.SecondaryKustomizationFileName} { - content, err := ldr.Load(kf) + var content []byte + match := 0 + for _, kf := range constants.KustomizationFileNames { + c, err := ldr.Load(kf) if err == nil { - return content, nil - } - if !strings.Contains(err.Error(), "no such file or directory") { - return nil, err + match += 1 + content = c } } - return nil, fmt.Errorf("no kustomization.yaml file under %s", ldr.Root()) + switch match { + case 0: + return nil, fmt.Errorf("no kustomization.yaml file under %s", ldr.Root()) + case 1: + return content, nil + default: + return nil, fmt.Errorf("Found multiple kustomization file under: %s\n", ldr.Root()) + } } func unmarshal(y []byte, o interface{}) error { diff --git a/pkg/target/utils_for_test.go b/pkg/target/utils_for_test.go index 97f17b5e3..e3541e6a7 100644 --- a/pkg/target/utils_for_test.go +++ b/pkg/target/utils_for_test.go @@ -74,7 +74,7 @@ func (th *KustTestHarness) writeF(dir string, content string) { } func (th *KustTestHarness) writeK(dir string, content string) { - th.writeF(filepath.Join(dir, constants.KustomizationFileName), ` + th.writeF(filepath.Join(dir, constants.KustomizationFileNames[0]), ` apiVersion: v1beta1 kind: Kustomization `+content) From a0c22b8216bde7f47aaf2ee06be941ae3cfa620a Mon Sep 17 00:00:00 2001 From: Seth Pollack Date: Sun, 20 Jan 2019 00:28:03 -0500 Subject: [PATCH 071/317] add add secret command --- pkg/commands/edit/add/all.go | 6 +- pkg/commands/edit/add/configmap.go | 22 +-- pkg/commands/edit/add/configmap_test.go | 12 +- .../{cmapflagsandargs.go => flagsandargs.go} | 10 +- ...gsandargs_test.go => flagsandargs_test.go} | 44 +++--- pkg/commands/edit/add/secret.go | 146 ++++++++++++++++++ pkg/commands/edit/add/secret_test.go | 131 ++++++++++++++++ 7 files changed, 327 insertions(+), 44 deletions(-) rename pkg/commands/edit/add/{cmapflagsandargs.go => flagsandargs.go} (86%) rename pkg/commands/edit/add/{cmapflagsandargs_test.go => flagsandargs_test.go} (66%) create mode 100644 pkg/commands/edit/add/secret.go create mode 100644 pkg/commands/edit/add/secret_test.go diff --git a/pkg/commands/edit/add/all.go b/pkg/commands/edit/add/all.go index da48ce400..25d791663 100644 --- a/pkg/commands/edit/add/all.go +++ b/pkg/commands/edit/add/all.go @@ -26,9 +26,12 @@ import ( func NewCmdAdd(fsys fs.FileSystem, v ifc.Validator, kf ifc.KunstructuredFactory) *cobra.Command { c := &cobra.Command{ Use: "add", - Short: "Adds configmap/resource/patch/base to the kustomization file.", + Short: "Adds an item to the kustomization file.", Long: "", Example: ` + # Adds a secret to the kustomization file + kustomize edit add secret NAME --from-literal=k=v + # Adds a configmap to the kustomization file kustomize edit add configmap NAME --from-literal=k=v @@ -53,6 +56,7 @@ func NewCmdAdd(fsys fs.FileSystem, v ifc.Validator, kf ifc.KunstructuredFactory) c.AddCommand( newCmdAddResource(fsys), newCmdAddPatch(fsys), + newCmdAddSecret(fsys, kf), newCmdAddConfigMap(fsys, kf), newCmdAddBase(fsys), newCmdAddLabel(fsys, v.MakeLabelValidator()), diff --git a/pkg/commands/edit/add/configmap.go b/pkg/commands/edit/add/configmap.go index 013967fd4..7eee21faf 100644 --- a/pkg/commands/edit/add/configmap.go +++ b/pkg/commands/edit/add/configmap.go @@ -29,7 +29,7 @@ import ( // newCmdAddConfigMap returns a new command. func newCmdAddConfigMap(fSys fs.FileSystem, kf ifc.KunstructuredFactory) *cobra.Command { - var flagsAndArgs cMapFlagsAndArgs + var flags flagsAndArgs cmd := &cobra.Command{ Use: "configmap NAME [--from-file=[key=]source] [--from-literal=key1=value1]", Short: "Adds a configmap to the kustomization file.", @@ -45,12 +45,12 @@ func newCmdAddConfigMap(fSys fs.FileSystem, kf ifc.KunstructuredFactory) *cobra. kustomize edit add configmap my-configmap --from-env-file=env/path.env `, RunE: func(_ *cobra.Command, args []string) error { - err := flagsAndArgs.ExpandFileSource(fSys) + err := flags.ExpandFileSource(fSys) if err != nil { return err } - err = flagsAndArgs.Validate(args) + err = flags.Validate(args) if err != nil { return err } @@ -68,7 +68,7 @@ func newCmdAddConfigMap(fSys fs.FileSystem, kf ifc.KunstructuredFactory) *cobra. // Add the flagsAndArgs map to the kustomization file. kf.Set(loader.NewFileLoaderAtCwd(fSys)) - err = addConfigMap(kustomization, flagsAndArgs, kf) + err = addConfigMap(kustomization, flags, kf) if err != nil { return err } @@ -79,19 +79,19 @@ func newCmdAddConfigMap(fSys fs.FileSystem, kf ifc.KunstructuredFactory) *cobra. } cmd.Flags().StringSliceVar( - &flagsAndArgs.FileSources, + &flags.FileSources, "from-file", []string{}, "Key file can be specified using its file path, in which case file basename will be used as configmap "+ "key, or optionally with a key and file path, in which case the given key will be used. Specifying a "+ "directory will iterate each named file in the directory whose basename is a valid configmap key.") cmd.Flags().StringArrayVar( - &flagsAndArgs.LiteralSources, + &flags.LiteralSources, "from-literal", []string{}, "Specify a key and literal value to insert in configmap (i.e. mykey=somevalue)") cmd.Flags().StringVar( - &flagsAndArgs.EnvFileSource, + &flags.EnvFileSource, "from-env-file", "", "Specify the path to a file to read lines of key=val pairs to create a configmap (i.e. a Docker .env file).") @@ -104,9 +104,9 @@ func newCmdAddConfigMap(fSys fs.FileSystem, kf ifc.KunstructuredFactory) *cobra. // Suggest passing a copy of kustomization file. func addConfigMap( k *types.Kustomization, - flagsAndArgs cMapFlagsAndArgs, kf ifc.KunstructuredFactory) error { - cmArgs := makeConfigMapArgs(k, flagsAndArgs.Name) - err := mergeFlagsIntoCmArgs(&cmArgs.DataSources, flagsAndArgs) + flags flagsAndArgs, kf ifc.KunstructuredFactory) error { + cmArgs := makeConfigMapArgs(k, flags.Name) + err := mergeFlagsIntoCmArgs(&cmArgs.DataSources, flags) if err != nil { return err } @@ -130,7 +130,7 @@ func makeConfigMapArgs(m *types.Kustomization, name string) *types.ConfigMapArgs return &m.ConfigMapGenerator[len(m.ConfigMapGenerator)-1] } -func mergeFlagsIntoCmArgs(src *types.DataSources, flags cMapFlagsAndArgs) error { +func mergeFlagsIntoCmArgs(src *types.DataSources, flags flagsAndArgs) error { src.LiteralSources = append(src.LiteralSources, flags.LiteralSources...) src.FileSources = append(src.FileSources, flags.FileSources...) if src.EnvSource != "" && src.EnvSource != flags.EnvFileSource { diff --git a/pkg/commands/edit/add/configmap_test.go b/pkg/commands/edit/add/configmap_test.go index 93c280d47..f55d1198a 100644 --- a/pkg/commands/edit/add/configmap_test.go +++ b/pkg/commands/edit/add/configmap_test.go @@ -67,7 +67,7 @@ func TestMakeConfigMapArgs(t *testing.T) { func TestMergeFlagsIntoCmArgs_LiteralSources(t *testing.T) { ds := &types.DataSources{} - err := mergeFlagsIntoCmArgs(ds, cMapFlagsAndArgs{LiteralSources: []string{"k1=v1"}}) + err := mergeFlagsIntoCmArgs(ds, flagsAndArgs{LiteralSources: []string{"k1=v1"}}) if err != nil { t.Fatalf("Merge initial literal source should not return error") } @@ -76,7 +76,7 @@ func TestMergeFlagsIntoCmArgs_LiteralSources(t *testing.T) { t.Fatalf("Initial literal source should have been added") } - err = mergeFlagsIntoCmArgs(ds, cMapFlagsAndArgs{LiteralSources: []string{"k2=v2"}}) + err = mergeFlagsIntoCmArgs(ds, flagsAndArgs{LiteralSources: []string{"k2=v2"}}) if err != nil { t.Fatalf("Merge second literal source should not return error") } @@ -89,7 +89,7 @@ func TestMergeFlagsIntoCmArgs_LiteralSources(t *testing.T) { func TestMergeFlagsIntoCmArgs_FileSources(t *testing.T) { ds := &types.DataSources{} - err := mergeFlagsIntoCmArgs(ds, cMapFlagsAndArgs{FileSources: []string{"file1"}}) + err := mergeFlagsIntoCmArgs(ds, flagsAndArgs{FileSources: []string{"file1"}}) if err != nil { t.Fatalf("Merge initial file source should not return error") } @@ -98,7 +98,7 @@ func TestMergeFlagsIntoCmArgs_FileSources(t *testing.T) { t.Fatalf("Initial file source should have been added") } - err = mergeFlagsIntoCmArgs(ds, cMapFlagsAndArgs{FileSources: []string{"file2"}}) + err = mergeFlagsIntoCmArgs(ds, flagsAndArgs{FileSources: []string{"file2"}}) if err != nil { t.Fatalf("Merge second file source should not return error") } @@ -113,7 +113,7 @@ func TestMergeFlagsIntoCmArgs_EnvSource(t *testing.T) { envFileName2 := "env2" ds := &types.DataSources{} - err := mergeFlagsIntoCmArgs(ds, cMapFlagsAndArgs{EnvFileSource: envFileName}) + err := mergeFlagsIntoCmArgs(ds, flagsAndArgs{EnvFileSource: envFileName}) if err != nil { t.Fatalf("Merge initial env source should not return error") } @@ -122,7 +122,7 @@ func TestMergeFlagsIntoCmArgs_EnvSource(t *testing.T) { t.Fatalf("Initial env source filename should have been added") } - err = mergeFlagsIntoCmArgs(ds, cMapFlagsAndArgs{EnvFileSource: envFileName2}) + err = mergeFlagsIntoCmArgs(ds, flagsAndArgs{EnvFileSource: envFileName2}) if err == nil { t.Fatalf("Updating env source should return an error") } diff --git a/pkg/commands/edit/add/cmapflagsandargs.go b/pkg/commands/edit/add/flagsandargs.go similarity index 86% rename from pkg/commands/edit/add/cmapflagsandargs.go rename to pkg/commands/edit/add/flagsandargs.go index 6575d2bde..77bcc6b61 100644 --- a/pkg/commands/edit/add/cmapflagsandargs.go +++ b/pkg/commands/edit/add/flagsandargs.go @@ -22,8 +22,8 @@ import ( "sigs.k8s.io/kustomize/pkg/fs" ) -// cMapFlagsAndArgs encapsulates the options for add configmap commands. -type cMapFlagsAndArgs struct { +// flagsAndArgs encapsulates the options for add secret/configmap commands. +type flagsAndArgs struct { // Name of configMap/Secret (required) Name string // FileSources to derive the configMap/Secret from (optional) @@ -33,10 +33,12 @@ type cMapFlagsAndArgs struct { // EnvFileSource to derive the configMap/Secret from (optional) // TODO: Rationalize this name with Generic.EnvSource EnvFileSource string + // Type of secret to create + Type string } // Validate validates required fields are set to support structured generation. -func (a *cMapFlagsAndArgs) Validate(args []string) error { +func (a *flagsAndArgs) Validate(args []string) error { if len(args) != 1 { return fmt.Errorf("name must be specified once") } @@ -51,7 +53,7 @@ func (a *cMapFlagsAndArgs) Validate(args []string) error { return nil } -func (a *cMapFlagsAndArgs) ExpandFileSource(fSys fs.FileSystem) error { +func (a *flagsAndArgs) ExpandFileSource(fSys fs.FileSystem) error { result, err := globPatterns(fSys, a.FileSources) if err != nil { return err diff --git a/pkg/commands/edit/add/cmapflagsandargs_test.go b/pkg/commands/edit/add/flagsandargs_test.go similarity index 66% rename from pkg/commands/edit/add/cmapflagsandargs_test.go rename to pkg/commands/edit/add/flagsandargs_test.go index ce5ed57ee..5638fe71f 100644 --- a/pkg/commands/edit/add/cmapflagsandargs_test.go +++ b/pkg/commands/edit/add/flagsandargs_test.go @@ -23,18 +23,18 @@ import ( "sigs.k8s.io/kustomize/pkg/fs" ) -func TestDataConfigValidation_NoName(t *testing.T) { - config := cMapFlagsAndArgs{} +func TestDataValidation_NoName(t *testing.T) { + fa := flagsAndArgs{} - if config.Validate([]string{}) == nil { + if fa.Validate([]string{}) == nil { t.Fatal("Validation should fail if no name is specified") } } -func TestDataConfigValidation_MoreThanOneName(t *testing.T) { - config := cMapFlagsAndArgs{} +func TestDataValidation_MoreThanOneName(t *testing.T) { + fa := flagsAndArgs{} - if config.Validate([]string{"name", "othername"}) == nil { + if fa.Validate([]string{"name", "othername"}) == nil { t.Fatal("Validation should fail if more than one name is specified") } } @@ -42,12 +42,12 @@ func TestDataConfigValidation_MoreThanOneName(t *testing.T) { func TestDataConfigValidation_Flags(t *testing.T) { tests := []struct { name string - config cMapFlagsAndArgs + fa flagsAndArgs shouldFail bool }{ { name: "env-file-source and literal are both set", - config: cMapFlagsAndArgs{ + fa: flagsAndArgs{ LiteralSources: []string{"one", "two"}, EnvFileSource: "three", }, @@ -55,7 +55,7 @@ func TestDataConfigValidation_Flags(t *testing.T) { }, { name: "env-file-source and from-file are both set", - config: cMapFlagsAndArgs{ + fa: flagsAndArgs{ FileSources: []string{"one", "two"}, EnvFileSource: "three", }, @@ -63,12 +63,12 @@ func TestDataConfigValidation_Flags(t *testing.T) { }, { name: "we don't have any option set", - config: cMapFlagsAndArgs{}, + fa: flagsAndArgs{}, shouldFail: true, }, { name: "we have from-file and literal ", - config: cMapFlagsAndArgs{ + fa: flagsAndArgs{ LiteralSources: []string{"one", "two"}, FileSources: []string{"three", "four"}, }, @@ -77,9 +77,9 @@ func TestDataConfigValidation_Flags(t *testing.T) { } for _, test := range tests { - if test.config.Validate([]string{"name"}) == nil && test.shouldFail { + if test.fa.Validate([]string{"name"}) == nil && test.shouldFail { t.Fatalf("Validation should fail if %s", test.name) - } else if test.config.Validate([]string{"name"}) != nil && !test.shouldFail { + } else if test.fa.Validate([]string{"name"}) != nil && !test.shouldFail { t.Fatalf("Validation should succeed if %s", test.name) } } @@ -87,18 +87,18 @@ func TestDataConfigValidation_Flags(t *testing.T) { func TestExpandFileSource(t *testing.T) { fakeFS := fs.MakeFakeFS() - fakeFS.Create("dir/config1") - fakeFS.Create("dir/config2") + fakeFS.Create("dir/fa1") + fakeFS.Create("dir/fa2") fakeFS.Create("dir/reademe") - config := cMapFlagsAndArgs{ - FileSources: []string{"dir/config*"}, + fa := flagsAndArgs{ + FileSources: []string{"dir/fa*"}, } - config.ExpandFileSource(fakeFS) + fa.ExpandFileSource(fakeFS) expected := []string{ - "dir/config1", - "dir/config2", + "dir/fa1", + "dir/fa2", } - if !reflect.DeepEqual(config.FileSources, expected) { - t.Fatalf("FileSources is not correctly expanded: %v", config.FileSources) + if !reflect.DeepEqual(fa.FileSources, expected) { + t.Fatalf("FileSources is not correctly expanded: %v", fa.FileSources) } } diff --git a/pkg/commands/edit/add/secret.go b/pkg/commands/edit/add/secret.go new file mode 100644 index 000000000..53f93dbd0 --- /dev/null +++ b/pkg/commands/edit/add/secret.go @@ -0,0 +1,146 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package add + +import ( + "fmt" + + "github.com/spf13/cobra" + "sigs.k8s.io/kustomize/pkg/commands/kustfile" + "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/loader" + "sigs.k8s.io/kustomize/pkg/types" +) + +// newCmdAddSecret returns a new command. +func newCmdAddSecret(fSys fs.FileSystem, kf ifc.KunstructuredFactory) *cobra.Command { + var flags flagsAndArgs + cmd := &cobra.Command{ + Use: "secret NAME [--from-file=[key=]source] [--from-literal=key1=value1] [--type=Opaque|kubernetes.io/tls]", + Short: "Adds a secret to the kustomization file.", + Long: "", + Example: ` + # Adds a secret to the kustomization file (with a specified key) + kustomize edit add secret my-secret --from-file=my-key=file/path --from-literal=my-literal=12345 + + # Adds a secret to the kustomization file (key is the filename) + kustomize edit add secret my-secret --from-file=file/path + + # Adds a secret from env-file + kustomize edit add secret my-secret --from-env-file=env/path.env +`, + RunE: func(_ *cobra.Command, args []string) error { + err := flags.ExpandFileSource(fSys) + if err != nil { + return err + } + + err = flags.Validate(args) + if err != nil { + return err + } + + // Load the kustomization file. + mf, err := kustfile.NewKustomizationFile(fSys) + if err != nil { + return err + } + + kustomization, err := mf.Read() + if err != nil { + return err + } + + // Add the flagsAndArgs map to the kustomization file. + kf.Set(loader.NewFileLoaderAtCwd(fSys)) + err = addSecret(kustomization, flags, kf) + if err != nil { + return err + } + + // Write out the kustomization file with added secret. + return mf.Write(kustomization) + }, + } + + cmd.Flags().StringSliceVar( + &flags.FileSources, + "from-file", + []string{}, + "Key file can be specified using its file path, in which case file basename will be used as secret "+ + "key, or optionally with a key and file path, in which case the given key will be used. Specifying a "+ + "directory will iterate each named file in the directory whose basename is a valid secret key.") + cmd.Flags().StringArrayVar( + &flags.LiteralSources, + "from-literal", + []string{}, + "Specify a key and literal value to insert in secret (i.e. mykey=somevalue)") + cmd.Flags().StringVar( + &flags.EnvFileSource, + "from-env-file", + "", + "Specify the path to a file to read lines of key=val pairs to create a secret (i.e. a Docker .env file).") + cmd.Flags().StringVar( + &flags.Type, + "type", + "Opaque", + "Specify the secret type this can be 'Opaque' (default), or 'kubernetes.io/tls'") + + return cmd +} + +// addSecret adds a secret to a kustomization file. +// Note: error may leave kustomization file in an undefined state. +// Suggest passing a copy of kustomization file. +func addSecret( + k *types.Kustomization, + flags flagsAndArgs, kf ifc.KunstructuredFactory) error { + secretArgs := makeSecretArgs(k, flags.Name, flags.Type) + err := mergeFlagsIntoSecretArgs(&secretArgs.DataSources, flags) + if err != nil { + return err + } + // Validate by trying to create corev1.secret. + _, err = kf.MakeSecret(secretArgs, k.GeneratorOptions) + if err != nil { + return err + } + return nil +} + +func makeSecretArgs(m *types.Kustomization, name, secretType string) *types.SecretArgs { + for i, v := range m.SecretGenerator { + if name == v.Name { + return &m.SecretGenerator[i] + } + } + // secret not found, create new one and add it to the kustomization file. + secret := &types.SecretArgs{GeneratorArgs: types.GeneratorArgs{Name: name}, Type: secretType} + m.SecretGenerator = append(m.SecretGenerator, *secret) + return &m.SecretGenerator[len(m.SecretGenerator)-1] +} + +func mergeFlagsIntoSecretArgs(src *types.DataSources, flags flagsAndArgs) error { + src.LiteralSources = append(src.LiteralSources, flags.LiteralSources...) + src.FileSources = append(src.FileSources, flags.FileSources...) + if src.EnvSource != "" && src.EnvSource != flags.EnvFileSource { + return fmt.Errorf("updating existing env source '%s' not allowed", src.EnvSource) + } + src.EnvSource = flags.EnvFileSource + return nil +} diff --git a/pkg/commands/edit/add/secret_test.go b/pkg/commands/edit/add/secret_test.go new file mode 100644 index 000000000..47ba26489 --- /dev/null +++ b/pkg/commands/edit/add/secret_test.go @@ -0,0 +1,131 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package add + +import ( + "testing" + + "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/types" +) + +func TestNewCmdAddSecretIsNotNil(t *testing.T) { + if newCmdAddSecret(fs.MakeFakeFS(), nil) == nil { + t.Fatal("newCmdAddSecret shouldn't be nil") + } +} + +func TestMakeSecretArgs(t *testing.T) { + secretName := "test-secret-name" + + kustomization := &types.Kustomization{ + NamePrefix: "test-name-prefix", + } + + secretType := "Opaque" + + if len(kustomization.SecretGenerator) != 0 { + t.Fatal("Initial kustomization should not have any secrets") + } + args := makeSecretArgs(kustomization, secretName, secretType) + + if args == nil { + t.Fatalf("args should always be non-nil") + } + + if len(kustomization.SecretGenerator) != 1 { + t.Fatalf("Kustomization should have newly created secret") + } + + if &kustomization.SecretGenerator[len(kustomization.SecretGenerator)-1] != args { + t.Fatalf("Pointer address for newly inserted secret generator should be same") + } + + args2 := makeSecretArgs(kustomization, secretName, secretType) + + if args2 != args { + t.Fatalf("should have returned an existing args with name: %v", secretName) + } + + if len(kustomization.SecretGenerator) != 1 { + t.Fatalf("Should not insert secret for an existing name: %v", secretName) + } +} + +func TestMergeFlagsIntoSecretArgs_LiteralSources(t *testing.T) { + ds := &types.DataSources{} + + err := mergeFlagsIntoSecretArgs(ds, flagsAndArgs{LiteralSources: []string{"k1=v1"}}) + if err != nil { + t.Fatalf("Merge initial literal source should not return error") + } + + if len(ds.LiteralSources) != 1 { + t.Fatalf("Initial literal source should have been added") + } + + err = mergeFlagsIntoSecretArgs(ds, flagsAndArgs{LiteralSources: []string{"k2=v2"}}) + if err != nil { + t.Fatalf("Merge second literal source should not return error") + } + + if len(ds.LiteralSources) != 2 { + t.Fatalf("Second literal source should have been added") + } +} + +func TestMergeFlagsIntoSecretArgs_FileSources(t *testing.T) { + ds := &types.DataSources{} + + err := mergeFlagsIntoSecretArgs(ds, flagsAndArgs{FileSources: []string{"file1"}}) + if err != nil { + t.Fatalf("Merge initial file source should not return error") + } + + if len(ds.FileSources) != 1 { + t.Fatalf("Initial file source should have been added") + } + + err = mergeFlagsIntoSecretArgs(ds, flagsAndArgs{FileSources: []string{"file2"}}) + if err != nil { + t.Fatalf("Merge second file source should not return error") + } + + if len(ds.FileSources) != 2 { + t.Fatalf("Second file source should have been added") + } +} + +func TestMergeFlagsIntoSecretArgs_EnvSource(t *testing.T) { + envFileName := "env1" + envFileName2 := "env2" + ds := &types.DataSources{} + + err := mergeFlagsIntoSecretArgs(ds, flagsAndArgs{EnvFileSource: envFileName}) + if err != nil { + t.Fatalf("Merge initial env source should not return error") + } + + if ds.EnvSource != envFileName { + t.Fatalf("Initial env source filename should have been added") + } + + err = mergeFlagsIntoSecretArgs(ds, flagsAndArgs{EnvFileSource: envFileName2}) + if err == nil { + t.Fatalf("Updating env source should return an error") + } +} From c21dfefbdf1fb874540106d1f58ba814d5150828 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Fri, 25 Jan 2019 12:21:03 -0800 Subject: [PATCH 072/317] Cover CleanedAbs --- pkg/fs/fakefs.go | 13 +++- pkg/fs/fs.go | 2 +- pkg/fs/realfs.go | 40 +++++++++++- pkg/fs/realfs_test.go | 116 ++++++++++++++++++++++++++++++++-- pkg/loader/fileloader.go | 32 ++++------ pkg/loader/fileloader_test.go | 2 +- pkg/resmap/factory_test.go | 2 +- 7 files changed, 173 insertions(+), 34 deletions(-) diff --git a/pkg/fs/fakefs.go b/pkg/fs/fakefs.go index f38260185..fb21f81bd 100644 --- a/pkg/fs/fakefs.go +++ b/pkg/fs/fakefs.go @@ -102,9 +102,16 @@ func (fs *fakeFs) Open(name string) (File, error) { return fs.m[name], nil } -// EvalSymlinks does nothing and cannot fail. -func (fs *fakeFs) EvalSymlinks(path string) (string, error) { - return path, nil +// CleanedAbs does nothing and cannot fail. +func (fs *fakeFs) CleanedAbs(path string) (string, string, error) { + if fs.IsDir(path) { + return path, "", nil + } + d := filepath.Dir(path) + if d == path { + return d, "", nil + } + return d, filepath.Base(path), nil } // Exists returns true if file is known. diff --git a/pkg/fs/fs.go b/pkg/fs/fs.go index 5d647850a..65f5e0148 100644 --- a/pkg/fs/fs.go +++ b/pkg/fs/fs.go @@ -30,7 +30,7 @@ type FileSystem interface { RemoveAll(name string) error Open(name string) (File, error) IsDir(name string) bool - EvalSymlinks(path string) (string, error) + CleanedAbs(path string) (string, string, error) Exists(name string) bool Glob(pattern string) ([]string, error) ReadFile(name string) ([]byte, error) diff --git a/pkg/fs/realfs.go b/pkg/fs/realfs.go index c4fad35c4..75f6f2987 100644 --- a/pkg/fs/realfs.go +++ b/pkg/fs/realfs.go @@ -17,7 +17,9 @@ limitations under the License. package fs import ( + "fmt" "io/ioutil" + "log" "os" "path/filepath" ) @@ -53,9 +55,41 @@ func (realFS) RemoveAll(name string) error { // Open delegates to os.Open. func (realFS) Open(name string) (File, error) { return os.Open(name) } -// EvalSymlinks delegates to filepath.EvalSymlinks. -func (realFS) EvalSymlinks(path string) (string, error) { - return filepath.EvalSymlinks(path) +// CleanedAbs returns a cleaned, absolute path +// with no symbolic links split into directory +// and file components. If the entire path is +// a directory, the file component is an empty +// string. +func (x realFS) CleanedAbs(path string) (string, string, error) { + absRoot, err := filepath.Abs(path) + if err != nil { + return "", "", fmt.Errorf( + "abs path error on '%s' : %v", path, err) + } + deLinked, err := filepath.EvalSymlinks(absRoot) + if err != nil { + return "", "", fmt.Errorf( + "evalsymlink failure on '%s' : %v", path, err) + } + if x.IsDir(deLinked) { + return deLinked, "", nil + } + d := filepath.Dir(deLinked) + if !x.IsDir(d) { + // Programmer/assumption error. + log.Fatalf("first part of '%s' not a directory", deLinked) + } + if d == deLinked { + // Programmer/assumption error. + log.Fatalf("d '%s' should be a subset of deLinked", d) + } + f := filepath.Base(deLinked) + if filepath.Join(d, f) != deLinked { + // Programmer/assumption error. + log.Fatalf("these should be equal: '%s', '%s'", + filepath.Join(d, f), deLinked) + } + return d, f, nil } // Exists returns true if os.Stat succeeds. diff --git a/pkg/fs/realfs_test.go b/pkg/fs/realfs_test.go index c1bf8a734..7add5fb64 100644 --- a/pkg/fs/realfs_test.go +++ b/pkg/fs/realfs_test.go @@ -17,18 +17,17 @@ limitations under the License. package fs import ( + "io/ioutil" "os" "path" + "path/filepath" "reflect" "testing" ) -func TestReadFilesRealFS(t *testing.T) { +func makeTestDir(t *testing.T) (FileSystem, string) { x := MakeRealFS() - testDir := "kustomize_testing_dir" - err := x.Mkdir(testDir) - defer os.RemoveAll(testDir) - + testDir, err := ioutil.TempDir("", "kustomize_testing_dir") if err != nil { t.Fatalf("unexpected error %s", err) } @@ -38,8 +37,113 @@ func TestReadFilesRealFS(t *testing.T) { if !x.IsDir(testDir) { t.Fatalf("expected directory") } + return x, testDir +} - err = x.WriteFile(path.Join(testDir, "foo"), []byte(`foo`)) +func TestCleanedAbs_1(t *testing.T) { + x, testDir := makeTestDir(t) + defer os.RemoveAll(testDir) + + d, f, err := x.CleanedAbs("") + if err != nil { + t.Fatalf("unexpected err=%v", err) + } + wd, err := os.Getwd() + if err != nil { + t.Fatalf("unexpected err=%v", err) + } + if d != wd { + t.Fatalf("unexpected d=%s", d) + } + if f != "" { + t.Fatalf("unexpected f=%s", f) + } +} + +func TestCleanedAbs_2(t *testing.T) { + x, testDir := makeTestDir(t) + defer os.RemoveAll(testDir) + + d, f, err := x.CleanedAbs("/") + if err != nil { + t.Fatalf("unexpected err=%v", err) + } + if d != "/" { + t.Fatalf("unexpected d=%s", d) + } + if f != "" { + t.Fatalf("unexpected f=%s", f) + } +} + +func TestCleanedAbs_3(t *testing.T) { + x, testDir := makeTestDir(t) + defer os.RemoveAll(testDir) + + err := x.WriteFile( + filepath.Join(testDir, "foo"), []byte(`foo`)) + if err != nil { + t.Fatalf("unexpected err=%v", err) + } + + d, f, err := x.CleanedAbs(filepath.Join(testDir, "foo")) + if err != nil { + t.Fatalf("unexpected err=%v", err) + } + if d != testDir { + t.Fatalf("unexpected d=%s", d) + } + if f != "foo" { + t.Fatalf("unexpected f=%s", f) + } + +} + +func TestCleanedAbs_4(t *testing.T) { + x, testDir := makeTestDir(t) + defer os.RemoveAll(testDir) + + err := x.MkdirAll(filepath.Join(testDir, "d1", "d2")) + if err != nil { + t.Fatalf("unexpected err=%v", err) + } + err = x.WriteFile( + filepath.Join(testDir, "d1", "d2", "bar"), + []byte(`bar`)) + if err != nil { + t.Fatalf("unexpected err=%v", err) + } + + d, f, err := x.CleanedAbs( + filepath.Join(testDir, "d1", "d2")) + if err != nil { + t.Fatalf("unexpected err=%v", err) + } + if d != filepath.Join(testDir, "d1", "d2") { + t.Fatalf("unexpected d=%s", d) + } + if f != "" { + t.Fatalf("unexpected f=%s", f) + } + + d, f, err = x.CleanedAbs( + filepath.Join(testDir, "d1", "d2", "bar")) + if err != nil { + t.Fatalf("unexpected err=%v", err) + } + if d != filepath.Join(testDir, "d1", "d2") { + t.Fatalf("unexpected d=%s", d) + } + if f != "bar" { + t.Fatalf("unexpected f=%s", f) + } +} + +func TestReadFilesRealFS(t *testing.T) { + x, testDir := makeTestDir(t) + defer os.RemoveAll(testDir) + + err := x.WriteFile(path.Join(testDir, "foo"), []byte(`foo`)) if err != nil { t.Fatalf("unexpected error %s", err) } diff --git a/pkg/loader/fileloader.go b/pkg/loader/fileloader.go index 9973e4e4b..0384020f8 100644 --- a/pkg/loader/fileloader.go +++ b/pkg/loader/fileloader.go @@ -123,11 +123,16 @@ func newFileLoaderAt( return nil, fmt.Errorf( "loader root cannot be empty") } - absRoot, err := cleanedAbs(root, fSys) + absRoot, f, err := fSys.CleanedAbs(root) if err != nil { return nil, fmt.Errorf( "absolute path error in '%s' : %v", root, err) } + if f != "" { + return nil, fmt.Errorf( + "got file '%s', but '%s' must be a directory to be a root", + f, root) + } if err := isPathEqualToOrAbove(absRoot, roots); err != nil { return nil, err } @@ -143,22 +148,6 @@ func newFileLoaderAt( }, nil } -// cleanedAbs returns a cleaned, absolute path -// with no symbolic links. -func cleanedAbs(path string, fSys fs.FileSystem) (string, error) { - absRoot, err := filepath.Abs(path) - if err != nil { - return "", fmt.Errorf( - "abs path error on '%s' : %v", path, err) - } - deLinked, err := fSys.EvalSymlinks(absRoot) - if err != nil { - return "", fmt.Errorf( - "evalsymlink failure on '%s' : %v", path, err) - } - return deLinked, nil -} - // New returns a new Loader, rooted relative to current loader, // or rooted in a temp directory holding a git repo clone. func (l *fileLoader) New(path string) (ifc.Loader, error) { @@ -226,11 +215,16 @@ func (l *fileLoader) Load(path string) ([]byte, error) { if filepath.IsAbs(path) { return nil, l.loadOutOfBounds(path) } - path, err := cleanedAbs( - filepath.Join(l.Root(), path), l.fSys) + d, f, err := l.fSys.CleanedAbs( + filepath.Join(l.Root(), path)) if err != nil { return nil, err } + if f == "" { + return nil, fmt.Errorf( + "'%s' must be a file (got d='%s')", path, d) + } + path = filepath.Join(d, f) if !l.isInOrBelowRoot(path) { return nil, l.loadOutOfBounds(path) } diff --git a/pkg/loader/fileloader_test.go b/pkg/loader/fileloader_test.go index bc94c2c09..f1e861005 100644 --- a/pkg/loader/fileloader_test.go +++ b/pkg/loader/fileloader_test.go @@ -75,7 +75,7 @@ func TestNewFileLoaderAt_DemandsDirectory(t *testing.T) { if err == nil { t.Fatalf("Expected error - a file should not work.") } - if !strings.Contains(err.Error(), "does not exist or is not a directory") { + if !strings.Contains(err.Error(), "must be a directory to be a root") { t.Fatalf("unexpected err: %v", err) } } diff --git a/pkg/resmap/factory_test.go b/pkg/resmap/factory_test.go index 8d4cb0d54..27e12b86d 100644 --- a/pkg/resmap/factory_test.go +++ b/pkg/resmap/factory_test.go @@ -145,7 +145,7 @@ func TestNewFromConfigMaps(t *testing.T) { expected ResMap } - l := loadertest.NewFakeLoader("/whatever/project/") + l := loadertest.NewFakeLoader("/whatever/project") testCases := []testCase{ { description: "construct config map from env", From c461f1f76677098daf83e4036a227f540fdd4329 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Fri, 25 Jan 2019 14:26:17 -0800 Subject: [PATCH 073/317] remove patches and imageTags from kustomization.yaml --- docs/kustomization.yaml | 23 +-- pkg/commands/edit/set/all.go | 1 - pkg/commands/edit/set/setimage.go | 3 + pkg/commands/edit/set/setimagetag.go | 132 ------------------ pkg/commands/edit/set/setimagetag_test.go | 101 -------------- pkg/commands/kustfile/kustomizationfile.go | 4 +- .../kustfile/kustomizationfile_test.go | 47 ------- pkg/target/baseandoverlaymedium_test.go | 2 +- pkg/target/baseandoverlaysmall_test.go | 2 +- pkg/target/kusttarget.go | 3 +- pkg/types/kustomization.go | 50 +++---- 11 files changed, 24 insertions(+), 344 deletions(-) delete mode 100644 pkg/commands/edit/set/setimagetag.go delete mode 100644 pkg/commands/edit/set/setimagetag_test.go diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index 377d7837c..15f03864c 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -156,7 +156,7 @@ bases: # a memory request/limit, change an env var in a # ConfigMap, etc. Small patches are easy to review and # easy to mix together in overlays. -patches: +patchesStrategicMerge: - service_port_8888.yaml - deployment_increase_replicas.yaml - deployment_increase_memory.yaml @@ -311,24 +311,3 @@ images: newName: my-app - name: alpine digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 - -# ImageTags is deprecated, instead use Image. -# ImageTags modify the tags for images without creating patches. -# E.g. Given this fragment of a Deployment: -# ``` -# containers: -# - name: myapp -# image: mycontainerregistry/myimage:v0 -# - name: nginxapp -# image: nginx:1.7.9 -#``` -# one can change the tag of myimage to v1 and the tag of nginx to 1.8.0 with the following: -# -# It also supports digests. If digest is present newTag is ignored. -imageTags: - - name: mycontainerregistry/myimage - newTag: v1 - - name: nginx - newTag: 1.8.0 - - name: alpine - digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 diff --git a/pkg/commands/edit/set/all.go b/pkg/commands/edit/set/all.go index ed78b06ff..0ac085711 100644 --- a/pkg/commands/edit/set/all.go +++ b/pkg/commands/edit/set/all.go @@ -42,7 +42,6 @@ func NewCmdSet(fsys fs.FileSystem, v ifc.Validator) *cobra.Command { newCmdSetNamePrefix(fsys), newCmdSetNameSuffix(fsys), newCmdSetNamespace(fsys, v), - newCmdSetImageTag(fsys), newCmdSetImage(fsys), ) return c diff --git a/pkg/commands/edit/set/setimage.go b/pkg/commands/edit/set/setimage.go index 8454ab0f8..e861504f5 100644 --- a/pkg/commands/edit/set/setimage.go +++ b/pkg/commands/edit/set/setimage.go @@ -18,6 +18,7 @@ package set import ( "errors" + "regexp" "sort" "strings" @@ -31,6 +32,8 @@ type setImageOptions struct { imageMap map[string]image.Image } +var pattern = regexp.MustCompile("^(.*):([a-zA-Z0-9._-]*)$") + // errors var ( diff --git a/pkg/commands/edit/set/setimagetag.go b/pkg/commands/edit/set/setimagetag.go deleted file mode 100644 index 2c8e5db32..000000000 --- a/pkg/commands/edit/set/setimagetag.go +++ /dev/null @@ -1,132 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package set - -import ( - "errors" - "log" - "regexp" - "sort" - "strings" - - "github.com/spf13/cobra" - "sigs.k8s.io/kustomize/pkg/commands/kustfile" - "sigs.k8s.io/kustomize/pkg/fs" - "sigs.k8s.io/kustomize/pkg/image" -) - -type setImageTagOptions struct { - imageTagMap map[string]image.ImageTag -} - -var pattern = regexp.MustCompile("^(.*):([a-zA-Z0-9._-]*)$") - -// newCmdSetImageTag sets the new tags for images in the kustomization. -func newCmdSetImageTag(fsys fs.FileSystem) *cobra.Command { - var o setImageTagOptions - - cmd := &cobra.Command{ - Use: "imagetag", - Short: "The `imagetag` command is deprecated, instead use `edit set image`.", - Example: ` -The command - set imagetag nginx:1.8.0 my-app:latest alpine@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 -will add - -imageTags: -- name: nginx - newTag: 1.8.0 -- name: my-app - newTag: latest -- name: alpine - digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 - -to the kustomization file if it doesn't exist, -and overwrite the previous ones if the image tag exists. -`, - RunE: func(cmd *cobra.Command, args []string) error { - log.Print(cmd.Short) - err := o.Validate(args) - if err != nil { - return err - } - return o.RunSetImageTags(fsys) - }, - } - return cmd -} - -// Validate validates setImageTag command. -func (o *setImageTagOptions) Validate(args []string) error { - if len(args) == 0 { - return errors.New("no image specified") - } - - o.imageTagMap = make(map[string]image.ImageTag) - - for _, arg := range args { - if s := strings.Split(arg, "@"); len(s) > 1 { - o.imageTagMap[s[0]] = image.ImageTag{ - Name: s[0], - Digest: s[1], - } - continue - } - - s := pattern.FindStringSubmatch(arg) - if len(s) != 3 { - return errors.New("invalid format of imagetag, must specify it as : or @") - } - o.imageTagMap[s[1]] = image.ImageTag{ - Name: s[1], - NewTag: s[2], - } - } - return nil -} - -// RunSetImageTags runs setImageTags command (does real work). -func (o *setImageTagOptions) RunSetImageTags(fSys fs.FileSystem) error { - mf, err := kustfile.NewKustomizationFile(fSys) - if err != nil { - return err - } - m, err := mf.Read() - if err != nil { - return err - } - - for _, it := range m.ImageTags { - if _, ok := o.imageTagMap[it.Name]; ok { - continue - } - - o.imageTagMap[it.Name] = it - } - - var imageTags []image.ImageTag - for _, v := range o.imageTagMap { - imageTags = append(imageTags, v) - } - sort.Slice(imageTags, func(i, j int) bool { - return imageTags[i].Name < imageTags[j].Name - }) - - m.ImageTags = imageTags - - return mf.Write(m) -} diff --git a/pkg/commands/edit/set/setimagetag_test.go b/pkg/commands/edit/set/setimagetag_test.go deleted file mode 100644 index b70d57c3c..000000000 --- a/pkg/commands/edit/set/setimagetag_test.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package set - -import ( - "strings" - "testing" - - "sigs.k8s.io/kustomize/pkg/fs" -) - -func TestSetImageTagsHappyPath(t *testing.T) { - fakeFS := fs.MakeFakeFS() - fakeFS.WriteTestKustomization() - - cmd := newCmdSetImageTag(fakeFS) - args := []string{"image1:tag1", "image2:tag2", "localhost:5000/operator:1.0.0", - "foo.bar.baz:5000/one/two@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"} - err := cmd.RunE(cmd, args) - if err != nil { - t.Errorf("unexpected cmd error: %v", err) - } - content, err := fakeFS.ReadTestKustomization() - if err != nil { - t.Errorf("unexpected read error: %v", err) - } - expected := []byte(` -imageTags: -- digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 - name: foo.bar.baz:5000/one/two -- name: image1 - newTag: tag1 -- name: image2 - newTag: tag2 -- name: localhost:5000/operator - newTag: 1.0.0 -`) - if !strings.Contains(string(content), string(expected)) { - t.Errorf("expected imageTags in kustomization file") - } -} - -func TestSetImageTagsOverride(t *testing.T) { - fakeFS := fs.MakeFakeFS() - fakeFS.WriteTestKustomization() - - cmd := newCmdSetImageTag(fakeFS) - args := []string{"image1:tag1", "image2:tag1"} - err := cmd.RunE(cmd, args) - if err != nil { - t.Errorf("unexpected cmd error: %v", err) - } - args = []string{"image2:tag2", "image3:tag3"} - err = cmd.RunE(cmd, args) - if err != nil { - t.Errorf("unexpected cmd error: %v", err) - } - content, err := fakeFS.ReadTestKustomization() - if err != nil { - t.Errorf("unexpected read error: %v", err) - } - expected := []byte(` -imageTags: -- name: image1 - newTag: tag1 -- name: image2 - newTag: tag2 -- name: image3 - newTag: tag3 -`) - if !strings.Contains(string(content), string(expected)) { - t.Errorf("expected imageTags in kustomization file %s", string(content)) - } -} - -func TestSetImageTagsNoArgs(t *testing.T) { - fakeFS := fs.MakeFakeFS() - - cmd := newCmdSetImageTag(fakeFS) - err := cmd.Execute() - if err == nil { - t.Errorf("expected error: %v", err) - } - if err.Error() != "no image specified" { - t.Errorf("incorrect error: %v", err.Error()) - } -} diff --git a/pkg/commands/kustfile/kustomizationfile.go b/pkg/commands/kustfile/kustomizationfile.go index 177ec604f..108170782 100644 --- a/pkg/commands/kustfile/kustomizationfile.go +++ b/pkg/commands/kustfile/kustomizationfile.go @@ -59,7 +59,6 @@ func determineFieldOrder() []string { "Crds", "CommonLabels", "CommonAnnotations", - "Patches", "PatchesStrategicMerge", "PatchesJson6902", "ConfigMapGenerator", @@ -67,7 +66,6 @@ func determineFieldOrder() []string { "GeneratorOptions", "Vars", "Images", - "ImageTags", "Configurations", } @@ -148,12 +146,12 @@ func (mf *kustomizationFile) Read() (*types.Kustomization, error) { if err != nil { return nil, err } + data = types.DealWithDeprecatedFields(data) var k types.Kustomization err = yaml.Unmarshal(data, &k) if err != nil { return nil, err } - k.DealWithDeprecatedFields() msgs := k.DealWithMissingFields() if len(msgs) > 0 { log.Printf(strings.Join(msgs, "\n")) diff --git a/pkg/commands/kustfile/kustomizationfile_test.go b/pkg/commands/kustfile/kustomizationfile_test.go index b1b1cc42a..80d9ca84f 100644 --- a/pkg/commands/kustfile/kustomizationfile_test.go +++ b/pkg/commands/kustfile/kustomizationfile_test.go @@ -45,7 +45,6 @@ func TestFieldOrder(t *testing.T) { "GeneratorOptions", "Vars", "Images", - "ImageTags", "Configurations", } actual := determineFieldOrder() @@ -85,52 +84,6 @@ func TestWriteAndRead(t *testing.T) { } } -// Deprecated fields should not survive being read. -func TestDeprecationOfPatches(t *testing.T) { - hasDeprecatedFields := []byte(` -namePrefix: acme -nameSuffix: emca -patches: -- alice -patchesStrategicMerge: -- bob -`) - fSys := fs.MakeFakeFS() - fSys.WriteTestKustomizationWith(hasDeprecatedFields) - mf, err := NewKustomizationFile(fSys) - if err != nil { - t.Fatalf("Unexpected Error: %v", err) - } - k, err := mf.Read() - if err != nil { - t.Fatalf("Couldn't read kustomization file: %v\n", err) - } - if k.NamePrefix != "acme" { - t.Fatalf("Unexpected name prefix") - } - if k.NameSuffix != "emca" { - t.Fatalf("Unexpected name suffix") - } - if len(k.Patches) > 0 { - t.Fatalf("Expected nothing in Patches.") - } - if len(k.PatchesStrategicMerge) != 2 { - t.Fatalf( - "Expected len(k.PatchesStrategicMerge) == 2, got %d", - len(k.PatchesStrategicMerge)) - } - m := make(map[string]bool) - for _, v := range k.PatchesStrategicMerge { - m[string(v)] = true - } - if _, f := m["alice"]; !f { - t.Fatalf("Expected alice in PatchesStrategicMerge") - } - if _, f := m["bob"]; !f { - t.Fatalf("Expected bob in PatchesStrategicMerge") - } -} - func TestNewNotExist(t *testing.T) { fakeFS := fs.MakeFakeFS() _, err := NewKustomizationFile(fakeFS) diff --git a/pkg/target/baseandoverlaymedium_test.go b/pkg/target/baseandoverlaymedium_test.go index fe2bf19bb..24f9558a4 100644 --- a/pkg/target/baseandoverlaymedium_test.go +++ b/pkg/target/baseandoverlaymedium_test.go @@ -162,7 +162,7 @@ configMapGenerator: - name: app-config files: - configmap/app-init.ini -imageTags: +images: - name: nginx newTag: 1.8.0`) diff --git a/pkg/target/baseandoverlaysmall_test.go b/pkg/target/baseandoverlaysmall_test.go index a8c72b7e6..d9cbdb3fe 100644 --- a/pkg/target/baseandoverlaysmall_test.go +++ b/pkg/target/baseandoverlaysmall_test.go @@ -111,7 +111,7 @@ bases: - ../base patchesStrategicMerge: - deployment/deployment.yaml -imageTags: +images: - name: whatever newTag: 1.8.0 `) diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 2dd0b2f02..138ffeaa6 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -58,13 +58,12 @@ func NewKustTarget( if err != nil { return nil, err } - + content = types.DealWithDeprecatedFields(content) var k types.Kustomization err = unmarshal(content, &k) if err != nil { return nil, err } - k.DealWithDeprecatedFields() msgs, errs := k.EnforceFields() if len(errs) > 0 { return nil, fmt.Errorf(strings.Join(errs, "\n")) diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index c59f550e9..4c75b0a43 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -18,6 +18,8 @@ limitations under the License. package types import ( + "regexp" + "sigs.k8s.io/kustomize/pkg/image" "sigs.k8s.io/kustomize/pkg/patch" ) @@ -128,40 +130,6 @@ type Kustomization struct { // Configurations is a list of transformer configuration files Configurations []string `json:"configurations,omitempty" yaml:"configurations,omitempty"` - - // - // Deprecated fields - See DealWithDeprecatedFields - // - - // Deprecated. - Patches []string `json:"patches,omitempty" yaml:"patches,omitempty"` - - // Deprecated. Use `Image` - ImageTags []image.ImageTag `json:"imageTags,omitempty" yaml:"imageTags,omitempty"` -} - -// DealWithDeprecatedFields should be called immediately after -// loading from storage. -func (k *Kustomization) DealWithDeprecatedFields() { - if len(k.Patches) > 0 { - // The Patches field, meant to hold strategic merge - // patches, is deprecated. Append anything found - // there to the PatchesStrategicMerge field. - // This happened when the PatchesJson6902 field - // was introduced. - k.PatchesStrategicMerge = patch.Append( - k.PatchesStrategicMerge, k.Patches...) - k.Patches = []string{} - } - - if len(k.ImageTags) > 0 { - // Transform `ImageTag` to `Image` - // for backwards compatibility - // images are appended first to keep - // higher precedence - k.Images = image.Append( - k.Images, k.ImageTags...) - } } // DealWithMissingFields fills the missing fields @@ -193,6 +161,20 @@ func (k *Kustomization) EnforceFields() ([]string, []string) { return msgs, errs } +// DealWithDeprecatedFields should be called immediately after +// loading from storage. +func DealWithDeprecatedFields(data []byte) []byte { + deprecateFieldsMap := map[string]string{ + "patches:": "patchesStrategicMerge:", + "imageTags:": "images:", + } + for oldname, newname := range deprecateFieldsMap { + pattern := regexp.MustCompile(oldname) + data = pattern.ReplaceAll(data, []byte(newname)) + } + return data +} + // GeneratorArgs contains arguments common to generators. type GeneratorArgs struct { // Namespace for the configmap, optional From dcb5682594dbbe837a4204f32ec28b2aa8f039bf Mon Sep 17 00:00:00 2001 From: jregan Date: Thu, 24 Jan 2019 19:55:44 -0800 Subject: [PATCH 074/317] Add more coverage for loader and strengthen type safety. --- pkg/fs/confirmeddir.go | 58 +++++++++++++ pkg/fs/confirmeddir_test.go | 87 +++++++++++++++++++ pkg/fs/fakefs.go | 10 +-- pkg/fs/fs.go | 2 +- pkg/fs/realfs.go | 7 +- pkg/fs/realfs_test.go | 8 +- pkg/loader/fileloader.go | 158 ++++++++++++++++------------------ pkg/loader/fileloader_test.go | 6 +- pkg/loader/gitcloner_test.go | 6 +- pkg/loader/loader.go | 4 +- 10 files changed, 243 insertions(+), 103 deletions(-) create mode 100644 pkg/fs/confirmeddir.go create mode 100644 pkg/fs/confirmeddir_test.go diff --git a/pkg/fs/confirmeddir.go b/pkg/fs/confirmeddir.go new file mode 100644 index 000000000..9774bb846 --- /dev/null +++ b/pkg/fs/confirmeddir.go @@ -0,0 +1,58 @@ +package fs + +import ( + "path/filepath" + "strings" +) + +// ConfirmedDir is a clean, absolute, delinkified path +// that was confirmed to point to an existing directory. +type ConfirmedDir string + +// HasPrefix returns true if the directory argument +// is a prefix of self (d) from the point of view of +// a file system. +// +// I.e., it's true if the argument equals or contains +// self (d) in a file path sense. +// +// HasPrefix emulates the semantics of strings.HasPrefix +// such that the following are true: +// +// strings.HasPrefix("foobar", "foobar") +// strings.HasPrefix("foobar", "foo") +// strings.HasPrefix("foobar", "") +// +// d := fSys.ConfirmDir("/foo/bar") +// d.HasPrefix("/foo/bar") +// d.HasPrefix("/foo") +// d.HasPrefix("/") +// +// Not contacting a file system here to check for +// actual path existence. +// +// This is tested on linux, but will have trouble +// on other operating systems. As soon as related +// work is completed in the core filepath package, +// this code should be refactored to use it. +// See: +// https://github.com/golang/go/issues/18355 +// https://github.com/golang/dep/issues/296 +// https://github.com/golang/dep/blob/master/internal/fs/fs.go#L33 +// https://codereview.appspot.com/5712045 +func (d ConfirmedDir) HasPrefix(path ConfirmedDir) bool { + if path.String() == string(filepath.Separator) || path == d { + return true + } + return strings.HasPrefix( + string(d), + string(path)+string(filepath.Separator)) +} + +func (d ConfirmedDir) Join(path string) string { + return filepath.Join(string(d), path) +} + +func (d ConfirmedDir) String() string { + return string(d) +} diff --git a/pkg/fs/confirmeddir_test.go b/pkg/fs/confirmeddir_test.go new file mode 100644 index 000000000..1f097b14e --- /dev/null +++ b/pkg/fs/confirmeddir_test.go @@ -0,0 +1,87 @@ +package fs + +import ( + "testing" +) + +func TestJoin(t *testing.T) { + fSys := MakeFakeFS() + err := fSys.Mkdir("/foo") + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + d, f, err := fSys.CleanedAbs("/foo") + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + if f != "" { + t.Fatalf("unexpected file: %v", f) + } + if d.Join("bar") != "/foo/bar" { + t.Fatalf("expected join %s", d.Join("bar")) + } +} + +func TestHasPrefix_Slash(t *testing.T) { + d, f, err := MakeFakeFS().CleanedAbs("/") + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + if f != "" { + t.Fatalf("unexpected file: %v", f) + } + if d.HasPrefix("/hey") { + t.Fatalf("should be false") + } + if !d.HasPrefix("/") { + t.Fatalf("/ should have the prefix /") + } +} + +func TestHasPrefix_SlashFoo(t *testing.T) { + fSys := MakeFakeFS() + err := fSys.Mkdir("/foo") + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + d, _, err := fSys.CleanedAbs("/foo") + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + if d.HasPrefix("/fo") { + t.Fatalf("/foo does not have path prefix /fo") + } + if d.HasPrefix("/fod") { + t.Fatalf("/foo does not have path prefix /fod") + } + if !d.HasPrefix("/foo") { + t.Fatalf("/foo should have prefix /foo") + } +} + +func TestHasPrefix_SlashFooBar(t *testing.T) { + fSys := MakeFakeFS() + err := fSys.MkdirAll("/foo/bar") + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + d, _, err := fSys.CleanedAbs("/foo/bar") + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + if d.HasPrefix("/fo") { + t.Fatalf("/foo/bar does not have path prefix /fo") + } + if d.HasPrefix("/foobar") { + t.Fatalf("/foo/bar does not have path prefix /foobar") + } + if !d.HasPrefix("/foo/bar") { + t.Fatalf("/foo/bar should have prefix /foo/bar") + } + if !d.HasPrefix("/foo") { + t.Fatalf("/foo/bar should have prefix /foo") + } + if !d.HasPrefix("/") { + t.Fatalf("/foo/bar should have prefix /") + } +} diff --git a/pkg/fs/fakefs.go b/pkg/fs/fakefs.go index 37669ed15..1a8fad667 100644 --- a/pkg/fs/fakefs.go +++ b/pkg/fs/fakefs.go @@ -102,16 +102,16 @@ func (fs *fakeFs) Open(name string) (File, error) { return fs.m[name], nil } -// CleanedAbs does nothing and cannot fail. -func (fs *fakeFs) CleanedAbs(path string) (string, string, error) { +// CleanedAbs cannot fail. +func (fs *fakeFs) CleanedAbs(path string) (ConfirmedDir, string, error) { if fs.IsDir(path) { - return path, "", nil + return ConfirmedDir(path), "", nil } d := filepath.Dir(path) if d == path { - return d, "", nil + return ConfirmedDir(d), "", nil } - return d, filepath.Base(path), nil + return ConfirmedDir(d), filepath.Base(path), nil } // Exists returns true if file is known. diff --git a/pkg/fs/fs.go b/pkg/fs/fs.go index 65f5e0148..4b47dba64 100644 --- a/pkg/fs/fs.go +++ b/pkg/fs/fs.go @@ -30,7 +30,7 @@ type FileSystem interface { RemoveAll(name string) error Open(name string) (File, error) IsDir(name string) bool - CleanedAbs(path string) (string, string, error) + CleanedAbs(path string) (ConfirmedDir, string, error) Exists(name string) bool Glob(pattern string) ([]string, error) ReadFile(name string) ([]byte, error) diff --git a/pkg/fs/realfs.go b/pkg/fs/realfs.go index 75f6f2987..11e5813b7 100644 --- a/pkg/fs/realfs.go +++ b/pkg/fs/realfs.go @@ -60,7 +60,8 @@ func (realFS) Open(name string) (File, error) { return os.Open(name) } // and file components. If the entire path is // a directory, the file component is an empty // string. -func (x realFS) CleanedAbs(path string) (string, string, error) { +func (x realFS) CleanedAbs( + path string) (ConfirmedDir, string, error) { absRoot, err := filepath.Abs(path) if err != nil { return "", "", fmt.Errorf( @@ -72,7 +73,7 @@ func (x realFS) CleanedAbs(path string) (string, string, error) { "evalsymlink failure on '%s' : %v", path, err) } if x.IsDir(deLinked) { - return deLinked, "", nil + return ConfirmedDir(deLinked), "", nil } d := filepath.Dir(deLinked) if !x.IsDir(d) { @@ -89,7 +90,7 @@ func (x realFS) CleanedAbs(path string) (string, string, error) { log.Fatalf("these should be equal: '%s', '%s'", filepath.Join(d, f), deLinked) } - return d, f, nil + return ConfirmedDir(d), f, nil } // Exists returns true if os.Stat succeeds. diff --git a/pkg/fs/realfs_test.go b/pkg/fs/realfs_test.go index 7add5fb64..74bc318cd 100644 --- a/pkg/fs/realfs_test.go +++ b/pkg/fs/realfs_test.go @@ -52,7 +52,7 @@ func TestCleanedAbs_1(t *testing.T) { if err != nil { t.Fatalf("unexpected err=%v", err) } - if d != wd { + if d.String() != wd { t.Fatalf("unexpected d=%s", d) } if f != "" { @@ -90,7 +90,7 @@ func TestCleanedAbs_3(t *testing.T) { if err != nil { t.Fatalf("unexpected err=%v", err) } - if d != testDir { + if d.String() != testDir { t.Fatalf("unexpected d=%s", d) } if f != "foo" { @@ -119,7 +119,7 @@ func TestCleanedAbs_4(t *testing.T) { if err != nil { t.Fatalf("unexpected err=%v", err) } - if d != filepath.Join(testDir, "d1", "d2") { + if d.String() != filepath.Join(testDir, "d1", "d2") { t.Fatalf("unexpected d=%s", d) } if f != "" { @@ -131,7 +131,7 @@ func TestCleanedAbs_4(t *testing.T) { if err != nil { t.Fatalf("unexpected err=%v", err) } - if d != filepath.Join(testDir, "d1", "d2") { + if d.String() != filepath.Join(testDir, "d1", "d2") { t.Fatalf("unexpected d=%s", d) } if f != "bar" { diff --git a/pkg/loader/fileloader.go b/pkg/loader/fileloader.go index 0384020f8..02864582c 100644 --- a/pkg/loader/fileloader.go +++ b/pkg/loader/fileloader.go @@ -78,10 +78,16 @@ import ( // from /etc/passwd will fail. // type fileLoader struct { - // Previously visited absolute directory paths. - // Tracked to avoid cycles. - // The last entry is the current root. - roots []string + // Loader that spawned this loader. + // Used to avoid cycles. + referrer *fileLoader + // An absolute, cleaned path to a directory. + // The Load function reads from this directory, + // or directories below it. + root fs.ConfirmedDir + // URI, if any, used for a download into root. + // TODO(monopole): use non-string type. + uri string // File system utilities. fSys fs.FileSystem // Used to clone repositories. @@ -103,12 +109,12 @@ func NewFileLoaderAtRoot(fSys fs.FileSystem) *fileLoader { // Root returns the absolute path that is prepended to any // relative paths used in Load. func (l *fileLoader) Root() string { - return l.roots[len(l.roots)-1] + return l.root.String() } func newLoaderOrDie(fSys fs.FileSystem, path string) *fileLoader { l, err := newFileLoaderAt( - path, fSys, []string{}, simpleGitCloner) + path, fSys, nil, simpleGitCloner) if err != nil { log.Fatalf("unable to make loader at '%s'; %v", path, err) } @@ -117,34 +123,33 @@ func newLoaderOrDie(fSys fs.FileSystem, path string) *fileLoader { // newFileLoaderAt returns a new fileLoader with given root. func newFileLoaderAt( - root string, fSys fs.FileSystem, - roots []string, cloner gitCloner) (*fileLoader, error) { - if root == "" { + possibleRoot string, fSys fs.FileSystem, + referrer *fileLoader, cloner gitCloner) (*fileLoader, error) { + if possibleRoot == "" { return nil, fmt.Errorf( "loader root cannot be empty") } - absRoot, f, err := fSys.CleanedAbs(root) + root, f, err := fSys.CleanedAbs(possibleRoot) if err != nil { return nil, fmt.Errorf( - "absolute path error in '%s' : %v", root, err) + "absolute path error in '%s' : %v", possibleRoot, err) } if f != "" { return nil, fmt.Errorf( "got file '%s', but '%s' must be a directory to be a root", - f, root) + f, possibleRoot) } - if err := isPathEqualToOrAbove(absRoot, roots); err != nil { - return nil, err - } - if !fSys.IsDir(absRoot) { - return nil, fmt.Errorf( - "'%s' does not exist or is not a directory", absRoot) + if referrer != nil { + if err := referrer.errIfArgEqualOrHigher(root); err != nil { + return nil, err + } } return &fileLoader{ - roots: append(roots, absRoot), - fSys: fSys, - cloner: cloner, - cleaner: func() error { return nil }, + root: root, + referrer: referrer, + fSys: fSys, + cloner: cloner, + cleaner: func() error { return nil }, }, nil } @@ -155,68 +160,82 @@ func (l *fileLoader) New(path string) (ifc.Loader, error) { return nil, fmt.Errorf("new root cannot be empty") } if isRepoUrl(path) { - // This works well enough for purpose at hand to detect - // previously visited URLs and thus avoid cycles. - if err := isPathEqualToOrAbove(path, l.roots); err != nil { + // Avoid cycles. + if err := l.errIfPreviouslySeenUri(path); err != nil { return nil, err } - return newGitLoader(path, l.fSys, l.roots, l.cloner) + return newGitLoader(path, l.fSys, l.referrer, l.cloner) } if filepath.IsAbs(path) { return nil, fmt.Errorf("new root '%s' cannot be absolute", path) } return newFileLoaderAt( - filepath.Join(l.Root(), path), l.fSys, l.roots, l.cloner) + l.root.Join(path), l.fSys, l, l.cloner) } // newGitLoader returns a new Loader pinned to a temporary // directory holding a cloned git repo. func newGitLoader( - root string, fSys fs.FileSystem, - roots []string, cloner gitCloner) (ifc.Loader, error) { - tmpDirForRepo, pathInRepo, err := cloner(root) + uri string, fSys fs.FileSystem, + referrer *fileLoader, cloner gitCloner) (ifc.Loader, error) { + tmpDirForRepo, pathInRepo, err := cloner(uri) if err != nil { return nil, err } - trueRoot := filepath.Join(tmpDirForRepo, pathInRepo) - if !fSys.IsDir(trueRoot) { + root, f, err := fSys.CleanedAbs( + filepath.Join(tmpDirForRepo, pathInRepo)) + if err != nil { + return nil, err + } + if f != "" { return nil, fmt.Errorf( - "something wrong cloning '%s'; unable to find '%s'", - root, trueRoot) + "'%s' refers to file '%s'; expecting directory", pathInRepo, f) } return &fileLoader{ - roots: append(roots, root, trueRoot), - fSys: fSys, - cloner: cloner, - cleaner: func() error { return fSys.RemoveAll(tmpDirForRepo) }, + root: root, + referrer: referrer, + uri: uri, + fSys: fSys, + cloner: cloner, + cleaner: func() error { return fSys.RemoveAll(tmpDirForRepo) }, }, nil } -// isPathEqualToOrAbove tests whether the 1st argument, -// viewed as a path to a directory, is equal to or above -// any of the paths in the 2nd argument. It's assumed -// that all paths are cleaned, delinkified and absolute. -func isPathEqualToOrAbove(path string, roots []string) error { - terminated := path + string(filepath.Separator) - for _, r := range roots { - if r == path || strings.HasPrefix(r, terminated) { - return fmt.Errorf( - "cycle detected: new root '%s' contains previous root '%s'", - path, r) - } +// errIfArgEqualOrHigher tests whether the argument, +// is equal to or above the root of any ancestor. +func (l *fileLoader) errIfArgEqualOrHigher( + candidateRoot fs.ConfirmedDir) error { + if l.root.HasPrefix(candidateRoot) { + return fmt.Errorf( + "cycle detected: candidate root '%s' contains visited root '%s'", + candidateRoot, l.root) } - return nil + if l.referrer == nil { + return nil + } + return l.referrer.errIfArgEqualOrHigher(candidateRoot) +} + +func (l *fileLoader) errIfPreviouslySeenUri(uri string) error { + if strings.HasPrefix(l.uri, uri) { + return fmt.Errorf( + "cycle detected: URI '%s' referenced by previous URI '%s'", + uri, l.uri) + } + if l.referrer == nil { + return nil + } + return l.referrer.errIfPreviouslySeenUri(uri) } // Load returns content of file at the given relative path, // else an error. The path must refer to a file in or -// below the current Root(). +// below the current root. func (l *fileLoader) Load(path string) ([]byte, error) { if filepath.IsAbs(path) { return nil, l.loadOutOfBounds(path) } - d, f, err := l.fSys.CleanedAbs( - filepath.Join(l.Root(), path)) + d, f, err := l.fSys.CleanedAbs(l.root.Join(path)) if err != nil { return nil, err } @@ -224,41 +243,16 @@ func (l *fileLoader) Load(path string) ([]byte, error) { return nil, fmt.Errorf( "'%s' must be a file (got d='%s')", path, d) } - path = filepath.Join(d, f) - if !l.isInOrBelowRoot(path) { + if !d.HasPrefix(l.root) { return nil, l.loadOutOfBounds(path) } - return l.fSys.ReadFile(path) -} - -// isInOrBelowRoot is true if the argument is in or -// below Root() from purely a path perspective (no -// check for actual file existence). For this to work, -// both the given argument "path" and l.Root() must -// be cleaned, absolute paths, and l.Root() must be -// a directory. Both conditions enforced elsewhere. -// -// This is tested on linux, but will have trouble -// on other operating systems. As soon as related -// work is completed in the core filepath package, -// this code should be refactored to use it. -// See: -// https://github.com/golang/go/issues/18355 -// https://github.com/golang/dep/issues/296 -// https://github.com/golang/dep/blob/master/internal/fs/fs.go#L33 -// https://codereview.appspot.com/5712045 -func (l *fileLoader) isInOrBelowRoot(path string) bool { - if l.Root() == string(filepath.Separator) { - return true - } - return strings.HasPrefix( - path, l.Root()+string(filepath.Separator)) + return l.fSys.ReadFile(d.Join(f)) } func (l *fileLoader) loadOutOfBounds(path string) error { return fmt.Errorf( "security; file '%s' is not in or below '%s'", - path, l.Root()) + path, l.root) } // Cleanup runs the cleaner. diff --git a/pkg/loader/fileloader_test.go b/pkg/loader/fileloader_test.go index f1e861005..82ca48d8d 100644 --- a/pkg/loader/fileloader_test.go +++ b/pkg/loader/fileloader_test.go @@ -63,15 +63,15 @@ func MakeFakeFs(td []testData) fs.FileSystem { func TestNewFileLoaderAt_DemandsDirectory(t *testing.T) { fSys := MakeFakeFs(testCases) - _, err := newFileLoaderAt("/foo", fSys, []string{}, nil) + _, err := newFileLoaderAt("/foo", fSys, nil, nil) if err != nil { t.Fatalf("Unexpected error - a directory should work.") } - _, err = newFileLoaderAt("/foo/project", fSys, []string{}, nil) + _, err = newFileLoaderAt("/foo/project", fSys, nil, nil) if err != nil { t.Fatalf("Unexpected error - a directory should work.") } - _, err = newFileLoaderAt("/foo/project/fileA.yaml", fSys, []string{}, nil) + _, err = newFileLoaderAt("/foo/project/fileA.yaml", fSys, nil, nil) if err == nil { t.Fatalf("Expected error - a file should not work.") } diff --git a/pkg/loader/gitcloner_test.go b/pkg/loader/gitcloner_test.go index 2c5df4474..a3867ca03 100644 --- a/pkg/loader/gitcloner_test.go +++ b/pkg/loader/gitcloner_test.go @@ -167,7 +167,7 @@ func TestGitLoader(t *testing.T) { whatever `)) l, err := newGitLoader( - url, fSys, []string{}, + url, fSys, nil, makeFakeGitCloner(t, fSys, coRoot)) if err != nil { t.Fatalf("unexpected err: %v\n", err) @@ -177,10 +177,10 @@ whatever coRoot+"/"+pathInRepo, l.Root()) } if _, err = l.New(url); err == nil { - t.Fatalf("expected cycle error") + t.Fatalf("expected cycle error 1") } if _, err = l.New(rootUrl + "/" + "foo"); err == nil { - t.Fatalf("expected cycle error") + t.Fatalf("expected cycle error 2") } pathInRepo = "foo/overlay" diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index 5e954095d..5e5aa8664 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -26,8 +26,8 @@ import ( func NewLoader(root string, fSys fs.FileSystem) (ifc.Loader, error) { if isRepoUrl(root) { return newGitLoader( - root, fSys, []string{}, simpleGitCloner) + root, fSys, nil, simpleGitCloner) } return newFileLoaderAt( - root, fSys, []string{}, simpleGitCloner) + root, fSys, nil, simpleGitCloner) } From fd3cd4756281797eb09481ea94491f8e0230f432 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Fri, 25 Jan 2019 16:05:40 -0800 Subject: [PATCH 075/317] Fix copyright, add TODOs --- pkg/fs/confirmeddir.go | 25 ++++++++++++++++++++----- pkg/fs/confirmeddir_test.go | 16 ++++++++++++++++ pkg/loader/fileloader.go | 4 ++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/pkg/fs/confirmeddir.go b/pkg/fs/confirmeddir.go index 9774bb846..a07335a89 100644 --- a/pkg/fs/confirmeddir.go +++ b/pkg/fs/confirmeddir.go @@ -1,3 +1,19 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package fs import ( @@ -32,11 +48,10 @@ type ConfirmedDir string // actual path existence. // // This is tested on linux, but will have trouble -// on other operating systems. As soon as related -// work is completed in the core filepath package, -// this code should be refactored to use it. -// See: -// https://github.com/golang/go/issues/18355 +// on other operating systems. +// TODO(monopole) Refactor when #golang/go/18358 closes. +// See also: +// https://github.com/golang/go/issues/18358 // https://github.com/golang/dep/issues/296 // https://github.com/golang/dep/blob/master/internal/fs/fs.go#L33 // https://codereview.appspot.com/5712045 diff --git a/pkg/fs/confirmeddir_test.go b/pkg/fs/confirmeddir_test.go index 1f097b14e..eddc2a198 100644 --- a/pkg/fs/confirmeddir_test.go +++ b/pkg/fs/confirmeddir_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package fs import ( diff --git a/pkg/loader/fileloader.go b/pkg/loader/fileloader.go index 02864582c..1d4e1e98b 100644 --- a/pkg/loader/fileloader.go +++ b/pkg/loader/fileloader.go @@ -216,6 +216,10 @@ func (l *fileLoader) errIfArgEqualOrHigher( return l.referrer.errIfArgEqualOrHigher(candidateRoot) } +// TODO(monopole): Distinguish branches? +// I.e. Allow a distinction between git URI with +// path foo and tag bar and a git URI with the same +// path but a different tag? func (l *fileLoader) errIfPreviouslySeenUri(uri string) error { if strings.HasPrefix(l.uri, uri) { return fmt.Errorf( From 1d9a20b391dbfb4237e337dd0a3229a422f17ca4 Mon Sep 17 00:00:00 2001 From: jregan Date: Sat, 26 Jan 2019 13:36:23 -0800 Subject: [PATCH 076/317] Move git code to its own pkg. --- pkg/{loader/gitcloner.go => git/cloner.go} | 12 +- .../gitcloner_test.go => git/cloner_test.go} | 104 +---------------- pkg/loader/fileloader.go | 25 +++-- pkg/loader/fileloader_test.go | 105 +++++++++++++++++- pkg/loader/loader.go | 11 +- 5 files changed, 129 insertions(+), 128 deletions(-) rename pkg/{loader/gitcloner.go => git/cloner.go} (95%) rename pkg/{loader/gitcloner_test.go => git/cloner_test.go} (72%) diff --git a/pkg/loader/gitcloner.go b/pkg/git/cloner.go similarity index 95% rename from pkg/loader/gitcloner.go rename to pkg/git/cloner.go index 56adc5770..d2f296974 100644 --- a/pkg/loader/gitcloner.go +++ b/pkg/git/cloner.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package loader +package git import ( "bytes" @@ -27,8 +27,8 @@ import ( "github.com/pkg/errors" ) -// gitCloner is a function that can clone a git repo. -type gitCloner func(url string) ( +// Cloner is a function that can clone a git repo. +type Cloner func(url string) ( // Directory where the repo is cloned to. checkoutDir string, // Relative path in the checkoutDir to location @@ -37,8 +37,8 @@ type gitCloner func(url string) ( // Any error encountered when cloning. err error) -// isRepoUrl checks if a string is likely a github repo Url. -func isRepoUrl(arg string) bool { +// IsRepoUrl checks if a string is likely a github repo Url. +func IsRepoUrl(arg string) bool { arg = strings.ToLower(arg) return !filepath.IsAbs(arg) && (strings.HasPrefix(arg, "git::") || @@ -54,7 +54,7 @@ func makeTmpDir() (string, error) { return ioutil.TempDir("", "kustomize-") } -func simpleGitCloner(spec string) ( +func ClonerUsingGitExec(spec string) ( checkoutDir string, pathInCoDir string, err error) { gitProgram, err := exec.LookPath("git") if err != nil { diff --git a/pkg/loader/gitcloner_test.go b/pkg/git/cloner_test.go similarity index 72% rename from pkg/loader/gitcloner_test.go rename to pkg/git/cloner_test.go index a3867ca03..67f5e9c04 100644 --- a/pkg/loader/gitcloner_test.go +++ b/pkg/git/cloner_test.go @@ -14,16 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -package loader +package git import ( "fmt" "path/filepath" - "strings" "testing" - - "sigs.k8s.io/kustomize/pkg/constants" - "sigs.k8s.io/kustomize/pkg/fs" ) func TestIsRepoURL(t *testing.T) { @@ -98,107 +94,13 @@ func TestIsRepoURL(t *testing.T) { }, } for _, tc := range testcases { - actual := isRepoUrl(tc.input) + actual := IsRepoUrl(tc.input) if actual != tc.expected { t.Errorf("unexpected error: unexpected result %t for input %s", actual, tc.input) } } } -func splitOnNthSlash(v string, n int) (string, string) { - left := "" - for i := 0; i < n; i++ { - k := strings.Index(v, "/") - if k < 0 { - break - } - left = left + v[:k+1] - v = v[k+1:] - } - return left[:len(left)-1], v -} - -func TestSplit(t *testing.T) { - path := "a/b/c/d/e/f/g" - if left, right := splitOnNthSlash(path, 2); left != "a/b" || right != "c/d/e/f/g" { - t.Fatalf("got left='%s', right='%s'", left, right) - } - if left, right := splitOnNthSlash(path, 3); left != "a/b/c" || right != "d/e/f/g" { - t.Fatalf("got left='%s', right='%s'", left, right) - } - if left, right := splitOnNthSlash(path, 6); left != "a/b/c/d/e/f" || right != "g" { - t.Fatalf("got left='%s', right='%s'", left, right) - } -} - -// makeFakeGitCloner returns a cloner that ignores the -// URL argument and returns a path in a fake file system -// that should already hold the 'repo' contents. -func makeFakeGitCloner(t *testing.T, fSys fs.FileSystem, coRoot string) gitCloner { - if !fSys.IsDir(coRoot) { - t.Fatalf("expecting a directory at '%s'", coRoot) - } - return func(url string) ( - checkoutDir string, pathInCoDir string, err error) { - _, path := splitOnNthSlash(url, 3) - if !fSys.IsDir(coRoot + "/" + path) { - t.Fatalf("expecting a directory at '%s'/'%s'", - coRoot, path) - } - return coRoot, path, nil - } -} - -func TestGitLoader(t *testing.T) { - rootUrl := "github.com/someOrg/someRepo" - pathInRepo := "foo/base" - url := rootUrl + "/" + pathInRepo - if !isRepoUrl(url) { - t.Fatalf("'%s' should be accepted as a repo url", url) - } - - coRoot := "/tmp" - fSys := fs.MakeFakeFS() - fSys.MkdirAll(coRoot) - fSys.MkdirAll(coRoot + "/" + pathInRepo) - fSys.WriteFile( - coRoot+"/"+pathInRepo+"/"+constants.KustomizationFileNames[0], - []byte(` -whatever -`)) - l, err := newGitLoader( - url, fSys, nil, - makeFakeGitCloner(t, fSys, coRoot)) - if err != nil { - t.Fatalf("unexpected err: %v\n", err) - } - if coRoot+"/"+pathInRepo != l.Root() { - t.Fatalf("expected root '%s', got '%s'\n", - coRoot+"/"+pathInRepo, l.Root()) - } - if _, err = l.New(url); err == nil { - t.Fatalf("expected cycle error 1") - } - if _, err = l.New(rootUrl + "/" + "foo"); err == nil { - t.Fatalf("expected cycle error 2") - } - - pathInRepo = "foo/overlay" - fSys.MkdirAll(coRoot + "/" + pathInRepo) - url = rootUrl + "/" + pathInRepo - if !isRepoUrl(url) { - t.Fatalf("'%s' should be accepted as a repo url", url) - } - l2, err := l.New(url) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if coRoot+"/"+pathInRepo != l2.Root() { - t.Fatalf("expected root '%s', got '%s'\n", - coRoot+"/"+pathInRepo, l2.Root()) - } -} - var repoNames = []string{"someOrg/someRepo", "kubernetes/website"} var paths = []string{"README.md", "foo/krusty.txt", ""} @@ -231,7 +133,7 @@ func TestParseGithubUrl(t *testing.T) { if hrefArg != "" { input = input + refQuery + hrefArg } - if !isRepoUrl(input) { + if !IsRepoUrl(input) { t.Errorf("Should smell like github arg: %s\n", input) continue } diff --git a/pkg/loader/fileloader.go b/pkg/loader/fileloader.go index 1d4e1e98b..ba59f39b8 100644 --- a/pkg/loader/fileloader.go +++ b/pkg/loader/fileloader.go @@ -23,6 +23,7 @@ import ( "strings" "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/git" "sigs.k8s.io/kustomize/pkg/ifc" ) @@ -91,7 +92,7 @@ type fileLoader struct { // File system utilities. fSys fs.FileSystem // Used to clone repositories. - cloner gitCloner + cloner git.Cloner // Used to clean up, as needed. cleaner func() error } @@ -113,18 +114,18 @@ func (l *fileLoader) Root() string { } func newLoaderOrDie(fSys fs.FileSystem, path string) *fileLoader { - l, err := newFileLoaderAt( - path, fSys, nil, simpleGitCloner) + l, err := newLoaderAtConfirmedDir( + path, fSys, nil, git.ClonerUsingGitExec) if err != nil { log.Fatalf("unable to make loader at '%s'; %v", path, err) } return l } -// newFileLoaderAt returns a new fileLoader with given root. -func newFileLoaderAt( +// newLoaderAtConfirmedDir returns a new fileLoader with given root. +func newLoaderAtConfirmedDir( possibleRoot string, fSys fs.FileSystem, - referrer *fileLoader, cloner gitCloner) (*fileLoader, error) { + referrer *fileLoader, cloner git.Cloner) (*fileLoader, error) { if possibleRoot == "" { return nil, fmt.Errorf( "loader root cannot be empty") @@ -159,25 +160,25 @@ func (l *fileLoader) New(path string) (ifc.Loader, error) { if path == "" { return nil, fmt.Errorf("new root cannot be empty") } - if isRepoUrl(path) { + if git.IsRepoUrl(path) { // Avoid cycles. if err := l.errIfPreviouslySeenUri(path); err != nil { return nil, err } - return newGitLoader(path, l.fSys, l.referrer, l.cloner) + return newLoaderAtGitClone(path, l.fSys, l.referrer, l.cloner) } if filepath.IsAbs(path) { return nil, fmt.Errorf("new root '%s' cannot be absolute", path) } - return newFileLoaderAt( + return newLoaderAtConfirmedDir( l.root.Join(path), l.fSys, l, l.cloner) } -// newGitLoader returns a new Loader pinned to a temporary +// newLoaderAtGitClone returns a new Loader pinned to a temporary // directory holding a cloned git repo. -func newGitLoader( +func newLoaderAtGitClone( uri string, fSys fs.FileSystem, - referrer *fileLoader, cloner gitCloner) (ifc.Loader, error) { + referrer *fileLoader, cloner git.Cloner) (ifc.Loader, error) { tmpDirForRepo, pathInRepo, err := cloner(uri) if err != nil { return nil, err diff --git a/pkg/loader/fileloader_test.go b/pkg/loader/fileloader_test.go index 82ca48d8d..a92974b02 100644 --- a/pkg/loader/fileloader_test.go +++ b/pkg/loader/fileloader_test.go @@ -25,6 +25,9 @@ import ( "strings" "testing" + "sigs.k8s.io/kustomize/pkg/constants" + "sigs.k8s.io/kustomize/pkg/git" + "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/ifc" ) @@ -61,17 +64,17 @@ func MakeFakeFs(td []testData) fs.FileSystem { return fSys } -func TestNewFileLoaderAt_DemandsDirectory(t *testing.T) { +func TestNewLoaderAtConfirmedDir_DemandsDirectory(t *testing.T) { fSys := MakeFakeFs(testCases) - _, err := newFileLoaderAt("/foo", fSys, nil, nil) + _, err := newLoaderAtConfirmedDir("/foo", fSys, nil, nil) if err != nil { t.Fatalf("Unexpected error - a directory should work.") } - _, err = newFileLoaderAt("/foo/project", fSys, nil, nil) + _, err = newLoaderAtConfirmedDir("/foo/project", fSys, nil, nil) if err != nil { t.Fatalf("Unexpected error - a directory should work.") } - _, err = newFileLoaderAt("/foo/project/fileA.yaml", fSys, nil, nil) + _, err = newLoaderAtConfirmedDir("/foo/project/fileA.yaml", fSys, nil, nil) if err == nil { t.Fatalf("Expected error - a file should not work.") } @@ -321,3 +324,97 @@ func TestRestrictedLoadingInRealLoader(t *testing.T) { t.Fatalf("unexpected err: %v", err) } } + +func splitOnNthSlash(v string, n int) (string, string) { + left := "" + for i := 0; i < n; i++ { + k := strings.Index(v, "/") + if k < 0 { + break + } + left = left + v[:k+1] + v = v[k+1:] + } + return left[:len(left)-1], v +} + +func TestSplit(t *testing.T) { + path := "a/b/c/d/e/f/g" + if left, right := splitOnNthSlash(path, 2); left != "a/b" || right != "c/d/e/f/g" { + t.Fatalf("got left='%s', right='%s'", left, right) + } + if left, right := splitOnNthSlash(path, 3); left != "a/b/c" || right != "d/e/f/g" { + t.Fatalf("got left='%s', right='%s'", left, right) + } + if left, right := splitOnNthSlash(path, 6); left != "a/b/c/d/e/f" || right != "g" { + t.Fatalf("got left='%s', right='%s'", left, right) + } +} + +// makeFakeGitCloner returns a cloner that ignores the +// URL argument and returns a path in a fake file system +// that should already hold the 'repo' contents. +func makeFakeGitCloner(t *testing.T, fSys fs.FileSystem, coRoot string) git.Cloner { + if !fSys.IsDir(coRoot) { + t.Fatalf("expecting a directory at '%s'", coRoot) + } + return func(url string) ( + checkoutDir string, pathInCoDir string, err error) { + _, path := splitOnNthSlash(url, 3) + if !fSys.IsDir(coRoot + "/" + path) { + t.Fatalf("expecting a directory at '%s'/'%s'", + coRoot, path) + } + return coRoot, path, nil + } +} + +func TestNewLoaderAtGitClone(t *testing.T) { + rootUrl := "github.com/someOrg/someRepo" + pathInRepo := "foo/base" + url := rootUrl + "/" + pathInRepo + if !git.IsRepoUrl(url) { + t.Fatalf("'%s' should be accepted as a repo url", url) + } + + coRoot := "/tmp" + fSys := fs.MakeFakeFS() + fSys.MkdirAll(coRoot) + fSys.MkdirAll(coRoot + "/" + pathInRepo) + fSys.WriteFile( + coRoot+"/"+pathInRepo+"/"+constants.KustomizationFileNames[0], + []byte(` +whatever +`)) + l, err := newLoaderAtGitClone( + url, fSys, nil, + makeFakeGitCloner(t, fSys, coRoot)) + if err != nil { + t.Fatalf("unexpected err: %v\n", err) + } + if coRoot+"/"+pathInRepo != l.Root() { + t.Fatalf("expected root '%s', got '%s'\n", + coRoot+"/"+pathInRepo, l.Root()) + } + if _, err = l.New(url); err == nil { + t.Fatalf("expected cycle error 1") + } + if _, err = l.New(rootUrl + "/" + "foo"); err == nil { + t.Fatalf("expected cycle error 2") + } + + pathInRepo = "foo/overlay" + fSys.MkdirAll(coRoot + "/" + pathInRepo) + url = rootUrl + "/" + pathInRepo + if !git.IsRepoUrl(url) { + t.Fatalf("'%s' should be accepted as a repo url", url) + } + l2, err := l.New(url) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if coRoot+"/"+pathInRepo != l2.Root() { + t.Fatalf("expected root '%s', got '%s'\n", + coRoot+"/"+pathInRepo, l2.Root()) + } +} diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index 5e5aa8664..5e55ddfc1 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -19,15 +19,16 @@ package loader import ( "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/git" "sigs.k8s.io/kustomize/pkg/ifc" ) // NewLoader returns a Loader. func NewLoader(root string, fSys fs.FileSystem) (ifc.Loader, error) { - if isRepoUrl(root) { - return newGitLoader( - root, fSys, nil, simpleGitCloner) + if git.IsRepoUrl(root) { + return newLoaderAtGitClone( + root, fSys, nil, git.ClonerUsingGitExec) } - return newFileLoaderAt( - root, fSys, nil, simpleGitCloner) + return newLoaderAtConfirmedDir( + root, fSys, nil, git.ClonerUsingGitExec) } From e2102dec3c2a93cc857b208c80e923eadf256287 Mon Sep 17 00:00:00 2001 From: jregan Date: Sun, 27 Jan 2019 07:26:30 -0800 Subject: [PATCH 077/317] Move cloner to cloner_tmp. --- pkg/git/{cloner.go => cloner_tmp.go} | 0 pkg/git/{cloner_test.go => cloner_tmp_test.go} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename pkg/git/{cloner.go => cloner_tmp.go} (100%) rename pkg/git/{cloner_test.go => cloner_tmp_test.go} (100%) diff --git a/pkg/git/cloner.go b/pkg/git/cloner_tmp.go similarity index 100% rename from pkg/git/cloner.go rename to pkg/git/cloner_tmp.go diff --git a/pkg/git/cloner_test.go b/pkg/git/cloner_tmp_test.go similarity index 100% rename from pkg/git/cloner_test.go rename to pkg/git/cloner_tmp_test.go From bcb939c19d51f027991785f09e378ad98bda1833 Mon Sep 17 00:00:00 2001 From: jregan Date: Sun, 27 Jan 2019 07:26:30 -0800 Subject: [PATCH 078/317] Move cloner to repospec. --- pkg/git/{cloner.go => repospec.go} | 0 pkg/git/{cloner_test.go => repospec_test.go} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename pkg/git/{cloner.go => repospec.go} (100%) rename pkg/git/{cloner_test.go => repospec_test.go} (100%) diff --git a/pkg/git/cloner.go b/pkg/git/repospec.go similarity index 100% rename from pkg/git/cloner.go rename to pkg/git/repospec.go diff --git a/pkg/git/cloner_test.go b/pkg/git/repospec_test.go similarity index 100% rename from pkg/git/cloner_test.go rename to pkg/git/repospec_test.go From 90b863d124f2e0e068501e82328bbbaa4ddf4e58 Mon Sep 17 00:00:00 2001 From: jregan Date: Sun, 27 Jan 2019 07:26:30 -0800 Subject: [PATCH 079/317] Move cloner_tmp back to cloner. --- pkg/git/{cloner_tmp.go => cloner.go} | 0 pkg/git/{cloner_tmp_test.go => cloner_test.go} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename pkg/git/{cloner_tmp.go => cloner.go} (100%) rename pkg/git/{cloner_tmp_test.go => cloner_test.go} (100%) diff --git a/pkg/git/cloner_tmp.go b/pkg/git/cloner.go similarity index 100% rename from pkg/git/cloner_tmp.go rename to pkg/git/cloner.go diff --git a/pkg/git/cloner_tmp_test.go b/pkg/git/cloner_test.go similarity index 100% rename from pkg/git/cloner_tmp_test.go rename to pkg/git/cloner_test.go From ad400cd13dce88ad3b1e9ec0ba1cddecf662a948 Mon Sep 17 00:00:00 2001 From: jregan Date: Sun, 27 Jan 2019 07:26:37 -0800 Subject: [PATCH 080/317] Introduce RepoSpec. This PR closes a TODO in the fileLoader type to replace the string representing a git repo url with a struct called holding validated fields. New struct is called RepoSpec. It holds what we need in coming PRs for remote repo base containment checks, and will also allow the overlay cycle prevention code to take into account different host schemes or branches. The struct is in a new file called repospec.go. The new file is mostly just a code move of url parsing code that was in cloner.go. Git "blame" history preserved through the move. No change in execution (see final commit by itself). --- pkg/fs/confirmeddir.go | 12 ++ pkg/git/cloner.go | 184 +++-------------------- pkg/git/cloner_test.go | 276 ---------------------------------- pkg/git/repospec.go | 107 ++++++------- pkg/git/repospec_test.go | 19 ++- pkg/loader/fileloader.go | 23 +-- pkg/loader/fileloader_test.go | 5 +- 7 files changed, 104 insertions(+), 522 deletions(-) diff --git a/pkg/fs/confirmeddir.go b/pkg/fs/confirmeddir.go index a07335a89..6d2f5c30d 100644 --- a/pkg/fs/confirmeddir.go +++ b/pkg/fs/confirmeddir.go @@ -17,6 +17,7 @@ limitations under the License. package fs import ( + "io/ioutil" "path/filepath" "strings" ) @@ -25,6 +26,17 @@ import ( // that was confirmed to point to an existing directory. type ConfirmedDir string +// Return a temporary dir, else error. +// The directory is cleaned, no symlinks, etc. so its +// returned as a ConfirmedDir. +func NewTmpConfirmedDir() (ConfirmedDir, error) { + n, err := ioutil.TempDir("", "kustomize-") + if err != nil { + return "", err + } + return ConfirmedDir(n), nil +} + // HasPrefix returns true if the directory argument // is a prefix of self (d) from the point of view of // a file system. diff --git a/pkg/git/cloner.go b/pkg/git/cloner.go index d2f296974..27e6ef712 100644 --- a/pkg/git/cloner.go +++ b/pkg/git/cloner.go @@ -18,193 +18,51 @@ package git import ( "bytes" - "io/ioutil" "os/exec" - "path/filepath" - "regexp" - "strings" "github.com/pkg/errors" + "sigs.k8s.io/kustomize/pkg/fs" ) // Cloner is a function that can clone a git repo. -type Cloner func(url string) ( - // Directory where the repo is cloned to. - checkoutDir string, - // Relative path in the checkoutDir to location - // of kustomization file. - pathInCoDir string, - // Any error encountered when cloning. - err error) +type Cloner func(url string) (*RepoSpec, error) -// IsRepoUrl checks if a string is likely a github repo Url. -func IsRepoUrl(arg string) bool { - arg = strings.ToLower(arg) - return !filepath.IsAbs(arg) && - (strings.HasPrefix(arg, "git::") || - strings.HasPrefix(arg, "gh:") || - strings.HasPrefix(arg, "ssh:") || - strings.HasPrefix(arg, "github.com") || - strings.HasPrefix(arg, "git@") || - strings.Index(arg, "github.com/") > -1 || - isAzureHost(arg) || isAWSHost(arg)) -} - -func makeTmpDir() (string, error) { - return ioutil.TempDir("", "kustomize-") -} - -func ClonerUsingGitExec(spec string) ( - checkoutDir string, pathInCoDir string, err error) { +// ClonerUsingGitExec uses a local git install, as opposed +// to say, some remote API, to obtain a local clone of +// a remote repo. +func ClonerUsingGitExec(spec string) (*RepoSpec, error) { gitProgram, err := exec.LookPath("git") if err != nil { - return "", "", errors.Wrap(err, "no 'git' program on path") + return nil, errors.Wrap(err, "no 'git' program on path") } - checkoutDir, err = makeTmpDir() + repoSpec, err := NewRepoSpecFromUrl(spec) if err != nil { - return + return nil, err } - repo, pathInCoDir, gitRef, err := parseUrl(spec) + repoSpec.cloneDir, err = fs.NewTmpConfirmedDir() if err != nil { - return + return nil, err } cmd := exec.Command( gitProgram, "clone", - repo, - checkoutDir) + repoSpec.repo, + repoSpec.cloneDir.String()) var out bytes.Buffer cmd.Stdout = &out err = cmd.Run() if err != nil { - return "", "", - errors.Wrapf(err, "trouble cloning %s", spec) + return nil, errors.Wrapf(err, "trouble cloning %s", spec) } - if gitRef == "" { - return + if repoSpec.ref == "" { + return repoSpec, nil } - cmd = exec.Command(gitProgram, "checkout", gitRef) - cmd.Dir = checkoutDir + cmd = exec.Command(gitProgram, "checkout", repoSpec.ref) + cmd.Dir = repoSpec.cloneDir.String() err = cmd.Run() if err != nil { - return "", "", - errors.Wrapf(err, "trouble checking out href %s", gitRef) + return nil, errors.Wrapf( + err, "trouble checking out href %s", repoSpec.ref) } - return checkoutDir, pathInCoDir, nil -} - -func parseUrl(n string) ( - repo string, path string, gitRef string, err error) { - host, repo, path, gitRef, err := parseGithubUrl(n) - if err != nil { - return - } - if isAzureHost(host) || isAWSHost(host) { - repo = host + repo - return - } - repo = host + repo + ".git" - return -} - -const ( - refQuery = "?ref=" - gitSuffix = ".git" -) - -// From strings like git@github.com:someOrg/someRepo.git or -// https://github.com/someOrg/someRepo?ref=someHash, extract -// the parts. -func parseGithubUrl(n string) ( - host string, repo string, path string, gitRef string, err error) { - host, n = parseHostSpec(n) - host = normalizeGitHostSpec(host) - - if strings.HasSuffix(n, gitSuffix) { - repo = n[0 : len(n)-len(gitSuffix)] - return - } - if strings.Contains(n, gitSuffix) { - index := strings.Index(n, gitSuffix) - repo = n[0:index] - n = n[index+len(gitSuffix):] - path, gitRef = peelQuery(n) - return - } - i := strings.Index(n, "/") - if i < 1 { - return "", "", "", "", errors.New("no separator") - } - j := strings.Index(n[i+1:], "/") - if j >= 0 { - j += i + 1 - repo = n[:j] - path, gitRef = peelQuery(n[j+1:]) - } else { - path = "" - repo, gitRef = peelQuery(n) - } - return -} - -func peelQuery(arg string) (string, string) { - j := strings.Index(arg, refQuery) - if j >= 0 { - return arg[:j], arg[j+len(refQuery):] - } - return arg, "" -} - -func parseHostSpec(n string) (string, string) { - var host string - for _, p := range []string{ - // Order matters here. - "git::", "gh:", "ssh://", "https://", "http://", - "git@", "github.com:", "github.com/"} { - if strings.ToLower(n[:len(p)]) == p { - n = n[len(p):] - host = host + p - } - } - - // If host is a http(s) or ssh URL, grab the domain part. - for _, p := range []string{ - "ssh://", "https://", "http://"} { - if strings.HasSuffix(strings.ToLower(host), p) { - index := regexp.MustCompile("^(.*?)/").FindStringIndex(n) - if len(index) > 0 { - host = host + n[0:index[len(index)-1]] - n = n[index[len(index)-1]:] - } - } - } - return host, n -} - -func normalizeGitHostSpec(host string) string { - s := strings.ToLower(host) - if strings.Contains(s, "github.com") { - if strings.Contains(s, "git@") || strings.Contains(s, "ssh:") { - host = "git@github.com:" - } else { - host = "https://github.com/" - } - } - if strings.HasPrefix(s, "git::") { - host = strings.TrimLeft(s, "git::") - } - return host -} - -// The format of Azure repo URL is documented -// https://docs.microsoft.com/en-us/azure/devops/repos/git/clone?view=vsts&tabs=visual-studio#clone_url -func isAzureHost(host string) bool { - return strings.Contains(host, "dev.azure.com") || - strings.Contains(host, "visualstudio.com") -} - -// The format of AWS repo URL is documented -// https://docs.aws.amazon.com/codecommit/latest/userguide/regions.html -func isAWSHost(host string) bool { - return strings.Contains(host, "amazonaws.com") + return repoSpec, nil } diff --git a/pkg/git/cloner_test.go b/pkg/git/cloner_test.go index 67f5e9c04..d3816aacf 100644 --- a/pkg/git/cloner_test.go +++ b/pkg/git/cloner_test.go @@ -15,279 +15,3 @@ limitations under the License. */ package git - -import ( - "fmt" - "path/filepath" - "testing" -) - -func TestIsRepoURL(t *testing.T) { - - testcases := []struct { - input string - expected bool - }{ - { - input: "https://github.com/org/repo", - expected: true, - }, - { - input: "github.com/org/repo", - expected: true, - }, - { - input: "git@github.com:org/repo", - expected: true, - }, - { - input: "gh:org/repo", - expected: true, - }, - { - input: "git::https://gitlab.com/org/repo", - expected: true, - }, - { - input: "git@gitlab2.sqtools.ru:10022/infra/kubernetes/thanos-base.git?ref=v0.1.0", - expected: true, - }, - { - input: "git@bitbucket.org:org/repo.git", - expected: true, - }, - { - input: "git::http://git.example.com/org/repo.git", - expected: true, - }, - { - input: "git::https://git.example.com/org/repo.git", - expected: true, - }, - { - input: "ssh://git.example.com:7999/org/repo.git", - expected: true, - }, - { - input: "/github.com/org/repo", - expected: false, - }, - { - input: "/abs/path/to/file", - expected: false, - }, - { - input: "../relative", - expected: false, - }, - { - input: "foo", - expected: false, - }, - { - input: ".", - expected: false, - }, - { - input: "", - expected: false, - }, - } - for _, tc := range testcases { - actual := IsRepoUrl(tc.input) - if actual != tc.expected { - t.Errorf("unexpected error: unexpected result %t for input %s", actual, tc.input) - } - } -} - -var repoNames = []string{"someOrg/someRepo", "kubernetes/website"} - -var paths = []string{"README.md", "foo/krusty.txt", ""} - -var hrefArgs = []string{"someBranch", ""} - -var extractFmts = map[string]string{ - "gh:%s": "gh:", - "GH:%s": "gh:", - "gitHub.com/%s": "https://github.com/", - "https://github.com/%s": "https://github.com/", - "hTTps://github.com/%s": "https://github.com/", - "git::https://gitlab.com/%s": "https://gitlab.com/", - "github.com:%s": "https://github.com/", - "git::http://git.example.com/%s": "http://git.example.com/", - "git::https://git.example.com/%s": "https://git.example.com/", - "ssh://git.example.com:7999/%s": "ssh://git.example.com:7999/", -} - -func TestParseGithubUrl(t *testing.T) { - for _, repoName := range repoNames { - for _, pathName := range paths { - for extractFmt, hostSpec := range extractFmts { - for _, hrefArg := range hrefArgs { - spec := repoName - if len(pathName) > 0 { - spec = filepath.Join(spec, pathName) - } - input := fmt.Sprintf(extractFmt, spec) - if hrefArg != "" { - input = input + refQuery + hrefArg - } - if !IsRepoUrl(input) { - t.Errorf("Should smell like github arg: %s\n", input) - continue - } - host, repo, path, gitRef, err := parseGithubUrl(input) - if err != nil { - t.Errorf("problem %v", err) - } - if host != hostSpec { - t.Errorf("\n"+ - " from %s\n"+ - " actual host %s\n"+ - "expected host %s\n", input, host, hostSpec) - } - if repo != repoName { - t.Errorf("\n"+ - " from %s\n"+ - " actual Repo %s\n"+ - "expected Repo %s\n", input, repo, repoName) - } - if path != pathName { - t.Errorf("\n"+ - " from %s\n"+ - " actual Path %s\n"+ - "expected Path %s\n", input, path, pathName) - } - if gitRef != hrefArg { - t.Errorf("\n"+ - " from %s\n"+ - " actual Href %s\n"+ - "expected Href %s\n", input, gitRef, hrefArg) - } - } - } - } - } -} - -func TestParseUrl(t *testing.T) { - testcases := []struct { - input string - repo string - path string - ref string - }{ - { - input: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo/somedir", - repo: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo", - path: "somedir", - ref: "", - }, - { - input: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo/somedir?ref=testbranch", - repo: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo", - path: "somedir", - ref: "testbranch", - }, - { - input: "https://fabrikops2.visualstudio.com/someorg/somerepo?ref=master", - repo: "https://fabrikops2.visualstudio.com/someorg/somerepo", - path: "", - ref: "master", - }, - { - input: "http://github.com/someorg/somerepo/somedir", - repo: "https://github.com/someorg/somerepo.git", - path: "somedir", - ref: "", - }, - { - input: "git@github.com:someorg/somerepo/somedir", - repo: "git@github.com:someorg/somerepo.git", - path: "somedir", - ref: "", - }, - { - input: "git@gitlab2.sqtools.ru:10022/infra/kubernetes/thanos-base.git?ref=v0.1.0", - repo: "git@gitlab2.sqtools.ru:10022/infra/kubernetes/thanos-base.git", - path: "", - ref: "v0.1.0", - }, - } - for _, testcase := range testcases { - repo, path, ref, err := parseUrl(testcase.input) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if repo != testcase.repo { - t.Errorf("repo expected to be %v, but got %v on %s", testcase.repo, repo, testcase.input) - } - if path != testcase.path { - t.Errorf("path expected to be %v, but got %v on %s", testcase.path, path, testcase.input) - } - if ref != testcase.ref { - t.Errorf("ref expected to be %v, but got %v on %s", testcase.ref, ref, testcase.input) - } - } -} - -func TestIsAzureHost(t *testing.T) { - testcases := []struct { - input string - expect bool - }{ - { - input: "https://git-codecommit.us-east-2.amazonaws.com", - expect: false, - }, - { - input: "ssh://git-codecommit.us-east-2.amazonaws.com", - expect: false, - }, - { - input: "https://fabrikops2.visualstudio.com/", - expect: true, - }, - { - input: "https://dev.azure.com/myorg/myproject/", - expect: true, - }, - } - for _, testcase := range testcases { - actual := isAzureHost(testcase.input) - if actual != testcase.expect { - t.Errorf("IsAzureHost: expected %v, but got %v on %s", testcase.expect, actual, testcase.input) - } - } -} - -func TestIsAWSHost(t *testing.T) { - testcases := []struct { - input string - expect bool - }{ - { - input: "https://git-codecommit.us-east-2.amazonaws.com", - expect: true, - }, - { - input: "ssh://git-codecommit.us-east-2.amazonaws.com", - expect: true, - }, - { - input: "git@github.com:", - expect: false, - }, - { - input: "http://github.com/", - expect: false, - }, - } - for _, testcase := range testcases { - actual := isAWSHost(testcase.input) - if actual != testcase.expect { - t.Errorf("IsAWSHost: expected %v, but got %v on %s", testcase.expect, actual, testcase.input) - } - } -} diff --git a/pkg/git/repospec.go b/pkg/git/repospec.go index d2f296974..90b5f38cc 100644 --- a/pkg/git/repospec.go +++ b/pkg/git/repospec.go @@ -17,25 +17,49 @@ limitations under the License. package git import ( - "bytes" - "io/ioutil" - "os/exec" "path/filepath" "regexp" "strings" "github.com/pkg/errors" + "sigs.k8s.io/kustomize/pkg/fs" ) -// Cloner is a function that can clone a git repo. -type Cloner func(url string) ( - // Directory where the repo is cloned to. - checkoutDir string, - // Relative path in the checkoutDir to location - // of kustomization file. - pathInCoDir string, - // Any error encountered when cloning. - err error) +// RepoSpec specifies a git repo and a branch and path therein. +type RepoSpec struct { + // Raw, original spec, used to look for cycles. + // TODO(monopole): Drop raw, use processed fields instead. + raw string + + // Repo, e.g. github.com/kubernetes-sigs/kustomize + repo string + + // ConfirmedDir where the repo is cloned to. + cloneDir fs.ConfirmedDir + + // Relative path in the repo, and in the cloneDir, + // to a Kustomization. + path string + + // Branch or tag reference. + ref string +} + +func (x *RepoSpec) CloneDir() fs.ConfirmedDir { + return x.cloneDir +} + +func (x *RepoSpec) Raw() string { + return x.raw +} + +func (x *RepoSpec) AbsPath() string { + return x.cloneDir.Join(x.path) +} + +func (x *RepoSpec) Cleaner(fSys fs.FileSystem) func() error { + return func() error { return fSys.RemoveAll(x.cloneDir.String()) } +} // IsRepoUrl checks if a string is likely a github repo Url. func IsRepoUrl(arg string) bool { @@ -50,61 +74,22 @@ func IsRepoUrl(arg string) bool { isAzureHost(arg) || isAWSHost(arg)) } -func makeTmpDir() (string, error) { - return ioutil.TempDir("", "kustomize-") -} - -func ClonerUsingGitExec(spec string) ( - checkoutDir string, pathInCoDir string, err error) { - gitProgram, err := exec.LookPath("git") - if err != nil { - return "", "", errors.Wrap(err, "no 'git' program on path") - } - checkoutDir, err = makeTmpDir() - if err != nil { - return - } - repo, pathInCoDir, gitRef, err := parseUrl(spec) - if err != nil { - return - } - cmd := exec.Command( - gitProgram, - "clone", - repo, - checkoutDir) - var out bytes.Buffer - cmd.Stdout = &out - err = cmd.Run() - if err != nil { - return "", "", - errors.Wrapf(err, "trouble cloning %s", spec) - } - if gitRef == "" { - return - } - cmd = exec.Command(gitProgram, "checkout", gitRef) - cmd.Dir = checkoutDir - err = cmd.Run() - if err != nil { - return "", "", - errors.Wrapf(err, "trouble checking out href %s", gitRef) - } - return checkoutDir, pathInCoDir, nil -} - -func parseUrl(n string) ( - repo string, path string, gitRef string, err error) { +func NewRepoSpecFromUrl(n string) (*RepoSpec, error) { host, repo, path, gitRef, err := parseGithubUrl(n) if err != nil { - return + return nil, err } if isAzureHost(host) || isAWSHost(host) { repo = host + repo - return + } else { + repo = host + repo + ".git" } - repo = host + repo + ".git" - return + return &RepoSpec{raw: n, repo: repo, path: path, ref: gitRef}, nil +} + +func NewRepoSpec( + raw string, cloneDir fs.ConfirmedDir, path string) *RepoSpec { + return &RepoSpec{raw: raw, cloneDir: cloneDir, path: path} } const ( diff --git a/pkg/git/repospec_test.go b/pkg/git/repospec_test.go index 67f5e9c04..dd1c76fee 100644 --- a/pkg/git/repospec_test.go +++ b/pkg/git/repospec_test.go @@ -171,7 +171,7 @@ func TestParseGithubUrl(t *testing.T) { } } -func TestParseUrl(t *testing.T) { +func TestNewRepoSpecFromUrl(t *testing.T) { testcases := []struct { input string repo string @@ -216,18 +216,21 @@ func TestParseUrl(t *testing.T) { }, } for _, testcase := range testcases { - repo, path, ref, err := parseUrl(testcase.input) + rs, err := NewRepoSpecFromUrl(testcase.input) if err != nil { t.Errorf("Unexpected error: %v", err) } - if repo != testcase.repo { - t.Errorf("repo expected to be %v, but got %v on %s", testcase.repo, repo, testcase.input) + if rs.repo != testcase.repo { + t.Errorf("repo expected to be %v, but got %v on %s", + testcase.repo, rs.repo, testcase.input) } - if path != testcase.path { - t.Errorf("path expected to be %v, but got %v on %s", testcase.path, path, testcase.input) + if rs.path != testcase.path { + t.Errorf("path expected to be %v, but got %v on %s", + testcase.path, rs.path, testcase.input) } - if ref != testcase.ref { - t.Errorf("ref expected to be %v, but got %v on %s", testcase.ref, ref, testcase.input) + if rs.ref != testcase.ref { + t.Errorf("ref expected to be %v, but got %v on %s", + testcase.ref, rs.ref, testcase.input) } } } diff --git a/pkg/loader/fileloader.go b/pkg/loader/fileloader.go index ba59f39b8..11138eb17 100644 --- a/pkg/loader/fileloader.go +++ b/pkg/loader/fileloader.go @@ -86,9 +86,9 @@ type fileLoader struct { // The Load function reads from this directory, // or directories below it. root fs.ConfirmedDir - // URI, if any, used for a download into root. - // TODO(monopole): use non-string type. - uri string + // If this is non-nil, the files were + // obtained from the given repository. + repoSpec *git.RepoSpec // File system utilities. fSys fs.FileSystem // Used to clone repositories. @@ -179,26 +179,26 @@ func (l *fileLoader) New(path string) (ifc.Loader, error) { func newLoaderAtGitClone( uri string, fSys fs.FileSystem, referrer *fileLoader, cloner git.Cloner) (ifc.Loader, error) { - tmpDirForRepo, pathInRepo, err := cloner(uri) + repoSpec, err := cloner(uri) if err != nil { return nil, err } - root, f, err := fSys.CleanedAbs( - filepath.Join(tmpDirForRepo, pathInRepo)) + root, f, err := fSys.CleanedAbs(repoSpec.AbsPath()) if err != nil { return nil, err } if f != "" { return nil, fmt.Errorf( - "'%s' refers to file '%s'; expecting directory", pathInRepo, f) + "'%s' refers to file '%s'; expecting directory", + repoSpec.AbsPath(), f) } return &fileLoader{ root: root, referrer: referrer, - uri: uri, + repoSpec: repoSpec, fSys: fSys, cloner: cloner, - cleaner: func() error { return fSys.RemoveAll(tmpDirForRepo) }, + cleaner: repoSpec.Cleaner(fSys), }, nil } @@ -221,11 +221,12 @@ func (l *fileLoader) errIfArgEqualOrHigher( // I.e. Allow a distinction between git URI with // path foo and tag bar and a git URI with the same // path but a different tag? +// TODO(monopole): Use parsed data instead of looking at Raw(). func (l *fileLoader) errIfPreviouslySeenUri(uri string) error { - if strings.HasPrefix(l.uri, uri) { + if strings.HasPrefix(l.repoSpec.Raw(), uri) { return fmt.Errorf( "cycle detected: URI '%s' referenced by previous URI '%s'", - uri, l.uri) + uri, l.repoSpec.Raw()) } if l.referrer == nil { return nil diff --git a/pkg/loader/fileloader_test.go b/pkg/loader/fileloader_test.go index a92974b02..bf27c487b 100644 --- a/pkg/loader/fileloader_test.go +++ b/pkg/loader/fileloader_test.go @@ -358,14 +358,13 @@ func makeFakeGitCloner(t *testing.T, fSys fs.FileSystem, coRoot string) git.Clon if !fSys.IsDir(coRoot) { t.Fatalf("expecting a directory at '%s'", coRoot) } - return func(url string) ( - checkoutDir string, pathInCoDir string, err error) { + return func(url string) (*git.RepoSpec, error) { _, path := splitOnNthSlash(url, 3) if !fSys.IsDir(coRoot + "/" + path) { t.Fatalf("expecting a directory at '%s'/'%s'", coRoot, path) } - return coRoot, path, nil + return git.NewRepoSpec(url, fs.ConfirmedDir(coRoot), path), nil } } From af8a1696191b513c4eb84f82aadeb6062e1ca9f3 Mon Sep 17 00:00:00 2001 From: Pascal Bourdier Date: Mon, 28 Jan 2019 11:57:43 +0100 Subject: [PATCH 081/317] typo in doc fix it --- pkg/commands/misc/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/commands/misc/config.go b/pkg/commands/misc/config.go index 45d7fd787..fc18e27b2 100644 --- a/pkg/commands/misc/config.go +++ b/pkg/commands/misc/config.go @@ -33,7 +33,7 @@ func NewCmdConfig(fsys fs.FileSystem) *cobra.Command { Short: "Config Kustomize transformers", Long: "", Example: ` - # Save the default transformer configrations to a local directory + # Save the default transformer configurations to a local directory kustomize config save -d ~/.kustomize/config `, Args: cobra.MinimumNArgs(1), @@ -56,7 +56,7 @@ func newCmdSave(fsys fs.FileSystem) *cobra.Command { Short: "Save default kustomize transformer configurations to a local directory", Long: "", Example: ` - # Save the default transformer configrations to a local directory + # Save the default transformer configurations to a local directory save -d ~/.kustomize/config `, From feb0502cb4ebe6ba71a742db3cfe9c227831233c Mon Sep 17 00:00:00 2001 From: Christopher Schmidt Date: Mon, 28 Jan 2019 12:39:44 +0100 Subject: [PATCH 082/317] added DaemonSet --- .../config/defaultconfig/varreference.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pkg/transformers/config/defaultconfig/varreference.go b/pkg/transformers/config/defaultconfig/varreference.go index 58e4b023f..35a92d78e 100644 --- a/pkg/transformers/config/defaultconfig/varreference.go +++ b/pkg/transformers/config/defaultconfig/varreference.go @@ -31,6 +31,12 @@ varReference: - path: spec/template/spec/containers/command kind: Deployment +- path: spec/template/spec/initContainers/command + kind: DaemonSet + +- path: spec/template/spec/containers/command + kind: DaemonSet + - path: spec/template/spec/containers/command kind: Job @@ -49,6 +55,12 @@ varReference: - path: spec/template/spec/containers/args kind: Deployment +- path: spec/template/spec/initContainers/args + kind: DaemonSet + +- path: spec/template/spec/containers/args + kind: DaemonSet + - path: spec/template/spec/containers/args kind: Job @@ -67,6 +79,12 @@ varReference: - path: spec/template/spec/containers/env/value kind: Deployment +- path: spec/template/spec/initContainers/env/value + kind: DaemonSet + +- path: spec/template/spec/containers/env/value + kind: DaemonSet + - path: spec/template/spec/containers/env/value kind: Job From 3ddc20f72c886a2186619dfc9dea850bea2f83e5 Mon Sep 17 00:00:00 2001 From: jregan Date: Sun, 27 Jan 2019 19:17:52 -0800 Subject: [PATCH 083/317] Increase git url parsing coverage. --- pkg/git/cloner.go | 2 +- pkg/git/repospec.go | 96 ++++++++++++++++--------- pkg/git/repospec_test.go | 147 ++++++++++++++++++++++++++++++++------- 3 files changed, 184 insertions(+), 61 deletions(-) diff --git a/pkg/git/cloner.go b/pkg/git/cloner.go index 27e6ef712..40c61ffba 100644 --- a/pkg/git/cloner.go +++ b/pkg/git/cloner.go @@ -46,7 +46,7 @@ func ClonerUsingGitExec(spec string) (*RepoSpec, error) { cmd := exec.Command( gitProgram, "clone", - repoSpec.repo, + repoSpec.CloneSpec(), repoSpec.cloneDir.String()) var out bytes.Buffer cmd.Stdout = &out diff --git a/pkg/git/repospec.go b/pkg/git/repospec.go index 90b5f38cc..046d92be9 100644 --- a/pkg/git/repospec.go +++ b/pkg/git/repospec.go @@ -17,27 +17,30 @@ limitations under the License. package git import ( + "fmt" "path/filepath" - "regexp" "strings" - "github.com/pkg/errors" "sigs.k8s.io/kustomize/pkg/fs" ) -// RepoSpec specifies a git repo and a branch and path therein. +// RepoSpec specifies a git repository and a branch and path therein. type RepoSpec struct { // Raw, original spec, used to look for cycles. // TODO(monopole): Drop raw, use processed fields instead. raw string - // Repo, e.g. github.com/kubernetes-sigs/kustomize - repo string + // Host, e.g. github.com + host string - // ConfirmedDir where the repo is cloned to. + // orgRepo name (organization/repoName), + // e.g. kubernetes-sigs/kustomize + orgRepo string + + // ConfirmedDir where the orgRepo is cloned to. cloneDir fs.ConfirmedDir - // Relative path in the repo, and in the cloneDir, + // Relative path in the repository, and in the cloneDir, // to a Kustomization. path string @@ -45,6 +48,14 @@ type RepoSpec struct { ref string } +// CloneSpec returns a string suitable for "git clone {spec}". +func (x *RepoSpec) CloneSpec() string { + if isAzureHost(x.host) || isAWSHost(x.host) { + return x.host + x.orgRepo + } + return x.host + x.orgRepo + gitSuffix +} + func (x *RepoSpec) CloneDir() fs.ConfirmedDir { return x.cloneDir } @@ -74,17 +85,23 @@ func IsRepoUrl(arg string) bool { isAzureHost(arg) || isAWSHost(arg)) } +// From strings like git@github.com:someOrg/someRepo.git or +// https://github.com/someOrg/someRepo?ref=someHash, extract +// the parts. func NewRepoSpecFromUrl(n string) (*RepoSpec, error) { - host, repo, path, gitRef, err := parseGithubUrl(n) - if err != nil { - return nil, err + if filepath.IsAbs(n) { + return nil, fmt.Errorf("uri looks like abs path: %s", n) } - if isAzureHost(host) || isAWSHost(host) { - repo = host + repo - } else { - repo = host + repo + ".git" + host, orgRepo, path, gitRef := parseGithubUrl(n) + if orgRepo == "" { + return nil, fmt.Errorf("url lacks orgRepo: %s", n) } - return &RepoSpec{raw: n, repo: repo, path: path, ref: gitRef}, nil + if host == "" { + return nil, fmt.Errorf("url lacks host: %s", n) + } + return &RepoSpec{ + raw: n, host: host, orgRepo: orgRepo, + path: path, ref: gitRef}, nil } func NewRepoSpec( @@ -101,33 +118,29 @@ const ( // https://github.com/someOrg/someRepo?ref=someHash, extract // the parts. func parseGithubUrl(n string) ( - host string, repo string, path string, gitRef string, err error) { + host string, orgRepo string, path string, gitRef string) { host, n = parseHostSpec(n) - host = normalizeGitHostSpec(host) - if strings.HasSuffix(n, gitSuffix) { - repo = n[0 : len(n)-len(gitSuffix)] - return - } if strings.Contains(n, gitSuffix) { index := strings.Index(n, gitSuffix) - repo = n[0:index] + orgRepo = n[0:index] n = n[index+len(gitSuffix):] path, gitRef = peelQuery(n) return } + i := strings.Index(n, "/") if i < 1 { - return "", "", "", "", errors.New("no separator") + return "", "", "", "" } j := strings.Index(n[i+1:], "/") if j >= 0 { j += i + 1 - repo = n[:j] + orgRepo = n[:j] path, gitRef = peelQuery(n[j+1:]) } else { path = "" - repo, gitRef = peelQuery(n) + orgRepo, gitRef = peelQuery(n) } return } @@ -142,28 +155,45 @@ func peelQuery(arg string) (string, string) { func parseHostSpec(n string) (string, string) { var host string + // Start accumulating the host part. for _, p := range []string{ // Order matters here. "git::", "gh:", "ssh://", "https://", "http://", "git@", "github.com:", "github.com/"} { - if strings.ToLower(n[:len(p)]) == p { + if len(p) < len(n) && strings.ToLower(n[:len(p)]) == p { n = n[len(p):] - host = host + p + host += p } } + if host == "git@" { + i := strings.Index(n, "/") + if i > -1 { + host += n[:i+1] + n = n[i+1:] + } else { + i = strings.Index(n, ":") + if i > -1 { + host += n[:i+1] + n = n[i+1:] + } + } + return host, n + } // If host is a http(s) or ssh URL, grab the domain part. for _, p := range []string{ "ssh://", "https://", "http://"} { - if strings.HasSuffix(strings.ToLower(host), p) { - index := regexp.MustCompile("^(.*?)/").FindStringIndex(n) - if len(index) > 0 { - host = host + n[0:index[len(index)-1]] - n = n[index[len(index)-1]:] + if strings.HasSuffix(host, p) { + i := strings.Index(n, "/") + if i > -1 { + host = host + n[0:i+1] + n = n[i+1:] } + break } } - return host, n + + return normalizeGitHostSpec(host), n } func normalizeGitHostSpec(host string) string { diff --git a/pkg/git/repospec_test.go b/pkg/git/repospec_test.go index dd1c76fee..95f170410 100644 --- a/pkg/git/repospec_test.go +++ b/pkg/git/repospec_test.go @@ -19,6 +19,7 @@ package git import ( "fmt" "path/filepath" + "strings" "testing" ) @@ -101,15 +102,16 @@ func TestIsRepoURL(t *testing.T) { } } -var repoNames = []string{"someOrg/someRepo", "kubernetes/website"} +var orgRepos = []string{"someOrg/someRepo", "kubernetes/website"} -var paths = []string{"README.md", "foo/krusty.txt", ""} +var pathNames = []string{"README.md", "foo/krusty.txt", ""} -var hrefArgs = []string{"someBranch", ""} +var hrefArgs = []string{"someBranch", "master", "v0.1.0", ""} -var extractFmts = map[string]string{ +var hostNamesRawAndNormalizedOld = map[string]string{ "gh:%s": "gh:", "GH:%s": "gh:", + "git@github.com:%s": "git@github.com:", "gitHub.com/%s": "https://github.com/", "https://github.com/%s": "https://github.com/", "hTTps://github.com/%s": "https://github.com/", @@ -118,40 +120,131 @@ var extractFmts = map[string]string{ "git::http://git.example.com/%s": "http://git.example.com/", "git::https://git.example.com/%s": "https://git.example.com/", "ssh://git.example.com:7999/%s": "ssh://git.example.com:7999/", + "https://git-codecommit.us-east-2.amazonaws.com/%s": "https://git-codecommit.us-east-2.amazonaws.com/", } -func TestParseGithubUrl(t *testing.T) { - for _, repoName := range repoNames { - for _, pathName := range paths { - for extractFmt, hostSpec := range extractFmts { +var hostNamesRawAndNormalized = [][]string{ + {"gh:", "gh:"}, + {"GH:", "gh:"}, + {"gitHub.com/", "https://github.com/"}, + {"github.com:", "https://github.com/"}, + {"http://github.com/", "https://github.com/"}, + {"https://github.com/", "https://github.com/"}, + {"hTTps://github.com/", "https://github.com/"}, + {"https://git-codecommit.us-east-2.amazonaws.com/", "https://git-codecommit.us-east-2.amazonaws.com/"}, + {"https://fabrikops2.visualstudio.com/", "https://fabrikops2.visualstudio.com/"}, + {"ssh://git.example.com:7999/", "ssh://git.example.com:7999/"}, + {"git::https://gitlab.com/", "https://gitlab.com/"}, + {"git::http://git.example.com/", "http://git.example.com/"}, + {"git::https://git.example.com/", "https://git.example.com/"}, + {"git@github.com:", "git@github.com:"}, + {"git@gitlab2.sqtools.ru:10022/", "git@gitlab2.sqtools.ru:10022/"}, +} + +func makeUrlOld(hostFmt, orgRepo, path, href string) string { + if len(path) > 0 { + orgRepo = filepath.Join(orgRepo, path) + } + url := fmt.Sprintf(hostFmt, orgRepo) + if href != "" { + url += refQuery + href + } + return url +} + +func makeUrl(hostFmt, orgRepo, path, href string) string { + if len(path) > 0 { + orgRepo = filepath.Join(orgRepo, path) + } + url := hostFmt + orgRepo + if href != "" { + url += refQuery + href + } + return url +} + +func TestNewRepoSpecFromUrl(t *testing.T) { + var bad [][]string + for _, tuple := range hostNamesRawAndNormalized { + hostRaw := tuple[0] + hostSpec := tuple[1] + for _, orgRepo := range orgRepos { + for _, pathName := range pathNames { for _, hrefArg := range hrefArgs { - spec := repoName - if len(pathName) > 0 { - spec = filepath.Join(spec, pathName) - } - input := fmt.Sprintf(extractFmt, spec) - if hrefArg != "" { - input = input + refQuery + hrefArg - } - if !IsRepoUrl(input) { - t.Errorf("Should smell like github arg: %s\n", input) - continue - } - host, repo, path, gitRef, err := parseGithubUrl(input) + uri := makeUrl(hostRaw, orgRepo, pathName, hrefArg) + rs, err := NewRepoSpecFromUrl(uri) if err != nil { t.Errorf("problem %v", err) } + if rs.host != hostSpec { + bad = append(bad, []string{"host", uri, rs.host, hostSpec}) + } + if rs.orgRepo != orgRepo { + bad = append(bad, []string{"orgRepo", uri, rs.orgRepo, orgRepo}) + } + if rs.path != pathName { + bad = append(bad, []string{"path", uri, rs.path, pathName}) + } + if rs.ref != hrefArg { + bad = append(bad, []string{"ref", uri, rs.ref, hrefArg}) + } + } + } + } + } + if len(bad) > 0 { + for _, tuple := range bad { + fmt.Printf("\n"+ + " from uri: %s\n"+ + " actual %4s: %s\n"+ + "expected %4s: %s\n", + tuple[1], tuple[0], tuple[2], tuple[0], tuple[3]) + } + t.Fail() + } +} + +var badData = [][]string{ + {"/tmp", "uri looks like abs path"}, + {"iauhsdiuashduas", "url lacks orgRepo"}, + {"htxxxtp://github.com/", "url lacks host"}, + {"ssh://git.example.com", "url lacks orgRepo"}, + {"git::___", "url lacks orgRepo"}, +} + +func TestNewRepoSpecFromUrlErrors(t *testing.T) { + for _, tuple := range badData { + _, err := NewRepoSpecFromUrl(tuple[0]) + if err == nil { + t.Error("expected error") + } + if !strings.Contains(err.Error(), tuple[1]) { + t.Errorf("unexpected error: %s", err) + } + } +} + +func TestParseGithubUrl(t *testing.T) { + for hostRawFmt, hostSpec := range hostNamesRawAndNormalizedOld { + for _, orgRepo := range orgRepos { + for _, pathName := range pathNames { + for _, hrefArg := range hrefArgs { + input := makeUrlOld(hostRawFmt, orgRepo, pathName, hrefArg) + if !IsRepoUrl(input) { + t.Errorf("Should smell like github arg: %s\n", input) + } + host, repo, path, gitRef := parseGithubUrl(input) if host != hostSpec { t.Errorf("\n"+ " from %s\n"+ " actual host %s\n"+ "expected host %s\n", input, host, hostSpec) } - if repo != repoName { + if repo != orgRepo { t.Errorf("\n"+ " from %s\n"+ " actual Repo %s\n"+ - "expected Repo %s\n", input, repo, repoName) + "expected Repo %s\n", input, repo, orgRepo) } if path != pathName { t.Errorf("\n"+ @@ -171,7 +264,7 @@ func TestParseGithubUrl(t *testing.T) { } } -func TestNewRepoSpecFromUrl(t *testing.T) { +func TestNewRepoSpecFromUrlOld(t *testing.T) { testcases := []struct { input string repo string @@ -220,9 +313,9 @@ func TestNewRepoSpecFromUrl(t *testing.T) { if err != nil { t.Errorf("Unexpected error: %v", err) } - if rs.repo != testcase.repo { - t.Errorf("repo expected to be %v, but got %v on %s", - testcase.repo, rs.repo, testcase.input) + if rs.CloneSpec() != testcase.repo { + t.Errorf("CloneSpec expected to be %v, but got %v on %s", + testcase.repo, rs.CloneSpec(), testcase.input) } if rs.path != testcase.path { t.Errorf("path expected to be %v, but got %v on %s", From 79d357b460ddae3ff4f0377c97b0d1a8cf75c3eb Mon Sep 17 00:00:00 2001 From: Andrew Sauber Date: Wed, 23 Jan 2019 18:27:54 -0500 Subject: [PATCH 084/317] remove warning for using prefix/suffix in conjunction with a Namespace --- pkg/transformers/prefixsuffixname.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/pkg/transformers/prefixsuffixname.go b/pkg/transformers/prefixsuffixname.go index ec3304178..c4ca85f53 100644 --- a/pkg/transformers/prefixsuffixname.go +++ b/pkg/transformers/prefixsuffixname.go @@ -19,7 +19,6 @@ package transformers import ( "errors" "fmt" - "log" "sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/resmap" @@ -43,12 +42,6 @@ var prefixSuffixFieldSpecsToSkip = []config.FieldSpec{ }, } -// deprecateNamePrefixSuffixFieldSpec will be moved into -// prefixSuffixFieldSpecsToSkip in next release -var deprecateNamePrefixSuffixFieldSpec = config.FieldSpec{ - Gvk: gvk.Gvk{Kind: "Namespace"}, -} - // NewNamePrefixSuffixTransformer makes a namePrefixSuffixTransformer. func NewNamePrefixSuffixTransformer( np, ns string, fieldSpecs []config.FieldSpec) (Transformer, error) { @@ -86,11 +79,6 @@ func (o *namePrefixSuffixTransformer) Transform(m resmap.ResMap) error { } for id := range mf { - if id.Gvk().IsSelected(&deprecateNamePrefixSuffixFieldSpec.Gvk) { - log.Println( - "Adding prefix and suffix to Namespace " + - "resource will be deprecated in next release.") - } objMap := mf[id].Map() for _, path := range o.fieldSpecsToUse { if !id.Gvk().IsSelected(&path.Gvk) { From 731a2a683e1d118012f1466a0a76995bfd45610a Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Mon, 28 Jan 2019 14:27:59 -0800 Subject: [PATCH 085/317] add another hostname to test --- pkg/git/repospec_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/git/repospec_test.go b/pkg/git/repospec_test.go index 95f170410..fca5f45ca 100644 --- a/pkg/git/repospec_test.go +++ b/pkg/git/repospec_test.go @@ -138,6 +138,7 @@ var hostNamesRawAndNormalized = [][]string{ {"git::http://git.example.com/", "http://git.example.com/"}, {"git::https://git.example.com/", "https://git.example.com/"}, {"git@github.com:", "git@github.com:"}, + {"git@github.com/", "git@github.com:"}, {"git@gitlab2.sqtools.ru:10022/", "git@gitlab2.sqtools.ru:10022/"}, } From 31691f03307adcc16ccee10a1b17749c228917f7 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Mon, 28 Jan 2019 14:09:36 -0800 Subject: [PATCH 086/317] Replace all repo uri strings with git.RepoSpec. --- pkg/git/cloner.go | 31 ++++++++----- pkg/loader/fileloader.go | 87 ++++++++++++++++++++--------------- pkg/loader/fileloader_test.go | 45 +++--------------- pkg/loader/loader.go | 13 ++++-- 4 files changed, 85 insertions(+), 91 deletions(-) diff --git a/pkg/git/cloner.go b/pkg/git/cloner.go index 40c61ffba..465fdb1d1 100644 --- a/pkg/git/cloner.go +++ b/pkg/git/cloner.go @@ -25,23 +25,19 @@ import ( ) // Cloner is a function that can clone a git repo. -type Cloner func(url string) (*RepoSpec, error) +type Cloner func(repoSpec *RepoSpec) error // ClonerUsingGitExec uses a local git install, as opposed // to say, some remote API, to obtain a local clone of // a remote repo. -func ClonerUsingGitExec(spec string) (*RepoSpec, error) { +func ClonerUsingGitExec(repoSpec *RepoSpec) error { gitProgram, err := exec.LookPath("git") if err != nil { - return nil, errors.Wrap(err, "no 'git' program on path") - } - repoSpec, err := NewRepoSpecFromUrl(spec) - if err != nil { - return nil, err + return errors.Wrap(err, "no 'git' program on path") } repoSpec.cloneDir, err = fs.NewTmpConfirmedDir() if err != nil { - return nil, err + return err } cmd := exec.Command( gitProgram, @@ -52,17 +48,28 @@ func ClonerUsingGitExec(spec string) (*RepoSpec, error) { cmd.Stdout = &out err = cmd.Run() if err != nil { - return nil, errors.Wrapf(err, "trouble cloning %s", spec) + return errors.Wrapf(err, "trouble cloning %s", repoSpec.raw) } if repoSpec.ref == "" { - return repoSpec, nil + return nil } cmd = exec.Command(gitProgram, "checkout", repoSpec.ref) cmd.Dir = repoSpec.cloneDir.String() err = cmd.Run() if err != nil { - return nil, errors.Wrapf( + return errors.Wrapf( err, "trouble checking out href %s", repoSpec.ref) } - return repoSpec, nil + return nil +} + +// DoNothingCloner returns a cloner that only sets +// cloneDir field in the repoSpec. It's assumed that +// the cloneDir is associated with some fake filesystem +// used in a test. +func DoNothingCloner(dir fs.ConfirmedDir) Cloner { + return func(rs *RepoSpec) error { + rs.cloneDir = dir + return nil + } } diff --git a/pkg/loader/fileloader.go b/pkg/loader/fileloader.go index 11138eb17..97da3a117 100644 --- a/pkg/loader/fileloader.go +++ b/pkg/loader/fileloader.go @@ -114,44 +114,45 @@ func (l *fileLoader) Root() string { } func newLoaderOrDie(fSys fs.FileSystem, path string) *fileLoader { - l, err := newLoaderAtConfirmedDir( - path, fSys, nil, git.ClonerUsingGitExec) + root, err := demandDirectoryRoot(fSys, path) if err != nil { log.Fatalf("unable to make loader at '%s'; %v", path, err) } - return l + return newLoaderAtConfirmedDir( + root, fSys, nil, git.ClonerUsingGitExec) } // newLoaderAtConfirmedDir returns a new fileLoader with given root. func newLoaderAtConfirmedDir( - possibleRoot string, fSys fs.FileSystem, - referrer *fileLoader, cloner git.Cloner) (*fileLoader, error) { - if possibleRoot == "" { - return nil, fmt.Errorf( - "loader root cannot be empty") - } - root, f, err := fSys.CleanedAbs(possibleRoot) - if err != nil { - return nil, fmt.Errorf( - "absolute path error in '%s' : %v", possibleRoot, err) - } - if f != "" { - return nil, fmt.Errorf( - "got file '%s', but '%s' must be a directory to be a root", - f, possibleRoot) - } - if referrer != nil { - if err := referrer.errIfArgEqualOrHigher(root); err != nil { - return nil, err - } - } + root fs.ConfirmedDir, fSys fs.FileSystem, + referrer *fileLoader, cloner git.Cloner) *fileLoader { return &fileLoader{ root: root, referrer: referrer, fSys: fSys, cloner: cloner, cleaner: func() error { return nil }, - }, nil + } +} + +// Assure that the given path is in fact a directory. +func demandDirectoryRoot( + fSys fs.FileSystem, path string) (fs.ConfirmedDir, error) { + if path == "" { + return "", fmt.Errorf( + "loader root cannot be empty") + } + d, f, err := fSys.CleanedAbs(path) + if err != nil { + return "", fmt.Errorf( + "absolute path error in '%s' : %v", path, err) + } + if f != "" { + return "", fmt.Errorf( + "got file '%s', but '%s' must be a directory to be a root", + f, path) + } + return d, nil } // New returns a new Loader, rooted relative to current loader, @@ -160,26 +161,34 @@ func (l *fileLoader) New(path string) (ifc.Loader, error) { if path == "" { return nil, fmt.Errorf("new root cannot be empty") } - if git.IsRepoUrl(path) { - // Avoid cycles. - if err := l.errIfPreviouslySeenUri(path); err != nil { + repoSpec, err := git.NewRepoSpecFromUrl(path) + if err == nil { + // Treat this as git repo clone request. + if err := l.errIfRepoCycle(repoSpec); err != nil { return nil, err } - return newLoaderAtGitClone(path, l.fSys, l.referrer, l.cloner) + return newLoaderAtGitClone(repoSpec, l.fSys, l.referrer, l.cloner) } if filepath.IsAbs(path) { return nil, fmt.Errorf("new root '%s' cannot be absolute", path) } + root, err := demandDirectoryRoot(l.fSys, l.root.Join(path)) + if err != nil { + return nil, err + } + if err := l.errIfArgEqualOrHigher(root); err != nil { + return nil, err + } return newLoaderAtConfirmedDir( - l.root.Join(path), l.fSys, l, l.cloner) + root, l.fSys, l, l.cloner), nil } // newLoaderAtGitClone returns a new Loader pinned to a temporary // directory holding a cloned git repo. func newLoaderAtGitClone( - uri string, fSys fs.FileSystem, + repoSpec *git.RepoSpec, fSys fs.FileSystem, referrer *fileLoader, cloner git.Cloner) (ifc.Loader, error) { - repoSpec, err := cloner(uri) + err := cloner(repoSpec) if err != nil { return nil, err } @@ -187,6 +196,10 @@ func newLoaderAtGitClone( if err != nil { return nil, err } + // We don't know that the path requested in repoSpec + // is a directory until we actually clone it and look + // inside. That just happened, hence the error check + // is here. if f != "" { return nil, fmt.Errorf( "'%s' refers to file '%s'; expecting directory", @@ -221,17 +234,17 @@ func (l *fileLoader) errIfArgEqualOrHigher( // I.e. Allow a distinction between git URI with // path foo and tag bar and a git URI with the same // path but a different tag? -// TODO(monopole): Use parsed data instead of looking at Raw(). -func (l *fileLoader) errIfPreviouslySeenUri(uri string) error { - if strings.HasPrefix(l.repoSpec.Raw(), uri) { +func (l *fileLoader) errIfRepoCycle(newRepoSpec *git.RepoSpec) error { + // TODO(monopole): Use parsed data instead of Raw(). + if strings.HasPrefix(l.repoSpec.Raw(), newRepoSpec.Raw()) { return fmt.Errorf( "cycle detected: URI '%s' referenced by previous URI '%s'", - uri, l.repoSpec.Raw()) + newRepoSpec.Raw(), l.repoSpec.Raw()) } if l.referrer == nil { return nil } - return l.referrer.errIfPreviouslySeenUri(uri) + return l.referrer.errIfRepoCycle(newRepoSpec) } // Load returns content of file at the given relative path, diff --git a/pkg/loader/fileloader_test.go b/pkg/loader/fileloader_test.go index bf27c487b..f02552b8f 100644 --- a/pkg/loader/fileloader_test.go +++ b/pkg/loader/fileloader_test.go @@ -64,25 +64,6 @@ func MakeFakeFs(td []testData) fs.FileSystem { return fSys } -func TestNewLoaderAtConfirmedDir_DemandsDirectory(t *testing.T) { - fSys := MakeFakeFs(testCases) - _, err := newLoaderAtConfirmedDir("/foo", fSys, nil, nil) - if err != nil { - t.Fatalf("Unexpected error - a directory should work.") - } - _, err = newLoaderAtConfirmedDir("/foo/project", fSys, nil, nil) - if err != nil { - t.Fatalf("Unexpected error - a directory should work.") - } - _, err = newLoaderAtConfirmedDir("/foo/project/fileA.yaml", fSys, nil, nil) - if err == nil { - t.Fatalf("Expected error - a file should not work.") - } - if !strings.Contains(err.Error(), "must be a directory to be a root") { - t.Fatalf("unexpected err: %v", err) - } -} - func TestLoaderLoad(t *testing.T) { l1 := NewFileLoaderAtRoot(MakeFakeFs(testCases)) if "/" != l1.Root() { @@ -351,23 +332,6 @@ func TestSplit(t *testing.T) { } } -// makeFakeGitCloner returns a cloner that ignores the -// URL argument and returns a path in a fake file system -// that should already hold the 'repo' contents. -func makeFakeGitCloner(t *testing.T, fSys fs.FileSystem, coRoot string) git.Cloner { - if !fSys.IsDir(coRoot) { - t.Fatalf("expecting a directory at '%s'", coRoot) - } - return func(url string) (*git.RepoSpec, error) { - _, path := splitOnNthSlash(url, 3) - if !fSys.IsDir(coRoot + "/" + path) { - t.Fatalf("expecting a directory at '%s'/'%s'", - coRoot, path) - } - return git.NewRepoSpec(url, fs.ConfirmedDir(coRoot), path), nil - } -} - func TestNewLoaderAtGitClone(t *testing.T) { rootUrl := "github.com/someOrg/someRepo" pathInRepo := "foo/base" @@ -385,9 +349,14 @@ func TestNewLoaderAtGitClone(t *testing.T) { []byte(` whatever `)) + + repoSpec, err := git.NewRepoSpecFromUrl(url) + if err != nil { + t.Fatalf("unexpected err: %v\n", err) + } l, err := newLoaderAtGitClone( - url, fSys, nil, - makeFakeGitCloner(t, fSys, coRoot)) + repoSpec, fSys, nil, + git.DoNothingCloner(fs.ConfirmedDir(coRoot))) if err != nil { t.Fatalf("unexpected err: %v\n", err) } diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index 5e55ddfc1..53de6553a 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -24,11 +24,16 @@ import ( ) // NewLoader returns a Loader. -func NewLoader(root string, fSys fs.FileSystem) (ifc.Loader, error) { - if git.IsRepoUrl(root) { +func NewLoader(path string, fSys fs.FileSystem) (ifc.Loader, error) { + repoSpec, err := git.NewRepoSpecFromUrl(path) + if err == nil { return newLoaderAtGitClone( - root, fSys, nil, git.ClonerUsingGitExec) + repoSpec, fSys, nil, git.ClonerUsingGitExec) + } + root, err := demandDirectoryRoot(fSys, path) + if err != nil { + return nil, err } return newLoaderAtConfirmedDir( - root, fSys, nil, git.ClonerUsingGitExec) + root, fSys, nil, git.ClonerUsingGitExec), nil } From 8c2bff2c91a176bffcac8e748dc5a2c40bb9fa58 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Fri, 25 Jan 2019 15:01:18 -0800 Subject: [PATCH 087/317] Disallow cloned kustomization from using a local base outside the clone dir. --- pkg/loader/fileloader.go | 31 ++++++++++++++ pkg/loader/fileloader_test.go | 76 +++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/pkg/loader/fileloader.go b/pkg/loader/fileloader.go index 97da3a117..69e5a3d0d 100644 --- a/pkg/loader/fileloader.go +++ b/pkg/loader/fileloader.go @@ -176,6 +176,9 @@ func (l *fileLoader) New(path string) (ifc.Loader, error) { if err != nil { return nil, err } + if err := l.errIfGitContainmentViolation(root); err != nil { + return nil, err + } if err := l.errIfArgEqualOrHigher(root); err != nil { return nil, err } @@ -215,6 +218,34 @@ func newLoaderAtGitClone( }, nil } +func (l *fileLoader) errIfGitContainmentViolation( + base fs.ConfirmedDir) error { + containingRepo := l.containingRepo() + if containingRepo == nil { + return nil + } + if !base.HasPrefix(containingRepo.CloneDir()) { + return fmt.Errorf( + "security; bases in kustomizations found in "+ + "cloned git repos must be within the repo, "+ + "but base '%s' is outside '%s'", + base, containingRepo.CloneDir()) + } + return nil +} + +// Looks back through referrers for a git repo, returning nil +// if none found. +func (l *fileLoader) containingRepo() *git.RepoSpec { + if l.repoSpec != nil { + return l.repoSpec + } + if l.referrer == nil { + return nil + } + return l.referrer.containingRepo() +} + // errIfArgEqualOrHigher tests whether the argument, // is equal to or above the root of any ancestor. func (l *fileLoader) errIfArgEqualOrHigher( diff --git a/pkg/loader/fileloader_test.go b/pkg/loader/fileloader_test.go index f02552b8f..8b50b5756 100644 --- a/pkg/loader/fileloader_test.go +++ b/pkg/loader/fileloader_test.go @@ -386,3 +386,79 @@ whatever coRoot+"/"+pathInRepo, l2.Root()) } } + +func TestLoaderDisallowsLocalBaseFromRemoteOverlay(t *testing.T) { + // Define an overlay-base structure in the file system. + topDir := "/whatever" + cloneRoot := topDir + "/someClone" + fSys := fs.MakeFakeFS() + fSys.MkdirAll(topDir + "/highBase") + fSys.MkdirAll(cloneRoot + "/foo/base") + fSys.MkdirAll(cloneRoot + "/foo/overlay") + + var l1 ifc.Loader + + // Establish that a local overlay can navigate + // to the local bases. + l1 = newLoaderOrDie(fSys, cloneRoot+"/foo/overlay") + if l1.Root() != cloneRoot+"/foo/overlay" { + t.Fatalf("unexpected root %s", l1.Root()) + } + l2, err := l1.New("../base") + if err != nil { + t.Fatalf("unexpected err: %v\n", err) + } + if l2.Root() != cloneRoot+"/foo/base" { + t.Fatalf("unexpected root %s", l2.Root()) + } + l3, err := l2.New("../../../highBase") + if err != nil { + t.Fatalf("unexpected err: %v\n", err) + } + if l3.Root() != topDir+"/highBase" { + t.Fatalf("unexpected root %s", l3.Root()) + } + + // Establish that a Kustomization found in cloned + // repo can reach (non-remote) bases inside the clone + // but cannot reach a (non-remote) base outside the + // clone but legitimately on the local file system. + // This is to avoid a surprising interaction between + // a remote K and local files. The remote K would be + // non-functional on its own since by definition it + // would refer to a non-remote base file that didn't + // exist in its own repository, so presumably the + // remote K would be deliberately designed to phish + // for local K's. + repoSpec, err := git.NewRepoSpecFromUrl( + "github.com/someOrg/someRepo/foo/overlay") + if err != nil { + t.Fatalf("unexpected err: %v\n", err) + } + l1, err = newLoaderAtGitClone( + repoSpec, fSys, nil, + git.DoNothingCloner(fs.ConfirmedDir(cloneRoot))) + if err != nil { + t.Fatalf("unexpected err: %v\n", err) + } + if l1.Root() != cloneRoot+"/foo/overlay" { + t.Fatalf("unexpected root %s", l1.Root()) + } + // This is okay. + l2, err = l1.New("../base") + if err != nil { + t.Fatalf("unexpected err: %v\n", err) + } + if l2.Root() != cloneRoot+"/foo/base" { + t.Fatalf("unexpected root %s", l2.Root()) + } + // This is not okay. + l3, err = l2.New("../../../highBase") + if err == nil { + t.Fatalf("expected err") + } + if !strings.Contains(err.Error(), + "base '/whatever/highBase' is outside '/whatever/someClone'") { + t.Fatalf("unexpected err: %v", err) + } +} From 209b115b7c16df9a8f2f9bfa68a25f0f488868b8 Mon Sep 17 00:00:00 2001 From: Andrew Lavery Date: Sun, 27 Jan 2019 22:23:48 -0800 Subject: [PATCH 088/317] ignore yaml files that do not include any entries --- k8sdeps/kunstruct/factory.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/k8sdeps/kunstruct/factory.go b/k8sdeps/kunstruct/factory.go index 44222408f..09bb2bbba 100644 --- a/k8sdeps/kunstruct/factory.go +++ b/k8sdeps/kunstruct/factory.go @@ -52,6 +52,9 @@ func (kf *KunstructuredFactoryImpl) SliceFromBytes( var out unstructured.Unstructured err = decoder.Decode(&out) if err == nil { + if len(out.Object) == 0 { + continue + } err = kf.validate(out) if err != nil { return nil, err From 1997606372bcceb7274384ed4bfc6dc834a6511e Mon Sep 17 00:00:00 2001 From: Andrew Lavery Date: Tue, 29 Jan 2019 13:16:00 -0800 Subject: [PATCH 089/317] add empty objects test for kunstruct SliceFromBytes --- k8sdeps/kunstruct/factory_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/k8sdeps/kunstruct/factory_test.go b/k8sdeps/kunstruct/factory_test.go index 2ef4acaa9..51e2be793 100644 --- a/k8sdeps/kunstruct/factory_test.go +++ b/k8sdeps/kunstruct/factory_test.go @@ -109,6 +109,18 @@ WOOOOOOOOOOOOOOOOOOOOOOOOT: woot expectedOut: []ifc.Kunstructured{}, expectedErr: true, }, + { + name: "emptyObjects", + input: []byte(` +--- +#a comment + +--- + +`), + expectedOut: []ifc.Kunstructured{}, + expectedErr: false, + }, { name: "Missing .metadata.name in object", input: []byte(` From 35daae1715d97201456e623d3471cd5d61259e76 Mon Sep 17 00:00:00 2001 From: jregan Date: Tue, 29 Jan 2019 11:59:00 -0800 Subject: [PATCH 090/317] Delete some dead code and fix nits. --- pkg/commands/build/build.go | 16 +- pkg/commands/build/build_test.go | 2 +- pkg/git/repospec.go | 18 --- pkg/git/repospec_test.go | 147 +----------------- pkg/image/append.go | 33 ---- pkg/image/{imagetag.go => deprecatedimage.go} | 5 +- pkg/loader/fileloader_test.go | 15 +- pkg/transformers/config/factory.go | 31 +--- pkg/transformers/config/factory_test.go | 6 +- pkg/transformers/image.go | 20 +-- 10 files changed, 30 insertions(+), 263 deletions(-) delete mode 100644 pkg/image/append.go rename pkg/image/{imagetag.go => deprecatedimage.go} (89%) diff --git a/pkg/commands/build/build.go b/pkg/commands/build/build.go index 0c3d1e425..43c1a982f 100644 --- a/pkg/commands/build/build.go +++ b/pkg/commands/build/build.go @@ -29,15 +29,15 @@ import ( "sigs.k8s.io/kustomize/pkg/target" ) -// BuildOptions contain the options for running a build -type BuildOptions struct { +// Options contain the options for running a build +type Options struct { kustomizationPath string outputPath string } -// NewBuildOptions creates a BuildOptions object -func NewBuildOptions(p, o string) *BuildOptions { - return &BuildOptions{ +// NewOptions creates a Options object +func NewOptions(p, o string) *Options { + return &Options{ kustomizationPath: p, outputPath: o, } @@ -63,7 +63,7 @@ func NewCmdBuild( out io.Writer, fs fs.FileSystem, rf *resmap.Factory, ptf transformer.Factory) *cobra.Command { - var o BuildOptions + var o Options cmd := &cobra.Command{ Use: "build [path]", @@ -86,7 +86,7 @@ func NewCmdBuild( } // Validate validates build command. -func (o *BuildOptions) Validate(args []string) error { +func (o *Options) Validate(args []string) error { if len(args) > 1 { return errors.New("specify one path to " + constants.KustomizationFileNames[0]) } @@ -100,7 +100,7 @@ func (o *BuildOptions) Validate(args []string) error { } // RunBuild runs build command. -func (o *BuildOptions) RunBuild( +func (o *Options) RunBuild( out io.Writer, fSys fs.FileSystem, rf *resmap.Factory, ptf transformer.Factory) error { ldr, err := loader.NewLoader(o.kustomizationPath, fSys) diff --git a/pkg/commands/build/build_test.go b/pkg/commands/build/build_test.go index 95859e529..169de1ad4 100644 --- a/pkg/commands/build/build_test.go +++ b/pkg/commands/build/build_test.go @@ -36,7 +36,7 @@ func TestBuildValidate(t *testing.T) { "", "specify one path to " + constants.KustomizationFileNames[0]}, } for _, mycase := range cases { - opts := BuildOptions{} + opts := Options{} e := opts.Validate(mycase.args) if len(mycase.erMsg) > 0 { if e == nil { diff --git a/pkg/git/repospec.go b/pkg/git/repospec.go index 046d92be9..db8b1b908 100644 --- a/pkg/git/repospec.go +++ b/pkg/git/repospec.go @@ -72,19 +72,6 @@ func (x *RepoSpec) Cleaner(fSys fs.FileSystem) func() error { return func() error { return fSys.RemoveAll(x.cloneDir.String()) } } -// IsRepoUrl checks if a string is likely a github repo Url. -func IsRepoUrl(arg string) bool { - arg = strings.ToLower(arg) - return !filepath.IsAbs(arg) && - (strings.HasPrefix(arg, "git::") || - strings.HasPrefix(arg, "gh:") || - strings.HasPrefix(arg, "ssh:") || - strings.HasPrefix(arg, "github.com") || - strings.HasPrefix(arg, "git@") || - strings.Index(arg, "github.com/") > -1 || - isAzureHost(arg) || isAWSHost(arg)) -} - // From strings like git@github.com:someOrg/someRepo.git or // https://github.com/someOrg/someRepo?ref=someHash, extract // the parts. @@ -104,11 +91,6 @@ func NewRepoSpecFromUrl(n string) (*RepoSpec, error) { path: path, ref: gitRef}, nil } -func NewRepoSpec( - raw string, cloneDir fs.ConfirmedDir, path string) *RepoSpec { - return &RepoSpec{raw: raw, cloneDir: cloneDir, path: path} -} - const ( refQuery = "?ref=" gitSuffix = ".git" diff --git a/pkg/git/repospec_test.go b/pkg/git/repospec_test.go index fca5f45ca..0413af6d7 100644 --- a/pkg/git/repospec_test.go +++ b/pkg/git/repospec_test.go @@ -23,106 +23,12 @@ import ( "testing" ) -func TestIsRepoURL(t *testing.T) { - - testcases := []struct { - input string - expected bool - }{ - { - input: "https://github.com/org/repo", - expected: true, - }, - { - input: "github.com/org/repo", - expected: true, - }, - { - input: "git@github.com:org/repo", - expected: true, - }, - { - input: "gh:org/repo", - expected: true, - }, - { - input: "git::https://gitlab.com/org/repo", - expected: true, - }, - { - input: "git@gitlab2.sqtools.ru:10022/infra/kubernetes/thanos-base.git?ref=v0.1.0", - expected: true, - }, - { - input: "git@bitbucket.org:org/repo.git", - expected: true, - }, - { - input: "git::http://git.example.com/org/repo.git", - expected: true, - }, - { - input: "git::https://git.example.com/org/repo.git", - expected: true, - }, - { - input: "ssh://git.example.com:7999/org/repo.git", - expected: true, - }, - { - input: "/github.com/org/repo", - expected: false, - }, - { - input: "/abs/path/to/file", - expected: false, - }, - { - input: "../relative", - expected: false, - }, - { - input: "foo", - expected: false, - }, - { - input: ".", - expected: false, - }, - { - input: "", - expected: false, - }, - } - for _, tc := range testcases { - actual := IsRepoUrl(tc.input) - if actual != tc.expected { - t.Errorf("unexpected error: unexpected result %t for input %s", actual, tc.input) - } - } -} - var orgRepos = []string{"someOrg/someRepo", "kubernetes/website"} var pathNames = []string{"README.md", "foo/krusty.txt", ""} var hrefArgs = []string{"someBranch", "master", "v0.1.0", ""} -var hostNamesRawAndNormalizedOld = map[string]string{ - "gh:%s": "gh:", - "GH:%s": "gh:", - "git@github.com:%s": "git@github.com:", - "gitHub.com/%s": "https://github.com/", - "https://github.com/%s": "https://github.com/", - "hTTps://github.com/%s": "https://github.com/", - "git::https://gitlab.com/%s": "https://gitlab.com/", - "github.com:%s": "https://github.com/", - "git::http://git.example.com/%s": "http://git.example.com/", - "git::https://git.example.com/%s": "https://git.example.com/", - "ssh://git.example.com:7999/%s": "ssh://git.example.com:7999/", - "https://git-codecommit.us-east-2.amazonaws.com/%s": "https://git-codecommit.us-east-2.amazonaws.com/", -} - var hostNamesRawAndNormalized = [][]string{ {"gh:", "gh:"}, {"GH:", "gh:"}, @@ -142,17 +48,6 @@ var hostNamesRawAndNormalized = [][]string{ {"git@gitlab2.sqtools.ru:10022/", "git@gitlab2.sqtools.ru:10022/"}, } -func makeUrlOld(hostFmt, orgRepo, path, href string) string { - if len(path) > 0 { - orgRepo = filepath.Join(orgRepo, path) - } - url := fmt.Sprintf(hostFmt, orgRepo) - if href != "" { - url += refQuery + href - } - return url -} - func makeUrl(hostFmt, orgRepo, path, href string) string { if len(path) > 0 { orgRepo = filepath.Join(orgRepo, path) @@ -225,47 +120,7 @@ func TestNewRepoSpecFromUrlErrors(t *testing.T) { } } -func TestParseGithubUrl(t *testing.T) { - for hostRawFmt, hostSpec := range hostNamesRawAndNormalizedOld { - for _, orgRepo := range orgRepos { - for _, pathName := range pathNames { - for _, hrefArg := range hrefArgs { - input := makeUrlOld(hostRawFmt, orgRepo, pathName, hrefArg) - if !IsRepoUrl(input) { - t.Errorf("Should smell like github arg: %s\n", input) - } - host, repo, path, gitRef := parseGithubUrl(input) - if host != hostSpec { - t.Errorf("\n"+ - " from %s\n"+ - " actual host %s\n"+ - "expected host %s\n", input, host, hostSpec) - } - if repo != orgRepo { - t.Errorf("\n"+ - " from %s\n"+ - " actual Repo %s\n"+ - "expected Repo %s\n", input, repo, orgRepo) - } - if path != pathName { - t.Errorf("\n"+ - " from %s\n"+ - " actual Path %s\n"+ - "expected Path %s\n", input, path, pathName) - } - if gitRef != hrefArg { - t.Errorf("\n"+ - " from %s\n"+ - " actual Href %s\n"+ - "expected Href %s\n", input, gitRef, hrefArg) - } - } - } - } - } -} - -func TestNewRepoSpecFromUrlOld(t *testing.T) { +func TestNewRepoSpecFromUrl_CloneSpecs(t *testing.T) { testcases := []struct { input string repo string diff --git a/pkg/image/append.go b/pkg/image/append.go deleted file mode 100644 index ae479b0f1..000000000 --- a/pkg/image/append.go +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package image - -// Append appends a slice of type Tag to slice of type Image -func Append(images []Image, tags ...ImageTag) []Image { - for _, tag := range tags { - images = append(images, toImage(tag)) - } - return images -} - -func toImage(tag ImageTag) Image { - return Image{ - Name: tag.Name, - NewTag: tag.NewTag, - Digest: tag.Digest, - } -} diff --git a/pkg/image/imagetag.go b/pkg/image/deprecatedimage.go similarity index 89% rename from pkg/image/imagetag.go rename to pkg/image/deprecatedimage.go index acff10a50..65db4051b 100644 --- a/pkg/image/imagetag.go +++ b/pkg/image/deprecatedimage.go @@ -16,9 +16,10 @@ limitations under the License. package image -// ImageTag contains an image and a new tag, which will replace the original tag. +// DeprecatedImage contains an image and a new tag, +// which will replace the original tag. // Deprecated, instead use Image. -type ImageTag struct { +type DeprecatedImage struct { // Name is a tag-less image name. Name string `json:"name,omitempty" yaml:"name,omitempty"` diff --git a/pkg/loader/fileloader_test.go b/pkg/loader/fileloader_test.go index 8b50b5756..92ae3368e 100644 --- a/pkg/loader/fileloader_test.go +++ b/pkg/loader/fileloader_test.go @@ -320,14 +320,14 @@ func splitOnNthSlash(v string, n int) (string, string) { } func TestSplit(t *testing.T) { - path := "a/b/c/d/e/f/g" - if left, right := splitOnNthSlash(path, 2); left != "a/b" || right != "c/d/e/f/g" { + p := "a/b/c/d/e/f/g" + if left, right := splitOnNthSlash(p, 2); left != "a/b" || right != "c/d/e/f/g" { t.Fatalf("got left='%s', right='%s'", left, right) } - if left, right := splitOnNthSlash(path, 3); left != "a/b/c" || right != "d/e/f/g" { + if left, right := splitOnNthSlash(p, 3); left != "a/b/c" || right != "d/e/f/g" { t.Fatalf("got left='%s', right='%s'", left, right) } - if left, right := splitOnNthSlash(path, 6); left != "a/b/c/d/e/f" || right != "g" { + if left, right := splitOnNthSlash(p, 6); left != "a/b/c/d/e/f" || right != "g" { t.Fatalf("got left='%s', right='%s'", left, right) } } @@ -336,10 +336,6 @@ func TestNewLoaderAtGitClone(t *testing.T) { rootUrl := "github.com/someOrg/someRepo" pathInRepo := "foo/base" url := rootUrl + "/" + pathInRepo - if !git.IsRepoUrl(url) { - t.Fatalf("'%s' should be accepted as a repo url", url) - } - coRoot := "/tmp" fSys := fs.MakeFakeFS() fSys.MkdirAll(coRoot) @@ -374,9 +370,6 @@ whatever pathInRepo = "foo/overlay" fSys.MkdirAll(coRoot + "/" + pathInRepo) url = rootUrl + "/" + pathInRepo - if !git.IsRepoUrl(url) { - t.Fatalf("'%s' should be accepted as a repo url", url) - } l2, err := l.New(url) if err != nil { t.Fatalf("unexpected error: %v", err) diff --git a/pkg/transformers/config/factory.go b/pkg/transformers/config/factory.go index 9def6a6e2..d0ea0d1dd 100644 --- a/pkg/transformers/config/factory.go +++ b/pkg/transformers/config/factory.go @@ -28,36 +28,9 @@ type Factory struct { ldr ifc.Loader } -// TODO(#606): Setting this to false satisfies the feature -// request in 606. The todo is to delete the non-active -// code path in a subsequent PR. -const demandExplicitConfig = false - -func MakeTransformerConfig( - ldr ifc.Loader, paths []string) (*TransformerConfig, error) { - if demandExplicitConfig { - return loadConfigFromDiskOrDefaults(ldr, paths) - } - return mergeCustomConfigWithDefaults(ldr, paths) -} - -// loadConfigFromDiskOrDefaults returns a TransformerConfig object -// built from either files or the hardcoded default configs. -// There's no merging, it's one or the other. This is preferred -// if one wants all configuration to be explicit in version -// control, as opposed to relying on a mix of files and -// hard-coded config. -func loadConfigFromDiskOrDefaults( - ldr ifc.Loader, paths []string) (*TransformerConfig, error) { - if paths == nil || len(paths) == 0 { - return MakeDefaultConfig(), nil - } - return NewFactory(ldr).FromFiles(paths) -} - -// mergeCustomConfigWithDefaults returns a merger of custom config, +// MakeTransformerConfig returns a merger of custom config, // if any, with default config. -func mergeCustomConfigWithDefaults( +func MakeTransformerConfig( ldr ifc.Loader, paths []string) (*TransformerConfig, error) { t1 := MakeDefaultConfig() if len(paths) == 0 { diff --git a/pkg/transformers/config/factory_test.go b/pkg/transformers/config/factory_test.go index a380af74c..04ad211d5 100644 --- a/pkg/transformers/config/factory_test.go +++ b/pkg/transformers/config/factory_test.go @@ -31,9 +31,9 @@ func TestMakeDefaultConfig(t *testing.T) { } func makeTestLoader(path, content string) ifc.Loader { - fs := fs.MakeFakeFS() - fs.WriteFile(path, []byte(content)) - return loader.NewFileLoaderAtRoot(fs) + fSys := fs.MakeFakeFS() + fSys.WriteFile(path, []byte(content)) + return loader.NewFileLoaderAtRoot(fSys) } func TestFromFiles(t *testing.T) { diff --git a/pkg/transformers/image.go b/pkg/transformers/image.go index 6dbc94412..f6f999d1e 100644 --- a/pkg/transformers/image.go +++ b/pkg/transformers/image.go @@ -84,22 +84,18 @@ func (pt *imageTransformer) updateContainers(obj map[string]interface{}, path st } imageName := containerImage.(string) - for _, image := range pt.images { - if isImageMatched(imageName, image.Name) { + for _, img := range pt.images { + if isImageMatched(imageName, img.Name) { name, tag := split(imageName) - - if image.NewName != "" { - name = image.NewName + if img.NewName != "" { + name = img.NewName } - - if image.NewTag != "" { - tag = ":" + image.NewTag + if img.NewTag != "" { + tag = ":" + img.NewTag } - - if image.Digest != "" { - tag = "@" + image.Digest + if img.Digest != "" { + tag = "@" + img.Digest } - container["image"] = name + tag break } From cdcc0052a6545e8e7b098af66080dcf07ccba028 Mon Sep 17 00:00:00 2001 From: Yoan Blanc Date: Wed, 30 Jan 2019 16:45:17 +0100 Subject: [PATCH 091/317] examples: typo --- examples/image.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/image.md b/examples/image.md index a6248c1f3..6e3eed6c0 100644 --- a/examples/image.md +++ b/examples/image.md @@ -52,7 +52,7 @@ cd $DEMO_HOME kustomize edit set image busybox=alpine:3.6 ``` -The folowing `images` will be added to `kustomization.yaml`: +The following `images` will be added to `kustomization.yaml`: > ``` > images: > - name: busybox From 199763dec8e8416311299ff97bb8c8894106f4d7 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Wed, 30 Jan 2019 09:48:12 -0800 Subject: [PATCH 092/317] add group name to kustomize.config.k8s.io --- docs/kustomization.yaml | 2 +- pkg/commands/kustfile/kustomizationfile_test.go | 6 +++--- pkg/fs/fakefs.go | 2 +- pkg/target/configmaps_test.go | 10 +++++----- pkg/target/crd_test.go | 4 ++-- pkg/target/generatormergeandreplace_test.go | 6 +++--- pkg/target/kusttarget_test.go | 2 +- pkg/target/multiplepatch_test.go | 4 ++-- pkg/target/namespacedgenerators_test.go | 2 +- pkg/target/utils_for_test.go | 2 +- pkg/target/variableref_test.go | 8 ++++---- pkg/types/kustomization.go | 2 +- 12 files changed, 25 insertions(+), 25 deletions(-) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index 15f03864c..781da106e 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -32,7 +32,7 @@ # visible in configuration reviews. # ---------------------------------------------------- # apiVersion and kind of Kustomization -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization # Adds namespace to all resources. diff --git a/pkg/commands/kustfile/kustomizationfile_test.go b/pkg/commands/kustfile/kustomizationfile_test.go index d2dd19a45..79e3a5da3 100644 --- a/pkg/commands/kustfile/kustomizationfile_test.go +++ b/pkg/commands/kustfile/kustomizationfile_test.go @@ -127,7 +127,7 @@ func TestPreserveComments(t *testing.T) { `# shem qing some comments # This is some comment we should preserve # don't delete it -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - pod.yaml @@ -181,7 +181,7 @@ resources: # See which field this comment goes into - service.yaml -APIVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: kustomization # something you may want to keep @@ -219,7 +219,7 @@ resources: - pod.yaml - service.yaml -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: kustomization # something you may want to keep diff --git a/pkg/fs/fakefs.go b/pkg/fs/fakefs.go index 1a8fad667..59c0966b2 100644 --- a/pkg/fs/fakefs.go +++ b/pkg/fs/fakefs.go @@ -40,7 +40,7 @@ func MakeFakeFS() *fakeFs { } // kustomizationContent is used in tests. -const kustomizationContent = `apiVersion: v1beta1 +const kustomizationContent = `apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namePrefix: some-prefix nameSuffix: some-suffix diff --git a/pkg/target/configmaps_test.go b/pkg/target/configmaps_test.go index 4de2ae326..9d62a6847 100644 --- a/pkg/target/configmaps_test.go +++ b/pkg/target/configmaps_test.go @@ -23,7 +23,7 @@ import ( func TestGenerator1(t *testing.T) { th := NewKustTestHarness(t, "/app/overlay") th.writeK("/app/base1", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namePrefix: p1- configMapGenerator: @@ -33,7 +33,7 @@ configMapGenerator: - from=base `) th.writeK("/app/base2", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namePrefix: p2- configMapGenerator: @@ -43,7 +43,7 @@ configMapGenerator: - from=base `) th.writeK("/app/overlay/o1", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization bases: - ../../base1 @@ -54,7 +54,7 @@ configMapGenerator: - from=overlay `) th.writeK("/app/overlay/o2", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization bases: - ../../base2 @@ -65,7 +65,7 @@ configMapGenerator: - from=overlay `) th.writeK("/app/overlay", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization bases: - o1 diff --git a/pkg/target/crd_test.go b/pkg/target/crd_test.go index f6d955134..a8e9a757d 100644 --- a/pkg/target/crd_test.go +++ b/pkg/target/crd_test.go @@ -22,7 +22,7 @@ import ( func writeBaseWithCrd(th *KustTestHarness) { th.writeK("/app/base", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization crds: - mycrd.json @@ -273,7 +273,7 @@ func TestCrdWithOverlay(t *testing.T) { th := NewKustTestHarness(t, "/app/overlay") writeBaseWithCrd(th) th.writeK("/app/overlay", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namePrefix: prod- bases: diff --git a/pkg/target/generatormergeandreplace_test.go b/pkg/target/generatormergeandreplace_test.go index a08ad37dc..028dd63e9 100644 --- a/pkg/target/generatormergeandreplace_test.go +++ b/pkg/target/generatormergeandreplace_test.go @@ -23,7 +23,7 @@ import ( func TestSimpleBase(t *testing.T) { th := NewKustTestHarness(t, "/app/base") th.writeK("/app/base", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namePrefix: team-foo- commonLabels: @@ -163,7 +163,7 @@ spec: func makeBaseWithGenerators(th *KustTestHarness) { th.writeK("/app", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namePrefix: team-foo- commonLabels: @@ -341,7 +341,7 @@ spec: name: configmap-in-overlay `) th.writeK("/overlay", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namePrefix: staging- commonLabels: diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index 7d720c666..de60fe016 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -33,7 +33,7 @@ import ( const ( kustomizationContent1 = ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namePrefix: foo- nameSuffix: -bar diff --git a/pkg/target/multiplepatch_test.go b/pkg/target/multiplepatch_test.go index ac4e350c6..6b5ed8ddb 100644 --- a/pkg/target/multiplepatch_test.go +++ b/pkg/target/multiplepatch_test.go @@ -23,7 +23,7 @@ import ( func makeCommonFileForMultiplePatchTest(th *KustTestHarness) { th.writeK("/app/base", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namePrefix: team-foo- commonLabels: @@ -80,7 +80,7 @@ spec: app: nginx `) th.writeK("/app/overlay/staging", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namePrefix: staging- commonLabels: diff --git a/pkg/target/namespacedgenerators_test.go b/pkg/target/namespacedgenerators_test.go index 7977d6737..2d46f0727 100644 --- a/pkg/target/namespacedgenerators_test.go +++ b/pkg/target/namespacedgenerators_test.go @@ -23,7 +23,7 @@ import ( func TestNamespacedGenerator(t *testing.T) { th := NewKustTestHarness(t, "/app") th.writeK("/app", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization configMapGenerator: - name: the-non-default-namespace-map diff --git a/pkg/target/utils_for_test.go b/pkg/target/utils_for_test.go index e3541e6a7..d62598a3b 100644 --- a/pkg/target/utils_for_test.go +++ b/pkg/target/utils_for_test.go @@ -75,7 +75,7 @@ func (th *KustTestHarness) writeF(dir string, content string) { func (th *KustTestHarness) writeK(dir string, content string) { th.writeF(filepath.Join(dir, constants.KustomizationFileNames[0]), ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization `+content) } diff --git a/pkg/target/variableref_test.go b/pkg/target/variableref_test.go index f923a026a..afe6ea3cb 100644 --- a/pkg/target/variableref_test.go +++ b/pkg/target/variableref_test.go @@ -23,7 +23,7 @@ import ( func TestVariableRef(t *testing.T) { th := NewKustTestHarness(t, "/app/overlay/staging") th.writeK("/app/base", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namePrefix: base- resources: @@ -323,7 +323,7 @@ spec: storage: 1Gi `) th.writeK("/app/overlay/staging", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namePrefix: dev- bases: @@ -583,7 +583,7 @@ spec: func TestVariableRefIngress(t *testing.T) { th := NewKustTestHarness(t, "/app/overlay") th.writeK("/app/base", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - deployment.yaml @@ -657,7 +657,7 @@ spec: targetPort: http `) th.writeK("/app/overlay", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization nameprefix: kustomized- bases: diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 4c75b0a43..c78fb9f89 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -25,7 +25,7 @@ import ( ) const ( - KustomizationVersion = "v1beta1" + KustomizationVersion = "kustomize.config.k8s.io/v1beta1" KustomizationKind = "Kustomization" ) From 1d263d24ddbff511f5616e5e40549f627b951f42 Mon Sep 17 00:00:00 2001 From: Andrew Lavery Date: Wed, 30 Jan 2019 14:52:07 -0800 Subject: [PATCH 093/317] replaceVars returns nil on nil input, not error includes an integration test for 'null' args inputs --- pkg/target/nullvalues_test.go | 78 +++++++++++++++++++++++++++++++++++ pkg/transformers/refvars.go | 2 + 2 files changed, 80 insertions(+) create mode 100644 pkg/target/nullvalues_test.go diff --git a/pkg/target/nullvalues_test.go b/pkg/target/nullvalues_test.go new file mode 100644 index 000000000..06ca1ddc0 --- /dev/null +++ b/pkg/target/nullvalues_test.go @@ -0,0 +1,78 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "testing" +) + +func TestNullValues(t *testing.T) { + th := NewKustTestHarness(t, "/app") + th.writeF("/app/deployment.yaml", ` +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: example + name: example +spec: + selector: + matchLabels: + app: example + template: + metadata: + labels: + app: example + spec: + containers: + - args: null + image: image + name: example +`) + th.writeF("/app/kustomization.yaml", ` +apiVersion: v1beta1 +kind: Kustomization +resources: +- deployment.yaml +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + + th.assertActualEqualsExpected(m, ` +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: example + name: example +spec: + selector: + matchLabels: + app: example + template: + metadata: + labels: + app: example + spec: + containers: + - args: null + image: image + name: example +`) +} diff --git a/pkg/transformers/refvars.go b/pkg/transformers/refvars.go index d2a9983af..3e2d18523 100644 --- a/pkg/transformers/refvars.go +++ b/pkg/transformers/refvars.go @@ -42,6 +42,8 @@ func (rv *refvarTransformer) replaceVars(in interface{}) (interface{}, error) { return nil, fmt.Errorf("%#v is expected to be %T", in, s) } return expansion.Expand(s, rv.mappingFunc), nil + case nil: + return nil, nil default: return "", fmt.Errorf("invalid type encountered %T", vt) } From f550540318f4584fbe01e2e0da9ceb9b62035e22 Mon Sep 17 00:00:00 2001 From: Roli Schilter Date: Wed, 30 Jan 2019 12:25:05 -0800 Subject: [PATCH 094/317] Document SMP behavior for custom resources Documents how strategic merge patches are treated as json merge patches when dealing with custom resources. --- docs/glossary.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/glossary.md b/docs/glossary.md index 4fca944db..7c5c7c989 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -5,6 +5,7 @@ [Declarative Application Management]: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/architecture/declarative-application-management.md [JSON]: https://www.json.org/ [JSONPatch]: https://tools.ietf.org/html/rfc6902 +[JSONMergePatch]: https://tools.ietf.org/html/rfc7386 [Resource]: #resource [YAML]: http://www.yaml.org/start.html [application]: #application @@ -298,6 +299,9 @@ directives include _replace_ (the default), _merge_ (avoid replacing a list), _delete_ and a few more (see [these notes][strategic-merge]). +Note that for custom resources, SMPs are treated as +[json merge patches][JSONMergePatch]. + Fun fact - any resource file can be used as an SMP, overwriting matching fields in another resource with the same group/version/kind/name, From bf18cf2d9e0638bd8c069b31bd167716b061b1fc Mon Sep 17 00:00:00 2001 From: Michael Goodness Date: Thu, 31 Jan 2019 09:20:49 -0600 Subject: [PATCH 095/317] Add Service nameReference to APIService Signed-off-by: Michael Goodness --- pkg/transformers/config/defaultconfig/namereference.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/transformers/config/defaultconfig/namereference.go b/pkg/transformers/config/defaultconfig/namereference.go index 0b188f867..35d4b7de0 100644 --- a/pkg/transformers/config/defaultconfig/namereference.go +++ b/pkg/transformers/config/defaultconfig/namereference.go @@ -245,6 +245,9 @@ nameReference: kind: Ingress - path: spec/backend/serviceName kind: Ingress + - path: spec/service/name + kind: APIService + group: apiregistration.k8s.io - kind: Role group: rbac.authorization.k8s.io From 84057436d683e2403318db38b3b4cb74c927b3e0 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Thu, 31 Jan 2019 15:14:10 -0800 Subject: [PATCH 096/317] Combine generatorArgs and generatorOptions into options of Resource --- k8sdeps/transformer/hash/namehash.go | 2 +- k8sdeps/transformer/hash/namehash_test.go | 10 ++-- pkg/resmap/factory_test.go | 16 ++--- pkg/resmap/resmap.go | 13 ++--- pkg/resmap/resmap_test.go | 31 +++++----- pkg/resource/factory.go | 28 +++++---- pkg/resource/resource.go | 30 +++++----- pkg/resource/resource_test.go | 4 +- pkg/target/generatoroptions_test.go | 71 +++++++++++++++++++++++ pkg/target/kusttarget.go | 12 +--- pkg/target/kusttarget_test.go | 8 +-- pkg/target/utils_for_test.go | 5 ++ pkg/types/genargs.go | 47 +++++++++++++++ pkg/{ifc => types}/generationbehavior.go | 2 +- 14 files changed, 202 insertions(+), 77 deletions(-) create mode 100644 pkg/target/generatoroptions_test.go create mode 100644 pkg/types/genargs.go rename pkg/{ifc => types}/generationbehavior.go (99%) diff --git a/k8sdeps/transformer/hash/namehash.go b/k8sdeps/transformer/hash/namehash.go index 75b9e893c..a52072e8a 100644 --- a/k8sdeps/transformer/hash/namehash.go +++ b/k8sdeps/transformer/hash/namehash.go @@ -35,7 +35,7 @@ func NewNameHashTransformer() transformers.Transformer { // Transform appends hash to generated resources. func (o *nameHashTransformer) Transform(m resmap.ResMap) error { for _, res := range m { - if res.IsGenerated() { + if res.NeedHashSuffix() { h, err := NewKustHash().Hash(res.Map()) if err != nil { return err diff --git a/k8sdeps/transformer/hash/namehash_test.go b/k8sdeps/transformer/hash/namehash_test.go index f476c14d8..7ca724511 100644 --- a/k8sdeps/transformer/hash/namehash_test.go +++ b/k8sdeps/transformer/hash/namehash_test.go @@ -21,10 +21,10 @@ import ( "testing" "sigs.k8s.io/kustomize/k8sdeps/kunstruct" - "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" + "sigs.k8s.io/kustomize/pkg/types" ) func TestNameHashTransformer(t *testing.T) { @@ -81,14 +81,14 @@ func TestNameHashTransformer(t *testing.T) { }, }, }), - resid.NewResId(secret, "secret1"): rf.FromMap( + resid.NewResId(secret, "secret1"): rf.FromMapAndOption( map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", "metadata": map[string]interface{}{ "name": "secret1", }, - }).SetBehavior(ifc.BehaviorCreate), + }, &types.GeneratorArgs{Behavior: "create"}, &types.GeneratorOptions{DisableNameSuffixHash: false}), } expected := resmap.ResMap{ @@ -142,14 +142,14 @@ func TestNameHashTransformer(t *testing.T) { }, }, }), - resid.NewResId(secret, "secret1"): rf.FromMap( + resid.NewResId(secret, "secret1"): rf.FromMapAndOption( map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", "metadata": map[string]interface{}{ "name": "secret1-7kc45hd5f7", }, - }).SetBehavior(ifc.BehaviorCreate), + }, &types.GeneratorArgs{Behavior: "create"}, &types.GeneratorOptions{DisableNameSuffixHash: false}), } tran := NewNameHashTransformer() diff --git a/pkg/resmap/factory_test.go b/pkg/resmap/factory_test.go index 27e12b86d..5d20250b1 100644 --- a/pkg/resmap/factory_test.go +++ b/pkg/resmap/factory_test.go @@ -162,7 +162,7 @@ func TestNewFromConfigMaps(t *testing.T) { filepath: "/whatever/project/app.env", content: "DB_USERNAME=admin\nDB_PASSWORD=somepw", expected: ResMap{ - resid.NewResId(cmap, "envConfigMap"): rf.FromMap( + resid.NewResId(cmap, "envConfigMap"): rf.FromMapAndOption( map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -173,7 +173,7 @@ func TestNewFromConfigMaps(t *testing.T) { "DB_USERNAME": "admin", "DB_PASSWORD": "somepw", }, - }).SetBehavior(ifc.BehaviorCreate), + }, &types.GeneratorArgs{}, nil), }, }, { @@ -190,7 +190,7 @@ func TestNewFromConfigMaps(t *testing.T) { filepath: "/whatever/project/app-init.ini", content: "FOO=bar\nBAR=baz\n", expected: ResMap{ - resid.NewResId(cmap, "fileConfigMap"): rf.FromMap( + resid.NewResId(cmap, "fileConfigMap"): rf.FromMapAndOption( map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -202,7 +202,7 @@ func TestNewFromConfigMaps(t *testing.T) { BAR=baz `, }, - }).SetBehavior(ifc.BehaviorCreate), + }, &types.GeneratorArgs{}, nil), }, }, { @@ -218,7 +218,7 @@ BAR=baz }, }, expected: ResMap{ - resid.NewResId(cmap, "literalConfigMap"): rf.FromMap( + resid.NewResId(cmap, "literalConfigMap"): rf.FromMapAndOption( map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -231,7 +231,7 @@ BAR=baz "c": "Good Morning", "d": "false", }, - }).SetBehavior(ifc.BehaviorCreate), + }, &types.GeneratorArgs{}, nil), }, }, // TODO: add testcase for data coming from multiple sources like @@ -279,7 +279,7 @@ func TestNewResMapFromSecretArgs(t *testing.T) { } expected := ResMap{ - resid.NewResId(secret, "apple"): rf.FromMap( + resid.NewResId(secret, "apple"): rf.FromMapAndOption( map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", @@ -291,7 +291,7 @@ func TestNewResMapFromSecretArgs(t *testing.T) { "DB_USERNAME": base64.StdEncoding.EncodeToString([]byte("admin")), "DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")), }, - }).SetBehavior(ifc.BehaviorCreate), + }, &types.GeneratorArgs{}, nil), } if !reflect.DeepEqual(actual, expected) { t.Fatalf("%#v\ndoesn't match expected:\n%#v", actual, expected) diff --git a/pkg/resmap/resmap.go b/pkg/resmap/resmap.go index 4ee304b30..d6936f6d5 100644 --- a/pkg/resmap/resmap.go +++ b/pkg/resmap/resmap.go @@ -24,9 +24,9 @@ import ( "sort" "github.com/ghodss/yaml" - "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resource" + "sigs.k8s.io/kustomize/pkg/types" ) // ResMap is a map from ResId to Resource. @@ -114,8 +114,7 @@ func (m ResMap) ErrorIfNotEqual(m2 ResMap) error { func (m ResMap) DeepCopy(rf *resource.Factory) ResMap { mcopy := make(ResMap) for id, obj := range m { - mcopy[id] = rf.FromKunstructured(obj.Copy()) - mcopy[id].SetBehavior(obj.Behavior()) + mcopy[id] = obj.DeepCopy() } return mcopy } @@ -182,20 +181,18 @@ func MergeWithOverride(maps ...ResMap) (ResMap, error) { if len(matchedId) == 1 { id = matchedId[0] switch r.Behavior() { - case ifc.BehaviorReplace: + case types.BehaviorReplace: r.Replace(result[id]) result[id] = r - result[id].SetBehavior(ifc.BehaviorCreate) - case ifc.BehaviorMerge: + case types.BehaviorMerge: r.Merge(result[id]) result[id] = r - result[id].SetBehavior(ifc.BehaviorCreate) default: return nil, fmt.Errorf("id %#v exists; must merge or replace", id) } } else if len(matchedId) == 0 { switch r.Behavior() { - case ifc.BehaviorMerge, ifc.BehaviorReplace: + case types.BehaviorMerge, types.BehaviorReplace: return nil, fmt.Errorf("id %#v does not exist; cannot merge or replace", id) default: result[id] = r diff --git a/pkg/resmap/resmap_test.go b/pkg/resmap/resmap_test.go index 14e6a7a45..7b1f569b1 100644 --- a/pkg/resmap/resmap_test.go +++ b/pkg/resmap/resmap_test.go @@ -22,9 +22,9 @@ import ( "sigs.k8s.io/kustomize/k8sdeps/kunstruct" "sigs.k8s.io/kustomize/pkg/gvk" - "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resource" + "sigs.k8s.io/kustomize/pkg/types" ) var deploy = gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"} @@ -435,10 +435,10 @@ func TestMergeWithoutOverride(t *testing.T) { } } -func generateMergeFixtures(b ifc.GenerationBehavior) []ResMap { +func generateMergeFixtures(b types.GenerationBehavior) []ResMap { input1 := ResMap{ - resid.NewResId(cmap, "cmap"): rf.FromMap( + resid.NewResId(cmap, "cmap"): rf.FromMapAndOption( map[string]interface{}{ "apiVersion": "apps/v1", "kind": "ConfigMap", @@ -449,10 +449,12 @@ func generateMergeFixtures(b ifc.GenerationBehavior) []ResMap { "a": "x", "b": "y", }, - }), + }, &types.GeneratorArgs{ + Behavior: "create", + }, nil), } input2 := ResMap{ - resid.NewResId(cmap, "cmap"): rf.FromMap( + resid.NewResId(cmap, "cmap"): rf.FromMapAndOption( map[string]interface{}{ "apiVersion": "apps/v1", "kind": "ConfigMap", @@ -464,16 +466,16 @@ func generateMergeFixtures(b ifc.GenerationBehavior) []ResMap { "b": "v", "c": "w", }, - }), + }, &types.GeneratorArgs{ + Behavior: b.String(), + }, nil), } - input1[resid.NewResId(cmap, "cmap")].SetBehavior(ifc.BehaviorCreate) - input2[resid.NewResId(cmap, "cmap")].SetBehavior(b) return []ResMap{input1, input2} } func TestMergeWithOverride(t *testing.T) { expected := ResMap{ - resid.NewResId(cmap, "cmap"): rf.FromMap( + resid.NewResId(cmap, "cmap"): rf.FromMapAndOption( map[string]interface{}{ "apiVersion": "apps/v1", "kind": "ConfigMap", @@ -487,10 +489,11 @@ func TestMergeWithOverride(t *testing.T) { "b": "v", "c": "w", }, - }), + }, &types.GeneratorArgs{ + Behavior: "create", + }, nil), } - expected[resid.NewResId(cmap, "cmap")].SetBehavior(ifc.BehaviorCreate) - merged, err := MergeWithOverride(generateMergeFixtures(ifc.BehaviorMerge)...) + merged, err := MergeWithOverride(generateMergeFixtures(types.BehaviorMerge)...) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -514,7 +517,7 @@ func TestMergeWithOverride(t *testing.T) { t.Fatalf("%#v doesn't equal expected %#v", merged2, expected) } - inputs := generateMergeFixtures(ifc.BehaviorReplace) + inputs := generateMergeFixtures(types.BehaviorReplace) replaced, err := MergeWithOverride(inputs...) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -524,7 +527,7 @@ func TestMergeWithOverride(t *testing.T) { t.Fatalf("%#v doesn't equal expected %#v", replaced, expectedReplaced) } - _, err = MergeWithOverride(generateMergeFixtures(ifc.BehaviorUnspecified)...) + _, err = MergeWithOverride(generateMergeFixtures(types.BehaviorUnspecified)...) if err == nil { t.Fatal("Merging with GenerationBehavior BehaviorUnspecified should return an error but does not") } diff --git a/pkg/resource/factory.go b/pkg/resource/factory.go index 789b4cafd..b016678a5 100644 --- a/pkg/resource/factory.go +++ b/pkg/resource/factory.go @@ -41,7 +41,16 @@ func NewFactory(kf ifc.KunstructuredFactory) *Factory { func (rf *Factory) FromMap(m map[string]interface{}) *Resource { return &Resource{ Kunstructured: rf.kf.FromMap(m), - b: ifc.BehaviorUnspecified} + options: types.NewGenArgs(nil, nil), + } +} + +// FromMapAndOption returns a new instance of Resource with given options. +func (rf *Factory) FromMapAndOption(m map[string]interface{}, args *types.GeneratorArgs, option *types.GeneratorOptions) *Resource { + return &Resource{ + Kunstructured: rf.kf.FromMap(m), + options: types.NewGenArgs(args, option), + } } // FromKunstructured returns a new instance of Resource. @@ -50,7 +59,10 @@ func (rf *Factory) FromKunstructured( if u == nil { log.Fatal("unstruct ifc must not be null") } - return &Resource{Kunstructured: u, b: ifc.BehaviorUnspecified} + return &Resource{ + Kunstructured: u, + options: types.NewGenArgs(nil, nil), + } } // SliceFromPatches returns a slice of resources given a patch path @@ -118,7 +130,7 @@ func (rf *Factory) MakeConfigMap(args *types.ConfigMapArgs, options *types.Gener if err != nil { return nil, err } - return &Resource{Kunstructured: u, b: fixBehavior(args.Behavior)}, nil + return &Resource{Kunstructured: u, options: types.NewGenArgs(&types.GeneratorArgs{Behavior: args.Behavior}, options)}, nil } // MakeSecret makes an instance of Resource for Secret @@ -127,13 +139,5 @@ func (rf *Factory) MakeSecret(args *types.SecretArgs, options *types.GeneratorOp if err != nil { return nil, err } - return &Resource{Kunstructured: u, b: fixBehavior(args.Behavior)}, nil -} - -func fixBehavior(s string) ifc.GenerationBehavior { - b := ifc.NewGenerationBehavior(s) - if b == ifc.BehaviorUnspecified { - return ifc.BehaviorCreate - } - return b + return &Resource{Kunstructured: u, options: types.NewGenArgs(&types.GeneratorArgs{Behavior: args.Behavior}, options)}, nil } diff --git a/pkg/resource/resource.go b/pkg/resource/resource.go index e952312b8..7cc87a745 100644 --- a/pkg/resource/resource.go +++ b/pkg/resource/resource.go @@ -22,13 +22,14 @@ import ( "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/resid" + "sigs.k8s.io/kustomize/pkg/types" ) // Resource is map representation of a Kubernetes API resource object // paired with a GenerationBehavior. type Resource struct { ifc.Kunstructured - b ifc.GenerationBehavior + options *types.GenArgs } // String returns resource as JSON. @@ -37,23 +38,25 @@ func (r *Resource) String() string { if err != nil { return "<" + err.Error() + ">" } - return r.b.String() + ":" + strings.TrimSpace(string(bs)) + return strings.TrimSpace(string(bs)) +} + +// DeepCopy returns a new copy of resource +func (r *Resource) DeepCopy() *Resource { + return &Resource{ + Kunstructured: r.Kunstructured.Copy(), + options: r.options, + } } // Behavior returns the behavior for the resource. -func (r *Resource) Behavior() ifc.GenerationBehavior { - return r.b +func (r *Resource) Behavior() types.GenerationBehavior { + return r.options.Behavior() } -// SetBehavior changes the resource to the new behavior -func (r *Resource) SetBehavior(b ifc.GenerationBehavior) *Resource { - r.b = b - return r -} - -// IsGenerated checks if the resource is generated from a generator -func (r *Resource) IsGenerated() bool { - return r.b != ifc.BehaviorUnspecified +// NeedAppendHash checks if the resource need a hash suffix +func (r *Resource) NeedHashSuffix() bool { + return r.options != nil && r.options.NeedsHashSuffix() } // Id returns the ResId for the resource. @@ -74,6 +77,7 @@ func (r *Resource) Replace(other *Resource) { r.SetAnnotations( mergeStringMaps(other.GetAnnotations(), r.GetAnnotations())) r.SetName(other.GetName()) + r.options = other.options } // TODO: Add BinaryData once we sync to new k8s.io/api diff --git a/pkg/resource/resource_test.go b/pkg/resource/resource_test.go index c7580868c..fbf4ba30b 100644 --- a/pkg/resource/resource_test.go +++ b/pkg/resource/resource_test.go @@ -37,7 +37,7 @@ var testConfigMap = factory.FromMap( }, }) -const testConfigMapString = `unspecified:{"apiVersion":"v1","kind":"ConfigMap","metadata":{"name":"winnie","namespace":"hundred-acre-wood"}}` +const testConfigMapString = `{"apiVersion":"v1","kind":"ConfigMap","metadata":{"name":"winnie","namespace":"hundred-acre-wood"}}` var testDeployment = factory.FromMap( map[string]interface{}{ @@ -48,7 +48,7 @@ var testDeployment = factory.FromMap( }, }) -const testDeploymentString = `unspecified:{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":"pooh"}}` +const testDeploymentString = `{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":"pooh"}}` func TestResourceString(t *testing.T) { tests := []struct { diff --git a/pkg/target/generatoroptions_test.go b/pkg/target/generatoroptions_test.go new file mode 100644 index 000000000..5836446fd --- /dev/null +++ b/pkg/target/generatoroptions_test.go @@ -0,0 +1,71 @@ +/* +Copyright 2019 The Kubernetes Authors. + Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target + +import ( + "testing" +) + +func TestGeneratorOptionsWithBases(t *testing.T) { + th := NewKustTestHarness(t, "/app/overlay") + th.writeK("/app/base", ` +apiVersion: v1beta1 +kind: Kustomization +generatorOptions: + disableNameSuffixHash: true + labels: + foo: bar +configMapGenerator: +- name: shouldNotHaveHash + literals: + - foo=bar +`) + th.writeK("/app/overlay", ` +apiVersion: v1beta1 +kind: Kustomization +bases: +- ../base +generatorOptions: + disableNameSuffixHash: false + labels: + fruit: apple +configMapGenerator: +- name: shouldHaveHash + literals: + - fruit=apple +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + fruit: apple +kind: ConfigMap +metadata: + labels: + fruit: apple + name: shouldHaveHash-2k9hc848ff +--- +apiVersion: v1 +data: + foo: bar +kind: ConfigMap +metadata: + labels: + foo: bar + name: shouldNotHaveHash +`) +} diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index eef539c28..78dba3913 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -117,15 +117,9 @@ func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) { if err != nil { return nil, err } - if kt.shouldAddHashSuffixesToGeneratedResources() { - // This effects only generated resources. - // It changes only the Name field in the - // resource held in the ResMap's value, not - // the Name in the key in the ResMap. - err := ra.Transform(kt.tFactory.MakeHashTransformer()) - if err != nil { - return nil, err - } + err = ra.Transform(kt.tFactory.MakeHashTransformer()) + if err != nil { + return nil, err } // Given that names have changed (prefixs/suffixes added), // fix all the back references to those names. diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index 7d720c666..380e1803d 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -126,7 +126,7 @@ func TestResources1(t *testing.T) { }), resid.NewResIdWithPrefixSuffixNamespace( gvk.Gvk{Version: "v1", Kind: "ConfigMap"}, - "literalConfigMap", "foo-", "-bar", "ns1"): th.fromMap( + "literalConfigMap", "foo-", "-bar", "ns1"): th.fromMapAndOption( map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -144,10 +144,10 @@ func TestResources1(t *testing.T) { "DB_USERNAME": "admin", "DB_PASSWORD": "somepw", }, - }).SetBehavior(ifc.BehaviorCreate), + }, &types.GeneratorArgs{}, nil), resid.NewResIdWithPrefixSuffixNamespace( gvk.Gvk{Version: "v1", Kind: "Secret"}, - "secret", "foo-", "-bar", "ns1"): th.fromMap( + "secret", "foo-", "-bar", "ns1"): th.fromMapAndOption( map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", @@ -166,7 +166,7 @@ func TestResources1(t *testing.T) { "DB_USERNAME": base64.StdEncoding.EncodeToString([]byte("admin")), "DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")), }, - }).SetBehavior(ifc.BehaviorCreate), + }, &types.GeneratorArgs{}, nil), resid.NewResIdWithPrefixSuffixNamespace( gvk.Gvk{Version: "v1", Kind: "Namespace"}, "ns1", "foo-", "-bar", ""): th.fromMap( diff --git a/pkg/target/utils_for_test.go b/pkg/target/utils_for_test.go index e3541e6a7..ddcd7b90c 100644 --- a/pkg/target/utils_for_test.go +++ b/pkg/target/utils_for_test.go @@ -32,6 +32,7 @@ import ( "sigs.k8s.io/kustomize/pkg/internal/loadertest" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" + "sigs.k8s.io/kustomize/pkg/types" ) type KustTestHarness struct { @@ -84,6 +85,10 @@ func (th *KustTestHarness) fromMap(m map[string]interface{}) *resource.Resource return th.rf.RF().FromMap(m) } +func (th *KustTestHarness) fromMapAndOption(m map[string]interface{}, args *types.GeneratorArgs, option *types.GeneratorOptions) *resource.Resource { + return th.rf.RF().FromMapAndOption(m, args, option) +} + func (th *KustTestHarness) writeDefaultConfigs(fName string) { m := defaultconfig.GetDefaultFieldSpecsAsMap() var content []byte diff --git a/pkg/types/genargs.go b/pkg/types/genargs.go new file mode 100644 index 000000000..a74a48d22 --- /dev/null +++ b/pkg/types/genargs.go @@ -0,0 +1,47 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package types + +// GenArgs contains both generator args and options +type GenArgs struct { + args *GeneratorArgs + opts *GeneratorOptions +} + +// NewGenArgs returns a new object of GenArgs +func NewGenArgs(args *GeneratorArgs, opts *GeneratorOptions) *GenArgs { + return &GenArgs{ + args: args, + opts: opts, + } +} + +// NeedHashSuffix returns true if the hash suffix is needed. +// It is needed when the two conditions are both met +// 1) GenArgs is not nil +// 2) DisableNameSuffixHash in GeneratorOptions is not set to true +func (g *GenArgs) NeedsHashSuffix() bool { + return g.args != nil && (g.opts == nil || g.opts.DisableNameSuffixHash == false) +} + +// Behavior returns Behavior field of GeneratorArgs +func (g *GenArgs) Behavior() GenerationBehavior { + if g.args == nil { + return BehaviorUnspecified + } + return NewGenerationBehavior(g.args.Behavior) +} diff --git a/pkg/ifc/generationbehavior.go b/pkg/types/generationbehavior.go similarity index 99% rename from pkg/ifc/generationbehavior.go rename to pkg/types/generationbehavior.go index e798ca33e..67ba8a0b5 100644 --- a/pkg/ifc/generationbehavior.go +++ b/pkg/types/generationbehavior.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package ifc +package types // GenerationBehavior specifies generation behavior of configmaps, secrets and maybe other resources. type GenerationBehavior int From d8585334ccdf884eb0762ddd82a401801baa7f5e Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Mon, 4 Feb 2019 09:44:33 -0800 Subject: [PATCH 097/317] minor fix: incorrect apiVersion and add NoOpTransformer for vars (#757) --- pkg/target/generatoroptions_test.go | 4 ++-- pkg/target/nullvalues_test.go | 2 +- pkg/transformers/refvars.go | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pkg/target/generatoroptions_test.go b/pkg/target/generatoroptions_test.go index 5836446fd..e3c81c1ee 100644 --- a/pkg/target/generatoroptions_test.go +++ b/pkg/target/generatoroptions_test.go @@ -20,7 +20,7 @@ import ( func TestGeneratorOptionsWithBases(t *testing.T) { th := NewKustTestHarness(t, "/app/overlay") th.writeK("/app/base", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization generatorOptions: disableNameSuffixHash: true @@ -32,7 +32,7 @@ configMapGenerator: - foo=bar `) th.writeK("/app/overlay", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization bases: - ../base diff --git a/pkg/target/nullvalues_test.go b/pkg/target/nullvalues_test.go index 06ca1ddc0..f04cfb932 100644 --- a/pkg/target/nullvalues_test.go +++ b/pkg/target/nullvalues_test.go @@ -44,7 +44,7 @@ spec: name: example `) th.writeF("/app/kustomization.yaml", ` -apiVersion: v1beta1 +apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - deployment.yaml diff --git a/pkg/transformers/refvars.go b/pkg/transformers/refvars.go index 3e2d18523..1d35c9602 100644 --- a/pkg/transformers/refvars.go +++ b/pkg/transformers/refvars.go @@ -18,6 +18,9 @@ type refvarTransformer struct { // The fieldSpecs are the places to look for occurrences of $(VAR). func NewRefVarTransformer( varMap map[string]string, fs []config.FieldSpec) Transformer { + if len(varMap) == 0 { + return NewNoOpTransformer() + } return &refvarTransformer{ fieldSpecs: fs, mappingFunc: expansion.MappingFuncFor(varMap), From 1d005d47b5c4581ced1b8d440d9d1a1243c2f27b Mon Sep 17 00:00:00 2001 From: Dimitri Mitropoulos Date: Mon, 4 Feb 2019 14:44:04 -0500 Subject: [PATCH 098/317] typo: makes verb number agree with subject also changed `one` to `someone` to be more English-as-a-Second-Language friendly --- docs/kustomization.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index 781da106e..cdfce186a 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -215,7 +215,7 @@ crds: # Vars are used to capture text from one resource's field # and insert that text elsewhere. # -# For example, suppose one specify the name of a k8s Service +# For example, suppose someone specifies the name of a k8s Service # object in a container's command line, and the name of a # k8s Secret object in a container's environment variable, # so that the following would work: From b15b20467ccd0d2d829901bcf574be5666cf23e3 Mon Sep 17 00:00:00 2001 From: Dimitri Mitropoulos Date: Mon, 4 Feb 2019 14:48:43 -0500 Subject: [PATCH 099/317] typo: changes verb number to agree with subject --- docs/kustomization.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index cdfce186a..807f58d26 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -255,7 +255,7 @@ vars: # reference within that object. That's where the text is found. # # The field reference is optional; it defaults to `metadata.name`, -# a normal default, since kustomize is used to generates or +# a normal default, since kustomize is used to generate or # modify the names of resources. # # At time of writing, only string type fields are supported. From 120e7b5744be65897f43e93fa5399fa71b3191a3 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Fri, 1 Feb 2019 16:40:17 -0800 Subject: [PATCH 100/317] Versioning policy --- docs/README.md | 3 + docs/versioningPolicy.md | 221 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 docs/versioningPolicy.md diff --git a/docs/README.md b/docs/README.md index 31c0acf45..fcbdd4eb3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,6 +6,9 @@ [kustomization](glossary.md#kustomization) with explanations of each field. + * [versioning policy](versioningPolicy.md) - How the code and the kustomization + file evolve in time. + * [workflow](workflows.md) - Some steps one might take in using bespoke and off-the-shelf configurations. diff --git a/docs/versioningPolicy.md b/docs/versioningPolicy.md new file mode 100644 index 000000000..2f9a08ea5 --- /dev/null +++ b/docs/versioningPolicy.md @@ -0,0 +1,221 @@ +# Versioning + +Running `kustomize` means one is running a +particular version of a program, reading a +particular version of a [kustomization] file. + +## Program Versioning + +The command `kustomize version` prints a three +field version tag (e.g. `1.0.11`) that aspires to +[semantic versioning]. + +When enough changes have accumulated to +(subjectively) warrant a new release, +a [release process] is followed, and the +fields in the version number are bumped +per semver. + +## Kustomization File Versioning + +At the time of writing (circa release of v2.0.0): + + - A [kustomization] file is just a YAML file that + can be successfully parsed into a particular Go + struct defined in the `kustomize` binary. + + - This struct does not have a version number, + which is the same as saying that its version + number matches the program's version number, + since it's compiled in. + +### Field Change Policy + +- A field's meaning cannot be changed. + +- A field may be deprecated, then removed. + +- Deprecation means triggering a _minor_ (semver) + version bump in the program, and + defining a migration path in a non-fatal + error message. + +- Removal means triggering a _major_ (semver) + version bump, and fatal error if field encountered + (as with any unknown field). + +### The `edit fix` Command + +This `kustomize` command reads a Kustomization +file, converts deprecated fields to new +fields, and writes it out again in the latest +format. + +This is a type version upgrade mechanism that +works within _major_ program revisions. There is +no downgrade capability, as there's no use case +for it (see discussion below). + +### Examples + +At the time of writing, in v1.0.x, there were 12 +minor releases, with backward compatible +deprecations fixable via `edit fix`. + +With the 2.0.0 release, there were three field +removals: + +- `imageTag` was deprecated when `image` was + introduced, because the latter offers more + general features for image data manipulation. + `imageTag` was removed in v2.0.0. + +- `patches` was deprecated and replaced by + `PatchesStrategicMerge` when `PatchesJson6902` + was introduced, to make a clearer + distinction between patch specification formats. + `patches` was removed in v2.0.0. + +- `secretGenerator/commands` was removed + due to security concerns in v2.0.0 + with no deprecation period. + +The `edit fix` command in a v2.0.x binary +will no longer recognize these fields. + +## Relationship to the k8s API + +### Review of k8s API versioning + +The k8s API has specific [conventions] and a +process for making a [changes]. + +The presence of an `apiVersion` field in a k8s +native type signals: + + - its reliability level (alpha vs beta vs + generally available), + + - the existence of code to provide default values + to fields not present in a serialization, + + - the existence of code to provide both forward + and backward conversion between different + versions of types. + +The k8s API promises a lossless _conversion_ +between versions over a specific range. This +means that a recent client can write an object +bearing the newest possible value for its version, +the server will accept it and store it in +"versionless" JSON form in storage, and can +convert it to a range of older versions should +an older client request data. + +For native k8s types, this all requires writing Go +code in the kubernetes core repo, to provide +defaulting and conversions. + +For CRDs, there's a [proposal] on how to manage +versioning (e.g. a remote service can offer type +defaulting and conversions). + +### Kustomization file versioning + +The critical difference between k8s API versioning +and kustomization file versioning is + + - A k8s API server is able to go _forward_ and + _backward_ in versioning, to work with older + clients, over [some range]. + + - The `kustomize edit fix` command only moves + _forward_ within a _major_ program + version. + +At the time of writing, the YAML in a +kustomization file does not represent a [k8s API] +object, and the kustomize command and associated +library is neither a server of, nor a client to, +the k8s API. + +### Additional Kustomization file rules + +In addition to the [field change policy] described +above, kustomization files conform to +the following rules. + +#### Eschew classic k8s fields + +Field names with dedicated meaning in k8s +(`metadata`, `spec`, `status`, etc.) aren't used. + +This is enforced via code review. + +#### Optional use of k8s `kind` and `apiVersion` + +At the time of writing two [special] k8s +resource fields are allowed, but not required, in +a kustomization file: [`kind`] and [`apiVersion`]. + +If either field is present, they both must be, and +they must have the following values: + +``` +kind: Kustomization +apiVersion: kustomize.config.k8s.io/v1beta1 +``` + +They are allowed to exist and have specific values +in a kustomization file only as a sort of +domain-squatting behavior for some future API. A +kustomize user gains nothing from adding these +fields to a kustomization file. + +### Why not require `kind` and `apiVersion`? + +#### Ease of use and setting proper expectations + +Use cases for a kustomization file don't include a +server storing muliple k8s kinds and offering +version downgrades. + +The kustomization file is more akin to a +`Makefile`. A kustomize command can either read a +kustomization file, or it cannot, and in the later +case will complain as specifically as possible +about why (e.g. `unknown field Foo`). + +So requiring a `kind` and `apiVersion` would just +be boilerplate in a user's files, and in all the +examples and tests. + +Nevertheless, _a user still benefits from a +versioning policy_ and has a `fix` command to +upgrade files as needed. + +#### We can change our minds + +When/if the kustomization struct graduates to some +kind of API status, with an expectation of +"versionless" storage and downgrade capability, +whatever it looks like at that moment can be +locked into `/v1beta1` or `/v1` and the `kind` +and `apiVersion` fields can be required from that +moment forward. + + +[field change policy]: #field-change-policy +[some range]: https://kubernetes.io/docs/reference/using-api/deprecation-policy +[proposal]: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/customresources-versioning.md +[beta-level rules]: https://github.com/kubernetes/community/blob/master/contributors/devel/api_changes.md#alpha-beta-and-stable-versions +[changes]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api_changes.md +[adapt]: https://github.com/kubernetes-sigs/kustomize/blob/master/pkg/types/kustomization.go#L166 +[special]: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#resources +[k8s API]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md +[conventions]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md +[release process]: ../build/README.md +[kustomization]: glossary.md#kustomization +[`kind`]: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#types-kinds +[`apiVersion`]: https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-versioning +[semantic versioning]: https://semver.org From e905704b0c71a79948e8873b9c7fa443e5060b48 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Mon, 4 Feb 2019 13:08:09 -0800 Subject: [PATCH 101/317] allow apiVersion and Kind to be empty or specific values --- pkg/target/kusttarget.go | 8 ++------ pkg/types/kustomization.go | 14 +++++--------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 78dba3913..f0b4db87b 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -21,7 +21,6 @@ import ( "bytes" "encoding/json" "fmt" - "log" "strings" "github.com/ghodss/yaml" @@ -64,12 +63,9 @@ func NewKustTarget( if err != nil { return nil, err } - msgs, errs := k.EnforceFields() + errs := k.EnforceFields() if len(errs) > 0 { - return nil, fmt.Errorf(strings.Join(errs, "\n")) - } - if len(msgs) > 0 { - log.Printf(strings.Join(msgs, "\n")) + return nil, fmt.Errorf("Failed to read kustomization file under %s:\n"+strings.Join(errs, "\n"), ldr.Root()) } return &KustTarget{ kustomization: &k, diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index c78fb9f89..12d09820f 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -146,19 +146,15 @@ func (k *Kustomization) DealWithMissingFields() []string { return msgs } -func (k *Kustomization) EnforceFields() ([]string, []string) { - var msgs, errs []string - if k.APIVersion == "" { - msgs = append(msgs, "apiVersion is not defined. This will not be allowed in the next release.\nPlease run `kustomize edit fix`") - } else if k.APIVersion != KustomizationVersion { +func (k *Kustomization) EnforceFields() []string { + var errs []string + if k.APIVersion != "" && k.APIVersion != KustomizationVersion { errs = append(errs, "apiVersion should be "+KustomizationVersion) } - if k.Kind == "" { - msgs = append(msgs, "kind is not defined. This will not be allowed in the next release.\nPlease run `kustomize edit fix`") - } else if k.Kind != KustomizationKind { + if k.Kind != "" && k.Kind != KustomizationKind { errs = append(errs, "kind should be "+KustomizationKind) } - return msgs, errs + return errs } // DealWithDeprecatedFields should be called immediately after From e14ebc0adf78aa4121fd74c3ef64d28d824bb989 Mon Sep 17 00:00:00 2001 From: Seth Pollack Date: Mon, 4 Feb 2019 17:19:57 -0500 Subject: [PATCH 102/317] refactor kv pairs --- .../configmapandsecret/configmapfactory.go | 86 +---------- k8sdeps/configmapandsecret/kv.go | 145 +++++++++--------- k8sdeps/configmapandsecret/secretfactory.go | 5 +- pkg/kv/kv.go | 101 ++++++++++++ .../configmapandsecret => pkg/kv}/kv_test.go | 18 +-- 5 files changed, 191 insertions(+), 164 deletions(-) create mode 100644 pkg/kv/kv.go rename {k8sdeps/configmapandsecret => pkg/kv}/kv_test.go (80%) diff --git a/k8sdeps/configmapandsecret/configmapfactory.go b/k8sdeps/configmapandsecret/configmapfactory.go index f0d8f4962..fc9a30da8 100644 --- a/k8sdeps/configmapandsecret/configmapfactory.go +++ b/k8sdeps/configmapandsecret/configmapfactory.go @@ -19,7 +19,6 @@ package configmapandsecret import ( "fmt" - "path" "strings" "unicode/utf8" @@ -28,6 +27,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/validation" "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/kv" "sigs.k8s.io/kustomize/pkg/types" ) @@ -55,7 +55,7 @@ func (f *ConfigMapFactory) makeFreshConfigMap( // MakeConfigMap returns a new ConfigMap, or nil and an error. func (f *ConfigMapFactory) MakeConfigMap( args *types.ConfigMapArgs, options *types.GeneratorOptions) (*corev1.ConfigMap, error) { - var all []kvPair + var all []kv.KVPair var err error cm := f.makeFreshConfigMap(args) @@ -82,7 +82,7 @@ func (f *ConfigMapFactory) MakeConfigMap( all = append(all, pairs...) for _, kv := range all { - err = addKvToConfigMap(cm, kv.key, kv.value) + err = addKvToConfigMap(cm, kv.Key, kv.Value) if err != nil { return nil, err } @@ -94,45 +94,6 @@ func (f *ConfigMapFactory) MakeConfigMap( return cm, nil } -func keyValuesFromLiteralSources(sources []string) ([]kvPair, error) { - var kvs []kvPair - for _, s := range sources { - k, v, err := parseLiteralSource(s) - if err != nil { - return nil, err - } - kvs = append(kvs, kvPair{key: k, value: v}) - } - return kvs, nil -} - -func keyValuesFromFileSources(ldr ifc.Loader, sources []string) ([]kvPair, error) { - var kvs []kvPair - for _, s := range sources { - k, fPath, err := parseFileSource(s) - if err != nil { - return nil, err - } - content, err := ldr.Load(fPath) - if err != nil { - return nil, err - } - kvs = append(kvs, kvPair{key: k, value: string(content)}) - } - return kvs, nil -} - -func keyValuesFromEnvFile(l ifc.Loader, path string) ([]kvPair, error) { - if path == "" { - return nil, nil - } - content, err := l.Load(path) - if err != nil { - return nil, err - } - return keyValuesFromLines(content) -} - // addKvToConfigMap adds the given key and data to the given config map. // Error if key invalid, or already exists. func addKvToConfigMap(configMap *v1.ConfigMap, keyName, data string) error { @@ -163,44 +124,3 @@ func addKvToConfigMap(configMap *v1.ConfigMap, keyName, data string) error { configMap.BinaryData[keyName] = []byte(data) return nil } - -// parseFileSource parses the source given. -// -// Acceptable formats include: -// 1. source-path: the basename will become the key name -// 2. source-name=source-path: the source-name will become the key name and -// source-path is the path to the key file. -// -// Key names cannot include '='. -func parseFileSource(source string) (keyName, filePath string, err error) { - numSeparators := strings.Count(source, "=") - switch { - case numSeparators == 0: - return path.Base(source), source, nil - case numSeparators == 1 && strings.HasPrefix(source, "="): - return "", "", fmt.Errorf("key name for file path %v missing", strings.TrimPrefix(source, "=")) - case numSeparators == 1 && strings.HasSuffix(source, "="): - return "", "", fmt.Errorf("file path for key name %v missing", strings.TrimSuffix(source, "=")) - case numSeparators > 1: - return "", "", errors.New("key names or file paths cannot contain '='") - default: - components := strings.Split(source, "=") - return components[0], components[1], nil - } -} - -// parseLiteralSource parses the source key=val pair into its component pieces. -// This functionality is distinguished from strings.SplitN(source, "=", 2) since -// it returns an error in the case of empty keys, values, or a missing equals sign. -func parseLiteralSource(source string) (keyName, value string, err error) { - // leading equal is invalid - if strings.Index(source, "=") == 0 { - return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source) - } - // split after the first equal (so values can have the = character) - items := strings.SplitN(source, "=", 2) - if len(items) != 2 { - return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source) - } - return items[0], strings.Trim(items[1], "\"'"), nil -} diff --git a/k8sdeps/configmapandsecret/kv.go b/k8sdeps/configmapandsecret/kv.go index 6d6c99249..8ba1e5f4a 100644 --- a/k8sdeps/configmapandsecret/kv.go +++ b/k8sdeps/configmapandsecret/kv.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2019 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,86 +17,91 @@ limitations under the License. package configmapandsecret import ( - "bufio" - "bytes" "fmt" - "os" + "path" "strings" - "unicode" - "unicode/utf8" - "k8s.io/apimachinery/pkg/util/validation" + "github.com/pkg/errors" + "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/kv" ) -// kvPair represents a key value pair. -type kvPair struct { - key string - value string -} - -var utf8bom = []byte{0xEF, 0xBB, 0xBF} - -// keyValuesFromLines parses given content in to a list of key-value pairs. -func keyValuesFromLines(content []byte) ([]kvPair, error) { - var kvs []kvPair - - scanner := bufio.NewScanner(bytes.NewReader(content)) - currentLine := 0 - for scanner.Scan() { - // Process the current line, retrieving a key/value pair if - // possible. - scannedBytes := scanner.Bytes() - kv, err := kvFromLine(scannedBytes, currentLine) +func keyValuesFromLiteralSources(sources []string) ([]kv.KVPair, error) { + var kvs []kv.KVPair + for _, s := range sources { + k, v, err := parseLiteralSource(s) if err != nil { return nil, err } - currentLine++ - - if len(kv.key) == 0 { - // no key means line was empty or a comment - continue - } - - kvs = append(kvs, kv) + kvs = append(kvs, kv.KVPair{Key: k, Value: v}) } return kvs, nil } -// kvFromLine returns a kv with blank key if the line is empty or a comment. -// The value will be retrieved from the environment if necessary. -func kvFromLine(line []byte, currentLine int) (kvPair, error) { - kv := kvPair{} - - if !utf8.Valid(line) { - return kv, fmt.Errorf("line %d has invalid utf8 bytes : %v", line, string(line)) +func keyValuesFromFileSources(ldr ifc.Loader, sources []string) ([]kv.KVPair, error) { + var kvs []kv.KVPair + for _, s := range sources { + k, fPath, err := parseFileSource(s) + if err != nil { + return nil, err + } + content, err := ldr.Load(fPath) + if err != nil { + return nil, err + } + kvs = append(kvs, kv.KVPair{Key: k, Value: string(content)}) } - - // We trim UTF8 BOM from the first line of the file but no others - if currentLine == 0 { - line = bytes.TrimPrefix(line, utf8bom) - } - - // trim the line from all leading whitespace first - line = bytes.TrimLeftFunc(line, unicode.IsSpace) - - // If the line is empty or a comment, we return a blank key/value pair. - if len(line) == 0 || line[0] == '#' { - return kv, nil - } - - data := strings.SplitN(string(line), "=", 2) - key := data[0] - if errs := validation.IsEnvVarName(key); len(errs) != 0 { - return kv, fmt.Errorf("%q is not a valid key name: %s", key, strings.Join(errs, ";")) - } - - if len(data) == 2 { - kv.value = data[1] - } else { - // No value (no `=` in the line) is a signal to obtain the value - // from the environment. - kv.value = os.Getenv(key) - } - kv.key = key - return kv, nil + return kvs, nil +} + +func keyValuesFromEnvFile(l ifc.Loader, path string) ([]kv.KVPair, error) { + if path == "" { + return nil, nil + } + content, err := l.Load(path) + if err != nil { + return nil, err + } + return kv.KeyValuesFromLines(content) +} + +// parseFileSource parses the source given. +// +// Acceptable formats include: +// 1. source-path: the basename will become the key name +// 2. source-name=source-path: the source-name will become the key name and +// source-path is the path to the key file. +// +// Key names cannot include '='. +func parseFileSource(source string) (keyName, filePath string, err error) { + numSeparators := strings.Count(source, "=") + switch { + case numSeparators == 0: + return path.Base(source), source, nil + case numSeparators == 1 && strings.HasPrefix(source, "="): + return "", "", fmt.Errorf("key name for file path %v missing", strings.TrimPrefix(source, "=")) + case numSeparators == 1 && strings.HasSuffix(source, "="): + return "", "", fmt.Errorf("file path for key name %v missing", strings.TrimSuffix(source, "=")) + case numSeparators > 1: + return "", "", errors.New("key names or file paths cannot contain '='") + default: + components := strings.Split(source, "=") + return components[0], components[1], nil + } +} + +// parseLiteralSource parses the source key=val pair into its component pieces. +// This functionality is distinguished from strings.SplitN(source, "=", 2) since +// it returns an error in the case of empty keys, values, or a missing equals sign. +func parseLiteralSource(source string) (keyName, value string, err error) { + // leading equal is invalid + if strings.Index(source, "=") == 0 { + return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source) + } + // split after the first equal (so values can have the = character) + items := strings.SplitN(source, "=", 2) + if len(items) != 2 { + return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source) + } + return items[0], strings.Trim(items[1], "\"'"), nil } diff --git a/k8sdeps/configmapandsecret/secretfactory.go b/k8sdeps/configmapandsecret/secretfactory.go index 1303c812c..e3a95f329 100644 --- a/k8sdeps/configmapandsecret/secretfactory.go +++ b/k8sdeps/configmapandsecret/secretfactory.go @@ -24,6 +24,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/validation" "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/kv" "sigs.k8s.io/kustomize/pkg/types" ) @@ -53,7 +54,7 @@ func (f *SecretFactory) makeFreshSecret(args *types.SecretArgs) *corev1.Secret { // MakeSecret returns a new secret. func (f *SecretFactory) MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (*corev1.Secret, error) { - var all []kvPair + var all []kv.KVPair var err error s := f.makeFreshSecret(args) @@ -80,7 +81,7 @@ func (f *SecretFactory) MakeSecret(args *types.SecretArgs, options *types.Genera all = append(all, pairs...) for _, kv := range all { - err = addKvToSecret(s, kv.key, kv.value) + err = addKvToSecret(s, kv.Key, kv.Value) if err != nil { return nil, err } diff --git a/pkg/kv/kv.go b/pkg/kv/kv.go new file mode 100644 index 000000000..36451fa68 --- /dev/null +++ b/pkg/kv/kv.go @@ -0,0 +1,101 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kv + +import ( + "bufio" + "bytes" + "fmt" + "os" + "strings" + "unicode" + "unicode/utf8" + + "k8s.io/apimachinery/pkg/util/validation" +) + +type KVPair struct { + Key string + Value string +} + +var utf8bom = []byte{0xEF, 0xBB, 0xBF} + +// KeyValuesFromLines parses given content in to a list of key-value pairs. +func KeyValuesFromLines(content []byte) ([]KVPair, error) { + var kvs []KVPair + + scanner := bufio.NewScanner(bytes.NewReader(content)) + currentLine := 0 + for scanner.Scan() { + // Process the current line, retrieving a key/value pair if + // possible. + scannedBytes := scanner.Bytes() + kv, err := KeyValuesFromLine(scannedBytes, currentLine) + if err != nil { + return nil, err + } + currentLine++ + + if len(kv.Key) == 0 { + // no key means line was empty or a comment + continue + } + + kvs = append(kvs, kv) + } + return kvs, nil +} + +// KeyValuesFromLine returns a kv with blank key if the line is empty or a comment. +// The value will be retrieved from the environment if necessary. +func KeyValuesFromLine(line []byte, currentLine int) (KVPair, error) { + kv := KVPair{} + + if !utf8.Valid(line) { + return kv, fmt.Errorf("line %d has invalid utf8 bytes : %v", line, string(line)) + } + + // We trim UTF8 BOM from the first line of the file but no others + if currentLine == 0 { + line = bytes.TrimPrefix(line, utf8bom) + } + + // trim the line from all leading whitespace first + line = bytes.TrimLeftFunc(line, unicode.IsSpace) + + // If the line is empty or a comment, we return a blank key/value pair. + if len(line) == 0 || line[0] == '#' { + return kv, nil + } + + data := strings.SplitN(string(line), "=", 2) + key := data[0] + if errs := validation.IsEnvVarName(key); len(errs) != 0 { + return kv, fmt.Errorf("%q is not a valid key name: %s", key, strings.Join(errs, ";")) + } + + if len(data) == 2 { + kv.Value = data[1] + } else { + // No value (no `=` in the line) is a signal to obtain the value + // from the environment. + kv.Value = os.Getenv(key) + } + kv.Key = key + return kv, nil +} diff --git a/k8sdeps/configmapandsecret/kv_test.go b/pkg/kv/kv_test.go similarity index 80% rename from k8sdeps/configmapandsecret/kv_test.go rename to pkg/kv/kv_test.go index 939e231f5..7a398ac8a 100644 --- a/k8sdeps/configmapandsecret/kv_test.go +++ b/pkg/kv/kv_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2019 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package configmapandsecret +package kv import ( "reflect" @@ -25,7 +25,7 @@ func TestKeyValuesFromLines(t *testing.T) { tests := []struct { desc string content string - expectedPairs []kvPair + expectedPairs []KVPair expectedErr bool }{ { @@ -34,9 +34,9 @@ func TestKeyValuesFromLines(t *testing.T) { k1=v1 k2=v2 `, - expectedPairs: []kvPair{ - {key: "k1", value: "v1"}, - {key: "k2", value: "v2"}, + expectedPairs: []KVPair{ + {Key: "k1", Value: "v1"}, + {Key: "k2", Value: "v2"}, }, expectedErr: false, }, @@ -46,8 +46,8 @@ func TestKeyValuesFromLines(t *testing.T) { k1=v1 #k2=v2 `, - expectedPairs: []kvPair{ - {key: "k1", value: "v1"}, + expectedPairs: []KVPair{ + {Key: "k1", Value: "v1"}, }, expectedErr: false, }, @@ -55,7 +55,7 @@ func TestKeyValuesFromLines(t *testing.T) { } for _, test := range tests { - pairs, err := keyValuesFromLines([]byte(test.content)) + pairs, err := KeyValuesFromLines([]byte(test.content)) if test.expectedErr && err == nil { t.Fatalf("%s should not return error", test.desc) } From e41ca934ac69702c8ac31acb3e19d85f9c70cbff Mon Sep 17 00:00:00 2001 From: Seth Pollack Date: Tue, 5 Feb 2019 15:38:52 -0500 Subject: [PATCH 103/317] move package and add tests --- .../configmapandsecret/configmapfactory.go | 2 +- k8sdeps/configmapandsecret/kv.go | 2 +- k8sdeps/configmapandsecret/kv_test.go | 57 +++++++++++++++++++ k8sdeps/configmapandsecret/secretfactory.go | 2 +- {pkg => k8sdeps}/kv/kv.go | 0 {pkg => k8sdeps}/kv/kv_test.go | 0 6 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 k8sdeps/configmapandsecret/kv_test.go rename {pkg => k8sdeps}/kv/kv.go (100%) rename {pkg => k8sdeps}/kv/kv_test.go (100%) diff --git a/k8sdeps/configmapandsecret/configmapfactory.go b/k8sdeps/configmapandsecret/configmapfactory.go index fc9a30da8..7dabad4b5 100644 --- a/k8sdeps/configmapandsecret/configmapfactory.go +++ b/k8sdeps/configmapandsecret/configmapfactory.go @@ -26,8 +26,8 @@ import ( "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/validation" + "sigs.k8s.io/kustomize/k8sdeps/kv" "sigs.k8s.io/kustomize/pkg/ifc" - "sigs.k8s.io/kustomize/pkg/kv" "sigs.k8s.io/kustomize/pkg/types" ) diff --git a/k8sdeps/configmapandsecret/kv.go b/k8sdeps/configmapandsecret/kv.go index 8ba1e5f4a..1ad4264e7 100644 --- a/k8sdeps/configmapandsecret/kv.go +++ b/k8sdeps/configmapandsecret/kv.go @@ -22,8 +22,8 @@ import ( "strings" "github.com/pkg/errors" + "sigs.k8s.io/kustomize/k8sdeps/kv" "sigs.k8s.io/kustomize/pkg/ifc" - "sigs.k8s.io/kustomize/pkg/kv" ) func keyValuesFromLiteralSources(sources []string) ([]kv.KVPair, error) { diff --git a/k8sdeps/configmapandsecret/kv_test.go b/k8sdeps/configmapandsecret/kv_test.go new file mode 100644 index 000000000..0b7fe5c37 --- /dev/null +++ b/k8sdeps/configmapandsecret/kv_test.go @@ -0,0 +1,57 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package configmapandsecret + +import ( + "reflect" + "testing" + + "sigs.k8s.io/kustomize/k8sdeps/kv" + "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/loader" +) + +func TestKeyValuesFromFileSources(t *testing.T) { + tests := []struct { + description string + sources []string + expected []kv.KVPair + }{ + { + description: "create kvs from file sources", + sources: []string{"files/app-init.ini"}, + expected: []kv.KVPair{ + { + Key: "app-init.ini", + Value: "FOO=bar", + }, + }, + }, + } + + fSys := fs.MakeFakeFS() + fSys.WriteFile("/files/app-init.ini", []byte("FOO=bar")) + for _, tc := range tests { + kvs, err := keyValuesFromFileSources(loader.NewFileLoaderAtRoot(fSys), tc.sources) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if !reflect.DeepEqual(kvs, tc.expected) { + t.Fatalf("in testcase: %q updated:\n%#v\ndoesn't match expected:\n%#v\n", tc.description, kvs, tc.expected) + } + } +} diff --git a/k8sdeps/configmapandsecret/secretfactory.go b/k8sdeps/configmapandsecret/secretfactory.go index e3a95f329..cc5d68b42 100644 --- a/k8sdeps/configmapandsecret/secretfactory.go +++ b/k8sdeps/configmapandsecret/secretfactory.go @@ -23,8 +23,8 @@ import ( "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/validation" + "sigs.k8s.io/kustomize/k8sdeps/kv" "sigs.k8s.io/kustomize/pkg/ifc" - "sigs.k8s.io/kustomize/pkg/kv" "sigs.k8s.io/kustomize/pkg/types" ) diff --git a/pkg/kv/kv.go b/k8sdeps/kv/kv.go similarity index 100% rename from pkg/kv/kv.go rename to k8sdeps/kv/kv.go diff --git a/pkg/kv/kv_test.go b/k8sdeps/kv/kv_test.go similarity index 100% rename from pkg/kv/kv_test.go rename to k8sdeps/kv/kv_test.go From fc5c7264cf6d41d87d630e3e0d481df149fcd060 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Wed, 30 Jan 2019 14:57:13 -0800 Subject: [PATCH 104/317] add documentation for kustomize 2.0.0 --- docs/README.md | 2 ++ docs/version2.0.0.md | 70 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 docs/version2.0.0.md diff --git a/docs/README.md b/docs/README.md index fcbdd4eb3..08108c789 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,6 +9,8 @@ * [versioning policy](versioningPolicy.md) - How the code and the kustomization file evolve in time. + * [version 2.0.0](version2.0.0.md) - Release note of Kustomize 2.0.0. + * [workflow](workflows.md) - Some steps one might take in using bespoke and off-the-shelf configurations. diff --git a/docs/version2.0.0.md b/docs/version2.0.0.md new file mode 100644 index 000000000..8d2c9b644 --- /dev/null +++ b/docs/version2.0.0.md @@ -0,0 +1,70 @@ +# Kustomize 2.0.0 + +After security review, a field use in secret generation was removed from the definition of a kustomization file with no mechanism to convert it to a new form. Also, the set of paths one may specify in a kustomization file has been further constrained. + +Per the [versioning policy](versioningPolicy.md), backward incompatible changes trigger an increment of the major version number, hence we go from 1.0.11 to 2.0.0. We're taking this major version increment opportunity to remove some already deprecated fields, and the code paths associated with them. + +## Backward Incompatible Changes + +### Kustomization Path Constraints +A kustomization file can specify paths to other files, including resources, patches, configmap generation data, secret generation data and bases. In the case of a base, the path can be a git URL instead. + +In 1.x, these paths had to be relative to the current kustomization directory (the location of the kustomization file used in the `build` command). + +In 2.0, bases can continue to specify, via relative paths, kustomizations outside the current kustomization directory. +But non-base paths are constrained to terminate in or below the current kustomization directory. Further, bases specified via a git URL may not reference files outside of the directory used to clone the repository. + +### Kustomization Field Removals + +#### patches +`patches` was deprecated and replaced by `patchesStrategicMerge` when `patchesJson6902` was introduced. +In Kustomize 2.0.0, `patches` is removed. Please use `patchesStrategicMerge` instead. + +#### imageTags +`imageTags` is replaced by `images` since `images` can provide more features to change image names, registries, tags and digests. + +#### secretGenerator/commands +`commands` is removed from SecretGenerator due to [security concern](https://docs.google.com/document/d/1FYgLVdq-siB_Cef9yuQBmit0PbrE8lsyTBdGI2eA2y8/edit). One can use `files` or `literals`, similar to ConfigMapGenerator, to generate a secret. +``` +secretGenerator: +- name: app-tls + files: + - secret/tls.cert + - secret/tls.key + type: "kubernetes.io/tls" +``` + +## Compatible Changes (New Features) +As this release is triggered by a security change, +there are no major new features to announce. A few things that are worth mentioning in this release are: + +* More than _40_ issues closed since 1.0.11 release (including many extensions to transformation rules). +* Users can run `kustomize edit fix` to migrate a kustomization file working with previous versions to one working with 2.0.0. For example, a kustomization.yaml with following content + ``` + patches: + - deployment-patch.yaml + imageTags: + - name: postgres + newTag: v1 + ``` + + will be converted to + + ``` + apiVersion: kustomize.config.k8s.io/v1beta1 + kind: Kustomization + patchesStrategicMerge: + - deployment-patch.yaml + images: + - name: postgres + newTag: v1 + ``` + +* Kustomization filename + + In previous versions, the canonical name of a kustomization file is `kustomization.yaml`. Kustomize 2.0.0 is extended to recognize more file names: `kustomization.yaml`, `kustomization.yml` and `Kustomization`. In a directory, only one of those filenames is allowed. If there are more than one found, Kustomize will exit with an error. Please select the best filename for your use cases. +* No longer planning to deprecate namespace prefix/suffix. The deprecation warning + ``` + Adding nameprefix and namesuffix to Namespace resource will be deprecated in next release. + ``` + is removed. Since changing this behavior will break many users' workflow. Kustomize will continue with adding nameprefix and namesuffix to Namespace resources. From 9e69b9dcc4b108d3e41dba576f81fe2b56c80203 Mon Sep 17 00:00:00 2001 From: Jeff Regan Date: Wed, 6 Feb 2019 10:59:44 -0800 Subject: [PATCH 105/317] Typos in versioning --- docs/versioningPolicy.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/versioningPolicy.md b/docs/versioningPolicy.md index 2f9a08ea5..8017b0f87 100644 --- a/docs/versioningPolicy.md +++ b/docs/versioningPolicy.md @@ -11,10 +11,9 @@ field version tag (e.g. `1.0.11`) that aspires to [semantic versioning]. When enough changes have accumulated to -(subjectively) warrant a new release, -a [release process] is followed, and the -fields in the version number are bumped -per semver. +warrant a new release, a [release process] +is followed, and the fields in the version +number are bumped per semver. ## Kustomization File Versioning @@ -88,7 +87,7 @@ will no longer recognize these fields. ### Review of k8s API versioning The k8s API has specific [conventions] and a -process for making a [changes]. +process for making [changes]. The presence of an `apiVersion` field in a k8s native type signals: From d720e9ef49ef9e8113976db069f2dcbb15c771e2 Mon Sep 17 00:00:00 2001 From: Jeff Regan Date: Wed, 6 Feb 2019 12:36:48 -0800 Subject: [PATCH 106/317] Fix some typos in versioning policy --- docs/version2.0.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/version2.0.0.md b/docs/version2.0.0.md index 8d2c9b644..65d10f748 100644 --- a/docs/version2.0.0.md +++ b/docs/version2.0.0.md @@ -1,6 +1,6 @@ # Kustomize 2.0.0 -After security review, a field use in secret generation was removed from the definition of a kustomization file with no mechanism to convert it to a new form. Also, the set of paths one may specify in a kustomization file has been further constrained. +After security review, a field used in secret generation (see below) was removed from the definition of a kustomization file with no mechanism to convert it to a new form. Also, the set of files accessible from a kustomization file has been further constrained. Per the [versioning policy](versioningPolicy.md), backward incompatible changes trigger an increment of the major version number, hence we go from 1.0.11 to 2.0.0. We're taking this major version increment opportunity to remove some already deprecated fields, and the code paths associated with them. From 7c8db246564864d144da039ab5050267db70d77d Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Wed, 6 Feb 2019 16:45:44 -0800 Subject: [PATCH 107/317] Rename kv.KVPair to kv.Pair --- k8sdeps/configmapandsecret/configmapfactory.go | 2 +- k8sdeps/configmapandsecret/kv.go | 14 +++++++------- k8sdeps/configmapandsecret/kv_test.go | 4 ++-- k8sdeps/configmapandsecret/secretfactory.go | 2 +- k8sdeps/kv/kv.go | 10 +++++----- k8sdeps/kv/kv_test.go | 6 +++--- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/k8sdeps/configmapandsecret/configmapfactory.go b/k8sdeps/configmapandsecret/configmapfactory.go index 7dabad4b5..97b013bf1 100644 --- a/k8sdeps/configmapandsecret/configmapfactory.go +++ b/k8sdeps/configmapandsecret/configmapfactory.go @@ -55,7 +55,7 @@ func (f *ConfigMapFactory) makeFreshConfigMap( // MakeConfigMap returns a new ConfigMap, or nil and an error. func (f *ConfigMapFactory) MakeConfigMap( args *types.ConfigMapArgs, options *types.GeneratorOptions) (*corev1.ConfigMap, error) { - var all []kv.KVPair + var all []kv.Pair var err error cm := f.makeFreshConfigMap(args) diff --git a/k8sdeps/configmapandsecret/kv.go b/k8sdeps/configmapandsecret/kv.go index 1ad4264e7..ffc7a1b14 100644 --- a/k8sdeps/configmapandsecret/kv.go +++ b/k8sdeps/configmapandsecret/kv.go @@ -26,20 +26,20 @@ import ( "sigs.k8s.io/kustomize/pkg/ifc" ) -func keyValuesFromLiteralSources(sources []string) ([]kv.KVPair, error) { - var kvs []kv.KVPair +func keyValuesFromLiteralSources(sources []string) ([]kv.Pair, error) { + var kvs []kv.Pair for _, s := range sources { k, v, err := parseLiteralSource(s) if err != nil { return nil, err } - kvs = append(kvs, kv.KVPair{Key: k, Value: v}) + kvs = append(kvs, kv.Pair{Key: k, Value: v}) } return kvs, nil } -func keyValuesFromFileSources(ldr ifc.Loader, sources []string) ([]kv.KVPair, error) { - var kvs []kv.KVPair +func keyValuesFromFileSources(ldr ifc.Loader, sources []string) ([]kv.Pair, error) { + var kvs []kv.Pair for _, s := range sources { k, fPath, err := parseFileSource(s) if err != nil { @@ -49,12 +49,12 @@ func keyValuesFromFileSources(ldr ifc.Loader, sources []string) ([]kv.KVPair, er if err != nil { return nil, err } - kvs = append(kvs, kv.KVPair{Key: k, Value: string(content)}) + kvs = append(kvs, kv.Pair{Key: k, Value: string(content)}) } return kvs, nil } -func keyValuesFromEnvFile(l ifc.Loader, path string) ([]kv.KVPair, error) { +func keyValuesFromEnvFile(l ifc.Loader, path string) ([]kv.Pair, error) { if path == "" { return nil, nil } diff --git a/k8sdeps/configmapandsecret/kv_test.go b/k8sdeps/configmapandsecret/kv_test.go index 0b7fe5c37..9b19f1515 100644 --- a/k8sdeps/configmapandsecret/kv_test.go +++ b/k8sdeps/configmapandsecret/kv_test.go @@ -29,12 +29,12 @@ func TestKeyValuesFromFileSources(t *testing.T) { tests := []struct { description string sources []string - expected []kv.KVPair + expected []kv.Pair }{ { description: "create kvs from file sources", sources: []string{"files/app-init.ini"}, - expected: []kv.KVPair{ + expected: []kv.Pair{ { Key: "app-init.ini", Value: "FOO=bar", diff --git a/k8sdeps/configmapandsecret/secretfactory.go b/k8sdeps/configmapandsecret/secretfactory.go index cc5d68b42..0308a27eb 100644 --- a/k8sdeps/configmapandsecret/secretfactory.go +++ b/k8sdeps/configmapandsecret/secretfactory.go @@ -54,7 +54,7 @@ func (f *SecretFactory) makeFreshSecret(args *types.SecretArgs) *corev1.Secret { // MakeSecret returns a new secret. func (f *SecretFactory) MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (*corev1.Secret, error) { - var all []kv.KVPair + var all []kv.Pair var err error s := f.makeFreshSecret(args) diff --git a/k8sdeps/kv/kv.go b/k8sdeps/kv/kv.go index 36451fa68..236a9f6a0 100644 --- a/k8sdeps/kv/kv.go +++ b/k8sdeps/kv/kv.go @@ -28,7 +28,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation" ) -type KVPair struct { +type Pair struct { Key string Value string } @@ -36,8 +36,8 @@ type KVPair struct { var utf8bom = []byte{0xEF, 0xBB, 0xBF} // KeyValuesFromLines parses given content in to a list of key-value pairs. -func KeyValuesFromLines(content []byte) ([]KVPair, error) { - var kvs []KVPair +func KeyValuesFromLines(content []byte) ([]Pair, error) { + var kvs []Pair scanner := bufio.NewScanner(bytes.NewReader(content)) currentLine := 0 @@ -63,8 +63,8 @@ func KeyValuesFromLines(content []byte) ([]KVPair, error) { // KeyValuesFromLine returns a kv with blank key if the line is empty or a comment. // The value will be retrieved from the environment if necessary. -func KeyValuesFromLine(line []byte, currentLine int) (KVPair, error) { - kv := KVPair{} +func KeyValuesFromLine(line []byte, currentLine int) (Pair, error) { + kv := Pair{} if !utf8.Valid(line) { return kv, fmt.Errorf("line %d has invalid utf8 bytes : %v", line, string(line)) diff --git a/k8sdeps/kv/kv_test.go b/k8sdeps/kv/kv_test.go index 7a398ac8a..f854a917f 100644 --- a/k8sdeps/kv/kv_test.go +++ b/k8sdeps/kv/kv_test.go @@ -25,7 +25,7 @@ func TestKeyValuesFromLines(t *testing.T) { tests := []struct { desc string content string - expectedPairs []KVPair + expectedPairs []Pair expectedErr bool }{ { @@ -34,7 +34,7 @@ func TestKeyValuesFromLines(t *testing.T) { k1=v1 k2=v2 `, - expectedPairs: []KVPair{ + expectedPairs: []Pair{ {Key: "k1", Value: "v1"}, {Key: "k2", Value: "v2"}, }, @@ -46,7 +46,7 @@ func TestKeyValuesFromLines(t *testing.T) { k1=v1 #k2=v2 `, - expectedPairs: []KVPair{ + expectedPairs: []Pair{ {Key: "k1", Value: "v1"}, }, expectedErr: false, From ccc44618278e260fa0d60fb8d95304c8be118be4 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Wed, 6 Feb 2019 17:11:43 -0800 Subject: [PATCH 108/317] Fix nil ptr bug --- pkg/loader/fileloader.go | 3 ++- pkg/loader/fileloader_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/pkg/loader/fileloader.go b/pkg/loader/fileloader.go index 69e5a3d0d..4fa5dca67 100644 --- a/pkg/loader/fileloader.go +++ b/pkg/loader/fileloader.go @@ -267,7 +267,8 @@ func (l *fileLoader) errIfArgEqualOrHigher( // path but a different tag? func (l *fileLoader) errIfRepoCycle(newRepoSpec *git.RepoSpec) error { // TODO(monopole): Use parsed data instead of Raw(). - if strings.HasPrefix(l.repoSpec.Raw(), newRepoSpec.Raw()) { + if l.repoSpec != nil && + strings.HasPrefix(l.repoSpec.Raw(), newRepoSpec.Raw()) { return fmt.Errorf( "cycle detected: URI '%s' referenced by previous URI '%s'", newRepoSpec.Raw(), l.repoSpec.Raw()) diff --git a/pkg/loader/fileloader_test.go b/pkg/loader/fileloader_test.go index 92ae3368e..b8affe10e 100644 --- a/pkg/loader/fileloader_test.go +++ b/pkg/loader/fileloader_test.go @@ -455,3 +455,29 @@ func TestLoaderDisallowsLocalBaseFromRemoteOverlay(t *testing.T) { t.Fatalf("unexpected err: %v", err) } } + +func TestLocalLoaderReferencingGitBase(t *testing.T) { + topDir := "/whatever" + cloneRoot := topDir + "/someClone" + fSys := fs.MakeFakeFS() + fSys.MkdirAll(topDir) + fSys.MkdirAll(cloneRoot + "/foo/base") + + root, err := demandDirectoryRoot(fSys, topDir) + if err != nil { + t.Fatalf("unexpected err: %v\n", err) + } + l1 := newLoaderAtConfirmedDir( + root, fSys, nil, + git.DoNothingCloner(fs.ConfirmedDir(cloneRoot))) + if l1.Root() != topDir { + t.Fatalf("unexpected root %s", l1.Root()) + } + l2, err := l1.New("github.com/someOrg/someRepo/foo/base") + if err != nil { + t.Fatalf("unexpected err: %v\n", err) + } + if l2.Root() != cloneRoot+"/foo/base" { + t.Fatalf("unexpected root %s", l2.Root()) + } +} From 242b9209d85d456d5978fe0973bdda0e9f8a2fe1 Mon Sep 17 00:00:00 2001 From: Alexander Brand Date: Wed, 6 Feb 2019 16:10:49 -0500 Subject: [PATCH 109/317] Improve error msg returned when no kustomization file is found Signed-off-by: Alexander Brand --- pkg/constants/constants.go | 2 +- pkg/target/kusttarget.go | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 0938f1567..dd50230fb 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -21,7 +21,7 @@ package constants // by Kustomize. // In each directory, Kustomize searches for file with the name in this list. // Only one match is allowed. -var KustomizationFileNames = [3]string{ +var KustomizationFileNames = []string{ "kustomization.yaml", "kustomization.yml", "Kustomization", diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index f0b4db87b..94a8b3f00 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -88,11 +88,12 @@ func loadKustFile(ldr ifc.Loader) ([]byte, error) { } switch match { case 0: - return nil, fmt.Errorf("no kustomization.yaml file under %s", ldr.Root()) + return nil, fmt.Errorf("No kustomization file found in %s. Kustomize supports the following kustomization files: %s", + ldr.Root(), strings.Join(constants.KustomizationFileNames, ", ")) case 1: return content, nil default: - return nil, fmt.Errorf("Found multiple kustomization file under: %s\n", ldr.Root()) + return nil, fmt.Errorf("Found multiple kustomization files under: %s\n", ldr.Root()) } } From cebcd8a44d511da8141615033c5a1a24a68f182e Mon Sep 17 00:00:00 2001 From: Sergey Date: Fri, 8 Feb 2019 18:42:47 +0500 Subject: [PATCH 110/317] transformers/image: loop refactoring --- pkg/transformers/image.go | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/pkg/transformers/image.go b/pkg/transformers/image.go index f6f999d1e..f59057f75 100644 --- a/pkg/transformers/image.go +++ b/pkg/transformers/image.go @@ -85,20 +85,21 @@ func (pt *imageTransformer) updateContainers(obj map[string]interface{}, path st imageName := containerImage.(string) for _, img := range pt.images { - if isImageMatched(imageName, img.Name) { - name, tag := split(imageName) - if img.NewName != "" { - name = img.NewName - } - if img.NewTag != "" { - tag = ":" + img.NewTag - } - if img.Digest != "" { - tag = "@" + img.Digest - } - container["image"] = name + tag - break + if !isImageMatched(imageName, img.Name) { + continue } + name, tag := split(imageName) + if img.NewName != "" { + name = img.NewName + } + if img.NewTag != "" { + tag = ":" + img.NewTag + } + if img.Digest != "" { + tag = "@" + img.Digest + } + container["image"] = name + tag + break } } return nil From 1f063d671237b145219be611a9837a3cf7b81a33 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Thu, 7 Feb 2019 10:45:23 -0800 Subject: [PATCH 111/317] Add more git url regression coverage --- pkg/git/repospec.go | 9 ++++- pkg/git/repospec_test.go | 72 ++++++++++++++++++++++------------------ 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/pkg/git/repospec.go b/pkg/git/repospec.go index db8b1b908..b3251f653 100644 --- a/pkg/git/repospec.go +++ b/pkg/git/repospec.go @@ -24,6 +24,13 @@ import ( "sigs.k8s.io/kustomize/pkg/fs" ) +// Used as a temporary non-empty occupant of the cloneDir +// field, as something distinguishable from the empty string +// in various outputs (especially tests). Not using an +// actual directory name here, as that's a temporary directory +// with a unique name that isn't created until clone time. +const notCloned = fs.ConfirmedDir("/notCloned") + // RepoSpec specifies a git repository and a branch and path therein. type RepoSpec struct { // Raw, original spec, used to look for cycles. @@ -88,7 +95,7 @@ func NewRepoSpecFromUrl(n string) (*RepoSpec, error) { } return &RepoSpec{ raw: n, host: host, orgRepo: orgRepo, - path: path, ref: gitRef}, nil + cloneDir: notCloned, path: path, ref: gitRef}, nil } const ( diff --git a/pkg/git/repospec_test.go b/pkg/git/repospec_test.go index 0413af6d7..c8ee5e2da 100644 --- a/pkg/git/repospec_test.go +++ b/pkg/git/repospec_test.go @@ -122,46 +122,52 @@ func TestNewRepoSpecFromUrlErrors(t *testing.T) { func TestNewRepoSpecFromUrl_CloneSpecs(t *testing.T) { testcases := []struct { - input string - repo string - path string - ref string + input string + cloneSpec string + absPath string + ref string }{ { - input: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo/somedir", - repo: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo", - path: "somedir", - ref: "", + input: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo/somedir", + cloneSpec: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo", + absPath: notCloned.Join("somedir"), + ref: "", }, { - input: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo/somedir?ref=testbranch", - repo: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo", - path: "somedir", - ref: "testbranch", + input: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo/somedir?ref=testbranch", + cloneSpec: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo", + absPath: notCloned.Join("somedir"), + ref: "testbranch", }, { - input: "https://fabrikops2.visualstudio.com/someorg/somerepo?ref=master", - repo: "https://fabrikops2.visualstudio.com/someorg/somerepo", - path: "", - ref: "master", + input: "https://fabrikops2.visualstudio.com/someorg/somerepo?ref=master", + cloneSpec: "https://fabrikops2.visualstudio.com/someorg/somerepo", + absPath: notCloned.String(), + ref: "master", }, { - input: "http://github.com/someorg/somerepo/somedir", - repo: "https://github.com/someorg/somerepo.git", - path: "somedir", - ref: "", + input: "http://github.com/someorg/somerepo/somedir", + cloneSpec: "https://github.com/someorg/somerepo.git", + absPath: notCloned.Join("somedir"), + ref: "", }, { - input: "git@github.com:someorg/somerepo/somedir", - repo: "git@github.com:someorg/somerepo.git", - path: "somedir", - ref: "", + input: "git@github.com:someorg/somerepo/somedir", + cloneSpec: "git@github.com:someorg/somerepo.git", + absPath: notCloned.Join("somedir"), + ref: "", }, { - input: "git@gitlab2.sqtools.ru:10022/infra/kubernetes/thanos-base.git?ref=v0.1.0", - repo: "git@gitlab2.sqtools.ru:10022/infra/kubernetes/thanos-base.git", - path: "", - ref: "v0.1.0", + input: "git@gitlab2.sqtools.ru:10022/infra/kubernetes/thanos-base.git?ref=v0.1.0", + cloneSpec: "git@gitlab2.sqtools.ru:10022/infra/kubernetes/thanos-base.git", + absPath: notCloned.String(), + ref: "v0.1.0", + }, + { + input: "git@bitbucket.org:company/project.git//path?ref=branch", + cloneSpec: "git@bitbucket.org:company/project.git", + absPath: notCloned.Join("path"), + ref: "branch", }, } for _, testcase := range testcases { @@ -169,13 +175,13 @@ func TestNewRepoSpecFromUrl_CloneSpecs(t *testing.T) { if err != nil { t.Errorf("Unexpected error: %v", err) } - if rs.CloneSpec() != testcase.repo { + if rs.CloneSpec() != testcase.cloneSpec { t.Errorf("CloneSpec expected to be %v, but got %v on %s", - testcase.repo, rs.CloneSpec(), testcase.input) + testcase.cloneSpec, rs.CloneSpec(), testcase.input) } - if rs.path != testcase.path { - t.Errorf("path expected to be %v, but got %v on %s", - testcase.path, rs.path, testcase.input) + if rs.AbsPath() != testcase.absPath { + t.Errorf("AbsPath expected to be %v, but got %v on %s", + testcase.absPath, rs.AbsPath(), testcase.input) } if rs.ref != testcase.ref { t.Errorf("ref expected to be %v, but got %v on %s", From 1a03dcabde7a40782148f5b621bc8936ed639e39 Mon Sep 17 00:00:00 2001 From: jregan Date: Sun, 10 Feb 2019 14:59:57 -0800 Subject: [PATCH 112/317] Test missing file report --- k8sdeps/configmapandsecret/configmapfactory.go | 4 ++-- k8sdeps/configmapandsecret/secretfactory.go | 4 ++-- pkg/target/kusttarget.go | 17 +++++++++++++++-- pkg/target/kusttarget_test.go | 14 ++++++++++++++ 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/k8sdeps/configmapandsecret/configmapfactory.go b/k8sdeps/configmapandsecret/configmapfactory.go index 97b013bf1..56362c24a 100644 --- a/k8sdeps/configmapandsecret/configmapfactory.go +++ b/k8sdeps/configmapandsecret/configmapfactory.go @@ -81,8 +81,8 @@ func (f *ConfigMapFactory) MakeConfigMap( } all = append(all, pairs...) - for _, kv := range all { - err = addKvToConfigMap(cm, kv.Key, kv.Value) + for _, p := range all { + err = addKvToConfigMap(cm, p.Key, p.Value) if err != nil { return nil, err } diff --git a/k8sdeps/configmapandsecret/secretfactory.go b/k8sdeps/configmapandsecret/secretfactory.go index 0308a27eb..677c74512 100644 --- a/k8sdeps/configmapandsecret/secretfactory.go +++ b/k8sdeps/configmapandsecret/secretfactory.go @@ -80,8 +80,8 @@ func (f *SecretFactory) MakeSecret(args *types.SecretArgs, options *types.Genera } all = append(all, pairs...) - for _, kv := range all { - err = addKvToSecret(s, kv.Key, kv.Value) + for _, p := range all { + err = addKvToSecret(s, p.Key, p.Value) if err != nil { return nil, err } diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 94a8b3f00..0e5eaa1e3 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -76,6 +76,18 @@ func NewKustTarget( }, nil } +func quoted(l []string) []string { + r := make([]string, len(l)) + for i, v := range l { + r[i] = "'" + v + "'" + } + return r +} + +func commaOr(q []string) string { + return strings.Join(q[:len(q)-1], ", ") + " or " + q[len(q)-1] +} + func loadKustFile(ldr ifc.Loader) ([]byte, error) { var content []byte match := 0 @@ -88,8 +100,9 @@ func loadKustFile(ldr ifc.Loader) ([]byte, error) { } switch match { case 0: - return nil, fmt.Errorf("No kustomization file found in %s. Kustomize supports the following kustomization files: %s", - ldr.Root(), strings.Join(constants.KustomizationFileNames, ", ")) + return nil, fmt.Errorf( + "unable to find one of %v in directory '%s'", + commaOr(quoted(constants.KustomizationFileNames)), ldr.Root()) case 1: return content, nil default: diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index 86d39bb79..87c15a19b 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -23,8 +23,10 @@ import ( "strings" "testing" + "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/internal/loadertest" "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" @@ -195,6 +197,18 @@ func TestResources1(t *testing.T) { } } +func TestKustomizationNotFound(t *testing.T) { + _, err := NewKustTarget( + loadertest.NewFakeLoader("/foo"), fs.MakeFakeFS(), nil, nil) + if err == nil { + t.Fatalf("expected an error") + } + if err.Error() != + `unable to find one of 'kustomization.yaml', 'kustomization.yml' or 'Kustomization' in directory '/foo'` { + t.Fatalf("unexpected error: %q", err) + } +} + func TestResourceNotFound(t *testing.T) { th := NewKustTestHarness(t, "/whatever") th.writeK("/whatever", kustomizationContent1) From 9837b5b4293b4e9a324049c0a59b4f9dcf45ea14 Mon Sep 17 00:00:00 2001 From: Nestor Date: Mon, 4 Feb 2019 09:26:25 +0100 Subject: [PATCH 113/317] add volumeMounts/mountPath to varreference Signed-off-by: Nestor --- .../config/defaultconfig/varreference.go | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/pkg/transformers/config/defaultconfig/varreference.go b/pkg/transformers/config/defaultconfig/varreference.go index 35a92d78e..068d83fd8 100644 --- a/pkg/transformers/config/defaultconfig/varreference.go +++ b/pkg/transformers/config/defaultconfig/varreference.go @@ -105,5 +105,47 @@ varReference: - path: spec/tls/hosts kind: Ingress + +- path: spec/template/spec/containers/volumeMounts/mountPath + kind: StatefulSet + +- path: spec/template/spec/initContainers/volumeMounts/mountPath + kind: StatefulSet + +- path: spec/containers/volumeMounts/mountPath + kind: Pod + +- path: spec/initContainers/volumeMounts/mountPath + kind: Pod + +- path: spec/template/spec/containers/volumeMounts/mountPath + kind: ReplicaSet + +- path: spec/template/spec/initContainers/volumeMounts/mountPath + kind: ReplicaSet + +- path: spec/template/spec/containers/volumeMounts/mountPath + kind: Job + +- path: spec/template/spec/initContainers/volumeMounts/mountPath + kind: Job + +- path: spec/template/spec/containers/volumeMounts/mountPath + kind: CronJob + +- path: spec/template/spec/initContainers/volumeMounts/mountPath + kind: CronJob + +- path: spec/template/spec/containers/volumeMounts/mountPath + kind: DaemonSet + +- path: spec/template/spec/initContainers/volumeMounts/mountPath + kind: DaemonSet + +- path: spec/template/spec/containers/volumeMounts/mountPath + kind: Deployment + +- path: spec/template/spec/initContainers/volumeMounts/mountPath + kind: Deployment ` ) From d968c0b4b10c429535f295b01633a9b122e58e6f Mon Sep 17 00:00:00 2001 From: Nestor Date: Mon, 11 Feb 2019 07:51:03 +0100 Subject: [PATCH 114/317] add varref mountpath test case --- pkg/target/variableref_test.go | 77 ++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/pkg/target/variableref_test.go b/pkg/target/variableref_test.go index afe6ea3cb..60aa47add 100644 --- a/pkg/target/variableref_test.go +++ b/pkg/target/variableref_test.go @@ -723,3 +723,80 @@ spec: - kustomized-nginx.example.com `) } + +func TestVariableRefMounthPath(t *testing.T) { + th := NewKustTestHarness(t, "/app/base") + th.writeK("/app/base", ` +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- deployment.yaml +- namespace.yaml + +vars: +- name: NAMESPACE + objref: + apiVersion: v1 + kind: Namespace + name: my-namespace + +`) + th.writeF("/app/base/deployment.yaml", ` + apiVersion: apps/v1 + kind: Deployment + metadata: + name: my-deployment + spec: + template: + spec: + containers: + - name: app + image: busybox + volumeMounts: + - name: my-volume + mountPath: "/$(NAMESPACE)" + env: + - name: NAMESPACE + value: $(NAMESPACE) + volumes: + - name: my-volume + emptyDir: {} +`) + th.writeF("/app/base/namespace.yaml", ` + apiVersion: v1 + kind: Namespace + metadata: + name: my-namespace +`) + + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +kind: Namespace +metadata: + name: my-namespace +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment +spec: + template: + spec: + containers: + - env: + - name: NAMESPACE + value: my-namespace + image: busybox + name: app + volumeMounts: + - mountPath: /my-namespace + name: my-volume + volumes: + - emptyDir: {} + name: my-volume +`) +} From 48717f3f3072a305eb2b4818e1fe90b90289f93a Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Mon, 11 Feb 2019 15:23:26 -0800 Subject: [PATCH 115/317] Switch to black box testing of KustTarget and Resource --- pkg/commands/build/build.go | 2 +- pkg/resource/factory_test.go | 3 +- pkg/resource/resource.go | 2 +- pkg/resource/resource_test.go | 13 +++-- pkg/target/baseandoverlaymedium_test.go | 2 +- pkg/target/baseandoverlaysmall_test.go | 2 +- pkg/target/configmaps_test.go | 2 +- pkg/target/crd_test.go | 2 +- pkg/target/customconfig_test.go | 2 +- pkg/target/generatormergeandreplace_test.go | 2 +- pkg/target/generatoroptions_test.go | 2 +- pkg/target/kusttarget.go | 16 +++---- pkg/target/kusttarget_test.go | 48 +++++++++++-------- ...ls_for_test.go => kusttestharness_test.go} | 17 ++----- pkg/target/multiplepatch_test.go | 2 +- pkg/target/namespacedgenerators_test.go | 2 +- pkg/target/nullvalues_test.go | 2 +- pkg/target/resaccumulator.go | 5 ++ pkg/target/resaccumulator_test.go | 3 +- pkg/target/resourceconflict_test.go | 2 +- pkg/target/variableref_test.go | 2 +- pkg/types/genargs.go | 17 +++++++ pkg/types/genargs_test.go | 47 ++++++++++++++++++ pkg/types/var.go | 6 ++- 24 files changed, 136 insertions(+), 67 deletions(-) rename pkg/target/{utils_for_test.go => kusttestharness_test.go} (87%) create mode 100644 pkg/types/genargs_test.go diff --git a/pkg/commands/build/build.go b/pkg/commands/build/build.go index 43c1a982f..e62747e32 100644 --- a/pkg/commands/build/build.go +++ b/pkg/commands/build/build.go @@ -108,7 +108,7 @@ func (o *Options) RunBuild( return err } defer ldr.Cleanup() - kt, err := target.NewKustTarget(ldr, fSys, rf, ptf) + kt, err := target.NewKustTarget(ldr, rf, ptf) if err != nil { return err } diff --git a/pkg/resource/factory_test.go b/pkg/resource/factory_test.go index 2fb0adeb8..45394f11d 100644 --- a/pkg/resource/factory_test.go +++ b/pkg/resource/factory_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package resource +package resource_test import ( "reflect" @@ -22,6 +22,7 @@ import ( "sigs.k8s.io/kustomize/pkg/internal/loadertest" "sigs.k8s.io/kustomize/pkg/patch" + . "sigs.k8s.io/kustomize/pkg/resource" ) func TestSliceFromPatches(t *testing.T) { diff --git a/pkg/resource/resource.go b/pkg/resource/resource.go index 7cc87a745..1e0e3764b 100644 --- a/pkg/resource/resource.go +++ b/pkg/resource/resource.go @@ -38,7 +38,7 @@ func (r *Resource) String() string { if err != nil { return "<" + err.Error() + ">" } - return strings.TrimSpace(string(bs)) + return strings.TrimSpace(string(bs)) + r.options.String() } // DeepCopy returns a new copy of resource diff --git a/pkg/resource/resource_test.go b/pkg/resource/resource_test.go index fbf4ba30b..b507d2633 100644 --- a/pkg/resource/resource_test.go +++ b/pkg/resource/resource_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package resource +package resource_test import ( "testing" @@ -22,6 +22,7 @@ import ( "sigs.k8s.io/kustomize/k8sdeps/kunstruct" "sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/resid" + . "sigs.k8s.io/kustomize/pkg/resource" ) var factory = NewFactory( @@ -37,7 +38,9 @@ var testConfigMap = factory.FromMap( }, }) -const testConfigMapString = `{"apiVersion":"v1","kind":"ConfigMap","metadata":{"name":"winnie","namespace":"hundred-acre-wood"}}` +const genArgOptions = "{nsfx:false,beh:unspecified}" + +const configMapAsString = `{"apiVersion":"v1","kind":"ConfigMap","metadata":{"name":"winnie","namespace":"hundred-acre-wood"}}` var testDeployment = factory.FromMap( map[string]interface{}{ @@ -48,7 +51,7 @@ var testDeployment = factory.FromMap( }, }) -const testDeploymentString = `{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":"pooh"}}` +const deploymentAsString = `{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":"pooh"}}` func TestResourceString(t *testing.T) { tests := []struct { @@ -57,11 +60,11 @@ func TestResourceString(t *testing.T) { }{ { in: testConfigMap, - s: testConfigMapString, + s: configMapAsString + genArgOptions, }, { in: testDeployment, - s: testDeploymentString, + s: deploymentAsString + genArgOptions, }, } for _, test := range tests { diff --git a/pkg/target/baseandoverlaymedium_test.go b/pkg/target/baseandoverlaymedium_test.go index 24f9558a4..6c409db28 100644 --- a/pkg/target/baseandoverlaymedium_test.go +++ b/pkg/target/baseandoverlaymedium_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test import ( "testing" diff --git a/pkg/target/baseandoverlaysmall_test.go b/pkg/target/baseandoverlaysmall_test.go index d9cbdb3fe..dfcd1fd43 100644 --- a/pkg/target/baseandoverlaysmall_test.go +++ b/pkg/target/baseandoverlaysmall_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test import ( "testing" diff --git a/pkg/target/configmaps_test.go b/pkg/target/configmaps_test.go index 9d62a6847..5c4ad8d08 100644 --- a/pkg/target/configmaps_test.go +++ b/pkg/target/configmaps_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test import ( "testing" diff --git a/pkg/target/crd_test.go b/pkg/target/crd_test.go index a8e9a757d..7bd71083c 100644 --- a/pkg/target/crd_test.go +++ b/pkg/target/crd_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test import ( "testing" diff --git a/pkg/target/customconfig_test.go b/pkg/target/customconfig_test.go index daf616681..8aaa91a96 100644 --- a/pkg/target/customconfig_test.go +++ b/pkg/target/customconfig_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test import ( "testing" diff --git a/pkg/target/generatormergeandreplace_test.go b/pkg/target/generatormergeandreplace_test.go index 028dd63e9..469c9c9e1 100644 --- a/pkg/target/generatormergeandreplace_test.go +++ b/pkg/target/generatormergeandreplace_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test import ( "testing" diff --git a/pkg/target/generatoroptions_test.go b/pkg/target/generatoroptions_test.go index e3c81c1ee..4dbdbb588 100644 --- a/pkg/target/generatoroptions_test.go +++ b/pkg/target/generatoroptions_test.go @@ -11,7 +11,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test import ( "testing" diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 0e5eaa1e3..f136b2683 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -26,7 +26,6 @@ import ( "github.com/ghodss/yaml" "github.com/pkg/errors" "sigs.k8s.io/kustomize/pkg/constants" - "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/ifc/transformer" interror "sigs.k8s.io/kustomize/pkg/internal/error" @@ -42,7 +41,6 @@ import ( type KustTarget struct { kustomization *types.Kustomization ldr ifc.Loader - fSys fs.FileSystem rFactory *resmap.Factory tFactory transformer.Factory } @@ -50,7 +48,6 @@ type KustTarget struct { // NewKustTarget returns a new instance of KustTarget primed with a Loader. func NewKustTarget( ldr ifc.Loader, - fSys fs.FileSystem, rFactory *resmap.Factory, tFactory transformer.Factory) (*KustTarget, error) { content, err := loadKustFile(ldr) @@ -70,7 +67,6 @@ func NewKustTarget( return &KustTarget{ kustomization: &k, ldr: ldr, - fSys: fSys, rFactory: rFactory, tFactory: tFactory, }, nil @@ -123,7 +119,7 @@ func unmarshal(y []byte, o interface{}) error { // MakeCustomizedResMap creates a ResMap per kustomization instructions. // The Resources in the returned ResMap are fully customized. func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) { - ra, err := kt.accumulateTarget() + ra, err := kt.AccumulateTarget() if err != nil { return nil, err } @@ -147,11 +143,11 @@ func (kt *KustTarget) shouldAddHashSuffixesToGeneratedResources() bool { !kt.kustomization.GeneratorOptions.DisableNameSuffixHash } -// accumulateTarget returns a new ResAccumulator, +// AccumulateTarget returns a new ResAccumulator, // holding customized resources and the data/rules used // to do so. The name back references and vars are // not yet fixed. -func (kt *KustTarget) accumulateTarget() ( +func (kt *KustTarget) AccumulateTarget() ( ra *ResAccumulator, err error) { // TODO(monopole): Get rid of the KustomizationErrors accumulator. // It's not consistently used, and complicates tests. @@ -249,15 +245,15 @@ func (kt *KustTarget) accumulateBases() ( continue } subKt, err := NewKustTarget( - ldr, kt.fSys, kt.rFactory, kt.tFactory) + ldr, kt.rFactory, kt.tFactory) if err != nil { errs.Append(errors.Wrap(err, "couldn't make target for "+path)) ldr.Cleanup() continue } - subRa, err := subKt.accumulateTarget() + subRa, err := subKt.AccumulateTarget() if err != nil { - errs.Append(errors.Wrap(err, "accumulateTarget")) + errs.Append(errors.Wrap(err, "AccumulateTarget")) ldr.Cleanup() continue } diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index 87c15a19b..e57fe0f37 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test import ( "encoding/base64" @@ -23,18 +23,18 @@ import ( "strings" "testing" - "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/internal/loadertest" "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" + . "sigs.k8s.io/kustomize/pkg/target" "sigs.k8s.io/kustomize/pkg/types" ) const ( - kustomizationContent1 = ` + kustomizationContent = ` apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namePrefix: foo- @@ -47,6 +47,8 @@ commonAnnotations: resources: - deployment.yaml - namespace.yaml +generatorOptions: + disableNameSuffixHash: false configMapGenerator: - name: literalConfigMap literals: @@ -83,9 +85,9 @@ metadata: ]` ) -func TestResources1(t *testing.T) { +func TestResources(t *testing.T) { th := NewKustTestHarness(t, "/whatever") - th.writeK("/whatever/", kustomizationContent1) + th.writeK("/whatever/", kustomizationContent) th.writeF("/whatever/deployment.yaml", deploymentContent) th.writeF("/whatever/namespace.yaml", namespaceContent) th.writeF("/whatever/jsonpatch.json", jsonpatchContent) @@ -146,7 +148,9 @@ func TestResources1(t *testing.T) { "DB_USERNAME": "admin", "DB_PASSWORD": "somepw", }, - }, &types.GeneratorArgs{}, nil), + }, + &types.GeneratorArgs{}, + &types.GeneratorOptions{}), resid.NewResIdWithPrefixSuffixNamespace( gvk.Gvk{Version: "v1", Kind: "Secret"}, "secret", "foo-", "-bar", "ns1"): th.fromMapAndOption( @@ -168,7 +172,9 @@ func TestResources1(t *testing.T) { "DB_USERNAME": base64.StdEncoding.EncodeToString([]byte("admin")), "DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")), }, - }, &types.GeneratorArgs{}, nil), + }, + &types.GeneratorArgs{}, + &types.GeneratorOptions{}), resid.NewResIdWithPrefixSuffixNamespace( gvk.Gvk{Version: "v1", Kind: "Namespace"}, "ns1", "foo-", "-bar", ""): th.fromMap( @@ -198,8 +204,7 @@ func TestResources1(t *testing.T) { } func TestKustomizationNotFound(t *testing.T) { - _, err := NewKustTarget( - loadertest.NewFakeLoader("/foo"), fs.MakeFakeFS(), nil, nil) + _, err := NewKustTarget(loadertest.NewFakeLoader("/foo"), nil, nil) if err == nil { t.Fatalf("expected an error") } @@ -211,7 +216,7 @@ func TestKustomizationNotFound(t *testing.T) { func TestResourceNotFound(t *testing.T) { th := NewKustTestHarness(t, "/whatever") - th.writeK("/whatever", kustomizationContent1) + th.writeK("/whatever", kustomizationContent) _, err := th.makeKustTarget().MakeCustomizedResMap() if err == nil { t.Fatalf("Didn't get the expected error for an unknown resource") @@ -232,13 +237,12 @@ func findSecret(m resmap.ResMap) *resource.Resource { func TestDisableNameSuffixHash(t *testing.T) { th := NewKustTestHarness(t, "/whatever") - th.writeK("/whatever/", kustomizationContent1) + th.writeK("/whatever/", kustomizationContent) th.writeF("/whatever/deployment.yaml", deploymentContent) th.writeF("/whatever/namespace.yaml", namespaceContent) th.writeF("/whatever/jsonpatch.json", jsonpatchContent) - kt := th.makeKustTarget() - m, err := kt.MakeCustomizedResMap() + m, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { t.Fatalf("unexpected Resources error %v", err) } @@ -250,9 +254,11 @@ func TestDisableNameSuffixHash(t *testing.T) { t.Errorf("unexpected secret resource name: %s", secret.GetName()) } - kt.kustomization.GeneratorOptions = &types.GeneratorOptions{ - DisableNameSuffixHash: true} - m, err = kt.MakeCustomizedResMap() + th.writeK("/whatever/", + strings.Replace(kustomizationContent, + "disableNameSuffixHash: false", + "disableNameSuffixHash: true", -1)) + m, err = th.makeKustTarget().MakeCustomizedResMap() if err != nil { t.Fatalf("unexpected Resources error %v", err) } @@ -338,11 +344,11 @@ vars: name: heron apiVersion: v300 `) - ra, err := th.makeKustTarget().accumulateTarget() + ra, err := th.makeKustTarget().AccumulateTarget() if err != nil { t.Fatalf("Err: %v", err) } - vars := ra.varSet.Set() + vars := ra.Vars() if len(vars) != 2 { t.Fatalf("unexpected size %d", len(vars)) } @@ -388,11 +394,11 @@ vars: bases: - ../o1 `) - ra, err := th.makeKustTarget().accumulateTarget() + ra, err := th.makeKustTarget().AccumulateTarget() if err != nil { t.Fatalf("Err: %v", err) } - vars := ra.varSet.Set() + vars := ra.Vars() if len(vars) != 4 { for i, v := range vars { fmt.Printf("%v: %v\n", i, v) @@ -441,7 +447,7 @@ vars: bases: - ../o1 `) - _, err := th.makeKustTarget().accumulateTarget() + _, err := th.makeKustTarget().AccumulateTarget() if err == nil { t.Fatalf("expected var collision") } diff --git a/pkg/target/utils_for_test.go b/pkg/target/kusttestharness_test.go similarity index 87% rename from pkg/target/utils_for_test.go rename to pkg/target/kusttestharness_test.go index 3b3a8f7e5..74cbab348 100644 --- a/pkg/target/utils_for_test.go +++ b/pkg/target/kusttestharness_test.go @@ -14,24 +14,24 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test // A collection of utilities used in target tests. import ( "fmt" "path/filepath" - "sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig" "strings" "testing" "sigs.k8s.io/kustomize/k8sdeps/kunstruct" "sigs.k8s.io/kustomize/k8sdeps/transformer" "sigs.k8s.io/kustomize/pkg/constants" - "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/internal/loadertest" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" + . "sigs.k8s.io/kustomize/pkg/target" + "sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig" "sigs.k8s.io/kustomize/pkg/types" ) @@ -50,17 +50,8 @@ func NewKustTestHarness(t *testing.T, path string) *KustTestHarness { } func (th *KustTestHarness) makeKustTarget() *KustTarget { - // Warning: the following filesystem - a fake - must be rooted at /. - // This fs root is used as the working directory for the shell spawned by - // the secretgenerator, and has nothing to do with the filesystem used - // to load relative paths from the fake filesystem. - // This trick only works for secret generator commands that don't actually - // try to read the file system, because these tests don't write to the - // real "/" directory. See use of exec package in the secretfactory. - fakeFs := fs.MakeFakeFS() - fakeFs.Mkdir("/") kt, err := NewKustTarget( - th.ldr, fakeFs, th.rf, transformer.NewFactoryImpl()) + th.ldr, th.rf, transformer.NewFactoryImpl()) if err != nil { th.t.Fatalf("Unexpected construction error %v", err) } diff --git a/pkg/target/multiplepatch_test.go b/pkg/target/multiplepatch_test.go index 6b5ed8ddb..6aa3bb6aa 100644 --- a/pkg/target/multiplepatch_test.go +++ b/pkg/target/multiplepatch_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test import ( "strings" diff --git a/pkg/target/namespacedgenerators_test.go b/pkg/target/namespacedgenerators_test.go index 2d46f0727..d6e550efc 100644 --- a/pkg/target/namespacedgenerators_test.go +++ b/pkg/target/namespacedgenerators_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test import ( "testing" diff --git a/pkg/target/nullvalues_test.go b/pkg/target/nullvalues_test.go index f04cfb932..7ccbbf1fa 100644 --- a/pkg/target/nullvalues_test.go +++ b/pkg/target/nullvalues_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test import ( "testing" diff --git a/pkg/target/resaccumulator.go b/pkg/target/resaccumulator.go index 41e448b8d..2ae05ba2c 100644 --- a/pkg/target/resaccumulator.go +++ b/pkg/target/resaccumulator.go @@ -55,6 +55,11 @@ func (ra *ResAccumulator) ResMap() resmap.ResMap { return result } +// Vars returns a copy of underlying vars. +func (ra *ResAccumulator) Vars() []types.Var { + return ra.varSet.Set() +} + func (ra *ResAccumulator) MergeResourcesWithErrorOnIdCollision( resources resmap.ResMap) (err error) { ra.resMap, err = resmap.MergeWithErrorOnIdCollision( diff --git a/pkg/target/resaccumulator_test.go b/pkg/target/resaccumulator_test.go index 69ec0b791..0bf1eedaa 100644 --- a/pkg/target/resaccumulator_test.go +++ b/pkg/target/resaccumulator_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test import ( "strings" @@ -25,6 +25,7 @@ import ( "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" + . "sigs.k8s.io/kustomize/pkg/target" "sigs.k8s.io/kustomize/pkg/transformers/config" "sigs.k8s.io/kustomize/pkg/types" ) diff --git a/pkg/target/resourceconflict_test.go b/pkg/target/resourceconflict_test.go index 991805a03..27a5bd18b 100644 --- a/pkg/target/resourceconflict_test.go +++ b/pkg/target/resourceconflict_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test import ( "strings" diff --git a/pkg/target/variableref_test.go b/pkg/target/variableref_test.go index 60aa47add..9d46030a4 100644 --- a/pkg/target/variableref_test.go +++ b/pkg/target/variableref_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package target_test import ( "testing" diff --git a/pkg/types/genargs.go b/pkg/types/genargs.go index a74a48d22..bef093d35 100644 --- a/pkg/types/genargs.go +++ b/pkg/types/genargs.go @@ -16,6 +16,11 @@ limitations under the License. package types +import ( + "strconv" + "strings" +) + // GenArgs contains both generator args and options type GenArgs struct { args *GeneratorArgs @@ -30,6 +35,18 @@ func NewGenArgs(args *GeneratorArgs, opts *GeneratorOptions) *GenArgs { } } +func (g *GenArgs) String() string { + if g == nil { + return "{nilGenArgs}" + } + return "{" + + strings.Join([]string{ + "nsfx:" + strconv.FormatBool(g.NeedsHashSuffix()), + "beh:" + g.Behavior().String()}, + ",") + + "}" +} + // NeedHashSuffix returns true if the hash suffix is needed. // It is needed when the two conditions are both met // 1) GenArgs is not nil diff --git a/pkg/types/genargs_test.go b/pkg/types/genargs_test.go new file mode 100644 index 000000000..a50dfd967 --- /dev/null +++ b/pkg/types/genargs_test.go @@ -0,0 +1,47 @@ +/* +Copyright 2018 The Kubernetes Authors. + Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package types_test + +import ( + "testing" + + . "sigs.k8s.io/kustomize/pkg/types" +) + +func TestGenArgs_String(t *testing.T) { + tests := []struct { + ga *GenArgs + expected string + }{ + { + ga: nil, + expected: "{nilGenArgs}", + }, + { + ga: &GenArgs{}, + expected: "{nsfx:false,beh:unspecified}", + }, + { + ga: NewGenArgs( + &GeneratorArgs{Behavior: "merge"}, + &GeneratorOptions{DisableNameSuffixHash: false}), + expected: "{nsfx:true,beh:merge}", + }, + } + for _, test := range tests { + if test.ga.String() != test.expected { + t.Fatalf("Expected '%s', got '%s'", test.expected, test.ga.String()) + } + } +} diff --git a/pkg/types/var.go b/pkg/types/var.go index 4be30078b..6a48032a0 100644 --- a/pkg/types/var.go +++ b/pkg/types/var.go @@ -75,9 +75,11 @@ type VarSet struct { set []Var } -// Set returns the var set. +// Set returns a copy of the var set. func (vs *VarSet) Set() []Var { - return vs.set + s := make([]Var, len(vs.set)) + copy(s, vs.set) + return s } // MergeSet absorbs other vars with error on name collision. From 1a43759ac3b5e8b320290a81de0ce266f11e7656 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Tue, 12 Feb 2019 08:57:56 -0800 Subject: [PATCH 116/317] fix invalid relative path in kustomization.yaml --- docs/kustomization.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index 781da106e..564762e72 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -69,7 +69,7 @@ commonAnnotations: # markers ("---"). resources: - some-service.yaml -- ../some-dir/some-deployment.yaml +- sub-dir/some-deployment.yaml # Each entry in this list results in the creation of # one ConfigMap resource (it's a generator of n maps). From fdba7df3c15e8a81b8bfda86d164b40407ff1f6e Mon Sep 17 00:00:00 2001 From: Andrew Lavery Date: Tue, 12 Feb 2019 12:28:08 -0800 Subject: [PATCH 117/317] if the kind matches '*List$', treat it as a list --- k8sdeps/kunstruct/factory.go | 2 +- pkg/resource/factory.go | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/k8sdeps/kunstruct/factory.go b/k8sdeps/kunstruct/factory.go index 09bb2bbba..cfd3ad309 100644 --- a/k8sdeps/kunstruct/factory.go +++ b/k8sdeps/kunstruct/factory.go @@ -108,7 +108,7 @@ func (kf *KunstructuredFactoryImpl) validate(u unstructured.Unstructured) error kind := u.GetKind() if kind == "" { return fmt.Errorf("missing kind in object %v", u) - } else if kind == "List" { + } else if strings.HasSuffix(kind, "List") { return nil } if u.GetName() == "" { diff --git a/pkg/resource/factory.go b/pkg/resource/factory.go index b016678a5..148323dd6 100644 --- a/pkg/resource/factory.go +++ b/pkg/resource/factory.go @@ -20,6 +20,7 @@ import ( "encoding/json" "fmt" "log" + "strings" "sigs.k8s.io/kustomize/pkg/ifc" internal "sigs.k8s.io/kustomize/pkg/internal/error" @@ -94,10 +95,14 @@ func (rf *Factory) SliceFromBytes(in []byte) ([]*Resource, error) { for len(kunStructs) > 0 { u := kunStructs[0] kunStructs = kunStructs[1:] - if u.GetKind() == "List" { + if strings.HasSuffix(u.GetKind(), "List") { items := u.Map()["items"] itemsSlice, ok := items.([]interface{}) if !ok { + if items == nil { + // an empty list + continue + } return nil, fmt.Errorf("items in List is type %T, expected array", items) } for _, item := range itemsSlice { From 3118ccfd05eafd5d3eba8b290a3d1735b8e88c8a Mon Sep 17 00:00:00 2001 From: Andrew Lavery Date: Tue, 12 Feb 2019 12:37:36 -0800 Subject: [PATCH 118/317] add tests for *List kinds and empty lists --- k8sdeps/kunstruct/factory_test.go | 27 +++++++++++++++++++++++++++ pkg/resource/factory_test.go | 15 ++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/k8sdeps/kunstruct/factory_test.go b/k8sdeps/kunstruct/factory_test.go index 51e2be793..4fe710934 100644 --- a/k8sdeps/kunstruct/factory_test.go +++ b/k8sdeps/kunstruct/factory_test.go @@ -42,6 +42,15 @@ func TestSliceFromBytes(t *testing.T) { testConfigMap.Map(), }, }) + testConfigMapList := factory.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "ConfigMapList", + "items": []interface{}{ + testConfigMap.Map(), + testConfigMap.Map(), + }, + }) tests := []struct { name string @@ -151,6 +160,24 @@ items: expectedOut: []ifc.Kunstructured{testList}, expectedErr: false, }, + { + name: "ConfigMapList", + input: []byte(` +apiVersion: v1 +kind: ConfigMapList +items: +- apiVersion: v1 + kind: ConfigMap + metadata: + name: winnie +- apiVersion: v1 + kind: ConfigMap + metadata: + name: winnie +`), + expectedOut: []ifc.Kunstructured{testConfigMapList}, + expectedErr: false, + }, } for _, test := range tests { diff --git a/pkg/resource/factory_test.go b/pkg/resource/factory_test.go index 45394f11d..b8138676f 100644 --- a/pkg/resource/factory_test.go +++ b/pkg/resource/factory_test.go @@ -68,7 +68,7 @@ items: patchList2 := patch.StrategicMerge("patch5.yaml") patch5 := ` apiVersion: v1 -kind: List +kind: DeploymentList items: - apiVersion: apps/v1 kind: Deployment @@ -87,6 +87,12 @@ items: name: deployment-b spec: <<: *hostAliases +` + patchList3 := patch.StrategicMerge("patch6.yaml") + patch6 := ` +apiVersion: v1 +kind: List +items: ` testDeploymentSpec := map[string]interface{}{ "template": map[string]interface{}{ @@ -126,6 +132,7 @@ items: l.AddFile("/"+string(patchBad), []byte(patch3)) l.AddFile("/"+string(patchList), []byte(patch4)) l.AddFile("/"+string(patchList2), []byte(patch5)) + l.AddFile("/"+string(patchList3), []byte(patch6)) tests := []struct { name string @@ -163,6 +170,12 @@ items: expectedOut: []*Resource{testDeploymentA, testDeploymentB}, expectedErr: false, }, + { + name: "listWithNoEntries", + input: []patch.StrategicMerge{patchList3}, + expectedOut: []*Resource{}, + expectedErr: false, + }, } for _, test := range tests { rs, err := factory.SliceFromPatches(l, test.input) From d72b16235accbcf5147c50b3cf39ee257bc5f20a Mon Sep 17 00:00:00 2001 From: Andrew Lavery Date: Tue, 12 Feb 2019 15:07:46 -0800 Subject: [PATCH 119/317] add a test for a list with no 'items:' provided --- pkg/resource/factory_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pkg/resource/factory_test.go b/pkg/resource/factory_test.go index b8138676f..8d9af62a3 100644 --- a/pkg/resource/factory_test.go +++ b/pkg/resource/factory_test.go @@ -93,6 +93,11 @@ items: apiVersion: v1 kind: List items: +` + patchList4 := patch.StrategicMerge("patch7.yaml") + patch7 := ` +apiVersion: v1 +kind: List ` testDeploymentSpec := map[string]interface{}{ "template": map[string]interface{}{ @@ -133,6 +138,7 @@ items: l.AddFile("/"+string(patchList), []byte(patch4)) l.AddFile("/"+string(patchList2), []byte(patch5)) l.AddFile("/"+string(patchList3), []byte(patch6)) + l.AddFile("/"+string(patchList4), []byte(patch7)) tests := []struct { name string @@ -176,6 +182,12 @@ items: expectedOut: []*Resource{}, expectedErr: false, }, + { + name: "listWithNo'items:'", + input: []patch.StrategicMerge{patchList4}, + expectedOut: []*Resource{}, + expectedErr: false, + }, } for _, test := range tests { rs, err := factory.SliceFromPatches(l, test.input) From 1382d87d7f40ac3fcea776e0018fcfcd5b824179 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 13 Feb 2019 00:24:20 +0200 Subject: [PATCH 120/317] Change ExpandFileSource to work with key=val patterns Signed-off-by: Chris --- pkg/commands/edit/add/flagsandargs.go | 32 +++++++++++++++++++--- pkg/commands/edit/add/flagsandargs_test.go | 30 ++++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/pkg/commands/edit/add/flagsandargs.go b/pkg/commands/edit/add/flagsandargs.go index 77bcc6b61..fb68fc87e 100644 --- a/pkg/commands/edit/add/flagsandargs.go +++ b/pkg/commands/edit/add/flagsandargs.go @@ -18,6 +18,7 @@ package add import ( "fmt" + "strings" "sigs.k8s.io/kustomize/pkg/fs" ) @@ -54,10 +55,33 @@ func (a *flagsAndArgs) Validate(args []string) error { } func (a *flagsAndArgs) ExpandFileSource(fSys fs.FileSystem) error { - result, err := globPatterns(fSys, a.FileSources) - if err != nil { - return err + var results []string + var key string + for _, pattern := range a.FileSources { + var patterns []string + key = "" + s := strings.Split(pattern, "=") + if len(s) == 2 { + patterns = append(patterns, s[1]) + key = s[0] + } else { + patterns = append(patterns, s[0]) + } + result, err := globPatterns(fSys, patterns) + if err != nil { + return err + } + if key != "" { + if len(result) != 1 { + msg := fmt.Sprintf("%s pattern should not catch more than one file", pattern) + return fmt.Errorf(msg) + } + fileSource := fmt.Sprintf("%s=%s", key, result[0]) + results = append(results, fileSource) + } else { + results = append(results, result...) + } } - a.FileSources = result + a.FileSources = results return nil } diff --git a/pkg/commands/edit/add/flagsandargs_test.go b/pkg/commands/edit/add/flagsandargs_test.go index 5638fe71f..108634d00 100644 --- a/pkg/commands/edit/add/flagsandargs_test.go +++ b/pkg/commands/edit/add/flagsandargs_test.go @@ -102,3 +102,33 @@ func TestExpandFileSource(t *testing.T) { t.Fatalf("FileSources is not correctly expanded: %v", fa.FileSources) } } + +func TestExpandFileSourceWithKey(t *testing.T) { + fakeFS := fs.MakeFakeFS() + fakeFS.Create("dir/fa1") + fakeFS.Create("dir/reademe") + fa := flagsAndArgs{ + FileSources: []string{"foo-key=dir/fa*"}, + } + fa.ExpandFileSource(fakeFS) + expected := []string{ + "foo-key=dir/fa1", + } + if !reflect.DeepEqual(fa.FileSources, expected) { + t.Fatalf("FileSources is not correctly expanded: %v", fa.FileSources) + } +} + +func TestExpandFileSourceWithKeyAndError(t *testing.T) { + fakeFS := fs.MakeFakeFS() + fakeFS.Create("dir/fa1") + fakeFS.Create("dir/fa2") + fakeFS.Create("dir/reademe") + fa := flagsAndArgs{ + FileSources: []string{"foo-key=dir/fa*"}, + } + err := fa.ExpandFileSource(fakeFS) + if err == nil { + t.Fatalf("FileSources should not be correctly expanded: %v", fa.FileSources) + } +} \ No newline at end of file From f5f8e49fa336e63747576c4f036715f60724493e Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Wed, 13 Feb 2019 09:38:13 +0200 Subject: [PATCH 121/317] Add explanatory comments and format Signed-off-by: Chris Mark --- pkg/commands/edit/add/flagsandargs.go | 4 ++++ pkg/commands/edit/add/flagsandargs_test.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/commands/edit/add/flagsandargs.go b/pkg/commands/edit/add/flagsandargs.go index fb68fc87e..b915cbf51 100644 --- a/pkg/commands/edit/add/flagsandargs.go +++ b/pkg/commands/edit/add/flagsandargs.go @@ -60,6 +60,8 @@ func (a *flagsAndArgs) ExpandFileSource(fSys fs.FileSystem) error { for _, pattern := range a.FileSources { var patterns []string key = "" + // check if the pattern is in `--from-file=[key=]source` format + // and if so split it to send only the file-pattern to glob function s := strings.Split(pattern, "=") if len(s) == 2 { patterns = append(patterns, s[1]) @@ -71,6 +73,8 @@ func (a *flagsAndArgs) ExpandFileSource(fSys fs.FileSystem) error { if err != nil { return err } + // if the format is `--from-file=[key=]source` accept only one result + // and extend it with the `key=` prefix if key != "" { if len(result) != 1 { msg := fmt.Sprintf("%s pattern should not catch more than one file", pattern) diff --git a/pkg/commands/edit/add/flagsandargs_test.go b/pkg/commands/edit/add/flagsandargs_test.go index 108634d00..5839f5a18 100644 --- a/pkg/commands/edit/add/flagsandargs_test.go +++ b/pkg/commands/edit/add/flagsandargs_test.go @@ -131,4 +131,4 @@ func TestExpandFileSourceWithKeyAndError(t *testing.T) { if err == nil { t.Fatalf("FileSources should not be correctly expanded: %v", fa.FileSources) } -} \ No newline at end of file +} From 7d3735b19e6b329dcf67ec1472235aa354255360 Mon Sep 17 00:00:00 2001 From: Todd Brown Date: Tue, 12 Feb 2019 12:35:09 -0600 Subject: [PATCH 122/317] Adding goos and goarch from runtime --- pkg/commands/misc/version.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/commands/misc/version.go b/pkg/commands/misc/version.go index d71749c5f..e9dbe9e59 100644 --- a/pkg/commands/misc/version.go +++ b/pkg/commands/misc/version.go @@ -19,14 +19,15 @@ package misc import ( "fmt" "io" + "runtime" "github.com/spf13/cobra" ) var ( kustomizeVersion = "unknown" - goos = "unknown" - goarch = "unknown" + goos = runtime.GOOS + goarch = runtime.GOARCH gitCommit = "$Format:%H$" // sha1 from git, output of $(git rev-parse HEAD) buildDate = "1970-01-01T00:00:00Z" // build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ') From 8c93f7ba745a7cab77b4897cee294664de8b377e Mon Sep 17 00:00:00 2001 From: Nestor Date: Mon, 11 Feb 2019 09:37:41 +0100 Subject: [PATCH 123/317] add support for varref in maps values --- pkg/target/variableref_test.go | 69 ++++++++++++-- .../config/defaultconfig/varreference.go | 2 + pkg/transformers/refvars.go | 11 +++ pkg/transformers/refvars_test.go | 91 +++++++++++++++++++ 4 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 pkg/transformers/refvars_test.go diff --git a/pkg/target/variableref_test.go b/pkg/target/variableref_test.go index 9d46030a4..a27c9ae9d 100644 --- a/pkg/target/variableref_test.go +++ b/pkg/target/variableref_test.go @@ -23,8 +23,6 @@ import ( func TestVariableRef(t *testing.T) { th := NewKustTestHarness(t, "/app/overlay/staging") th.writeK("/app/base", ` -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization namePrefix: base- resources: - cockroachdb-statefulset-secure.yaml @@ -323,8 +321,6 @@ spec: storage: 1Gi `) th.writeK("/app/overlay/staging", ` -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization namePrefix: dev- bases: - ../../base @@ -583,8 +579,6 @@ spec: func TestVariableRefIngress(t *testing.T) { th := NewKustTestHarness(t, "/app/overlay") th.writeK("/app/base", ` -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization resources: - deployment.yaml - ingress.yaml @@ -657,8 +651,6 @@ spec: targetPort: http `) th.writeK("/app/overlay", ` -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization nameprefix: kustomized- bases: - ../base @@ -727,8 +719,6 @@ spec: func TestVariableRefMounthPath(t *testing.T) { th := NewKustTestHarness(t, "/app/base") th.writeK("/app/base", ` -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization resources: - deployment.yaml - namespace.yaml @@ -800,3 +790,62 @@ spec: name: my-volume `) } + +func TestVariableRefMaps(t *testing.T) { + th := NewKustTestHarness(t, "/app/base") + th.writeK("/app/base", ` +resources: +- deployment.yaml +- namespace.yaml +vars: +- name: NAMESPACE + objref: + apiVersion: v1 + kind: Namespace + name: my-namespace +`) + th.writeF("/app/base/deployment.yaml", ` + apiVersion: apps/v1 + kind: Deployment + metadata: + name: my-deployment + labels: + my-label: $(NAMESPACE) + spec: + template: + spec: + containers: + - name: app + image: busybox +`) + th.writeF("/app/base/namespace.yaml", ` + apiVersion: v1 + kind: Namespace + metadata: + name: my-namespace +`) + + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +kind: Namespace +metadata: + name: my-namespace +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + my-label: my-namespace + name: my-deployment +spec: + template: + spec: + containers: + - image: busybox + name: app +`) +} diff --git a/pkg/transformers/config/defaultconfig/varreference.go b/pkg/transformers/config/defaultconfig/varreference.go index 068d83fd8..d83a43ad6 100644 --- a/pkg/transformers/config/defaultconfig/varreference.go +++ b/pkg/transformers/config/defaultconfig/varreference.go @@ -147,5 +147,7 @@ varReference: - path: spec/template/spec/initContainers/volumeMounts/mountPath kind: Deployment + +- path: metadata/labels ` ) diff --git a/pkg/transformers/refvars.go b/pkg/transformers/refvars.go index 1d35c9602..cace71f16 100644 --- a/pkg/transformers/refvars.go +++ b/pkg/transformers/refvars.go @@ -39,6 +39,17 @@ func (rv *refvarTransformer) replaceVars(in interface{}) (interface{}, error) { xs = append(xs, expansion.Expand(a.(string), rv.mappingFunc)) } return xs, nil + case map[string]interface{}: + inMap := in.(map[string]interface{}) + xs := make(map[string]interface{}, len(inMap)) + for k, v := range inMap { + s, ok := v.(string) + if !ok { + return nil, fmt.Errorf("%#v is expected to be %T", v, s) + } + xs[k] = expansion.Expand(s, rv.mappingFunc) + } + return xs, nil case interface{}: s, ok := in.(string) if !ok { diff --git a/pkg/transformers/refvars_test.go b/pkg/transformers/refvars_test.go new file mode 100644 index 000000000..fd2e9695b --- /dev/null +++ b/pkg/transformers/refvars_test.go @@ -0,0 +1,91 @@ +package transformers + +import ( + "reflect" + "testing" + + "sigs.k8s.io/kustomize/pkg/resid" + + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/transformers/config" +) + +func TestVarRef(t *testing.T) { + type given struct { + varMap map[string]string + fs []config.FieldSpec + res resmap.ResMap + } + type expected struct { + res resmap.ResMap + } + testCases := []struct { + description string + given given + expected expected + }{ + { + description: "var replacement in map[string]", + given: given{ + varMap: map[string]string{ + "FOO": "BAR", + }, + fs: []config.FieldSpec{ + {Gvk: cmap, Path: "data"}, + }, + res: resmap.ResMap{ + resid.NewResId(cmap, "cm1"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "ConfigMap", + "metadata": map[string]interface{}{ + "name": "cm1", + }, + "data": map[string]interface{}{ + "item1": "$(FOO)", + "item2": "bla", + }, + }), + }, + }, + expected: expected{ + res: resmap.ResMap{ + resid.NewResId(cmap, "cm1"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "ConfigMap", + "metadata": map[string]interface{}{ + "name": "cm1", + }, + "data": map[string]interface{}{ + "item1": "BAR", + "item2": "bla", + }, + }), + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.description, func(t *testing.T) { + // arrange + tr := NewRefVarTransformer(tc.given.varMap, tc.given.fs) + + // act + err := tr.Transform(tc.given.res) + + // assert + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + a, e := tc.given.res, tc.expected.res + if !reflect.DeepEqual(a, e) { + err = e.ErrorIfNotEqual(a) + t.Fatalf("actual doesn't match expected: \nACTUAL:\n%v\nEXPECTED:\n%v\nERR: %v", a, e, err) + } + + }) + } +} From 0f30c09cbfc5822ef32cfc7b7ff6059332e65ac0 Mon Sep 17 00:00:00 2001 From: jregan Date: Sat, 16 Feb 2019 11:47:27 -0800 Subject: [PATCH 124/317] Delete extraneous copyright. --- pkg/patch/transformer/patchjson6902json.go | 31 ++++++++++++++- pkg/patch/transformer/util.go | 46 ---------------------- 2 files changed, 29 insertions(+), 48 deletions(-) delete mode 100644 pkg/patch/transformer/util.go diff --git a/pkg/patch/transformer/patchjson6902json.go b/pkg/patch/transformer/patchjson6902json.go index 6737b959c..fa2fce49a 100644 --- a/pkg/patch/transformer/patchjson6902json.go +++ b/pkg/patch/transformer/patchjson6902json.go @@ -17,9 +17,12 @@ limitations under the License. package transformer import ( + "fmt" + "github.com/evanphx/json-patch" "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/resource" "sigs.k8s.io/kustomize/pkg/transformers" ) @@ -40,8 +43,8 @@ func newPatchJson6902JSONTransformer(t resid.ResId, p jsonpatch.Patch) (transfor } // Transform apply the json patches on top of the base resources. -func (t *patchJson6902JSONTransformer) Transform(baseResourceMap resmap.ResMap) error { - obj, err := findTargetObj(baseResourceMap, t.target) +func (t *patchJson6902JSONTransformer) Transform(m resmap.ResMap) error { + obj, err := t.findTargetObj(m) if obj == nil { return err } @@ -59,3 +62,27 @@ func (t *patchJson6902JSONTransformer) Transform(baseResourceMap resmap.ResMap) } return nil } + +func (t *patchJson6902JSONTransformer) findTargetObj( + m resmap.ResMap) (*resource.Resource, error) { + matched := m.FindByGVKN(t.target) + if t.target.Namespace() != "" { + var ids []resid.ResId + for _, id := range matched { + if id.Namespace() == t.target.Namespace() { + ids = append(ids, id) + } + } + matched = ids + } + if len(matched) == 0 { + return nil, fmt.Errorf( + "couldn't find target %v for json patch", t.target) + } + if len(matched) > 1 { + return nil, fmt.Errorf( + "found multiple targets %v matching %v for json patch", + matched, t.target) + } + return m[matched[0]], nil +} diff --git a/pkg/patch/transformer/util.go b/pkg/patch/transformer/util.go deleted file mode 100644 index aaed1e1cc..000000000 --- a/pkg/patch/transformer/util.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package transformer - -import ( - "fmt" - - "sigs.k8s.io/kustomize/pkg/resid" - "sigs.k8s.io/kustomize/pkg/resmap" - "sigs.k8s.io/kustomize/pkg/resource" -) - -func findTargetObj(m resmap.ResMap, targetId resid.ResId) (*resource.Resource, error) { - matchedIds := m.FindByGVKN(targetId) - if targetId.Namespace() != "" { - var ids []resid.ResId - for _, id := range matchedIds { - if id.Namespace() == targetId.Namespace() { - ids = append(ids, id) - } - } - matchedIds = ids - } - - if len(matchedIds) == 0 { - return nil, fmt.Errorf("couldn't find any object to apply the json patch %v", targetId) - } - if len(matchedIds) > 1 { - return nil, fmt.Errorf("found multiple objects that the patch can apply %v", matchedIds) - } - return m[matchedIds[0]], nil -} From d4d993a53ca4eef896c483dca135c58436f668f4 Mon Sep 17 00:00:00 2001 From: jregan Date: Sat, 16 Feb 2019 11:22:32 -0800 Subject: [PATCH 125/317] Add more resid test coverage. --- k8sdeps/transformer/patch/patch.go | 2 +- pkg/patch/transformer/patchjson6902json.go | 26 +- pkg/resid/resid.go | 41 ++- pkg/resid/resid_test.go | 346 ++++++++++++++++----- pkg/resmap/factory.go | 4 +- pkg/resmap/factory_test.go | 5 +- pkg/resmap/resmap.go | 17 +- pkg/resmap/resmap_test.go | 85 ++++- pkg/target/resaccumulator.go | 2 +- pkg/transformers/namereference.go | 4 +- 10 files changed, 411 insertions(+), 121 deletions(-) diff --git a/k8sdeps/transformer/patch/patch.go b/k8sdeps/transformer/patch/patch.go index 4a2764bfb..357f3daba 100644 --- a/k8sdeps/transformer/patch/patch.go +++ b/k8sdeps/transformer/patch/patch.go @@ -60,7 +60,7 @@ func (pt *patchTransformer) Transform(baseResourceMap resmap.ResMap) error { for _, patch := range patches { // Merge patches with base resource. id := patch.Id() - matchedIds := baseResourceMap.FindByGVKN(id) + matchedIds := baseResourceMap.GetMatchingIds(id.GvknEquals) if len(matchedIds) == 0 { return fmt.Errorf("failed to find an object with %s to apply the patch", id.GvknString()) } diff --git a/pkg/patch/transformer/patchjson6902json.go b/pkg/patch/transformer/patchjson6902json.go index fa2fce49a..c8f6e9e3e 100644 --- a/pkg/patch/transformer/patchjson6902json.go +++ b/pkg/patch/transformer/patchjson6902json.go @@ -35,17 +35,18 @@ type patchJson6902JSONTransformer struct { var _ transformers.Transformer = &patchJson6902JSONTransformer{} // newPatchJson6902JSONTransformer constructs a PatchJson6902 transformer. -func newPatchJson6902JSONTransformer(t resid.ResId, p jsonpatch.Patch) (transformers.Transformer, error) { +func newPatchJson6902JSONTransformer( + id resid.ResId, p jsonpatch.Patch) (transformers.Transformer, error) { if len(p) == 0 { return transformers.NewNoOpTransformer(), nil } - return &patchJson6902JSONTransformer{target: t, patch: p}, nil + return &patchJson6902JSONTransformer{target: id, patch: p}, nil } // Transform apply the json patches on top of the base resources. func (t *patchJson6902JSONTransformer) Transform(m resmap.ResMap) error { obj, err := t.findTargetObj(m) - if obj == nil { + if err != nil { return err } rawObj, err := obj.MarshalJSON() @@ -65,15 +66,18 @@ func (t *patchJson6902JSONTransformer) Transform(m resmap.ResMap) error { func (t *patchJson6902JSONTransformer) findTargetObj( m resmap.ResMap) (*resource.Resource, error) { - matched := m.FindByGVKN(t.target) + var matched []resid.ResId + // TODO(monopole): namespace bug in json patch? + // Since introduction in PR #300 + // (see pkg/patch/transformer/util.go), + // this code has treated an empty namespace like a wildcard + // rather than like an additional restriction to match + // only the empty namespace. No test coverage to confirm. + // Not sure if desired, keeping it for now. if t.target.Namespace() != "" { - var ids []resid.ResId - for _, id := range matched { - if id.Namespace() == t.target.Namespace() { - ids = append(ids, id) - } - } - matched = ids + matched = m.GetMatchingIds(t.target.NsGvknEquals) + } else { + matched = m.GetMatchingIds(t.target.GvknEquals) } if len(matched) == 0 { return nil, fmt.Errorf( diff --git a/pkg/resid/resid.go b/pkg/resid/resid.go index 2af7c02a5..dbf9a3e92 100644 --- a/pkg/resid/resid.go +++ b/pkg/resid/resid.go @@ -22,23 +22,30 @@ import ( "sigs.k8s.io/kustomize/pkg/gvk" ) -// ResId conflates GroupVersionKind with a textual name to uniquely identify a kubernetes resource (object). +// ResId is an immutable identifier of a k8s resource object. type ResId struct { // Gvk of the resource. gvKind gvk.Gvk - // original name of the resource before transformation. + + // name of the resource before transformation. name string - // namePrefix of the resource - // an untransformed resource has no prefix, fully transformed resource has an arbitrary number of prefixes - // concatenated together. + + // namePrefix of the resource. + // An untransformed resource has no prefix. + // A fully transformed resource has an arbitrary + // number of prefixes concatenated together. prefix string - // nameSuffix of the resource - // an untransformed resource has no suffix, fully transformed resource has an arbitrary number of suffixes - // concatenated together. + + // nameSuffix of the resource. + // An untransformed resource has no suffix. + // A fully transformed resource has an arbitrary + // number of suffixes concatenated together. suffix string - // namespace the resource belongs to - // an untransformed resource has no namespace, fully transformed resource has the namespace from - // the top most overlay + + // Namespace the resource belongs to. + // An untransformed resource has no namespace. + // A fully transformed resource has the namespace + // from the top most overlay. namespace string } @@ -108,10 +115,16 @@ func (n ResId) GvknString() string { return n.gvKind.String() + separator + n.name } -// GvknEquals return if two ResId have the same Group/Version/Kind and name -// The comparison excludes prefix and suffix +// GvknEquals returns true if the other id matches +// Group/Version/Kind/name. func (n ResId) GvknEquals(id ResId) bool { - return n.gvKind.Equals(id.gvKind) && n.name == id.name + return n.name == id.name && n.gvKind.Equals(id.gvKind) +} + +// NsGvknEquals returns true if the other id matches +// namespace/Group/Version/Kind/name. +func (n ResId) NsGvknEquals(id ResId) bool { + return n.namespace == id.namespace && n.GvknEquals(id) } // Gvk returns Group/Version/Kind of the resource. diff --git a/pkg/resid/resid_test.go b/pkg/resid/resid_test.go index 85bafd447..cf3d46a82 100644 --- a/pkg/resid/resid_test.go +++ b/pkg/resid/resid_test.go @@ -10,31 +10,80 @@ var stringTests = []struct { x ResId s string }{ - {ResId{gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, - name: "nm", prefix: "p", suffix: "s", namespace: "ns"}, - "g_v_k|ns|p|nm|s"}, - {ResId{gvKind: gvk.Gvk{Version: "v", Kind: "k"}, - name: "nm", prefix: "p", suffix: "s", namespace: "ns"}, - "~G_v_k|ns|p|nm|s"}, - {ResId{gvKind: gvk.Gvk{Kind: "k"}, - name: "nm", prefix: "p", suffix: "s", namespace: "ns"}, - "~G_~V_k|ns|p|nm|s"}, - {ResId{gvKind: gvk.Gvk{}, - name: "nm", prefix: "p", suffix: "s", namespace: "ns"}, - "~G_~V_~K|ns|p|nm|s"}, - {ResId{gvKind: gvk.Gvk{}, - name: "nm", prefix: "p", suffix: "s"}, - "~G_~V_~K|~X|p|nm|s"}, - {ResId{gvKind: gvk.Gvk{}, - name: "nm", suffix: "s"}, - "~G_~V_~K|~X|~P|nm|s"}, - {ResId{gvKind: gvk.Gvk{}, - suffix: "s"}, - "~G_~V_~K|~X|~P|~N|s"}, - {ResId{gvKind: gvk.Gvk{}}, - "~G_~V_~K|~X|~P|~N|~S"}, - {ResId{}, - "~G_~V_~K|~X|~P|~N|~S"}, + { + ResId{ + namespace: "ns", + gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, + name: "nm", + prefix: "p", + suffix: "s", + }, + "g_v_k|ns|p|nm|s", + }, + { + ResId{ + namespace: "ns", + gvKind: gvk.Gvk{Version: "v", Kind: "k"}, + name: "nm", + prefix: "p", + suffix: "s", + }, + "~G_v_k|ns|p|nm|s", + }, + { + ResId{ + namespace: "ns", + gvKind: gvk.Gvk{Kind: "k"}, + name: "nm", + prefix: "p", + suffix: "s", + }, + "~G_~V_k|ns|p|nm|s", + }, + { + ResId{ + namespace: "ns", + gvKind: gvk.Gvk{}, + name: "nm", + prefix: "p", + suffix: "s", + }, + "~G_~V_~K|ns|p|nm|s", + }, + { + ResId{ + gvKind: gvk.Gvk{}, + name: "nm", + prefix: "p", + suffix: "s", + }, + "~G_~V_~K|~X|p|nm|s", + }, + { + ResId{ + gvKind: gvk.Gvk{}, + name: "nm", + suffix: "s", + }, + "~G_~V_~K|~X|~P|nm|s", + }, + { + ResId{ + gvKind: gvk.Gvk{}, + suffix: "s", + }, + "~G_~V_~K|~X|~P|~N|s", + }, + { + ResId{ + gvKind: gvk.Gvk{}, + }, + "~G_~V_~K|~X|~P|~N|~S", + }, + { + ResId{}, + "~G_~V_~K|~X|~P|~N|~S", + }, } func TestString(t *testing.T) { @@ -49,31 +98,80 @@ var gvknStringTests = []struct { x ResId s string }{ - {ResId{gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, - name: "nm", prefix: "p", suffix: "s", namespace: "ns"}, - "g_v_k|nm"}, - {ResId{gvKind: gvk.Gvk{Version: "v", Kind: "k"}, - name: "nm", prefix: "p", suffix: "s", namespace: "ns"}, - "~G_v_k|nm"}, - {ResId{gvKind: gvk.Gvk{Kind: "k"}, - name: "nm", prefix: "p", suffix: "s", namespace: "ns"}, - "~G_~V_k|nm"}, - {ResId{gvKind: gvk.Gvk{}, - name: "nm", prefix: "p", suffix: "s", namespace: "ns"}, - "~G_~V_~K|nm"}, - {ResId{gvKind: gvk.Gvk{}, - name: "nm", prefix: "p", suffix: "s"}, - "~G_~V_~K|nm"}, - {ResId{gvKind: gvk.Gvk{}, - name: "nm", suffix: "s"}, - "~G_~V_~K|nm"}, - {ResId{gvKind: gvk.Gvk{}, - suffix: "s"}, - "~G_~V_~K|"}, - {ResId{gvKind: gvk.Gvk{}}, - "~G_~V_~K|"}, - {ResId{}, - "~G_~V_~K|"}, + { + ResId{ + namespace: "ns", + gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, + name: "nm", + prefix: "p", + suffix: "s", + }, + "g_v_k|nm", + }, + { + ResId{ + namespace: "ns", + gvKind: gvk.Gvk{Version: "v", Kind: "k"}, + name: "nm", + prefix: "p", + suffix: "s", + }, + "~G_v_k|nm", + }, + { + ResId{ + namespace: "ns", + gvKind: gvk.Gvk{Kind: "k"}, + name: "nm", + prefix: "p", + suffix: "s", + }, + "~G_~V_k|nm", + }, + { + ResId{ + namespace: "ns", + gvKind: gvk.Gvk{}, + name: "nm", + prefix: "p", + suffix: "s", + }, + "~G_~V_~K|nm", + }, + { + ResId{ + gvKind: gvk.Gvk{}, + name: "nm", + prefix: "p", + suffix: "s", + }, + "~G_~V_~K|nm", + }, + { + ResId{ + gvKind: gvk.Gvk{}, + name: "nm", + suffix: "s", + }, + "~G_~V_~K|nm", + }, + { + ResId{ + gvKind: gvk.Gvk{}, + suffix: "s", + }, + "~G_~V_~K|", + }, + { + ResId{ + gvKind: gvk.Gvk{}, + }, + "~G_~V_~K|", + }, + { + ResId{}, + "~G_~V_~K|", + }, } func TestGvknString(t *testing.T) { @@ -85,47 +183,147 @@ func TestGvknString(t *testing.T) { } var GvknEqualsTest = []struct { - x1 ResId - x2 ResId + id1 ResId + id2 ResId + gVknResult bool + nSgVknResult bool }{ - {ResId{gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, - name: "nm", prefix: "AA", suffix: "aa", namespace: "X"}, - ResId{gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, - name: "nm", prefix: "BB", suffix: "bb", namespace: "Z"}}, - {ResId{gvKind: gvk.Gvk{Version: "v", Kind: "k"}, - name: "nm", prefix: "AA", suffix: "aa", namespace: "X"}, - ResId{gvKind: gvk.Gvk{Version: "v", Kind: "k"}, - name: "nm", prefix: "BB", suffix: "bb", namespace: "Z"}}, - {ResId{gvKind: gvk.Gvk{Kind: "k"}, - name: "nm", prefix: "AA", suffix: "aa", namespace: "X"}, - ResId{gvKind: gvk.Gvk{Kind: "k"}, - name: "nm", prefix: "BB", suffix: "bb", namespace: "Z"}}, - {ResId{name: "nm", prefix: "AA", suffix: "aa", namespace: "X"}, - ResId{name: "nm", prefix: "BB", suffix: "bb", namespace: "Z"}}, + { + id1: ResId{ + namespace: "X", + gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, + name: "nm", + prefix: "AA", + suffix: "aa", + }, + id2: ResId{ + namespace: "X", + gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, + name: "nm", + prefix: "BB", + suffix: "bb", + }, + gVknResult: true, + nSgVknResult: true, + }, + { + id1: ResId{ + namespace: "X", + gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, + name: "nm", + prefix: "AA", + suffix: "aa", + }, + id2: ResId{ + namespace: "Z", + gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, + name: "nm", + prefix: "BB", + suffix: "bb", + }, + gVknResult: true, + nSgVknResult: false, + }, + { + id1: ResId{ + namespace: "X", + gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, + name: "nm", + prefix: "AA", + suffix: "aa", + }, + id2: ResId{ + gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, + name: "nm", + prefix: "BB", + suffix: "bb", + }, + gVknResult: true, + nSgVknResult: false, + }, + { + id1: ResId{ + namespace: "X", + gvKind: gvk.Gvk{Version: "v", Kind: "k"}, + name: "nm", + prefix: "AA", + suffix: "aa", + }, + id2: ResId{ + namespace: "Z", + gvKind: gvk.Gvk{Version: "v", Kind: "k"}, + name: "nm", + prefix: "BB", + suffix: "bb", + }, + gVknResult: true, + nSgVknResult: false, + }, + { + id1: ResId{ + namespace: "X", + gvKind: gvk.Gvk{Kind: "k"}, + name: "nm", + prefix: "AA", + suffix: "aa", + }, + id2: ResId{ + namespace: "Z", + gvKind: gvk.Gvk{Kind: "k"}, + name: "nm", + prefix: "BB", + suffix: "bb", + }, + gVknResult: true, + nSgVknResult: false, + }, + { + id1: ResId{ + namespace: "X", + name: "nm", + prefix: "AA", + suffix: "aa", + }, + id2: ResId{ + namespace: "Z", + name: "nm", + prefix: "BB", + suffix: "bb", + }, + gVknResult: true, + nSgVknResult: false, + }, } func TestEquals(t *testing.T) { - for _, hey := range GvknEqualsTest { - if !hey.x1.GvknEquals(hey.x2) { - t.Fatalf("%v should equal %v", hey.x1, hey.x2) + for _, tst := range GvknEqualsTest { + if tst.id1.GvknEquals(tst.id2) != tst.gVknResult { + t.Fatalf("GvknEquals(\n%v,\n%v\n) should be %v", + tst.id1, tst.id2, tst.gVknResult) + } + if tst.id1.NsGvknEquals(tst.id2) != tst.nSgVknResult { + t.Fatalf("NsGvknEquals(\n%v,\n%v\n) should be %v", + tst.id1, tst.id2, tst.nSgVknResult) } } } func TestCopyWithNewPrefixSuffix(t *testing.T) { r1 := ResId{ + namespace: "X", gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, name: "nm", prefix: "a", suffix: "b", - namespace: "X"} + } r2 := r1.CopyWithNewPrefixSuffix("p-", "-s") expected := ResId{ + namespace: "X", gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, name: "nm", prefix: "p-a", suffix: "b-s", - namespace: "X"} + } if !r2.GvknEquals(expected) { t.Fatalf("%v should equal %v", r2, expected) } @@ -133,18 +331,20 @@ func TestCopyWithNewPrefixSuffix(t *testing.T) { func TestCopyWithNewNamespace(t *testing.T) { r1 := ResId{ + namespace: "X", gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, name: "nm", prefix: "a", suffix: "b", - namespace: "X"} + } r2 := r1.CopyWithNewNamespace("zzz") expected := ResId{ + namespace: "zzz", gvKind: gvk.Gvk{Group: "g", Version: "v", Kind: "k"}, name: "nm", prefix: "a", suffix: "b", - namespace: "zzz"} + } if !r2.GvknEquals(expected) { t.Fatalf("%v should equal %v", r2, expected) } diff --git a/pkg/resmap/factory.go b/pkg/resmap/factory.go index 9e64dbee4..923cde232 100644 --- a/pkg/resmap/factory.go +++ b/pkg/resmap/factory.go @@ -50,7 +50,7 @@ func (rmF *Factory) FromFiles( if err != nil { return nil, errors.Wrap(err, "Load from path "+path+" failed") } - res, err := rmF.newResMapFromBytes(content) + res, err := rmF.NewResMapFromBytes(content) if err != nil { return nil, internal.Handler(err, path) } @@ -60,7 +60,7 @@ func (rmF *Factory) FromFiles( } // newResMapFromBytes decodes a list of objects in byte array format. -func (rmF *Factory) newResMapFromBytes(b []byte) (ResMap, error) { +func (rmF *Factory) NewResMapFromBytes(b []byte) (ResMap, error) { resources, err := rmF.resF.SliceFromBytes(b) if err != nil { return nil, err diff --git a/pkg/resmap/factory_test.go b/pkg/resmap/factory_test.go index 5d20250b1..272871b0f 100644 --- a/pkg/resmap/factory_test.go +++ b/pkg/resmap/factory_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package resmap +package resmap_test import ( "encoding/base64" @@ -28,6 +28,7 @@ import ( "sigs.k8s.io/kustomize/pkg/internal/loadertest" "sigs.k8s.io/kustomize/pkg/loader" "sigs.k8s.io/kustomize/pkg/resid" + . "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/types" ) @@ -124,7 +125,7 @@ metadata: }, }), } - m, err := rmF.newResMapFromBytes(encoded) + m, err := rmF.NewResMapFromBytes(encoded) fmt.Printf("%v\n", m) if err != nil { t.Fatalf("unexpected error: %v", err) diff --git a/pkg/resmap/resmap.go b/pkg/resmap/resmap.go index d6936f6d5..bb6dec478 100644 --- a/pkg/resmap/resmap.go +++ b/pkg/resmap/resmap.go @@ -32,20 +32,23 @@ import ( // ResMap is a map from ResId to Resource. type ResMap map[resid.ResId]*resource.Resource -// FindByGVKN find the matched ResIds by Group/Version/Kind and Name -func (m ResMap) FindByGVKN(inputId resid.ResId) []resid.ResId { +type IdMatcher func(resid.ResId) bool + +// GetMatchingIds returns a slice of ResId keys from the map +// that all satisfy the given matcher function. +func (m ResMap) GetMatchingIds(matches IdMatcher) []resid.ResId { var result []resid.ResId for id := range m { - if id.GvknEquals(inputId) { + if matches(id) { result = append(result, id) } } return result } -// DemandOneMatchForId find the matched resource by Group/Version/Kind and Name -func (m ResMap) DemandOneMatchForId(inputId resid.ResId) (*resource.Resource, bool) { - result := m.FindByGVKN(inputId) +// DemandOneGvknMatchForId find the matched resource by Group/Version/Kind and Name +func (m ResMap) DemandOneGvknMatchForId(inputId resid.ResId) (*resource.Resource, bool) { + result := m.GetMatchingIds(inputId.GvknEquals) if len(result) == 1 { return m[result[0]], true } @@ -177,7 +180,7 @@ func MergeWithOverride(maps ...ResMap) (ResMap, error) { continue } for id, r := range m { - matchedId := result.FindByGVKN(id) + matchedId := result.GetMatchingIds(id.GvknEquals) if len(matchedId) == 1 { id = matchedId[0] switch r.Behavior() { diff --git a/pkg/resmap/resmap_test.go b/pkg/resmap/resmap_test.go index 7b1f569b1..74a43cdd6 100644 --- a/pkg/resmap/resmap_test.go +++ b/pkg/resmap/resmap_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package resmap +package resmap_test import ( "reflect" @@ -23,6 +23,7 @@ import ( "sigs.k8s.io/kustomize/k8sdeps/kunstruct" "sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/resid" + . "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" "sigs.k8s.io/kustomize/pkg/types" ) @@ -71,7 +72,7 @@ metadata: } } -func TestDemandOneMatchForId(t *testing.T) { +func TestDemandOneGvknMatchForId(t *testing.T) { rm1 := ResMap{ resid.NewResIdWithPrefixNamespace(cmap, "cm1", "prefix1", "ns1"): rf.FromMap( map[string]interface{}{ @@ -91,19 +92,22 @@ func TestDemandOneMatchForId(t *testing.T) { }), } - _, ok := rm1.DemandOneMatchForId(resid.NewResIdWithPrefixNamespace(cmap, "cm2", "prefix1", "ns1")) + _, ok := rm1.DemandOneGvknMatchForId( + resid.NewResIdWithPrefixNamespace(cmap, "cm2", "prefix1", "ns1")) if !ok { t.Fatal("Expected single map entry but got none") } // confirm that ns and prefix are not included in match - _, ok = rm1.DemandOneMatchForId(resid.NewResIdWithPrefixNamespace(cmap, "cm2", "prefix", "ns")) + _, ok = rm1.DemandOneGvknMatchForId( + resid.NewResIdWithPrefixNamespace(cmap, "cm2", "prefix", "ns")) if !ok { t.Fatal("Expected single map entry but got none") } // confirm that name is matched correctly - result, ok := rm1.DemandOneMatchForId(resid.NewResIdWithPrefixNamespace(cmap, "cm3", "prefix1", "ns1")) + result, ok := rm1.DemandOneGvknMatchForId( + resid.NewResIdWithPrefixNamespace(cmap, "cm3", "prefix1", "ns1")) if ok { t.Fatalf("Expected no map entries but got %v", result) } @@ -111,7 +115,8 @@ func TestDemandOneMatchForId(t *testing.T) { cmap2 := gvk.Gvk{Version: "v2", Kind: "ConfigMap"} // confirm that gvk is matched correctly - result, ok = rm1.DemandOneMatchForId(resid.NewResIdWithPrefixNamespace(cmap2, "cm2", "prefix1", "ns1")) + result, ok = rm1.DemandOneGvknMatchForId( + resid.NewResIdWithPrefixNamespace(cmap2, "cm2", "prefix1", "ns1")) if ok { t.Fatalf("Expected no map entries but got %v", result) } @@ -291,8 +296,73 @@ func TestDeepCopy(t *testing.T) { } } -func TestErrorIfNotEqual(t *testing.T) { +func TestGetMatchingIds(t *testing.T) { + // These ids used as map keys. + // They must be different to avoid overwriting + // map entries during construction. + ids := []resid.ResId{ + resid.NewResId( + gvk.Gvk{Kind: "vegetable"}, + "bedlam"), + resid.NewResId( + gvk.Gvk{Group: "g1", Version: "v1", Kind: "vegetable"}, + "domino"), + resid.NewResIdWithPrefixNamespace( + gvk.Gvk{Kind: "vegetable"}, + "peter", "p", "happy"), + resid.NewResIdWithPrefixNamespace( + gvk.Gvk{Version: "v1", Kind: "fruit"}, + "shatterstar", "p", "happy"), + } + m := ResMap{} + for _, id := range ids { + // Resources values don't matter in this test. + m[id] = nil + } + if len(m) != len(ids) { + t.Fatalf("unexpected map len %d presumably due to duplicate keys", len(m)) + } + + tests := []struct { + name string + matcher IdMatcher + count int + }{ + { + "match everything", + func(resid.ResId) bool { return true }, + 4, + }, + { + "match nothing", + func(resid.ResId) bool { return false }, + 0, + }, + { + "name is peter", + func(x resid.ResId) bool { return x.Name() == "peter" }, + 1, + }, + { + "happy vegetable", + func(x resid.ResId) bool { + return x.Namespace() == "happy" && + x.Gvk().Kind == "vegetable" + }, + 1, + }, + } + for _, tst := range tests { + result := m.GetMatchingIds(tst.matcher) + if len(result) != tst.count { + t.Fatalf("test '%s'; actual: %d, expected: %d", + tst.name, len(result), tst.count) + } + } +} + +func TestErrorIfNotEqual(t *testing.T) { rm1 := ResMap{ resid.NewResId(cmap, "cm1"): rf.FromMap( map[string]interface{}{ @@ -436,7 +506,6 @@ func TestMergeWithoutOverride(t *testing.T) { } func generateMergeFixtures(b types.GenerationBehavior) []ResMap { - input1 := ResMap{ resid.NewResId(cmap, "cmap"): rf.FromMapAndOption( map[string]interface{}{ diff --git a/pkg/target/resaccumulator.go b/pkg/target/resaccumulator.go index 2ae05ba2c..c6ba0cd84 100644 --- a/pkg/target/resaccumulator.go +++ b/pkg/target/resaccumulator.go @@ -103,7 +103,7 @@ func (ra *ResAccumulator) makeVarReplacementMap() (map[string]string, error) { result := map[string]string{} for _, v := range ra.varSet.Set() { id := resid.NewResId(v.ObjRef.GVK(), v.ObjRef.Name) - if r, found := ra.resMap.DemandOneMatchForId(id); found { + if r, found := ra.resMap.DemandOneGvknMatchForId(id); found { s, err := r.GetFieldValue(v.FieldRef.FieldPath) if err != nil { return nil, fmt.Errorf("field path err for var: %+v", v) diff --git a/pkg/transformers/namereference.go b/pkg/transformers/namereference.go index 899813776..a4e8a7f8e 100644 --- a/pkg/transformers/namereference.go +++ b/pkg/transformers/namereference.go @@ -89,7 +89,7 @@ func (o *nameReferenceTransformer) updateNameReference( s, _ := in.(string) for id, res := range m { if id.Gvk().IsSelected(&backRef) && id.Name() == s { - matchedIds := m.FindByGVKN(id) + matchedIds := m.GetMatchingIds(id.GvknEquals) // If there's more than one match, there's no way // to know which one to pick, so emit error. if len(matchedIds) > 1 { @@ -115,7 +115,7 @@ func (o *nameReferenceTransformer) updateNameReference( for id, res := range m { indexes := indexOf(id.Name(), names) if id.Gvk().IsSelected(&backRef) && len(indexes) > 0 { - matchedIds := m.FindByGVKN(id) + matchedIds := m.GetMatchingIds(id.GvknEquals) if len(matchedIds) > 1 { return nil, fmt.Errorf( "Multiple matches for name %s:\n %v", id, matchedIds) From 77eebb89fd511c0f18aaacd6d9c8aabe6cdd0b5b Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Mon, 18 Feb 2019 09:28:04 +0200 Subject: [PATCH 126/317] Review changes Signed-off-by: Chris Mark --- pkg/commands/edit/add/flagsandargs.go | 24 ++++++++++++++++++---- pkg/commands/edit/add/flagsandargs_test.go | 16 +++++++++------ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/pkg/commands/edit/add/flagsandargs.go b/pkg/commands/edit/add/flagsandargs.go index b915cbf51..a842ed817 100644 --- a/pkg/commands/edit/add/flagsandargs.go +++ b/pkg/commands/edit/add/flagsandargs.go @@ -54,12 +54,28 @@ func (a *flagsAndArgs) Validate(args []string) error { return nil } +// ExpandFileSource normalizes a string list, possibly +// containing globs, into a validated, globless list. +// For example, this list: +// some/path +// some/dir/a* +// bfile=some/dir/b* +// becomes: +// some/path +// some/dir/airplane +// some/dir/ant +// some/dir/apple +// bfile=some/dir/banana +// i.e. everything is converted to a key=value pair, +// where the value is always a relative file path, +// and the key, if missing, is the same as the value. +// In the case where the key is explicitly declared, +// the globbing, if present, must have exactly one match. func (a *flagsAndArgs) ExpandFileSource(fSys fs.FileSystem) error { var results []string - var key string for _, pattern := range a.FileSources { var patterns []string - key = "" + key := "" // check if the pattern is in `--from-file=[key=]source` format // and if so split it to send only the file-pattern to glob function s := strings.Split(pattern, "=") @@ -77,8 +93,8 @@ func (a *flagsAndArgs) ExpandFileSource(fSys fs.FileSystem) error { // and extend it with the `key=` prefix if key != "" { if len(result) != 1 { - msg := fmt.Sprintf("%s pattern should not catch more than one file", pattern) - return fmt.Errorf(msg) + return fmt.Errorf( + "'pattern '%s' catches files %v, should catch only one.", pattern, result) } fileSource := fmt.Sprintf("%s=%s", key, result[0]) results = append(results, fileSource) diff --git a/pkg/commands/edit/add/flagsandargs_test.go b/pkg/commands/edit/add/flagsandargs_test.go index 5839f5a18..797a4639e 100644 --- a/pkg/commands/edit/add/flagsandargs_test.go +++ b/pkg/commands/edit/add/flagsandargs_test.go @@ -89,7 +89,7 @@ func TestExpandFileSource(t *testing.T) { fakeFS := fs.MakeFakeFS() fakeFS.Create("dir/fa1") fakeFS.Create("dir/fa2") - fakeFS.Create("dir/reademe") + fakeFS.Create("dir/readme") fa := flagsAndArgs{ FileSources: []string{"dir/fa*"}, } @@ -105,14 +105,18 @@ func TestExpandFileSource(t *testing.T) { func TestExpandFileSourceWithKey(t *testing.T) { fakeFS := fs.MakeFakeFS() - fakeFS.Create("dir/fa1") - fakeFS.Create("dir/reademe") + fakeFS.Create("dir/faaaaaaaaaabbbbbbbbbccccccccccccccccc") + fakeFS.Create("dir/foobar") + fakeFS.Create("dir/simplebar") + fakeFS.Create("dir/readme") fa := flagsAndArgs{ - FileSources: []string{"foo-key=dir/fa*"}, + FileSources: []string{"foo-key=dir/fa*", "bar-key=dir/foobar", "dir/simplebar"}, } fa.ExpandFileSource(fakeFS) expected := []string{ - "foo-key=dir/fa1", + "foo-key=dir/faaaaaaaaaabbbbbbbbbccccccccccccccccc", + "bar-key=dir/foobar", + "dir/simplebar", } if !reflect.DeepEqual(fa.FileSources, expected) { t.Fatalf("FileSources is not correctly expanded: %v", fa.FileSources) @@ -123,7 +127,7 @@ func TestExpandFileSourceWithKeyAndError(t *testing.T) { fakeFS := fs.MakeFakeFS() fakeFS.Create("dir/fa1") fakeFS.Create("dir/fa2") - fakeFS.Create("dir/reademe") + fakeFS.Create("dir/readme") fa := flagsAndArgs{ FileSources: []string{"foo-key=dir/fa*"}, } From bf1c801a5e825aaef71d42c8aa75bf5c7e8949e0 Mon Sep 17 00:00:00 2001 From: Don Bowman Date: Thu, 21 Feb 2019 11:31:54 -0500 Subject: [PATCH 127/317] Add doc indicating existing of 'behavior' in configMapGenerator It appears from the code that configMapGenerator can take a parameter of 'behavior' which is 'merge','create','replace'. Add note to the 'docs/kustomization.yaml' indicating so. Signed-off-by: Don Bowman --- docs/kustomization.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index dba67d75c..2674cf3f4 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -76,6 +76,9 @@ resources: # The example below creates two ConfigMaps. One with the # names and contents of the given files, the other with # key/value as data. +# The configMapGenerator accepts a paramter of +# behavior: [create|replace|merge]. This can allow +# an overlay to augment the configMapGenerator of the parent configMapGenerator: - name: myJavaServerProps files: From 773c1f21991ddbbddea26fdaa98a482b3b6a8bba Mon Sep 17 00:00:00 2001 From: Don Bowman Date: Thu, 21 Feb 2019 11:53:12 -0500 Subject: [PATCH 128/317] Make requested wording changes from PR for behavior document Signed-off-by: Don Bowman --- docs/kustomization.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index 2674cf3f4..75e1701fe 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -76,9 +76,9 @@ resources: # The example below creates two ConfigMaps. One with the # names and contents of the given files, the other with # key/value as data. -# The configMapGenerator accepts a paramter of -# behavior: [create|replace|merge]. This can allow -# an overlay to augment the configMapGenerator of the parent +# Each configMapGenerator item accepts a parameter of +# behavior: [create|replace|merge]. This allows an overlay to modify or +# replace an existing configMap from the parent. configMapGenerator: - name: myJavaServerProps files: From 1d65f24b04985d302920222fd9cd605d520c8c56 Mon Sep 17 00:00:00 2001 From: Ken Maglio Date: Thu, 21 Feb 2019 19:54:48 -0600 Subject: [PATCH 129/317] adds documentation for choco package --- docs/INSTALL.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 80b8f3730..cfe9f8222 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -8,6 +8,11 @@ manager: brew install kustomize +On windows, you can install kusztomize with Chocolatey package +manager: + + choco install kustomize + For all operating systems, download a binary from the [release page]. From 0e459ebac895ee4c80948a15e5feec0d3d8b171e Mon Sep 17 00:00:00 2001 From: Nestor Date: Fri, 22 Feb 2019 08:55:38 +0100 Subject: [PATCH 130/317] prevent panic on image transformer Signed-off-by: Nestor --- pkg/transformers/image.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/transformers/image.go b/pkg/transformers/image.go index f59057f75..734b5aca7 100644 --- a/pkg/transformers/image.go +++ b/pkg/transformers/image.go @@ -17,6 +17,7 @@ limitations under the License. package transformers import ( + "fmt" "regexp" "strings" @@ -75,7 +76,10 @@ func (pt *imageTransformer) findAndReplaceImage(obj map[string]interface{}) erro } func (pt *imageTransformer) updateContainers(obj map[string]interface{}, path string) error { - containers := obj[path].([]interface{}) + containers, ok := obj[path].([]interface{}) + if !ok { + return fmt.Errorf("containers path is not of type []interface{} but %T", obj[path]) + } for i := range containers { container := containers[i].(map[string]interface{}) containerImage, found := container["image"] From 0488f570cb02f9714fc4c9d60cdeb87a8917ec48 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Fri, 22 Feb 2019 06:27:29 -0800 Subject: [PATCH 131/317] More generator tests. --- pkg/target/configmaps_test.go | 149 +++++++++++++++++++++++++++++++--- 1 file changed, 138 insertions(+), 11 deletions(-) diff --git a/pkg/target/configmaps_test.go b/pkg/target/configmaps_test.go index 5c4ad8d08..cad35066b 100644 --- a/pkg/target/configmaps_test.go +++ b/pkg/target/configmaps_test.go @@ -20,11 +20,146 @@ import ( "testing" ) -func TestGenerator1(t *testing.T) { +// Generate a Secret and a ConfigMap from the same data +// to compare the result. +func TestGeneratorBasics(t *testing.T) { + th := NewKustTestHarness(t, "/app") + th.writeK("/app", ` +namePrefix: blah- +configMapGenerator: +- name: bob + literals: + - fruit=apple + - vegetable=broccoli + env: foo.env + files: + - passphrase=phrase.dat + - forces.txt +secretGenerator: +- name: bob + literals: + - fruit=apple + - vegetable=broccoli + env: foo.env + files: + - passphrase=phrase.dat + - forces.txt +`) + th.writeF("/app/foo.env", ` +MOUNTAIN=everest +OCEAN=pacific +`) + th.writeF("/app/phrase.dat", ` +Life is short. +But the years are long. +Not while the evil days come not. +`) + th.writeF("/app/forces.txt", ` +gravitational +electromagnetic +strong nuclear +weak nuclear +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + MOUNTAIN: everest + OCEAN: pacific + forces.txt: |2 + + gravitational + electromagnetic + strong nuclear + weak nuclear + fruit: apple + passphrase: |2 + + Life is short. + But the years are long. + Not while the evil days come not. + vegetable: broccoli +kind: ConfigMap +metadata: + name: blah-bob-k772g5db55 +--- +apiVersion: v1 +data: + MOUNTAIN: ZXZlcmVzdA== + OCEAN: cGFjaWZpYw== + forces.txt: CmdyYXZpdGF0aW9uYWwKZWxlY3Ryb21hZ25ldGljCnN0cm9uZyBudWNsZWFyCndlYWsgbnVjbGVhcgo= + fruit: YXBwbGU= + passphrase: CkxpZmUgaXMgc2hvcnQuCkJ1dCB0aGUgeWVhcnMgYXJlIGxvbmcuCk5vdCB3aGlsZSB0aGUgZXZpbCBkYXlzIGNvbWUgbm90Lgo= + vegetable: YnJvY2NvbGk= +kind: Secret +metadata: + name: blah-bob-gmc2824f4b +type: Opaque +`) +} + +// TODO: These should be errors instead. +func TestGeneratorRepeatsInKustomization(t *testing.T) { + th := NewKustTestHarness(t, "/app") + th.writeK("/app", ` +namePrefix: blah- +configMapGenerator: +- name: bob + behavior: create + literals: + - bean=pinto + - star=wolf-rayet + literals: + - fruit=apple + - vegetable=broccoli + files: + - forces.txt + files: + - nobles=nobility.txt +`) + th.writeF("/app/forces.txt", ` +gravitational +electromagnetic +strong nuclear +weak nuclear +`) + th.writeF("/app/nobility.txt", ` +helium +neon +argon +krypton +xenon +radon +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + fruit: apple + nobles: |2 + + helium + neon + argon + krypton + xenon + radon + vegetable: broccoli +kind: ConfigMap +metadata: + name: blah-bob-gfkcbk5ckf +`) +} + +func TestGeneratorOverlays(t *testing.T) { th := NewKustTestHarness(t, "/app/overlay") th.writeK("/app/base1", ` -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization namePrefix: p1- configMapGenerator: - name: com1 @@ -33,8 +168,6 @@ configMapGenerator: - from=base `) th.writeK("/app/base2", ` -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization namePrefix: p2- configMapGenerator: - name: com2 @@ -43,8 +176,6 @@ configMapGenerator: - from=base `) th.writeK("/app/overlay/o1", ` -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization bases: - ../../base1 configMapGenerator: @@ -54,8 +185,6 @@ configMapGenerator: - from=overlay `) th.writeK("/app/overlay/o2", ` -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization bases: - ../../base2 configMapGenerator: @@ -65,8 +194,6 @@ configMapGenerator: - from=overlay `) th.writeK("/app/overlay", ` -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization bases: - o1 - o2 From 1eab47b63fae03be99362938e83ee79e86370a30 Mon Sep 17 00:00:00 2001 From: Nestor Date: Fri, 22 Feb 2019 15:08:26 +0100 Subject: [PATCH 132/317] fix abs path with symlinks Signed-off-by: Nestor --- pkg/fs/confirmeddir.go | 12 ++++++++++-- pkg/fs/confirmeddir_test.go | 16 ++++++++++++++++ pkg/fs/realfs_test.go | 6 +++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/pkg/fs/confirmeddir.go b/pkg/fs/confirmeddir.go index 6d2f5c30d..5d12bf077 100644 --- a/pkg/fs/confirmeddir.go +++ b/pkg/fs/confirmeddir.go @@ -26,7 +26,7 @@ import ( // that was confirmed to point to an existing directory. type ConfirmedDir string -// Return a temporary dir, else error. +// NewTmpConfirmedDir returns a temporary dir, else error. // The directory is cleaned, no symlinks, etc. so its // returned as a ConfirmedDir. func NewTmpConfirmedDir() (ConfirmedDir, error) { @@ -34,7 +34,15 @@ func NewTmpConfirmedDir() (ConfirmedDir, error) { if err != nil { return "", err } - return ConfirmedDir(n), nil + + // In MacOs `ioutil.TempDir` creates a directory + // with root in the `/var` folder, which is in turn a symlinked path + // to `/private/var`. + // Function `filepath.EvalSymlinks`is used to + // resolve the real absolute path. + deLinked, err := filepath.EvalSymlinks(n) + return ConfirmedDir(deLinked), err + } // HasPrefix returns true if the directory argument diff --git a/pkg/fs/confirmeddir_test.go b/pkg/fs/confirmeddir_test.go index eddc2a198..7b603f733 100644 --- a/pkg/fs/confirmeddir_test.go +++ b/pkg/fs/confirmeddir_test.go @@ -17,6 +17,7 @@ limitations under the License. package fs import ( + "path/filepath" "testing" ) @@ -101,3 +102,18 @@ func TestHasPrefix_SlashFooBar(t *testing.T) { t.Fatalf("/foo/bar should have prefix /") } } + +func TestNewTempConfirmDir(t *testing.T) { + tmp, err := NewTmpConfirmedDir() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + delinked, err := filepath.EvalSymlinks(string(tmp)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if string(tmp) != delinked { + t.Fatalf("unexpected path containing symlinks") + } +} diff --git a/pkg/fs/realfs_test.go b/pkg/fs/realfs_test.go index 74bc318cd..6e07f2fe3 100644 --- a/pkg/fs/realfs_test.go +++ b/pkg/fs/realfs_test.go @@ -27,7 +27,11 @@ import ( func makeTestDir(t *testing.T) (FileSystem, string) { x := MakeRealFS() - testDir, err := ioutil.TempDir("", "kustomize_testing_dir") + td, err := ioutil.TempDir("", "kustomize_testing_dir") + if err != nil { + t.Fatalf("unexpected error %s", err) + } + testDir, err := filepath.EvalSymlinks(td) if err != nil { t.Fatalf("unexpected error %s", err) } From 901455eb0bbde695c503440ad7ea63ee7f261b8f Mon Sep 17 00:00:00 2001 From: Yujun Zhang Date: Sun, 24 Feb 2019 11:36:09 +0800 Subject: [PATCH 133/317] Add Pod initContainer to var reference --- pkg/transformers/config/defaultconfig/varreference.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pkg/transformers/config/defaultconfig/varreference.go b/pkg/transformers/config/defaultconfig/varreference.go index d83a43ad6..71953f576 100644 --- a/pkg/transformers/config/defaultconfig/varreference.go +++ b/pkg/transformers/config/defaultconfig/varreference.go @@ -100,6 +100,15 @@ varReference: - path: spec/containers/env/value kind: Pod +- path: spec/initContainers/command + kind: Pod + +- path: spec/initContainers/args + kind: Pod + +- path: spec/initContainers/env/value + kind: Pod + - path: spec/rules/host kind: Ingress From 5e6c06fb6172ebd44fa7a91d9862e9a9e8bd4c08 Mon Sep 17 00:00:00 2001 From: Shota Ito Date: Mon, 25 Feb 2019 20:23:36 +0900 Subject: [PATCH 134/317] Change imagetag to image in docs/eschewedFeatures.md --- docs/eschewedFeatures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/eschewedFeatures.md b/docs/eschewedFeatures.md index 33e067ad6..36607fd8e 100644 --- a/docs/eschewedFeatures.md +++ b/docs/eschewedFeatures.md @@ -96,7 +96,7 @@ For example, to set the tag used on an image to match an environment variable, run ``` -kustomize edit set imagetag nginx:$MY_NGINX_VERSION +kustomize edit set image nginx:$MY_NGINX_VERSION ``` as part of some encapsulating work flow executed before From 8bbe147c1434224f6f4b943a81c20e6cf3ad5e13 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Mon, 25 Feb 2019 10:23:00 -0800 Subject: [PATCH 135/317] Add webhooks to order list of gvk --- pkg/gvk/gvk.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/gvk/gvk.go b/pkg/gvk/gvk.go index 00e44f7ea..890c8e8b5 100644 --- a/pkg/gvk/gvk.go +++ b/pkg/gvk/gvk.go @@ -73,6 +73,8 @@ var order = []string{ "Namespace", "StorageClass", "CustomResourceDefinition", + "MutatingWebhookConfiguration", + "ValidatingWebhookConfiguration", "ServiceAccount", "Role", "ClusterRole", From 9d77cbea8c8e08d7511dcf21a56cbc340a140e80 Mon Sep 17 00:00:00 2001 From: Prasad Ghangal Date: Wed, 27 Feb 2019 00:44:10 +0530 Subject: [PATCH 136/317] Update golang/x/net dependency to release-branch.go1.11 --- Gopkg.lock | 7 +- vendor/golang.org/x/net/http/httpguts/guts.go | 50 + .../{lex/httplex => http/httpguts}/httplex.go | 7 +- vendor/golang.org/x/net/http2/ciphers.go | 2 +- .../x/net/http2/client_conn_pool.go | 28 +- .../x/net/http2/configure_transport.go | 80 - vendor/golang.org/x/net/http2/flow.go | 10 +- vendor/golang.org/x/net/http2/frame.go | 71 +- vendor/golang.org/x/net/http2/go111.go | 29 + vendor/golang.org/x/net/http2/go16.go | 16 - vendor/golang.org/x/net/http2/go17.go | 106 - vendor/golang.org/x/net/http2/go17_not18.go | 36 - vendor/golang.org/x/net/http2/go18.go | 56 - vendor/golang.org/x/net/http2/go19.go | 16 - vendor/golang.org/x/net/http2/headermap.go | 20 +- vendor/golang.org/x/net/http2/hpack/encode.go | 2 +- vendor/golang.org/x/net/http2/hpack/hpack.go | 14 + .../golang.org/x/net/http2/hpack/huffman.go | 20 +- vendor/golang.org/x/net/http2/http2.go | 25 +- vendor/golang.org/x/net/http2/not_go111.go | 20 + vendor/golang.org/x/net/http2/not_go16.go | 21 - vendor/golang.org/x/net/http2/not_go17.go | 87 - vendor/golang.org/x/net/http2/not_go18.go | 29 - vendor/golang.org/x/net/http2/not_go19.go | 16 - vendor/golang.org/x/net/http2/server.go | 212 +- vendor/golang.org/x/net/http2/transport.go | 772 ++- vendor/golang.org/x/net/http2/write.go | 15 +- vendor/golang.org/x/net/idna/idna.go | 126 +- vendor/golang.org/x/net/idna/tables.go | 4396 +++++++++-------- vendor/golang.org/x/net/idna/trieval.go | 17 +- 30 files changed, 3289 insertions(+), 3017 deletions(-) create mode 100644 vendor/golang.org/x/net/http/httpguts/guts.go rename vendor/golang.org/x/net/{lex/httplex => http/httpguts}/httplex.go (97%) delete mode 100644 vendor/golang.org/x/net/http2/configure_transport.go create mode 100644 vendor/golang.org/x/net/http2/go111.go delete mode 100644 vendor/golang.org/x/net/http2/go16.go delete mode 100644 vendor/golang.org/x/net/http2/go17.go delete mode 100644 vendor/golang.org/x/net/http2/go17_not18.go delete mode 100644 vendor/golang.org/x/net/http2/go18.go delete mode 100644 vendor/golang.org/x/net/http2/go19.go create mode 100644 vendor/golang.org/x/net/http2/not_go111.go delete mode 100644 vendor/golang.org/x/net/http2/not_go16.go delete mode 100644 vendor/golang.org/x/net/http2/not_go17.go delete mode 100644 vendor/golang.org/x/net/http2/not_go18.go delete mode 100644 vendor/golang.org/x/net/http2/not_go19.go diff --git a/Gopkg.lock b/Gopkg.lock index 2218dcd51..a910721e2 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -207,16 +207,16 @@ [[projects]] branch = "master" - digest = "1:d1a6ebe75268a41b6fbb1d43947cf8688d8580423b7484fa5ae608beef6df24d" + digest = "1:18108bc7e384e395b4805632a637405a3df71fa518e22f9b39b0c08b89a52b96" name = "golang.org/x/net" packages = [ + "http/httpguts", "http2", "http2/hpack", "idna", - "lex/httplex", ] pruneopts = "NUT" - revision = "1c05540f6879653db88113bc4a2b70aec4bd491f" + revision = "fe579d43d83210096a79b46dcca0e3721058393a" [[projects]] digest = "1:e33513a825fcd765e97b5de639a2f7547542d1a8245df0cef18e1fd390b778a9" @@ -366,6 +366,7 @@ input-imports = [ "github.com/evanphx/json-patch", "github.com/ghodss/yaml", + "github.com/go-openapi/spec", "github.com/pkg/errors", "github.com/spf13/cobra", "gopkg.in/yaml.v2", diff --git a/vendor/golang.org/x/net/http/httpguts/guts.go b/vendor/golang.org/x/net/http/httpguts/guts.go new file mode 100644 index 000000000..e6cd0ced3 --- /dev/null +++ b/vendor/golang.org/x/net/http/httpguts/guts.go @@ -0,0 +1,50 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package httpguts provides functions implementing various details +// of the HTTP specification. +// +// This package is shared by the standard library (which vendors it) +// and x/net/http2. It comes with no API stability promise. +package httpguts + +import ( + "net/textproto" + "strings" +) + +// ValidTrailerHeader reports whether name is a valid header field name to appear +// in trailers. +// See RFC 7230, Section 4.1.2 +func ValidTrailerHeader(name string) bool { + name = textproto.CanonicalMIMEHeaderKey(name) + if strings.HasPrefix(name, "If-") || badTrailer[name] { + return false + } + return true +} + +var badTrailer = map[string]bool{ + "Authorization": true, + "Cache-Control": true, + "Connection": true, + "Content-Encoding": true, + "Content-Length": true, + "Content-Range": true, + "Content-Type": true, + "Expect": true, + "Host": true, + "Keep-Alive": true, + "Max-Forwards": true, + "Pragma": true, + "Proxy-Authenticate": true, + "Proxy-Authorization": true, + "Proxy-Connection": true, + "Range": true, + "Realm": true, + "Te": true, + "Trailer": true, + "Transfer-Encoding": true, + "Www-Authenticate": true, +} diff --git a/vendor/golang.org/x/net/lex/httplex/httplex.go b/vendor/golang.org/x/net/http/httpguts/httplex.go similarity index 97% rename from vendor/golang.org/x/net/lex/httplex/httplex.go rename to vendor/golang.org/x/net/http/httpguts/httplex.go index 20f2b8940..e7de24ee6 100644 --- a/vendor/golang.org/x/net/lex/httplex/httplex.go +++ b/vendor/golang.org/x/net/http/httpguts/httplex.go @@ -2,12 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package httplex contains rules around lexical matters of various -// HTTP-related specifications. -// -// This package is shared by the standard library (which vendors it) -// and x/net/http2. It comes with no API stability promise. -package httplex +package httpguts import ( "net" diff --git a/vendor/golang.org/x/net/http2/ciphers.go b/vendor/golang.org/x/net/http2/ciphers.go index 698860b77..c9a0cf3b4 100644 --- a/vendor/golang.org/x/net/http2/ciphers.go +++ b/vendor/golang.org/x/net/http2/ciphers.go @@ -5,7 +5,7 @@ package http2 // A list of the possible cipher suite ids. Taken from -// http://www.iana.org/assignments/tls-parameters/tls-parameters.txt +// https://www.iana.org/assignments/tls-parameters/tls-parameters.txt const ( cipher_TLS_NULL_WITH_NULL_NULL uint16 = 0x0000 diff --git a/vendor/golang.org/x/net/http2/client_conn_pool.go b/vendor/golang.org/x/net/http2/client_conn_pool.go index bdf5652b0..f4d9b5ece 100644 --- a/vendor/golang.org/x/net/http2/client_conn_pool.go +++ b/vendor/golang.org/x/net/http2/client_conn_pool.go @@ -52,9 +52,31 @@ const ( noDialOnMiss = false ) +// shouldTraceGetConn reports whether getClientConn should call any +// ClientTrace.GetConn hook associated with the http.Request. +// +// This complexity is needed to avoid double calls of the GetConn hook +// during the back-and-forth between net/http and x/net/http2 (when the +// net/http.Transport is upgraded to also speak http2), as well as support +// the case where x/net/http2 is being used directly. +func (p *clientConnPool) shouldTraceGetConn(st clientConnIdleState) bool { + // If our Transport wasn't made via ConfigureTransport, always + // trace the GetConn hook if provided, because that means the + // http2 package is being used directly and it's the one + // dialing, as opposed to net/http. + if _, ok := p.t.ConnPool.(noDialClientConnPool); !ok { + return true + } + // Otherwise, only use the GetConn hook if this connection has + // been used previously for other requests. For fresh + // connections, the net/http package does the dialing. + return !st.freshConn +} + func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) { if isConnectionCloseRequest(req) && dialOnMiss { // It gets its own connection. + traceGetConn(req, addr) const singleUse = true cc, err := p.t.dialClientConn(addr, singleUse) if err != nil { @@ -64,7 +86,10 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis } p.mu.Lock() for _, cc := range p.conns[addr] { - if cc.CanTakeNewRequest() { + if st := cc.idleState(); st.canTakeNewRequest { + if p.shouldTraceGetConn(st) { + traceGetConn(req, addr) + } p.mu.Unlock() return cc, nil } @@ -73,6 +98,7 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis p.mu.Unlock() return nil, ErrNoCachedConn } + traceGetConn(req, addr) call := p.getStartDialLocked(addr) p.mu.Unlock() <-call.done diff --git a/vendor/golang.org/x/net/http2/configure_transport.go b/vendor/golang.org/x/net/http2/configure_transport.go deleted file mode 100644 index b65fc6d42..000000000 --- a/vendor/golang.org/x/net/http2/configure_transport.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.6 - -package http2 - -import ( - "crypto/tls" - "fmt" - "net/http" -) - -func configureTransport(t1 *http.Transport) (*Transport, error) { - connPool := new(clientConnPool) - t2 := &Transport{ - ConnPool: noDialClientConnPool{connPool}, - t1: t1, - } - connPool.t = t2 - if err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil { - return nil, err - } - if t1.TLSClientConfig == nil { - t1.TLSClientConfig = new(tls.Config) - } - if !strSliceContains(t1.TLSClientConfig.NextProtos, "h2") { - t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...) - } - if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") { - t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1") - } - upgradeFn := func(authority string, c *tls.Conn) http.RoundTripper { - addr := authorityAddr("https", authority) - if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil { - go c.Close() - return erringRoundTripper{err} - } else if !used { - // Turns out we don't need this c. - // For example, two goroutines made requests to the same host - // at the same time, both kicking off TCP dials. (since protocol - // was unknown) - go c.Close() - } - return t2 - } - if m := t1.TLSNextProto; len(m) == 0 { - t1.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{ - "h2": upgradeFn, - } - } else { - m["h2"] = upgradeFn - } - return t2, nil -} - -// registerHTTPSProtocol calls Transport.RegisterProtocol but -// converting panics into errors. -func registerHTTPSProtocol(t *http.Transport, rt http.RoundTripper) (err error) { - defer func() { - if e := recover(); e != nil { - err = fmt.Errorf("%v", e) - } - }() - t.RegisterProtocol("https", rt) - return nil -} - -// noDialH2RoundTripper is a RoundTripper which only tries to complete the request -// if there's already has a cached connection to the host. -type noDialH2RoundTripper struct{ t *Transport } - -func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - res, err := rt.t.RoundTrip(req) - if err == ErrNoCachedConn { - return nil, http.ErrSkipAltProtocol - } - return res, err -} diff --git a/vendor/golang.org/x/net/http2/flow.go b/vendor/golang.org/x/net/http2/flow.go index 957de2542..cea601fcd 100644 --- a/vendor/golang.org/x/net/http2/flow.go +++ b/vendor/golang.org/x/net/http2/flow.go @@ -41,10 +41,10 @@ func (f *flow) take(n int32) { // add adds n bytes (positive or negative) to the flow control window. // It returns false if the sum would exceed 2^31-1. func (f *flow) add(n int32) bool { - remain := (1<<31 - 1) - f.n - if n > remain { - return false + sum := f.n + n + if (sum > n) == (f.n > 0) { + f.n = sum + return true } - f.n += n - return true + return false } diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index 3b1489072..514c126c5 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -14,8 +14,8 @@ import ( "strings" "sync" + "golang.org/x/net/http/httpguts" "golang.org/x/net/http2/hpack" - "golang.org/x/net/lex/httplex" ) const frameHeaderLen = 9 @@ -643,7 +643,7 @@ func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error { return f.WriteDataPadded(streamID, endStream, data, nil) } -// WriteData writes a DATA frame with optional padding. +// WriteDataPadded writes a DATA frame with optional padding. // // If pad is nil, the padding bit is not sent. // The length of pad must not exceed 255 bytes. @@ -733,32 +733,67 @@ func (f *SettingsFrame) IsAck() bool { return f.FrameHeader.Flags.Has(FlagSettingsAck) } -func (f *SettingsFrame) Value(s SettingID) (v uint32, ok bool) { +func (f *SettingsFrame) Value(id SettingID) (v uint32, ok bool) { f.checkValid() - buf := f.p - for len(buf) > 0 { - settingID := SettingID(binary.BigEndian.Uint16(buf[:2])) - if settingID == s { - return binary.BigEndian.Uint32(buf[2:6]), true + for i := 0; i < f.NumSettings(); i++ { + if s := f.Setting(i); s.ID == id { + return s.Val, true } - buf = buf[6:] } return 0, false } +// Setting returns the setting from the frame at the given 0-based index. +// The index must be >= 0 and less than f.NumSettings(). +func (f *SettingsFrame) Setting(i int) Setting { + buf := f.p + return Setting{ + ID: SettingID(binary.BigEndian.Uint16(buf[i*6 : i*6+2])), + Val: binary.BigEndian.Uint32(buf[i*6+2 : i*6+6]), + } +} + +func (f *SettingsFrame) NumSettings() int { return len(f.p) / 6 } + +// HasDuplicates reports whether f contains any duplicate setting IDs. +func (f *SettingsFrame) HasDuplicates() bool { + num := f.NumSettings() + if num == 0 { + return false + } + // If it's small enough (the common case), just do the n^2 + // thing and avoid a map allocation. + if num < 10 { + for i := 0; i < num; i++ { + idi := f.Setting(i).ID + for j := i + 1; j < num; j++ { + idj := f.Setting(j).ID + if idi == idj { + return true + } + } + } + return false + } + seen := map[SettingID]bool{} + for i := 0; i < num; i++ { + id := f.Setting(i).ID + if seen[id] { + return true + } + seen[id] = true + } + return false +} + // ForeachSetting runs fn for each setting. // It stops and returns the first error. func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error { f.checkValid() - buf := f.p - for len(buf) > 0 { - if err := fn(Setting{ - SettingID(binary.BigEndian.Uint16(buf[:2])), - binary.BigEndian.Uint32(buf[2:6]), - }); err != nil { + for i := 0; i < f.NumSettings(); i++ { + if err := fn(f.Setting(i)); err != nil { return err } - buf = buf[6:] } return nil } @@ -1442,7 +1477,7 @@ func (fr *Framer) maxHeaderStringLen() int { } // readMetaFrame returns 0 or more CONTINUATION frames from fr and -// merge them into into the provided hf and returns a MetaHeadersFrame +// merge them into the provided hf and returns a MetaHeadersFrame // with the decoded hpack values. func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { if fr.AllowIllegalReads { @@ -1462,7 +1497,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { if VerboseLogs && fr.logReads { fr.debugReadLoggerf("http2: decoded hpack field %+v", hf) } - if !httplex.ValidHeaderFieldValue(hf.Value) { + if !httpguts.ValidHeaderFieldValue(hf.Value) { invalid = headerFieldValueError(hf.Value) } isPseudo := strings.HasPrefix(hf.Name, ":") diff --git a/vendor/golang.org/x/net/http2/go111.go b/vendor/golang.org/x/net/http2/go111.go new file mode 100644 index 000000000..3a131016b --- /dev/null +++ b/vendor/golang.org/x/net/http2/go111.go @@ -0,0 +1,29 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.11 + +package http2 + +import ( + "net/http/httptrace" + "net/textproto" +) + +func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool { + return trace != nil && trace.WroteHeaderField != nil +} + +func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) { + if trace != nil && trace.WroteHeaderField != nil { + trace.WroteHeaderField(k, []string{v}) + } +} + +func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error { + if trace != nil { + return trace.Got1xxResponse + } + return nil +} diff --git a/vendor/golang.org/x/net/http2/go16.go b/vendor/golang.org/x/net/http2/go16.go deleted file mode 100644 index 00b2e9e3c..000000000 --- a/vendor/golang.org/x/net/http2/go16.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.6 - -package http2 - -import ( - "net/http" - "time" -) - -func transportExpectContinueTimeout(t1 *http.Transport) time.Duration { - return t1.ExpectContinueTimeout -} diff --git a/vendor/golang.org/x/net/http2/go17.go b/vendor/golang.org/x/net/http2/go17.go deleted file mode 100644 index 47b7fae08..000000000 --- a/vendor/golang.org/x/net/http2/go17.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.7 - -package http2 - -import ( - "context" - "net" - "net/http" - "net/http/httptrace" - "time" -) - -type contextContext interface { - context.Context -} - -func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx contextContext, cancel func()) { - ctx, cancel = context.WithCancel(context.Background()) - ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr()) - if hs := opts.baseConfig(); hs != nil { - ctx = context.WithValue(ctx, http.ServerContextKey, hs) - } - return -} - -func contextWithCancel(ctx contextContext) (_ contextContext, cancel func()) { - return context.WithCancel(ctx) -} - -func requestWithContext(req *http.Request, ctx contextContext) *http.Request { - return req.WithContext(ctx) -} - -type clientTrace httptrace.ClientTrace - -func reqContext(r *http.Request) context.Context { return r.Context() } - -func (t *Transport) idleConnTimeout() time.Duration { - if t.t1 != nil { - return t.t1.IdleConnTimeout - } - return 0 -} - -func setResponseUncompressed(res *http.Response) { res.Uncompressed = true } - -func traceGotConn(req *http.Request, cc *ClientConn) { - trace := httptrace.ContextClientTrace(req.Context()) - if trace == nil || trace.GotConn == nil { - return - } - ci := httptrace.GotConnInfo{Conn: cc.tconn} - cc.mu.Lock() - ci.Reused = cc.nextStreamID > 1 - ci.WasIdle = len(cc.streams) == 0 && ci.Reused - if ci.WasIdle && !cc.lastActive.IsZero() { - ci.IdleTime = time.Now().Sub(cc.lastActive) - } - cc.mu.Unlock() - - trace.GotConn(ci) -} - -func traceWroteHeaders(trace *clientTrace) { - if trace != nil && trace.WroteHeaders != nil { - trace.WroteHeaders() - } -} - -func traceGot100Continue(trace *clientTrace) { - if trace != nil && trace.Got100Continue != nil { - trace.Got100Continue() - } -} - -func traceWait100Continue(trace *clientTrace) { - if trace != nil && trace.Wait100Continue != nil { - trace.Wait100Continue() - } -} - -func traceWroteRequest(trace *clientTrace, err error) { - if trace != nil && trace.WroteRequest != nil { - trace.WroteRequest(httptrace.WroteRequestInfo{Err: err}) - } -} - -func traceFirstResponseByte(trace *clientTrace) { - if trace != nil && trace.GotFirstResponseByte != nil { - trace.GotFirstResponseByte() - } -} - -func requestTrace(req *http.Request) *clientTrace { - trace := httptrace.ContextClientTrace(req.Context()) - return (*clientTrace)(trace) -} - -// Ping sends a PING frame to the server and waits for the ack. -func (cc *ClientConn) Ping(ctx context.Context) error { - return cc.ping(ctx) -} diff --git a/vendor/golang.org/x/net/http2/go17_not18.go b/vendor/golang.org/x/net/http2/go17_not18.go deleted file mode 100644 index b4c52ecec..000000000 --- a/vendor/golang.org/x/net/http2/go17_not18.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.7,!go1.8 - -package http2 - -import "crypto/tls" - -// temporary copy of Go 1.7's private tls.Config.clone: -func cloneTLSConfig(c *tls.Config) *tls.Config { - return &tls.Config{ - Rand: c.Rand, - Time: c.Time, - Certificates: c.Certificates, - NameToCertificate: c.NameToCertificate, - GetCertificate: c.GetCertificate, - RootCAs: c.RootCAs, - NextProtos: c.NextProtos, - ServerName: c.ServerName, - ClientAuth: c.ClientAuth, - ClientCAs: c.ClientCAs, - InsecureSkipVerify: c.InsecureSkipVerify, - CipherSuites: c.CipherSuites, - PreferServerCipherSuites: c.PreferServerCipherSuites, - SessionTicketsDisabled: c.SessionTicketsDisabled, - SessionTicketKey: c.SessionTicketKey, - ClientSessionCache: c.ClientSessionCache, - MinVersion: c.MinVersion, - MaxVersion: c.MaxVersion, - CurvePreferences: c.CurvePreferences, - DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, - Renegotiation: c.Renegotiation, - } -} diff --git a/vendor/golang.org/x/net/http2/go18.go b/vendor/golang.org/x/net/http2/go18.go deleted file mode 100644 index 4f30d228a..000000000 --- a/vendor/golang.org/x/net/http2/go18.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.8 - -package http2 - -import ( - "crypto/tls" - "io" - "net/http" -) - -func cloneTLSConfig(c *tls.Config) *tls.Config { - c2 := c.Clone() - c2.GetClientCertificate = c.GetClientCertificate // golang.org/issue/19264 - return c2 -} - -var _ http.Pusher = (*responseWriter)(nil) - -// Push implements http.Pusher. -func (w *responseWriter) Push(target string, opts *http.PushOptions) error { - internalOpts := pushOptions{} - if opts != nil { - internalOpts.Method = opts.Method - internalOpts.Header = opts.Header - } - return w.push(target, internalOpts) -} - -func configureServer18(h1 *http.Server, h2 *Server) error { - if h2.IdleTimeout == 0 { - if h1.IdleTimeout != 0 { - h2.IdleTimeout = h1.IdleTimeout - } else { - h2.IdleTimeout = h1.ReadTimeout - } - } - return nil -} - -func shouldLogPanic(panicValue interface{}) bool { - return panicValue != nil && panicValue != http.ErrAbortHandler -} - -func reqGetBody(req *http.Request) func() (io.ReadCloser, error) { - return req.GetBody -} - -func reqBodyIsNoBody(body io.ReadCloser) bool { - return body == http.NoBody -} - -func go18httpNoBody() io.ReadCloser { return http.NoBody } // for tests only diff --git a/vendor/golang.org/x/net/http2/go19.go b/vendor/golang.org/x/net/http2/go19.go deleted file mode 100644 index 38124ba56..000000000 --- a/vendor/golang.org/x/net/http2/go19.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.9 - -package http2 - -import ( - "net/http" -) - -func configureServer19(s *http.Server, conf *Server) error { - s.RegisterOnShutdown(conf.state.startGracefulShutdown) - return nil -} diff --git a/vendor/golang.org/x/net/http2/headermap.go b/vendor/golang.org/x/net/http2/headermap.go index c2805f6ac..c3ff3fa1c 100644 --- a/vendor/golang.org/x/net/http2/headermap.go +++ b/vendor/golang.org/x/net/http2/headermap.go @@ -7,15 +7,21 @@ package http2 import ( "net/http" "strings" + "sync" ) var ( - commonLowerHeader = map[string]string{} // Go-Canonical-Case -> lower-case - commonCanonHeader = map[string]string{} // lower-case -> Go-Canonical-Case + commonBuildOnce sync.Once + commonLowerHeader map[string]string // Go-Canonical-Case -> lower-case + commonCanonHeader map[string]string // lower-case -> Go-Canonical-Case ) -func init() { - for _, v := range []string{ +func buildCommonHeaderMapsOnce() { + commonBuildOnce.Do(buildCommonHeaderMaps) +} + +func buildCommonHeaderMaps() { + common := []string{ "accept", "accept-charset", "accept-encoding", @@ -63,7 +69,10 @@ func init() { "vary", "via", "www-authenticate", - } { + } + commonLowerHeader = make(map[string]string, len(common)) + commonCanonHeader = make(map[string]string, len(common)) + for _, v := range common { chk := http.CanonicalHeaderKey(v) commonLowerHeader[chk] = v commonCanonHeader[v] = chk @@ -71,6 +80,7 @@ func init() { } func lowerHeader(v string) string { + buildCommonHeaderMapsOnce() if s, ok := commonLowerHeader[v]; ok { return s } diff --git a/vendor/golang.org/x/net/http2/hpack/encode.go b/vendor/golang.org/x/net/http2/hpack/encode.go index 54726c2a3..1565cf270 100644 --- a/vendor/golang.org/x/net/http2/hpack/encode.go +++ b/vendor/golang.org/x/net/http2/hpack/encode.go @@ -206,7 +206,7 @@ func appendVarInt(dst []byte, n byte, i uint64) []byte { } // appendHpackString appends s, as encoded in "String Literal" -// representation, to dst and returns the the extended buffer. +// representation, to dst and returns the extended buffer. // // s will be encoded in Huffman codes only when it produces strictly // shorter byte string. diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go index 176644acd..85f18a2b0 100644 --- a/vendor/golang.org/x/net/http2/hpack/hpack.go +++ b/vendor/golang.org/x/net/http2/hpack/hpack.go @@ -92,6 +92,8 @@ type Decoder struct { // saveBuf is previous data passed to Write which we weren't able // to fully parse before. Unlike buf, we own this data. saveBuf bytes.Buffer + + firstField bool // processing the first field of the header block } // NewDecoder returns a new decoder with the provided maximum dynamic @@ -101,6 +103,7 @@ func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decod d := &Decoder{ emit: emitFunc, emitEnabled: true, + firstField: true, } d.dynTab.table.init() d.dynTab.allowedMaxSize = maxDynamicTableSize @@ -226,11 +229,15 @@ func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) { return hf, nil } +// Close declares that the decoding is complete and resets the Decoder +// to be reused again for a new header block. If there is any remaining +// data in the decoder's buffer, Close returns an error. func (d *Decoder) Close() error { if d.saveBuf.Len() > 0 { d.saveBuf.Reset() return DecodingError{errors.New("truncated headers")} } + d.firstField = true return nil } @@ -266,6 +273,7 @@ func (d *Decoder) Write(p []byte) (n int, err error) { d.saveBuf.Write(d.buf) return len(p), nil } + d.firstField = false if err != nil { break } @@ -389,6 +397,12 @@ func (d *Decoder) callEmit(hf HeaderField) error { // (same invariants and behavior as parseHeaderFieldRepr) func (d *Decoder) parseDynamicTableSizeUpdate() error { + // RFC 7541, sec 4.2: This dynamic table size update MUST occur at the + // beginning of the first header block following the change to the dynamic table size. + if !d.firstField && d.dynTab.size > 0 { + return DecodingError{errors.New("dynamic table size update MUST occur at the beginning of a header block")} + } + buf := d.buf size, buf, err := readVarInt(5, buf) if err != nil { diff --git a/vendor/golang.org/x/net/http2/hpack/huffman.go b/vendor/golang.org/x/net/http2/hpack/huffman.go index 8850e3946..b412a96c5 100644 --- a/vendor/golang.org/x/net/http2/hpack/huffman.go +++ b/vendor/golang.org/x/net/http2/hpack/huffman.go @@ -47,6 +47,7 @@ var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data") // If maxLen is greater than 0, attempts to write more to buf than // maxLen bytes will return ErrStringLength. func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error { + rootHuffmanNode := getRootHuffmanNode() n := rootHuffmanNode // cur is the bit buffer that has not been fed into n. // cbits is the number of low order bits in cur that are valid. @@ -106,7 +107,7 @@ func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error { type node struct { // children is non-nil for internal nodes - children []*node + children *[256]*node // The following are only valid if children is nil: codeLen uint8 // number of bits that led to the output of sym @@ -114,22 +115,31 @@ type node struct { } func newInternalNode() *node { - return &node{children: make([]*node, 256)} + return &node{children: new([256]*node)} } -var rootHuffmanNode = newInternalNode() +var ( + buildRootOnce sync.Once + lazyRootHuffmanNode *node +) -func init() { +func getRootHuffmanNode() *node { + buildRootOnce.Do(buildRootHuffmanNode) + return lazyRootHuffmanNode +} + +func buildRootHuffmanNode() { if len(huffmanCodes) != 256 { panic("unexpected size") } + lazyRootHuffmanNode = newInternalNode() for i, code := range huffmanCodes { addDecoderNode(byte(i), code, huffmanCodeLen[i]) } } func addDecoderNode(sym byte, code uint32, codeLen uint8) { - cur := rootHuffmanNode + cur := lazyRootHuffmanNode for codeLen > 8 { codeLen -= 8 i := uint8(code >> codeLen) diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go index d565f40e0..bdaba1d46 100644 --- a/vendor/golang.org/x/net/http2/http2.go +++ b/vendor/golang.org/x/net/http2/http2.go @@ -29,7 +29,7 @@ import ( "strings" "sync" - "golang.org/x/net/lex/httplex" + "golang.org/x/net/http/httpguts" ) var ( @@ -179,7 +179,7 @@ var ( ) // validWireHeaderFieldName reports whether v is a valid header field -// name (key). See httplex.ValidHeaderName for the base rules. +// name (key). See httpguts.ValidHeaderName for the base rules. // // Further, http2 says: // "Just as in HTTP/1.x, header field names are strings of ASCII @@ -191,7 +191,7 @@ func validWireHeaderFieldName(v string) bool { return false } for _, r := range v { - if !httplex.IsTokenRune(r) { + if !httpguts.IsTokenRune(r) { return false } if 'A' <= r && r <= 'Z' { @@ -201,19 +201,12 @@ func validWireHeaderFieldName(v string) bool { return true } -var httpCodeStringCommon = map[int]string{} // n -> strconv.Itoa(n) - -func init() { - for i := 100; i <= 999; i++ { - if v := http.StatusText(i); v != "" { - httpCodeStringCommon[i] = strconv.Itoa(i) - } - } -} - func httpCodeString(code int) string { - if s, ok := httpCodeStringCommon[code]; ok { - return s + switch code { + case 200: + return "200" + case 404: + return "404" } return strconv.Itoa(code) } @@ -312,7 +305,7 @@ func mustUint31(v int32) uint32 { } // bodyAllowedForStatus reports whether a given response status code -// permits a body. See RFC 2616, section 4.4. +// permits a body. See RFC 7230, section 3.3. func bodyAllowedForStatus(status int) bool { switch { case status >= 100 && status <= 199: diff --git a/vendor/golang.org/x/net/http2/not_go111.go b/vendor/golang.org/x/net/http2/not_go111.go new file mode 100644 index 000000000..161bca7ce --- /dev/null +++ b/vendor/golang.org/x/net/http2/not_go111.go @@ -0,0 +1,20 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.11 + +package http2 + +import ( + "net/http/httptrace" + "net/textproto" +) + +func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool { return false } + +func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) {} + +func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error { + return nil +} diff --git a/vendor/golang.org/x/net/http2/not_go16.go b/vendor/golang.org/x/net/http2/not_go16.go deleted file mode 100644 index 508cebcc4..000000000 --- a/vendor/golang.org/x/net/http2/not_go16.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.6 - -package http2 - -import ( - "net/http" - "time" -) - -func configureTransport(t1 *http.Transport) (*Transport, error) { - return nil, errTransportVersion -} - -func transportExpectContinueTimeout(t1 *http.Transport) time.Duration { - return 0 - -} diff --git a/vendor/golang.org/x/net/http2/not_go17.go b/vendor/golang.org/x/net/http2/not_go17.go deleted file mode 100644 index 140434a79..000000000 --- a/vendor/golang.org/x/net/http2/not_go17.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.7 - -package http2 - -import ( - "crypto/tls" - "net" - "net/http" - "time" -) - -type contextContext interface { - Done() <-chan struct{} - Err() error -} - -type fakeContext struct{} - -func (fakeContext) Done() <-chan struct{} { return nil } -func (fakeContext) Err() error { panic("should not be called") } - -func reqContext(r *http.Request) fakeContext { - return fakeContext{} -} - -func setResponseUncompressed(res *http.Response) { - // Nothing. -} - -type clientTrace struct{} - -func requestTrace(*http.Request) *clientTrace { return nil } -func traceGotConn(*http.Request, *ClientConn) {} -func traceFirstResponseByte(*clientTrace) {} -func traceWroteHeaders(*clientTrace) {} -func traceWroteRequest(*clientTrace, error) {} -func traceGot100Continue(trace *clientTrace) {} -func traceWait100Continue(trace *clientTrace) {} - -func nop() {} - -func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx contextContext, cancel func()) { - return nil, nop -} - -func contextWithCancel(ctx contextContext) (_ contextContext, cancel func()) { - return ctx, nop -} - -func requestWithContext(req *http.Request, ctx contextContext) *http.Request { - return req -} - -// temporary copy of Go 1.6's private tls.Config.clone: -func cloneTLSConfig(c *tls.Config) *tls.Config { - return &tls.Config{ - Rand: c.Rand, - Time: c.Time, - Certificates: c.Certificates, - NameToCertificate: c.NameToCertificate, - GetCertificate: c.GetCertificate, - RootCAs: c.RootCAs, - NextProtos: c.NextProtos, - ServerName: c.ServerName, - ClientAuth: c.ClientAuth, - ClientCAs: c.ClientCAs, - InsecureSkipVerify: c.InsecureSkipVerify, - CipherSuites: c.CipherSuites, - PreferServerCipherSuites: c.PreferServerCipherSuites, - SessionTicketsDisabled: c.SessionTicketsDisabled, - SessionTicketKey: c.SessionTicketKey, - ClientSessionCache: c.ClientSessionCache, - MinVersion: c.MinVersion, - MaxVersion: c.MaxVersion, - CurvePreferences: c.CurvePreferences, - } -} - -func (cc *ClientConn) Ping(ctx contextContext) error { - return cc.ping(ctx) -} - -func (t *Transport) idleConnTimeout() time.Duration { return 0 } diff --git a/vendor/golang.org/x/net/http2/not_go18.go b/vendor/golang.org/x/net/http2/not_go18.go deleted file mode 100644 index 6f8d3f86f..000000000 --- a/vendor/golang.org/x/net/http2/not_go18.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.8 - -package http2 - -import ( - "io" - "net/http" -) - -func configureServer18(h1 *http.Server, h2 *Server) error { - // No IdleTimeout to sync prior to Go 1.8. - return nil -} - -func shouldLogPanic(panicValue interface{}) bool { - return panicValue != nil -} - -func reqGetBody(req *http.Request) func() (io.ReadCloser, error) { - return nil -} - -func reqBodyIsNoBody(io.ReadCloser) bool { return false } - -func go18httpNoBody() io.ReadCloser { return nil } // for tests only diff --git a/vendor/golang.org/x/net/http2/not_go19.go b/vendor/golang.org/x/net/http2/not_go19.go deleted file mode 100644 index 5ae07726b..000000000 --- a/vendor/golang.org/x/net/http2/not_go19.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.9 - -package http2 - -import ( - "net/http" -) - -func configureServer19(s *http.Server, conf *Server) error { - // not supported prior to go1.9 - return nil -} diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index eae143ddf..8f1701914 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -28,6 +28,7 @@ package http2 import ( "bufio" "bytes" + "context" "crypto/tls" "errors" "fmt" @@ -46,6 +47,7 @@ import ( "sync" "time" + "golang.org/x/net/http/httpguts" "golang.org/x/net/http2/hpack" ) @@ -208,24 +210,29 @@ func ConfigureServer(s *http.Server, conf *Server) error { conf = new(Server) } conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})} - if err := configureServer18(s, conf); err != nil { - return err - } - if err := configureServer19(s, conf); err != nil { - return err + if h1, h2 := s, conf; h2.IdleTimeout == 0 { + if h1.IdleTimeout != 0 { + h2.IdleTimeout = h1.IdleTimeout + } else { + h2.IdleTimeout = h1.ReadTimeout + } } + s.RegisterOnShutdown(conf.state.startGracefulShutdown) if s.TLSConfig == nil { s.TLSConfig = new(tls.Config) } else if s.TLSConfig.CipherSuites != nil { // If they already provided a CipherSuite list, return // an error if it has a bad order or is missing - // ECDHE_RSA_WITH_AES_128_GCM_SHA256. - const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + // ECDHE_RSA_WITH_AES_128_GCM_SHA256 or ECDHE_ECDSA_WITH_AES_128_GCM_SHA256. haveRequired := false sawBad := false for i, cs := range s.TLSConfig.CipherSuites { - if cs == requiredCipher { + switch cs { + case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + // Alternative MTI cipher to not discourage ECDSA-only servers. + // See http://golang.org/cl/30721 for further information. + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: haveRequired = true } if isBadCipher(cs) { @@ -235,7 +242,7 @@ func ConfigureServer(s *http.Server, conf *Server) error { } } if !haveRequired { - return fmt.Errorf("http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256") + return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher.") } } @@ -403,7 +410,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { // addresses during development. // // TODO: optionally enforce? Or enforce at the time we receive - // a new request, and verify the the ServerName matches the :authority? + // a new request, and verify the ServerName matches the :authority? // But that precludes proxy situations, perhaps. // // So for now, do nothing here again. @@ -431,6 +438,15 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { sc.serve() } +func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx context.Context, cancel func()) { + ctx, cancel = context.WithCancel(context.Background()) + ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr()) + if hs := opts.baseConfig(); hs != nil { + ctx = context.WithValue(ctx, http.ServerContextKey, hs) + } + return +} + func (sc *serverConn) rejectConn(err ErrCode, debug string) { sc.vlogf("http2: server rejecting conn: %v, %s", err, debug) // ignoring errors. hanging up anyway. @@ -446,7 +462,7 @@ type serverConn struct { conn net.Conn bw *bufferedWriter // writing to conn handler http.Handler - baseCtx contextContext + baseCtx context.Context framer *Framer doneServing chan struct{} // closed when serverConn.serve ends readFrameCh chan readFrameResult // written by serverConn.readFrames @@ -526,7 +542,7 @@ type stream struct { id uint32 body *pipe // non-nil if expecting DATA frames cw closeWaiter // closed wait stream transitions to closed state - ctx contextContext + ctx context.Context cancelCtx func() // owned by serverConn's serve loop: @@ -649,7 +665,7 @@ func (sc *serverConn) condlogf(err error, format string, args ...interface{}) { if err == nil { return } - if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) { + if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) || err == errPrefaceTimeout { // Boring, expected errors. sc.vlogf(format, args...) } else { @@ -659,6 +675,7 @@ func (sc *serverConn) condlogf(err error, format string, args ...interface{}) { func (sc *serverConn) canonicalHeader(v string) string { sc.serveG.check() + buildCommonHeaderMapsOnce() cv, ok := commonCanonHeader[v] if ok { return cv @@ -853,8 +870,13 @@ func (sc *serverConn) serve() { } } - if sc.inGoAway && sc.curOpenStreams() == 0 && !sc.needToSendGoAway && !sc.writingFrame { - return + // Start the shutdown timer after sending a GOAWAY. When sending GOAWAY + // with no error code (graceful shutdown), don't start the timer until + // all open streams have been completed. + sentGoAway := sc.inGoAway && !sc.needToSendGoAway && !sc.writingFrame + gracefulShutdownComplete := sc.goAwayCode == ErrCodeNo && sc.curOpenStreams() == 0 + if sentGoAway && sc.shutdownTimer == nil && (sc.goAwayCode != ErrCodeNo || gracefulShutdownComplete) { + sc.shutDownIn(goAwayTimeout) } } } @@ -889,8 +911,11 @@ func (sc *serverConn) sendServeMsg(msg interface{}) { } } -// readPreface reads the ClientPreface greeting from the peer -// or returns an error on timeout or an invalid greeting. +var errPrefaceTimeout = errors.New("timeout waiting for client preface") + +// readPreface reads the ClientPreface greeting from the peer or +// returns errPrefaceTimeout on timeout, or an error if the greeting +// is invalid. func (sc *serverConn) readPreface() error { errc := make(chan error, 1) go func() { @@ -908,7 +933,7 @@ func (sc *serverConn) readPreface() error { defer timer.Stop() select { case <-timer.C: - return errors.New("timeout waiting for client preface") + return errPrefaceTimeout case err := <-errc: if err == nil { if VerboseLogs { @@ -1097,7 +1122,7 @@ func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) { // errHandlerPanicked is the error given to any callers blocked in a read from // Request.Body when the main goroutine panics. Since most handlers read in the -// the main ServeHTTP goroutine, this will show up rarely. +// main ServeHTTP goroutine, this will show up rarely. var errHandlerPanicked = errors.New("http2: handler panicked") // wroteFrame is called on the serve goroutine with the result of @@ -1218,30 +1243,31 @@ func (sc *serverConn) startGracefulShutdown() { sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) }) } +// After sending GOAWAY, the connection will close after goAwayTimeout. +// If we close the connection immediately after sending GOAWAY, there may +// be unsent data in our kernel receive buffer, which will cause the kernel +// to send a TCP RST on close() instead of a FIN. This RST will abort the +// connection immediately, whether or not the client had received the GOAWAY. +// +// Ideally we should delay for at least 1 RTT + epsilon so the client has +// a chance to read the GOAWAY and stop sending messages. Measuring RTT +// is hard, so we approximate with 1 second. See golang.org/issue/18701. +// +// This is a var so it can be shorter in tests, where all requests uses the +// loopback interface making the expected RTT very small. +// +// TODO: configurable? +var goAwayTimeout = 1 * time.Second + func (sc *serverConn) startGracefulShutdownInternal() { - sc.goAwayIn(ErrCodeNo, 0) + sc.goAway(ErrCodeNo) } func (sc *serverConn) goAway(code ErrCode) { - sc.serveG.check() - var forceCloseIn time.Duration - if code != ErrCodeNo { - forceCloseIn = 250 * time.Millisecond - } else { - // TODO: configurable - forceCloseIn = 1 * time.Second - } - sc.goAwayIn(code, forceCloseIn) -} - -func (sc *serverConn) goAwayIn(code ErrCode, forceCloseIn time.Duration) { sc.serveG.check() if sc.inGoAway { return } - if forceCloseIn != 0 { - sc.shutDownIn(forceCloseIn) - } sc.inGoAway = true sc.needToSendGoAway = true sc.goAwayCode = code @@ -1474,6 +1500,12 @@ func (sc *serverConn) processSettings(f *SettingsFrame) error { } return nil } + if f.NumSettings() > 100 || f.HasDuplicates() { + // This isn't actually in the spec, but hang up on + // suspiciously large settings frames or those with + // duplicate entries. + return ConnectionError(ErrCodeProtocol) + } if err := f.ForeachSetting(sc.processSetting); err != nil { return err } @@ -1595,7 +1627,10 @@ func (sc *serverConn) processData(f *DataFrame) error { // Sender sending more than they'd declared? if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes { st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes)) - return streamError(id, ErrCodeStreamClosed) + // RFC 7540, sec 8.1.2.6: A request or response is also malformed if the + // value of a content-length header field does not equal the sum of the + // DATA frame payload lengths that form the body. + return streamError(id, ErrCodeProtocol) } if f.Length > 0 { // Check whether the client has flow control quota. @@ -1705,6 +1740,13 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // processing this frame. return nil } + // RFC 7540, sec 5.1: If an endpoint receives additional frames, other than + // WINDOW_UPDATE, PRIORITY, or RST_STREAM, for a stream that is in + // this state, it MUST respond with a stream error (Section 5.4.2) of + // type STREAM_CLOSED. + if st.state == stateHalfClosedRemote { + return streamError(id, ErrCodeStreamClosed) + } return st.processTrailerHeaders(f) } @@ -1805,7 +1847,7 @@ func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error { if st.trailer != nil { for _, hf := range f.RegularFields() { key := sc.canonicalHeader(hf.Name) - if !ValidTrailerHeader(key) { + if !httpguts.ValidTrailerHeader(key) { // TODO: send more details to the peer somehow. But http2 has // no way to send debug data at a stream level. Discuss with // HTTP folk. @@ -1846,7 +1888,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream panic("internal error: cannot create stream with id 0") } - ctx, cancelCtx := contextWithCancel(sc.baseCtx) + ctx, cancelCtx := context.WithCancel(sc.baseCtx) st := &stream{ sc: sc, id: id, @@ -2012,7 +2054,7 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r Body: body, Trailer: trailer, } - req = requestWithContext(req, st.ctx) + req = req.WithContext(st.ctx) rws := responseWriterStatePool.Get().(*responseWriterState) bwSave := rws.bw @@ -2040,7 +2082,7 @@ func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler stream: rw.rws.stream, }) // Same as net/http: - if shouldLogPanic(e) { + if e != nil && e != http.ErrAbortHandler { const size = 64 << 10 buf := make([]byte, size) buf = buf[:runtime.Stack(buf, false)] @@ -2272,8 +2314,8 @@ func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) != // written in the trailers at the end of the response. func (rws *responseWriterState) declareTrailer(k string) { k = http.CanonicalHeaderKey(k) - if !ValidTrailerHeader(k) { - // Forbidden by RFC 2616 14.40. + if !httpguts.ValidTrailerHeader(k) { + // Forbidden by RFC 7230, section 4.1.2. rws.conn.logf("ignoring invalid trailer %q", k) return } @@ -2310,7 +2352,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { clen = strconv.Itoa(len(p)) } _, hasContentType := rws.snapHeader["Content-Type"] - if !hasContentType && bodyAllowedForStatus(rws.status) { + if !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 { ctype = http.DetectContentType(p) } var date string @@ -2323,6 +2365,19 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { foreachHeaderElement(v, rws.declareTrailer) } + // "Connection" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2), + // but respect "Connection" == "close" to mean sending a GOAWAY and tearing + // down the TCP connection when idle, like we do for HTTP/1. + // TODO: remove more Connection-specific header fields here, in addition + // to "Connection". + if _, ok := rws.snapHeader["Connection"]; ok { + v := rws.snapHeader.Get("Connection") + delete(rws.snapHeader, "Connection") + if v == "close" { + rws.conn.startGracefulShutdown() + } + } + endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{ streamID: rws.stream.id, @@ -2394,7 +2449,7 @@ const TrailerPrefix = "Trailer:" // after the header has already been flushed. Because the Go // ResponseWriter interface has no way to set Trailers (only the // Header), and because we didn't want to expand the ResponseWriter -// interface, and because nobody used trailers, and because RFC 2616 +// interface, and because nobody used trailers, and because RFC 7230 // says you SHOULD (but not must) predeclare any trailers in the // header, the official ResponseWriter rules said trailers in Go must // be predeclared, and then we reuse the same ResponseWriter.Header() @@ -2478,6 +2533,24 @@ func (w *responseWriter) Header() http.Header { return rws.handlerHeader } +// checkWriteHeaderCode is a copy of net/http's checkWriteHeaderCode. +func checkWriteHeaderCode(code int) { + // Issue 22880: require valid WriteHeader status codes. + // For now we only enforce that it's three digits. + // In the future we might block things over 599 (600 and above aren't defined + // at http://httpwg.org/specs/rfc7231.html#status.codes) + // and we might block under 200 (once we have more mature 1xx support). + // But for now any three digits. + // + // We used to send "HTTP/1.1 000 0" on the wire in responses but there's + // no equivalent bogus thing we can realistically send in HTTP/2, + // so we'll consistently panic instead and help people find their bugs + // early. (We can't return an error from WriteHeader even if we wanted to.) + if code < 100 || code > 999 { + panic(fmt.Sprintf("invalid WriteHeader code %v", code)) + } +} + func (w *responseWriter) WriteHeader(code int) { rws := w.rws if rws == nil { @@ -2488,6 +2561,7 @@ func (w *responseWriter) WriteHeader(code int) { func (rws *responseWriterState) writeHeader(code int) { if !rws.wroteHeader { + checkWriteHeaderCode(code) rws.wroteHeader = true rws.status = code if len(rws.handlerHeader) > 0 { @@ -2570,14 +2644,9 @@ var ( ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS") ) -// pushOptions is the internal version of http.PushOptions, which we -// cannot include here because it's only defined in Go 1.8 and later. -type pushOptions struct { - Method string - Header http.Header -} +var _ http.Pusher = (*responseWriter)(nil) -func (w *responseWriter) push(target string, opts pushOptions) error { +func (w *responseWriter) Push(target string, opts *http.PushOptions) error { st := w.rws.stream sc := st.sc sc.serveG.checkNotOn() @@ -2588,6 +2657,10 @@ func (w *responseWriter) push(target string, opts pushOptions) error { return ErrRecursivePush } + if opts == nil { + opts = new(http.PushOptions) + } + // Default options. if opts.Method == "" { opts.Method = "GET" @@ -2759,7 +2832,7 @@ func (sc *serverConn) startPush(msg *startPushRequest) { } // foreachHeaderElement splits v according to the "#rule" construction -// in RFC 2616 section 2.1 and calls fn for each non-empty element. +// in RFC 7230 section 7 and calls fn for each non-empty element. func foreachHeaderElement(v string, fn func(string)) { v = textproto.TrimString(v) if v == "" { @@ -2807,41 +2880,6 @@ func new400Handler(err error) http.HandlerFunc { } } -// ValidTrailerHeader reports whether name is a valid header field name to appear -// in trailers. -// See: http://tools.ietf.org/html/rfc7230#section-4.1.2 -func ValidTrailerHeader(name string) bool { - name = http.CanonicalHeaderKey(name) - if strings.HasPrefix(name, "If-") || badTrailer[name] { - return false - } - return true -} - -var badTrailer = map[string]bool{ - "Authorization": true, - "Cache-Control": true, - "Connection": true, - "Content-Encoding": true, - "Content-Length": true, - "Content-Range": true, - "Content-Type": true, - "Expect": true, - "Host": true, - "Keep-Alive": true, - "Max-Forwards": true, - "Pragma": true, - "Proxy-Authenticate": true, - "Proxy-Authorization": true, - "Proxy-Connection": true, - "Range": true, - "Realm": true, - "Te": true, - "Trailer": true, - "Transfer-Encoding": true, - "Www-Authenticate": true, -} - // h1ServerKeepAlivesDisabled reports whether hs has its keep-alives // disabled. See comments on h1ServerShutdownChan above for why // the code is written this way. diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index e0dfe9f6a..f272e8f9f 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -10,6 +10,7 @@ import ( "bufio" "bytes" "compress/gzip" + "context" "crypto/rand" "crypto/tls" "errors" @@ -21,15 +22,17 @@ import ( mathrand "math/rand" "net" "net/http" + "net/http/httptrace" + "net/textproto" "sort" "strconv" "strings" "sync" "time" + "golang.org/x/net/http/httpguts" "golang.org/x/net/http2/hpack" "golang.org/x/net/idna" - "golang.org/x/net/lex/httplex" ) const ( @@ -87,13 +90,23 @@ type Transport struct { // MaxHeaderListSize is the http2 SETTINGS_MAX_HEADER_LIST_SIZE to // send in the initial settings frame. It is how many bytes - // of response headers are allow. Unlike the http2 spec, zero here + // of response headers are allowed. Unlike the http2 spec, zero here // means to use a default limit (currently 10MB). If you actually // want to advertise an ulimited value to the peer, Transport // interprets the highest possible value here (0xffffffff or 1<<32-1) // to mean no limit. MaxHeaderListSize uint32 + // StrictMaxConcurrentStreams controls whether the server's + // SETTINGS_MAX_CONCURRENT_STREAMS should be respected + // globally. If false, new TCP connections are created to the + // server as needed to keep each under the per-connection + // SETTINGS_MAX_CONCURRENT_STREAMS limit. If true, the + // server's SETTINGS_MAX_CONCURRENT_STREAMS is interpreted as + // a global limit and callers of RoundTrip block when needed, + // waiting for their turn. + StrictMaxConcurrentStreams bool + // t1, if non-nil, is the standard library Transport using // this transport. Its settings are used (but not its // RoundTrip method, etc). @@ -117,16 +130,56 @@ func (t *Transport) disableCompression() bool { return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression) } -var errTransportVersion = errors.New("http2: ConfigureTransport is only supported starting at Go 1.6") - // ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2. -// It requires Go 1.6 or later and returns an error if the net/http package is too old -// or if t1 has already been HTTP/2-enabled. +// It returns an error if t1 has already been HTTP/2-enabled. func ConfigureTransport(t1 *http.Transport) error { - _, err := configureTransport(t1) // in configure_transport.go (go1.6) or not_go16.go + _, err := configureTransport(t1) return err } +func configureTransport(t1 *http.Transport) (*Transport, error) { + connPool := new(clientConnPool) + t2 := &Transport{ + ConnPool: noDialClientConnPool{connPool}, + t1: t1, + } + connPool.t = t2 + if err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil { + return nil, err + } + if t1.TLSClientConfig == nil { + t1.TLSClientConfig = new(tls.Config) + } + if !strSliceContains(t1.TLSClientConfig.NextProtos, "h2") { + t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...) + } + if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") { + t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1") + } + upgradeFn := func(authority string, c *tls.Conn) http.RoundTripper { + addr := authorityAddr("https", authority) + if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil { + go c.Close() + return erringRoundTripper{err} + } else if !used { + // Turns out we don't need this c. + // For example, two goroutines made requests to the same host + // at the same time, both kicking off TCP dials. (since protocol + // was unknown) + go c.Close() + } + return t2 + } + if m := t1.TLSNextProto; len(m) == 0 { + t1.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{ + "h2": upgradeFn, + } + } else { + m["h2"] = upgradeFn + } + return t2, nil +} + func (t *Transport) connPool() ClientConnPool { t.connPoolOnce.Do(t.initConnPool) return t.connPoolOrDef @@ -159,6 +212,7 @@ type ClientConn struct { cond *sync.Cond // hold mu; broadcast on flow/closed changes flow flow // our conn-level flow control quota (cs.flow is per stream) inflow flow // peer's conn-level flow control + closing bool closed bool wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back goAway *GoAwayFrame // if non-nil, the GoAwayFrame we received @@ -172,9 +226,10 @@ type ClientConn struct { fr *Framer lastActive time.Time // Settings from peer: (also guarded by mu) - maxFrameSize uint32 - maxConcurrentStreams uint32 - initialWindowSize uint32 + maxFrameSize uint32 + maxConcurrentStreams uint32 + peerMaxHeaderListSize uint64 + initialWindowSize uint32 hbuf bytes.Buffer // HPACK encoder writes into this henc *hpack.Encoder @@ -189,7 +244,7 @@ type ClientConn struct { type clientStream struct { cc *ClientConn req *http.Request - trace *clientTrace // or nil + trace *httptrace.ClientTrace // or nil ID uint32 resc chan resAndError bufPipe pipe // buffered pipe with the flow-controlled response payload @@ -210,9 +265,10 @@ type clientStream struct { done chan struct{} // closed when stream remove from cc.streams map; close calls guarded by cc.mu // owned by clientConnReadLoop: - firstByte bool // got the first response byte - pastHeaders bool // got first MetaHeadersFrame (actual headers) - pastTrailers bool // got optional second MetaHeadersFrame (trailers) + firstByte bool // got the first response byte + pastHeaders bool // got first MetaHeadersFrame (actual headers) + pastTrailers bool // got optional second MetaHeadersFrame (trailers) + num1xx uint8 // number of 1xx responses seen trailer http.Header // accumulated trailers resTrailer *http.Header // client's Response.Trailer @@ -222,7 +278,7 @@ type clientStream struct { // channel to be signaled. A non-nil error is returned only if the request was // canceled. func awaitRequestCancel(req *http.Request, done <-chan struct{}) error { - ctx := reqContext(req) + ctx := req.Context() if req.Cancel == nil && ctx.Done() == nil { return nil } @@ -236,6 +292,17 @@ func awaitRequestCancel(req *http.Request, done <-chan struct{}) error { } } +var got1xxFuncForTests func(int, textproto.MIMEHeader) error + +// get1xxTraceFunc returns the value of request's httptrace.ClientTrace.Got1xxResponse func, +// if any. It returns nil if not set or if the Go version is too old. +func (cs *clientStream) get1xxTraceFunc() func(int, textproto.MIMEHeader) error { + if fn := got1xxFuncForTests; fn != nil { + return fn + } + return traceGot1xxResponseFunc(cs.trace) +} + // awaitRequestCancel waits for the user to cancel a request, its context to // expire, or for the request to be done (any way it might be removed from the // cc.streams map: peer reset, successful completion, TCP connection breakage, @@ -273,6 +340,13 @@ func (cs *clientStream) checkResetOrDone() error { } } +func (cs *clientStream) getStartedWrite() bool { + cc := cs.cc + cc.mu.Lock() + defer cc.mu.Unlock() + return cs.startedWrite +} + func (cs *clientStream) abortRequestBodyWrite(err error) { if err == nil { panic("nil error") @@ -298,7 +372,26 @@ func (sew stickyErrWriter) Write(p []byte) (n int, err error) { return } -var ErrNoCachedConn = errors.New("http2: no cached connection was available") +// noCachedConnError is the concrete type of ErrNoCachedConn, which +// needs to be detected by net/http regardless of whether it's its +// bundled version (in h2_bundle.go with a rewritten type name) or +// from a user's x/net/http2. As such, as it has a unique method name +// (IsHTTP2NoCachedConnError) that net/http sniffs for via func +// isNoCachedConnError. +type noCachedConnError struct{} + +func (noCachedConnError) IsHTTP2NoCachedConnError() {} +func (noCachedConnError) Error() string { return "http2: no cached connection was available" } + +// isNoCachedConnError reports whether err is of type noCachedConnError +// or its equivalent renamed type in net/http2's h2_bundle.go. Both types +// may coexist in the same running program. +func isNoCachedConnError(err error) bool { + _, ok := err.(interface{ IsHTTP2NoCachedConnError() }) + return ok +} + +var ErrNoCachedConn error = noCachedConnError{} // RoundTripOpt are options for the Transport.RoundTripOpt method. type RoundTripOpt struct { @@ -348,14 +441,9 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res return nil, err } traceGotConn(req, cc) - res, err := cc.RoundTrip(req) + res, gotErrAfterReqBodyWrite, err := cc.roundTrip(req) if err != nil && retry <= 6 { - afterBodyWrite := false - if e, ok := err.(afterReqBodyWriteError); ok { - err = e - afterBodyWrite = true - } - if req, err = shouldRetryRequest(req, err, afterBodyWrite); err == nil { + if req, err = shouldRetryRequest(req, err, gotErrAfterReqBodyWrite); err == nil { // After the first retry, do exponential backoff with 10% jitter. if retry == 0 { continue @@ -365,8 +453,8 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res select { case <-time.After(time.Second * time.Duration(backoff)): continue - case <-reqContext(req).Done(): - return nil, reqContext(req).Err() + case <-req.Context().Done(): + return nil, req.Context().Err() } } } @@ -393,16 +481,6 @@ var ( errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY") ) -// afterReqBodyWriteError is a wrapper around errors returned by ClientConn.RoundTrip. -// It is used to signal that err happened after part of Request.Body was sent to the server. -type afterReqBodyWriteError struct { - err error -} - -func (e afterReqBodyWriteError) Error() string { - return e.err.Error() + "; some request body already written" -} - // shouldRetryRequest is called by RoundTrip when a request fails to get // response headers. It is always called with a non-nil error. // It returns either a request to retry (either the same request, or a @@ -411,27 +489,35 @@ func shouldRetryRequest(req *http.Request, err error, afterBodyWrite bool) (*htt if !canRetryError(err) { return nil, err } + // If the Body is nil (or http.NoBody), it's safe to reuse + // this request and its Body. + if req.Body == nil || req.Body == http.NoBody { + return req, nil + } + + // If the request body can be reset back to its original + // state via the optional req.GetBody, do that. + if req.GetBody != nil { + // TODO: consider a req.Body.Close here? or audit that all caller paths do? + body, err := req.GetBody() + if err != nil { + return nil, err + } + newReq := *req + newReq.Body = body + return &newReq, nil + } + + // The Request.Body can't reset back to the beginning, but we + // don't seem to have started to read from it yet, so reuse + // the request directly. The "afterBodyWrite" means the + // bodyWrite process has started, which becomes true before + // the first Read. if !afterBodyWrite { return req, nil } - // If the Body is nil (or http.NoBody), it's safe to reuse - // this request and its Body. - if req.Body == nil || reqBodyIsNoBody(req.Body) { - return req, nil - } - // Otherwise we depend on the Request having its GetBody - // func defined. - getBody := reqGetBody(req) // Go 1.8: getBody = req.GetBody - if getBody == nil { - return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err) - } - body, err := getBody() - if err != nil { - return nil, err - } - newReq := *req - newReq.Body = body - return &newReq, nil + + return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err) } func canRetryError(err error) bool { @@ -459,7 +545,7 @@ func (t *Transport) dialClientConn(addr string, singleUse bool) (*ClientConn, er func (t *Transport) newTLSConfig(host string) *tls.Config { cfg := new(tls.Config) if t.TLSClientConfig != nil { - *cfg = *cloneTLSConfig(t.TLSClientConfig) + *cfg = *t.TLSClientConfig.Clone() } if !strSliceContains(cfg.NextProtos, NextProtoTLS) { cfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...) @@ -510,7 +596,7 @@ func (t *Transport) expectContinueTimeout() time.Duration { if t.t1 == nil { return 0 } - return transportExpectContinueTimeout(t.t1) + return t.t1.ExpectContinueTimeout } func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { @@ -519,17 +605,18 @@ func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) { cc := &ClientConn{ - t: t, - tconn: c, - readerDone: make(chan struct{}), - nextStreamID: 1, - maxFrameSize: 16 << 10, // spec default - initialWindowSize: 65535, // spec default - maxConcurrentStreams: 1000, // "infinite", per spec. 1000 seems good enough. - streams: make(map[uint32]*clientStream), - singleUse: singleUse, - wantSettingsAck: true, - pings: make(map[[8]byte]chan struct{}), + t: t, + tconn: c, + readerDone: make(chan struct{}), + nextStreamID: 1, + maxFrameSize: 16 << 10, // spec default + initialWindowSize: 65535, // spec default + maxConcurrentStreams: 1000, // "infinite", per spec. 1000 seems good enough. + peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead. + streams: make(map[uint32]*clientStream), + singleUse: singleUse, + wantSettingsAck: true, + pings: make(map[[8]byte]chan struct{}), } if d := t.idleConnTimeout(); d != 0 { cc.idleTimeout = d @@ -554,6 +641,10 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro // henc in response to SETTINGS frames? cc.henc = hpack.NewEncoder(&cc.hbuf) + if t.AllowHTTP { + cc.nextStreamID = 3 + } + if cs, ok := c.(connectionStater); ok { state := cs.ConnectionState() cc.tlsState = &state @@ -613,12 +704,43 @@ func (cc *ClientConn) CanTakeNewRequest() bool { return cc.canTakeNewRequestLocked() } -func (cc *ClientConn) canTakeNewRequestLocked() bool { +// clientConnIdleState describes the suitability of a client +// connection to initiate a new RoundTrip request. +type clientConnIdleState struct { + canTakeNewRequest bool + freshConn bool // whether it's unused by any previous request +} + +func (cc *ClientConn) idleState() clientConnIdleState { + cc.mu.Lock() + defer cc.mu.Unlock() + return cc.idleStateLocked() +} + +func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { if cc.singleUse && cc.nextStreamID > 1 { - return false + return } - return cc.goAway == nil && !cc.closed && - int64(cc.nextStreamID)+int64(cc.pendingRequests) < math.MaxInt32 + var maxConcurrentOkay bool + if cc.t.StrictMaxConcurrentStreams { + // We'll tell the caller we can take a new request to + // prevent the caller from dialing a new TCP + // connection, but then we'll block later before + // writing it. + maxConcurrentOkay = true + } else { + maxConcurrentOkay = int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams) + } + + st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay && + int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 + st.freshConn = cc.nextStreamID == 1 && st.canTakeNewRequest + return +} + +func (cc *ClientConn) canTakeNewRequestLocked() bool { + st := cc.idleStateLocked() + return st.canTakeNewRequest } // onIdleTimeout is called from a time.AfterFunc goroutine. It will @@ -648,6 +770,87 @@ func (cc *ClientConn) closeIfIdle() { cc.tconn.Close() } +var shutdownEnterWaitStateHook = func() {} + +// Shutdown gracefully close the client connection, waiting for running streams to complete. +func (cc *ClientConn) Shutdown(ctx context.Context) error { + if err := cc.sendGoAway(); err != nil { + return err + } + // Wait for all in-flight streams to complete or connection to close + done := make(chan error, 1) + cancelled := false // guarded by cc.mu + go func() { + cc.mu.Lock() + defer cc.mu.Unlock() + for { + if len(cc.streams) == 0 || cc.closed { + cc.closed = true + done <- cc.tconn.Close() + break + } + if cancelled { + break + } + cc.cond.Wait() + } + }() + shutdownEnterWaitStateHook() + select { + case err := <-done: + return err + case <-ctx.Done(): + cc.mu.Lock() + // Free the goroutine above + cancelled = true + cc.cond.Broadcast() + cc.mu.Unlock() + return ctx.Err() + } +} + +func (cc *ClientConn) sendGoAway() error { + cc.mu.Lock() + defer cc.mu.Unlock() + cc.wmu.Lock() + defer cc.wmu.Unlock() + if cc.closing { + // GOAWAY sent already + return nil + } + // Send a graceful shutdown frame to server + maxStreamID := cc.nextStreamID + if err := cc.fr.WriteGoAway(maxStreamID, ErrCodeNo, nil); err != nil { + return err + } + if err := cc.bw.Flush(); err != nil { + return err + } + // Prevent new requests + cc.closing = true + return nil +} + +// Close closes the client connection immediately. +// +// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead. +func (cc *ClientConn) Close() error { + cc.mu.Lock() + defer cc.cond.Broadcast() + defer cc.mu.Unlock() + err := errors.New("http2: client connection force closed via ClientConn.Close") + for id, cs := range cc.streams { + select { + case cs.resc <- resAndError{err: err}: + default: + } + cs.bufPipe.CloseWithError(err) + delete(cc.streams, id) + } + cc.closed = true + return cc.tconn.Close() +} + const maxAllocFrameSize = 512 << 10 // frameBuffer returns a scratch buffer suitable for writing DATA frames. @@ -730,7 +933,7 @@ func checkConnHeaders(req *http.Request) error { if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") { return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv) } - if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "close" && vv[0] != "keep-alive") { + if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !strings.EqualFold(vv[0], "close") && !strings.EqualFold(vv[0], "keep-alive")) { return fmt.Errorf("http2: invalid Connection request header: %q", vv) } return nil @@ -740,7 +943,7 @@ func checkConnHeaders(req *http.Request) error { // req.ContentLength, where 0 actually means zero (not unknown) and -1 // means unknown. func actualContentLength(req *http.Request) int64 { - if req.Body == nil || reqBodyIsNoBody(req.Body) { + if req.Body == nil || req.Body == http.NoBody { return 0 } if req.ContentLength != 0 { @@ -750,8 +953,13 @@ func actualContentLength(req *http.Request) int64 { } func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { + resp, _, err := cc.roundTrip(req) + return resp, err +} + +func (cc *ClientConn) roundTrip(req *http.Request) (res *http.Response, gotErrAfterReqBodyWrite bool, err error) { if err := checkConnHeaders(req); err != nil { - return nil, err + return nil, false, err } if cc.idleTimer != nil { cc.idleTimer.Stop() @@ -759,14 +967,14 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { trailers, err := commaSeparatedTrailers(req) if err != nil { - return nil, err + return nil, false, err } hasTrailers := trailers != "" cc.mu.Lock() if err := cc.awaitOpenSlotForRequest(req); err != nil { cc.mu.Unlock() - return nil, err + return nil, false, err } body := req.Body @@ -800,19 +1008,19 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { hdrs, err := cc.encodeHeaders(req, requestedGzip, trailers, contentLen) if err != nil { cc.mu.Unlock() - return nil, err + return nil, false, err } cs := cc.newStream() cs.req = req - cs.trace = requestTrace(req) + cs.trace = httptrace.ContextClientTrace(req.Context()) cs.requestedGzip = requestedGzip bodyWriter := cc.t.getBodyWriterState(cs, body) cs.on100 = bodyWriter.on100 cc.wmu.Lock() endStream := !hasBody && !hasTrailers - werr := cc.writeHeaders(cs.ID, endStream, hdrs) + werr := cc.writeHeaders(cs.ID, endStream, int(cc.maxFrameSize), hdrs) cc.wmu.Unlock() traceWroteHeaders(cs.trace) cc.mu.Unlock() @@ -826,7 +1034,7 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { // Don't bother sending a RST_STREAM (our write already failed; // no need to keep writing) traceWroteRequest(cs.trace, werr) - return nil, werr + return nil, false, werr } var respHeaderTimer <-chan time.Time @@ -843,9 +1051,9 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { readLoopResCh := cs.resc bodyWritten := false - ctx := reqContext(req) + ctx := req.Context() - handleReadLoopResponse := func(re resAndError) (*http.Response, error) { + handleReadLoopResponse := func(re resAndError) (*http.Response, bool, error) { res := re.res if re.err != nil || res.StatusCode > 299 { // On error or status code 3xx, 4xx, 5xx, etc abort any @@ -861,18 +1069,12 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { cs.abortRequestBodyWrite(errStopReqBodyWrite) } if re.err != nil { - cc.mu.Lock() - afterBodyWrite := cs.startedWrite - cc.mu.Unlock() cc.forgetStreamID(cs.ID) - if afterBodyWrite { - return nil, afterReqBodyWriteError{re.err} - } - return nil, re.err + return nil, cs.getStartedWrite(), re.err } res.Request = req res.TLS = cc.tlsState - return res, nil + return res, false, nil } for { @@ -887,7 +1089,7 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel) } cc.forgetStreamID(cs.ID) - return nil, errTimeout + return nil, cs.getStartedWrite(), errTimeout case <-ctx.Done(): if !hasBody || bodyWritten { cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) @@ -896,7 +1098,7 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel) } cc.forgetStreamID(cs.ID) - return nil, ctx.Err() + return nil, cs.getStartedWrite(), ctx.Err() case <-req.Cancel: if !hasBody || bodyWritten { cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) @@ -905,12 +1107,12 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel) } cc.forgetStreamID(cs.ID) - return nil, errRequestCanceled + return nil, cs.getStartedWrite(), errRequestCanceled case <-cs.peerReset: // processResetStream already removed the // stream from the streams map; no need for // forgetStreamID. - return nil, cs.resetErr + return nil, cs.getStartedWrite(), cs.resetErr case err := <-bodyWriter.resc: // Prefer the read loop's response, if available. Issue 16102. select { @@ -919,7 +1121,8 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { default: } if err != nil { - return nil, err + cc.forgetStreamID(cs.ID) + return nil, cs.getStartedWrite(), err } bodyWritten = true if d := cc.responseHeaderTimeout(); d != 0 { @@ -939,6 +1142,9 @@ func (cc *ClientConn) awaitOpenSlotForRequest(req *http.Request) error { for { cc.lastActive = time.Now() if cc.closed || !cc.canTakeNewRequestLocked() { + if waitingForConn != nil { + close(waitingForConn) + } return errClientConnUnusable } if int64(len(cc.streams))+1 <= int64(cc.maxConcurrentStreams) { @@ -971,13 +1177,12 @@ func (cc *ClientConn) awaitOpenSlotForRequest(req *http.Request) error { } // requires cc.wmu be held -func (cc *ClientConn) writeHeaders(streamID uint32, endStream bool, hdrs []byte) error { +func (cc *ClientConn) writeHeaders(streamID uint32, endStream bool, maxFrameSize int, hdrs []byte) error { first := true // first frame written (HEADERS is first, then CONTINUATION) - frameSize := int(cc.maxFrameSize) for len(hdrs) > 0 && cc.werr == nil { chunk := hdrs - if len(chunk) > frameSize { - chunk = chunk[:frameSize] + if len(chunk) > maxFrameSize { + chunk = chunk[:maxFrameSize] } hdrs = hdrs[len(chunk):] endHeaders := len(hdrs) == 0 @@ -1038,6 +1243,7 @@ func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) ( sawEOF = true err = nil } else if err != nil { + cc.writeStreamReset(cs.ID, ErrCodeCancel, err) return err } @@ -1085,17 +1291,26 @@ func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) ( var trls []byte if hasTrailers { cc.mu.Lock() - defer cc.mu.Unlock() - trls = cc.encodeTrailers(req) + trls, err = cc.encodeTrailers(req) + cc.mu.Unlock() + if err != nil { + cc.writeStreamReset(cs.ID, ErrCodeInternal, err) + cc.forgetStreamID(cs.ID) + return err + } } + cc.mu.Lock() + maxFrameSize := int(cc.maxFrameSize) + cc.mu.Unlock() + cc.wmu.Lock() defer cc.wmu.Unlock() // Two ways to send END_STREAM: either with trailers, or // with an empty DATA frame. if len(trls) > 0 { - err = cc.writeHeaders(cs.ID, true, trls) + err = cc.writeHeaders(cs.ID, true, maxFrameSize, trls) } else { err = cc.fr.WriteData(cs.ID, true, nil) } @@ -1154,7 +1369,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail if host == "" { host = req.URL.Host } - host, err := httplex.PunycodeHostPort(host) + host, err := httpguts.PunycodeHostPort(host) if err != nil { return nil, err } @@ -1179,72 +1394,103 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail // potentially pollute our hpack state. (We want to be able to // continue to reuse the hpack encoder for future requests) for k, vv := range req.Header { - if !httplex.ValidHeaderFieldName(k) { + if !httpguts.ValidHeaderFieldName(k) { return nil, fmt.Errorf("invalid HTTP header name %q", k) } for _, v := range vv { - if !httplex.ValidHeaderFieldValue(v) { + if !httpguts.ValidHeaderFieldValue(v) { return nil, fmt.Errorf("invalid HTTP header value %q for header %q", v, k) } } } - // 8.1.2.3 Request Pseudo-Header Fields - // The :path pseudo-header field includes the path and query parts of the - // target URI (the path-absolute production and optionally a '?' character - // followed by the query production (see Sections 3.3 and 3.4 of - // [RFC3986]). - cc.writeHeader(":authority", host) - cc.writeHeader(":method", req.Method) - if req.Method != "CONNECT" { - cc.writeHeader(":path", path) - cc.writeHeader(":scheme", req.URL.Scheme) - } - if trailers != "" { - cc.writeHeader("trailer", trailers) + enumerateHeaders := func(f func(name, value string)) { + // 8.1.2.3 Request Pseudo-Header Fields + // The :path pseudo-header field includes the path and query parts of the + // target URI (the path-absolute production and optionally a '?' character + // followed by the query production (see Sections 3.3 and 3.4 of + // [RFC3986]). + f(":authority", host) + f(":method", req.Method) + if req.Method != "CONNECT" { + f(":path", path) + f(":scheme", req.URL.Scheme) + } + if trailers != "" { + f("trailer", trailers) + } + + var didUA bool + for k, vv := range req.Header { + if strings.EqualFold(k, "host") || strings.EqualFold(k, "content-length") { + // Host is :authority, already sent. + // Content-Length is automatic, set below. + continue + } else if strings.EqualFold(k, "connection") || strings.EqualFold(k, "proxy-connection") || + strings.EqualFold(k, "transfer-encoding") || strings.EqualFold(k, "upgrade") || + strings.EqualFold(k, "keep-alive") { + // Per 8.1.2.2 Connection-Specific Header + // Fields, don't send connection-specific + // fields. We have already checked if any + // are error-worthy so just ignore the rest. + continue + } else if strings.EqualFold(k, "user-agent") { + // Match Go's http1 behavior: at most one + // User-Agent. If set to nil or empty string, + // then omit it. Otherwise if not mentioned, + // include the default (below). + didUA = true + if len(vv) < 1 { + continue + } + vv = vv[:1] + if vv[0] == "" { + continue + } + + } + + for _, v := range vv { + f(k, v) + } + } + if shouldSendReqContentLength(req.Method, contentLength) { + f("content-length", strconv.FormatInt(contentLength, 10)) + } + if addGzipHeader { + f("accept-encoding", "gzip") + } + if !didUA { + f("user-agent", defaultUserAgent) + } } - var didUA bool - for k, vv := range req.Header { - lowKey := strings.ToLower(k) - switch lowKey { - case "host", "content-length": - // Host is :authority, already sent. - // Content-Length is automatic, set below. - continue - case "connection", "proxy-connection", "transfer-encoding", "upgrade", "keep-alive": - // Per 8.1.2.2 Connection-Specific Header - // Fields, don't send connection-specific - // fields. We have already checked if any - // are error-worthy so just ignore the rest. - continue - case "user-agent": - // Match Go's http1 behavior: at most one - // User-Agent. If set to nil or empty string, - // then omit it. Otherwise if not mentioned, - // include the default (below). - didUA = true - if len(vv) < 1 { - continue - } - vv = vv[:1] - if vv[0] == "" { - continue - } + // Do a first pass over the headers counting bytes to ensure + // we don't exceed cc.peerMaxHeaderListSize. This is done as a + // separate pass before encoding the headers to prevent + // modifying the hpack state. + hlSize := uint64(0) + enumerateHeaders(func(name, value string) { + hf := hpack.HeaderField{Name: name, Value: value} + hlSize += uint64(hf.Size()) + }) + + if hlSize > cc.peerMaxHeaderListSize { + return nil, errRequestHeaderListSize + } + + trace := httptrace.ContextClientTrace(req.Context()) + traceHeaders := traceHasWroteHeaderField(trace) + + // Header list size is ok. Write the headers. + enumerateHeaders(func(name, value string) { + name = strings.ToLower(name) + cc.writeHeader(name, value) + if traceHeaders { + traceWroteHeaderField(trace, name, value) } - for _, v := range vv { - cc.writeHeader(lowKey, v) - } - } - if shouldSendReqContentLength(req.Method, contentLength) { - cc.writeHeader("content-length", strconv.FormatInt(contentLength, 10)) - } - if addGzipHeader { - cc.writeHeader("accept-encoding", "gzip") - } - if !didUA { - cc.writeHeader("user-agent", defaultUserAgent) - } + }) + return cc.hbuf.Bytes(), nil } @@ -1271,17 +1517,29 @@ func shouldSendReqContentLength(method string, contentLength int64) bool { } // requires cc.mu be held. -func (cc *ClientConn) encodeTrailers(req *http.Request) []byte { +func (cc *ClientConn) encodeTrailers(req *http.Request) ([]byte, error) { cc.hbuf.Reset() + + hlSize := uint64(0) for k, vv := range req.Trailer { - // Transfer-Encoding, etc.. have already been filter at the + for _, v := range vv { + hf := hpack.HeaderField{Name: k, Value: v} + hlSize += uint64(hf.Size()) + } + } + if hlSize > cc.peerMaxHeaderListSize { + return nil, errRequestHeaderListSize + } + + for k, vv := range req.Trailer { + // Transfer-Encoding, etc.. have already been filtered at the // start of RoundTrip lowKey := strings.ToLower(k) for _, v := range vv { cc.writeHeader(lowKey, v) } } - return cc.hbuf.Bytes() + return cc.hbuf.Bytes(), nil } func (cc *ClientConn) writeHeader(name, value string) { @@ -1339,17 +1597,12 @@ func (cc *ClientConn) streamByID(id uint32, andRemove bool) *clientStream { // clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop. type clientConnReadLoop struct { cc *ClientConn - activeRes map[uint32]*clientStream // keyed by streamID closeWhenIdle bool } // readLoop runs in its own goroutine and reads and dispatches frames. func (cc *ClientConn) readLoop() { - rl := &clientConnReadLoop{ - cc: cc, - activeRes: make(map[uint32]*clientStream), - } - + rl := &clientConnReadLoop{cc: cc} defer rl.cleanup() cc.readerErr = rl.run() if ce, ok := cc.readerErr.(ConnectionError); ok { @@ -1404,10 +1657,8 @@ func (rl *clientConnReadLoop) cleanup() { } else if err == io.EOF { err = io.ErrUnexpectedEOF } - for _, cs := range rl.activeRes { - cs.bufPipe.CloseWithError(err) - } for _, cs := range cc.streams { + cs.bufPipe.CloseWithError(err) // no-op if already closed select { case cs.resc <- resAndError{err: err}: default: @@ -1485,7 +1736,7 @@ func (rl *clientConnReadLoop) run() error { } return err } - if rl.closeWhenIdle && gotReply && maybeIdle && len(rl.activeRes) == 0 { + if rl.closeWhenIdle && gotReply && maybeIdle { cc.closeIfIdle() } } @@ -1493,13 +1744,31 @@ func (rl *clientConnReadLoop) run() error { func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error { cc := rl.cc - cs := cc.streamByID(f.StreamID, f.StreamEnded()) + cs := cc.streamByID(f.StreamID, false) if cs == nil { // We'd get here if we canceled a request while the // server had its response still in flight. So if this // was just something we canceled, ignore it. return nil } + if f.StreamEnded() { + // Issue 20521: If the stream has ended, streamByID() causes + // clientStream.done to be closed, which causes the request's bodyWriter + // to be closed with an errStreamClosed, which may be received by + // clientConn.RoundTrip before the result of processing these headers. + // Deferring stream closure allows the header processing to occur first. + // clientConn.RoundTrip may still receive the bodyWriter error first, but + // the fix for issue 16102 prioritises any response. + // + // Issue 22413: If there is no request body, we should close the + // stream before writing to cs.resc so that the stream is closed + // immediately once RoundTrip returns. + if cs.req.Body != nil { + defer cc.forgetStreamID(f.StreamID) + } else { + cc.forgetStreamID(f.StreamID) + } + } if !cs.firstByte { if cs.trace != nil { // TODO(bradfitz): move first response byte earlier, @@ -1523,6 +1792,7 @@ func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error { } // Any other error type is a stream error. cs.cc.writeStreamReset(f.StreamID, ErrCodeProtocol, err) + cc.forgetStreamID(cs.ID) cs.resc <- resAndError{err: err} return nil // return nil from process* funcs to keep conn alive } @@ -1530,9 +1800,6 @@ func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error { // (nil, nil) special case. See handleResponse docs. return nil } - if res.Body != noBody { - rl.activeRes[cs.ID] = cs - } cs.resTrailer = &res.Trailer cs.resc <- resAndError{res: res} return nil @@ -1543,8 +1810,7 @@ func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error { // is the detail. // // As a special case, handleResponse may return (nil, nil) to skip the -// frame (currently only used for 100 expect continue). This special -// case is going away after Issue 13851 is fixed. +// frame (currently only used for 1xx responses). func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFrame) (*http.Response, error) { if f.Truncated { return nil, errResponseHeaderListSize @@ -1552,20 +1818,11 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra status := f.PseudoValue("status") if status == "" { - return nil, errors.New("missing status pseudo header") + return nil, errors.New("malformed response from server: missing status pseudo header") } statusCode, err := strconv.Atoi(status) if err != nil { - return nil, errors.New("malformed non-numeric status pseudo header") - } - - if statusCode == 100 { - traceGot100Continue(cs.trace) - if cs.on100 != nil { - cs.on100() // forces any write delay timer to fire - } - cs.pastHeaders = false // do it all again - return nil, nil + return nil, errors.New("malformed response from server: malformed non-numeric status pseudo header") } header := make(http.Header) @@ -1592,6 +1849,27 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra } } + if statusCode >= 100 && statusCode <= 199 { + cs.num1xx++ + const max1xxResponses = 5 // arbitrary bound on number of informational responses, same as net/http + if cs.num1xx > max1xxResponses { + return nil, errors.New("http2: too many 1xx informational responses") + } + if fn := cs.get1xxTraceFunc(); fn != nil { + if err := fn(statusCode, textproto.MIMEHeader(header)); err != nil { + return nil, err + } + } + if statusCode == 100 { + traceGot100Continue(cs.trace) + if cs.on100 != nil { + cs.on100() // forces any write delay timer to fire + } + } + cs.pastHeaders = false // do it all again + return nil, nil + } + streamEnded := f.StreamEnded() isHead := cs.req.Method == "HEAD" if !streamEnded || isHead { @@ -1624,7 +1902,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra res.Header.Del("Content-Length") res.ContentLength = -1 res.Body = &gzipReader{body: res.Body} - setResponseUncompressed(res) + res.Uncompressed = true } return res, nil } @@ -1789,7 +2067,23 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { } return nil } + if !cs.firstByte { + cc.logf("protocol error: received DATA before a HEADERS frame") + rl.endStreamError(cs, StreamError{ + StreamID: f.StreamID, + Code: ErrCodeProtocol, + }) + return nil + } if f.Length > 0 { + if cs.req.Method == "HEAD" && len(data) > 0 { + cc.logf("protocol error: received DATA on a HEAD request") + rl.endStreamError(cs, StreamError{ + StreamID: f.StreamID, + Code: ErrCodeProtocol, + }) + return nil + } // Check connection-level flow control. cc.mu.Lock() if cs.inflow.available() >= int32(f.Length) { @@ -1851,11 +2145,10 @@ func (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) { err = io.EOF code = cs.copyTrailers } - cs.bufPipe.closeWithErrorAndCode(err, code) - delete(rl.activeRes, cs.ID) if isConnectionCloseRequest(cs.req) { rl.closeWhenIdle = true } + cs.bufPipe.closeWithErrorAndCode(err, code) select { case cs.resc <- resAndError{err: err}: @@ -1903,6 +2196,8 @@ func (rl *clientConnReadLoop) processSettings(f *SettingsFrame) error { cc.maxFrameSize = s.Val case SettingMaxConcurrentStreams: cc.maxConcurrentStreams = s.Val + case SettingMaxHeaderListSize: + cc.peerMaxHeaderListSize = uint64(s.Val) case SettingInitialWindowSize: // Values above the maximum flow-control // window size of 2^31-1 MUST be treated as a @@ -1980,13 +2275,11 @@ func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error { cs.bufPipe.CloseWithError(err) cs.cc.cond.Broadcast() // wake up checkResetOrDone via clientStream.awaitFlowControl } - delete(rl.activeRes, cs.ID) return nil } // Ping sends a PING frame to the server and waits for the ack. -// Public implementation is in go17.go and not_go17.go -func (cc *ClientConn) ping(ctx contextContext) error { +func (cc *ClientConn) Ping(ctx context.Context) error { c := make(chan struct{}) // Generate a random payload var p [8]byte @@ -2069,6 +2362,7 @@ func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, err error) var ( errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit") + errRequestHeaderListSize = errors.New("http2: request header list larger than peer's advertised limit") errPseudoTrailers = errors.New("http2: invalid pseudo header in trailers") ) @@ -2162,7 +2456,7 @@ func (t *Transport) getBodyWriterState(cs *clientStream, body io.Reader) (s body } s.delay = t.expectContinueTimeout() if s.delay == 0 || - !httplex.HeaderValuesContainsToken( + !httpguts.HeaderValuesContainsToken( cs.req.Header["Expect"], "100-continue") { return @@ -2217,5 +2511,93 @@ func (s bodyWriterState) scheduleBodyWrite() { // isConnectionCloseRequest reports whether req should use its own // connection for a single request and then close the connection. func isConnectionCloseRequest(req *http.Request) bool { - return req.Close || httplex.HeaderValuesContainsToken(req.Header["Connection"], "close") + return req.Close || httpguts.HeaderValuesContainsToken(req.Header["Connection"], "close") +} + +// registerHTTPSProtocol calls Transport.RegisterProtocol but +// converting panics into errors. +func registerHTTPSProtocol(t *http.Transport, rt noDialH2RoundTripper) (err error) { + defer func() { + if e := recover(); e != nil { + err = fmt.Errorf("%v", e) + } + }() + t.RegisterProtocol("https", rt) + return nil +} + +// noDialH2RoundTripper is a RoundTripper which only tries to complete the request +// if there's already has a cached connection to the host. +// (The field is exported so it can be accessed via reflect from net/http; tested +// by TestNoDialH2RoundTripperType) +type noDialH2RoundTripper struct{ *Transport } + +func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + res, err := rt.Transport.RoundTrip(req) + if isNoCachedConnError(err) { + return nil, http.ErrSkipAltProtocol + } + return res, err +} + +func (t *Transport) idleConnTimeout() time.Duration { + if t.t1 != nil { + return t.t1.IdleConnTimeout + } + return 0 +} + +func traceGetConn(req *http.Request, hostPort string) { + trace := httptrace.ContextClientTrace(req.Context()) + if trace == nil || trace.GetConn == nil { + return + } + trace.GetConn(hostPort) +} + +func traceGotConn(req *http.Request, cc *ClientConn) { + trace := httptrace.ContextClientTrace(req.Context()) + if trace == nil || trace.GotConn == nil { + return + } + ci := httptrace.GotConnInfo{Conn: cc.tconn} + cc.mu.Lock() + ci.Reused = cc.nextStreamID > 1 + ci.WasIdle = len(cc.streams) == 0 && ci.Reused + if ci.WasIdle && !cc.lastActive.IsZero() { + ci.IdleTime = time.Now().Sub(cc.lastActive) + } + cc.mu.Unlock() + + trace.GotConn(ci) +} + +func traceWroteHeaders(trace *httptrace.ClientTrace) { + if trace != nil && trace.WroteHeaders != nil { + trace.WroteHeaders() + } +} + +func traceGot100Continue(trace *httptrace.ClientTrace) { + if trace != nil && trace.Got100Continue != nil { + trace.Got100Continue() + } +} + +func traceWait100Continue(trace *httptrace.ClientTrace) { + if trace != nil && trace.Wait100Continue != nil { + trace.Wait100Continue() + } +} + +func traceWroteRequest(trace *httptrace.ClientTrace, err error) { + if trace != nil && trace.WroteRequest != nil { + trace.WroteRequest(httptrace.WroteRequestInfo{Err: err}) + } +} + +func traceFirstResponseByte(trace *httptrace.ClientTrace) { + if trace != nil && trace.GotFirstResponseByte != nil { + trace.GotFirstResponseByte() + } } diff --git a/vendor/golang.org/x/net/http2/write.go b/vendor/golang.org/x/net/http2/write.go index 6b0dfae31..3849bc263 100644 --- a/vendor/golang.org/x/net/http2/write.go +++ b/vendor/golang.org/x/net/http2/write.go @@ -10,10 +10,9 @@ import ( "log" "net/http" "net/url" - "time" + "golang.org/x/net/http/httpguts" "golang.org/x/net/http2/hpack" - "golang.org/x/net/lex/httplex" ) // writeFramer is implemented by any type that is used to write frames. @@ -90,11 +89,7 @@ type writeGoAway struct { func (p *writeGoAway) writeFrame(ctx writeContext) error { err := ctx.Framer().WriteGoAway(p.maxStreamID, p.code, nil) - if p.code != 0 { - ctx.Flush() // ignore error: we're hanging up on them anyway - time.Sleep(50 * time.Millisecond) - ctx.CloseConn() - } + ctx.Flush() // ignore error: we're hanging up on them anyway return err } @@ -204,7 +199,7 @@ func (w *writeResHeaders) staysWithinBuffer(max int) bool { // TODO: this is a common one. It'd be nice to return true // here and get into the fast path if we could be clever and // calculate the size fast enough, or at least a conservative - // uppper bound that usually fires. (Maybe if w.h and + // upper bound that usually fires. (Maybe if w.h and // w.trailers are nil, so we don't need to enumerate it.) // Otherwise I'm afraid that just calculating the length to // answer this question would be slower than the ~2µs benefit. @@ -334,7 +329,7 @@ func (wu writeWindowUpdate) writeFrame(ctx writeContext) error { } // encodeHeaders encodes an http.Header. If keys is not nil, then (k, h[k]) -// is encoded only only if k is in keys. +// is encoded only if k is in keys. func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) { if keys == nil { sorter := sorterPool.Get().(*sorter) @@ -355,7 +350,7 @@ func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) { } isTE := k == "transfer-encoding" for _, v := range vv { - if !httplex.ValidHeaderFieldValue(v) { + if !httpguts.ValidHeaderFieldValue(v) { // TODO: return an error? golang.org/issue/14048 // For now just omit it. continue diff --git a/vendor/golang.org/x/net/idna/idna.go b/vendor/golang.org/x/net/idna/idna.go index eb2473507..346fe4423 100644 --- a/vendor/golang.org/x/net/idna/idna.go +++ b/vendor/golang.org/x/net/idna/idna.go @@ -21,6 +21,7 @@ import ( "unicode/utf8" "golang.org/x/text/secure/bidirule" + "golang.org/x/text/unicode/bidi" "golang.org/x/text/unicode/norm" ) @@ -68,7 +69,7 @@ func VerifyDNSLength(verify bool) Option { } // RemoveLeadingDots removes leading label separators. Leading runes that map to -// dots, such as U+3002, are removed as well. +// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well. // // This is the behavior suggested by the UTS #46 and is adopted by some // browsers. @@ -92,7 +93,7 @@ func ValidateLabels(enable bool) Option { } } -// StrictDomainName limits the set of permissable ASCII characters to those +// StrictDomainName limits the set of permissible ASCII characters to those // allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the // hyphen). This is set by default for MapForLookup and ValidateForRegistration. // @@ -142,7 +143,6 @@ func MapForLookup() Option { o.mapping = validateAndMap StrictDomainName(true)(o) ValidateLabels(true)(o) - RemoveLeadingDots(true)(o) } } @@ -160,14 +160,14 @@ type options struct { // mapping implements a validation and mapping step as defined in RFC 5895 // or UTS 46, tailored to, for example, domain registration or lookup. - mapping func(p *Profile, s string) (string, error) + mapping func(p *Profile, s string) (mapped string, isBidi bool, err error) // bidirule, if specified, checks whether s conforms to the Bidi Rule // defined in RFC 5893. bidirule func(s string) bool } -// A Profile defines the configuration of a IDNA mapper. +// A Profile defines the configuration of an IDNA mapper. type Profile struct { options } @@ -251,23 +251,21 @@ var ( punycode = &Profile{} lookup = &Profile{options{ - transitional: true, - useSTD3Rules: true, - validateLabels: true, - removeLeadingDots: true, - trie: trie, - fromPuny: validateFromPunycode, - mapping: validateAndMap, - bidirule: bidirule.ValidString, + transitional: true, + useSTD3Rules: true, + validateLabels: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateAndMap, + bidirule: bidirule.ValidString, }} display = &Profile{options{ - useSTD3Rules: true, - validateLabels: true, - removeLeadingDots: true, - trie: trie, - fromPuny: validateFromPunycode, - mapping: validateAndMap, - bidirule: bidirule.ValidString, + useSTD3Rules: true, + validateLabels: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateAndMap, + bidirule: bidirule.ValidString, }} registration = &Profile{options{ useSTD3Rules: true, @@ -302,14 +300,16 @@ func (e runeError) Error() string { // see http://www.unicode.org/reports/tr46. func (p *Profile) process(s string, toASCII bool) (string, error) { var err error + var isBidi bool if p.mapping != nil { - s, err = p.mapping(p, s) + s, isBidi, err = p.mapping(p, s) } // Remove leading empty labels. if p.removeLeadingDots { for ; len(s) > 0 && s[0] == '.'; s = s[1:] { } } + // TODO: allow for a quick check of the tables data. // It seems like we should only create this error on ToASCII, but the // UTS 46 conformance tests suggests we should always check this. if err == nil && p.verifyDNSLength && s == "" { @@ -335,6 +335,7 @@ func (p *Profile) process(s string, toASCII bool) (string, error) { // Spec says keep the old label. continue } + isBidi = isBidi || bidirule.DirectionString(u) != bidi.LeftToRight labels.set(u) if err == nil && p.validateLabels { err = p.fromPuny(p, u) @@ -349,6 +350,14 @@ func (p *Profile) process(s string, toASCII bool) (string, error) { err = p.validateLabel(label) } } + if isBidi && p.bidirule != nil && err == nil { + for labels.reset(); !labels.done(); labels.next() { + if !p.bidirule(labels.label()) { + err = &labelError{s, "B"} + break + } + } + } if toASCII { for labels.reset(); !labels.done(); labels.next() { label := labels.label() @@ -380,16 +389,26 @@ func (p *Profile) process(s string, toASCII bool) (string, error) { return s, err } -func normalize(p *Profile, s string) (string, error) { - return norm.NFC.String(s), nil +func normalize(p *Profile, s string) (mapped string, isBidi bool, err error) { + // TODO: consider first doing a quick check to see if any of these checks + // need to be done. This will make it slower in the general case, but + // faster in the common case. + mapped = norm.NFC.String(s) + isBidi = bidirule.DirectionString(mapped) == bidi.RightToLeft + return mapped, isBidi, nil } -func validateRegistration(p *Profile, s string) (string, error) { +func validateRegistration(p *Profile, s string) (idem string, bidi bool, err error) { + // TODO: filter need for normalization in loop below. if !norm.NFC.IsNormalString(s) { - return s, &labelError{s, "V1"} + return s, false, &labelError{s, "V1"} } for i := 0; i < len(s); { v, sz := trie.lookupString(s[i:]) + if sz == 0 { + return s, bidi, runeError(utf8.RuneError) + } + bidi = bidi || info(v).isBidi(s[i:]) // Copy bytes not copied so far. switch p.simplify(info(v).category()) { // TODO: handle the NV8 defined in the Unicode idna data set to allow @@ -397,21 +416,50 @@ func validateRegistration(p *Profile, s string) (string, error) { case valid, deviation: case disallowed, mapped, unknown, ignored: r, _ := utf8.DecodeRuneInString(s[i:]) - return s, runeError(r) + return s, bidi, runeError(r) } i += sz } - return s, nil + return s, bidi, nil } -func validateAndMap(p *Profile, s string) (string, error) { +func (c info) isBidi(s string) bool { + if !c.isMapped() { + return c&attributesMask == rtl + } + // TODO: also store bidi info for mapped data. This is possible, but a bit + // cumbersome and not for the common case. + p, _ := bidi.LookupString(s) + switch p.Class() { + case bidi.R, bidi.AL, bidi.AN: + return true + } + return false +} + +func validateAndMap(p *Profile, s string) (vm string, bidi bool, err error) { var ( - err error - b []byte - k int + b []byte + k int ) + // combinedInfoBits contains the or-ed bits of all runes. We use this + // to derive the mayNeedNorm bit later. This may trigger normalization + // overeagerly, but it will not do so in the common case. The end result + // is another 10% saving on BenchmarkProfile for the common case. + var combinedInfoBits info for i := 0; i < len(s); { v, sz := trie.lookupString(s[i:]) + if sz == 0 { + b = append(b, s[k:i]...) + b = append(b, "\ufffd"...) + k = len(s) + if err == nil { + err = runeError(utf8.RuneError) + } + break + } + combinedInfoBits |= info(v) + bidi = bidi || info(v).isBidi(s[i:]) start := i i += sz // Copy bytes not copied so far. @@ -438,7 +486,9 @@ func validateAndMap(p *Profile, s string) (string, error) { } if k == 0 { // No changes so far. - s = norm.NFC.String(s) + if combinedInfoBits&mayNeedNorm != 0 { + s = norm.NFC.String(s) + } } else { b = append(b, s[k:]...) if norm.NFC.QuickSpan(b) != len(b) { @@ -447,7 +497,7 @@ func validateAndMap(p *Profile, s string) (string, error) { // TODO: the punycode converters require strings as input. s = string(b) } - return s, err + return s, bidi, err } // A labelIter allows iterating over domain name labels. @@ -542,8 +592,13 @@ func validateFromPunycode(p *Profile, s string) error { if !norm.NFC.IsNormalString(s) { return &labelError{s, "V1"} } + // TODO: detect whether string may have to be normalized in the following + // loop. for i := 0; i < len(s); { v, sz := trie.lookupString(s[i:]) + if sz == 0 { + return runeError(utf8.RuneError) + } if c := p.simplify(info(v).category()); c != valid && c != deviation { return &labelError{s, "V6"} } @@ -616,16 +671,13 @@ var joinStates = [][numJoinTypes]joinState{ // validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are // already implicitly satisfied by the overall implementation. -func (p *Profile) validateLabel(s string) error { +func (p *Profile) validateLabel(s string) (err error) { if s == "" { if p.verifyDNSLength { return &labelError{s, "A4"} } return nil } - if p.bidirule != nil && !p.bidirule(s) { - return &labelError{s, "B"} - } if !p.validateLabels { return nil } diff --git a/vendor/golang.org/x/net/idna/tables.go b/vendor/golang.org/x/net/idna/tables.go index d2819345f..f910b2691 100644 --- a/vendor/golang.org/x/net/idna/tables.go +++ b/vendor/golang.org/x/net/idna/tables.go @@ -3,7 +3,7 @@ package idna // UnicodeVersion is the Unicode version from which the tables in this package are derived. -const UnicodeVersion = "9.0.0" +const UnicodeVersion = "10.0.0" var mappings string = "" + // Size: 8176 bytes "\x00\x01 \x03 ̈\x01a\x03 ̄\x012\x013\x03 ́\x03 ̧\x011\x01o\x051⁄4\x051⁄2" + @@ -544,7 +544,7 @@ func (t *idnaTrie) lookupStringUnsafe(s string) uint16 { return 0 } -// idnaTrie. Total size: 28496 bytes (27.83 KiB). Checksum: 43288b883596640e. +// idnaTrie. Total size: 29052 bytes (28.37 KiB). Checksum: ef06e7ecc26f36dd. type idnaTrie struct{} func newIdnaTrie(i int) *idnaTrie { @@ -554,17 +554,17 @@ func newIdnaTrie(i int) *idnaTrie { // lookupValue determines the type of block n and looks up the value for b. func (t *idnaTrie) lookupValue(n uint32, b byte) uint16 { switch { - case n < 123: + case n < 125: return uint16(idnaValues[n<<6+uint32(b)]) default: - n -= 123 + n -= 125 return uint16(idnaSparse.lookup(n, b)) } } -// idnaValues: 125 blocks, 8000 entries, 16000 bytes +// idnaValues: 127 blocks, 8128 entries, 16256 bytes // The third block is the zero block. -var idnaValues = [8000]uint16{ +var idnaValues = [8128]uint16{ // Block 0x0, offset 0x0 0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080, 0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080, @@ -675,14 +675,14 @@ var idnaValues = [8000]uint16{ 0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018, 0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018, // Block 0xa, offset 0x280 - 0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x1308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d, - 0x286: 0x1308, 0x287: 0x1308, 0x288: 0x1308, 0x289: 0x1308, 0x28a: 0x1308, 0x28b: 0x1308, - 0x28c: 0x1308, 0x28d: 0x1308, 0x28e: 0x1308, 0x28f: 0x13c0, 0x290: 0x1308, 0x291: 0x1308, - 0x292: 0x1308, 0x293: 0x1308, 0x294: 0x1308, 0x295: 0x1308, 0x296: 0x1308, 0x297: 0x1308, - 0x298: 0x1308, 0x299: 0x1308, 0x29a: 0x1308, 0x29b: 0x1308, 0x29c: 0x1308, 0x29d: 0x1308, - 0x29e: 0x1308, 0x29f: 0x1308, 0x2a0: 0x1308, 0x2a1: 0x1308, 0x2a2: 0x1308, 0x2a3: 0x1308, - 0x2a4: 0x1308, 0x2a5: 0x1308, 0x2a6: 0x1308, 0x2a7: 0x1308, 0x2a8: 0x1308, 0x2a9: 0x1308, - 0x2aa: 0x1308, 0x2ab: 0x1308, 0x2ac: 0x1308, 0x2ad: 0x1308, 0x2ae: 0x1308, 0x2af: 0x1308, + 0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d, + 0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308, + 0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308, + 0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308, + 0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308, + 0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308, + 0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308, + 0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308, 0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008, 0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008, 0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d, @@ -723,8 +723,8 @@ var idnaValues = [8000]uint16{ 0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008, 0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008, // Block 0xe, offset 0x380 - 0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x1308, 0x384: 0x1308, 0x385: 0x1308, - 0x386: 0x1308, 0x387: 0x1308, 0x388: 0x1318, 0x389: 0x1318, 0x38a: 0xe00d, 0x38b: 0x0008, + 0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308, + 0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008, 0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008, 0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008, 0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008, @@ -759,129 +759,129 @@ var idnaValues = [8000]uint16{ 0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5, 0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5, // Block 0x11, offset 0x440 - 0x440: 0x0040, 0x441: 0x0040, 0x442: 0x0040, 0x443: 0x0040, 0x444: 0x0040, 0x445: 0x0040, - 0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0018, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0018, - 0x44c: 0x0018, 0x44d: 0x0018, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x1308, 0x451: 0x1308, - 0x452: 0x1308, 0x453: 0x1308, 0x454: 0x1308, 0x455: 0x1308, 0x456: 0x1308, 0x457: 0x1308, - 0x458: 0x1308, 0x459: 0x1308, 0x45a: 0x1308, 0x45b: 0x0018, 0x45c: 0x0340, 0x45d: 0x0040, - 0x45e: 0x0018, 0x45f: 0x0018, 0x460: 0x0208, 0x461: 0x0008, 0x462: 0x0408, 0x463: 0x0408, - 0x464: 0x0408, 0x465: 0x0408, 0x466: 0x0208, 0x467: 0x0408, 0x468: 0x0208, 0x469: 0x0408, - 0x46a: 0x0208, 0x46b: 0x0208, 0x46c: 0x0208, 0x46d: 0x0208, 0x46e: 0x0208, 0x46f: 0x0408, - 0x470: 0x0408, 0x471: 0x0408, 0x472: 0x0408, 0x473: 0x0208, 0x474: 0x0208, 0x475: 0x0208, - 0x476: 0x0208, 0x477: 0x0208, 0x478: 0x0208, 0x479: 0x0208, 0x47a: 0x0208, 0x47b: 0x0208, - 0x47c: 0x0208, 0x47d: 0x0208, 0x47e: 0x0208, 0x47f: 0x0208, + 0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840, + 0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818, + 0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308, + 0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308, + 0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040, + 0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08, + 0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08, + 0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08, + 0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08, + 0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08, + 0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08, // Block 0x12, offset 0x480 - 0x480: 0x0408, 0x481: 0x0208, 0x482: 0x0208, 0x483: 0x0408, 0x484: 0x0408, 0x485: 0x0408, - 0x486: 0x0408, 0x487: 0x0408, 0x488: 0x0408, 0x489: 0x0408, 0x48a: 0x0408, 0x48b: 0x0408, - 0x48c: 0x0208, 0x48d: 0x0408, 0x48e: 0x0208, 0x48f: 0x0408, 0x490: 0x0208, 0x491: 0x0208, - 0x492: 0x0408, 0x493: 0x0408, 0x494: 0x0018, 0x495: 0x0408, 0x496: 0x1308, 0x497: 0x1308, - 0x498: 0x1308, 0x499: 0x1308, 0x49a: 0x1308, 0x49b: 0x1308, 0x49c: 0x1308, 0x49d: 0x0040, - 0x49e: 0x0018, 0x49f: 0x1308, 0x4a0: 0x1308, 0x4a1: 0x1308, 0x4a2: 0x1308, 0x4a3: 0x1308, - 0x4a4: 0x1308, 0x4a5: 0x0008, 0x4a6: 0x0008, 0x4a7: 0x1308, 0x4a8: 0x1308, 0x4a9: 0x0018, - 0x4aa: 0x1308, 0x4ab: 0x1308, 0x4ac: 0x1308, 0x4ad: 0x1308, 0x4ae: 0x0408, 0x4af: 0x0408, - 0x4b0: 0x0008, 0x4b1: 0x0008, 0x4b2: 0x0008, 0x4b3: 0x0008, 0x4b4: 0x0008, 0x4b5: 0x0008, - 0x4b6: 0x0008, 0x4b7: 0x0008, 0x4b8: 0x0008, 0x4b9: 0x0008, 0x4ba: 0x0208, 0x4bb: 0x0208, - 0x4bc: 0x0208, 0x4bd: 0x0008, 0x4be: 0x0008, 0x4bf: 0x0208, + 0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08, + 0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308, + 0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308, + 0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308, + 0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308, + 0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808, + 0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808, + 0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08, + 0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429, + 0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08, + 0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08, // Block 0x13, offset 0x4c0 - 0x4c0: 0x0018, 0x4c1: 0x0018, 0x4c2: 0x0018, 0x4c3: 0x0018, 0x4c4: 0x0018, 0x4c5: 0x0018, - 0x4c6: 0x0018, 0x4c7: 0x0018, 0x4c8: 0x0018, 0x4c9: 0x0018, 0x4ca: 0x0018, 0x4cb: 0x0018, - 0x4cc: 0x0018, 0x4cd: 0x0018, 0x4ce: 0x0040, 0x4cf: 0x0340, 0x4d0: 0x0408, 0x4d1: 0x1308, - 0x4d2: 0x0208, 0x4d3: 0x0208, 0x4d4: 0x0208, 0x4d5: 0x0408, 0x4d6: 0x0408, 0x4d7: 0x0408, - 0x4d8: 0x0408, 0x4d9: 0x0408, 0x4da: 0x0208, 0x4db: 0x0208, 0x4dc: 0x0208, 0x4dd: 0x0208, - 0x4de: 0x0408, 0x4df: 0x0208, 0x4e0: 0x0208, 0x4e1: 0x0208, 0x4e2: 0x0208, 0x4e3: 0x0208, - 0x4e4: 0x0208, 0x4e5: 0x0208, 0x4e6: 0x0208, 0x4e7: 0x0208, 0x4e8: 0x0408, 0x4e9: 0x0208, - 0x4ea: 0x0408, 0x4eb: 0x0208, 0x4ec: 0x0408, 0x4ed: 0x0208, 0x4ee: 0x0208, 0x4ef: 0x0408, - 0x4f0: 0x1308, 0x4f1: 0x1308, 0x4f2: 0x1308, 0x4f3: 0x1308, 0x4f4: 0x1308, 0x4f5: 0x1308, - 0x4f6: 0x1308, 0x4f7: 0x1308, 0x4f8: 0x1308, 0x4f9: 0x1308, 0x4fa: 0x1308, 0x4fb: 0x1308, - 0x4fc: 0x1308, 0x4fd: 0x1308, 0x4fe: 0x1308, 0x4ff: 0x1308, + 0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08, + 0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08, + 0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08, + 0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308, + 0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840, + 0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308, + 0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018, + 0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08, + 0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008, + 0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08, + 0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08, // Block 0x14, offset 0x500 - 0x500: 0x1008, 0x501: 0x1308, 0x502: 0x1308, 0x503: 0x1308, 0x504: 0x1308, 0x505: 0x1308, - 0x506: 0x1308, 0x507: 0x1308, 0x508: 0x1308, 0x509: 0x1008, 0x50a: 0x1008, 0x50b: 0x1008, - 0x50c: 0x1008, 0x50d: 0x1b08, 0x50e: 0x1008, 0x50f: 0x1008, 0x510: 0x0008, 0x511: 0x1308, - 0x512: 0x1308, 0x513: 0x1308, 0x514: 0x1308, 0x515: 0x1308, 0x516: 0x1308, 0x517: 0x1308, - 0x518: 0x04c9, 0x519: 0x0501, 0x51a: 0x0539, 0x51b: 0x0571, 0x51c: 0x05a9, 0x51d: 0x05e1, - 0x51e: 0x0619, 0x51f: 0x0651, 0x520: 0x0008, 0x521: 0x0008, 0x522: 0x1308, 0x523: 0x1308, - 0x524: 0x0018, 0x525: 0x0018, 0x526: 0x0008, 0x527: 0x0008, 0x528: 0x0008, 0x529: 0x0008, - 0x52a: 0x0008, 0x52b: 0x0008, 0x52c: 0x0008, 0x52d: 0x0008, 0x52e: 0x0008, 0x52f: 0x0008, - 0x530: 0x0018, 0x531: 0x0008, 0x532: 0x0008, 0x533: 0x0008, 0x534: 0x0008, 0x535: 0x0008, - 0x536: 0x0008, 0x537: 0x0008, 0x538: 0x0008, 0x539: 0x0008, 0x53a: 0x0008, 0x53b: 0x0008, - 0x53c: 0x0008, 0x53d: 0x0008, 0x53e: 0x0008, 0x53f: 0x0008, + 0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818, + 0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818, + 0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308, + 0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08, + 0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08, + 0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08, + 0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08, + 0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08, + 0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308, + 0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308, + 0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308, // Block 0x15, offset 0x540 - 0x540: 0x0008, 0x541: 0x1308, 0x542: 0x1008, 0x543: 0x1008, 0x544: 0x0040, 0x545: 0x0008, - 0x546: 0x0008, 0x547: 0x0008, 0x548: 0x0008, 0x549: 0x0008, 0x54a: 0x0008, 0x54b: 0x0008, - 0x54c: 0x0008, 0x54d: 0x0040, 0x54e: 0x0040, 0x54f: 0x0008, 0x550: 0x0008, 0x551: 0x0040, - 0x552: 0x0040, 0x553: 0x0008, 0x554: 0x0008, 0x555: 0x0008, 0x556: 0x0008, 0x557: 0x0008, - 0x558: 0x0008, 0x559: 0x0008, 0x55a: 0x0008, 0x55b: 0x0008, 0x55c: 0x0008, 0x55d: 0x0008, - 0x55e: 0x0008, 0x55f: 0x0008, 0x560: 0x0008, 0x561: 0x0008, 0x562: 0x0008, 0x563: 0x0008, - 0x564: 0x0008, 0x565: 0x0008, 0x566: 0x0008, 0x567: 0x0008, 0x568: 0x0008, 0x569: 0x0040, - 0x56a: 0x0008, 0x56b: 0x0008, 0x56c: 0x0008, 0x56d: 0x0008, 0x56e: 0x0008, 0x56f: 0x0008, - 0x570: 0x0008, 0x571: 0x0040, 0x572: 0x0008, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040, - 0x576: 0x0008, 0x577: 0x0008, 0x578: 0x0008, 0x579: 0x0008, 0x57a: 0x0040, 0x57b: 0x0040, - 0x57c: 0x1308, 0x57d: 0x0008, 0x57e: 0x1008, 0x57f: 0x1008, + 0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08, + 0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08, + 0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08, + 0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0808, 0x557: 0x0808, + 0x558: 0x0808, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040, + 0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08, + 0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08, + 0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040, + 0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040, + 0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040, + 0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040, // Block 0x16, offset 0x580 - 0x580: 0x1008, 0x581: 0x1308, 0x582: 0x1308, 0x583: 0x1308, 0x584: 0x1308, 0x585: 0x0040, - 0x586: 0x0040, 0x587: 0x1008, 0x588: 0x1008, 0x589: 0x0040, 0x58a: 0x0040, 0x58b: 0x1008, - 0x58c: 0x1008, 0x58d: 0x1b08, 0x58e: 0x0008, 0x58f: 0x0040, 0x590: 0x0040, 0x591: 0x0040, - 0x592: 0x0040, 0x593: 0x0040, 0x594: 0x0040, 0x595: 0x0040, 0x596: 0x0040, 0x597: 0x1008, - 0x598: 0x0040, 0x599: 0x0040, 0x59a: 0x0040, 0x59b: 0x0040, 0x59c: 0x0689, 0x59d: 0x06c1, - 0x59e: 0x0040, 0x59f: 0x06f9, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x1308, 0x5a3: 0x1308, - 0x5a4: 0x0040, 0x5a5: 0x0040, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008, + 0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308, + 0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008, + 0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308, + 0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308, + 0x598: 0x04c9, 0x599: 0x0501, 0x59a: 0x0539, 0x59b: 0x0571, 0x59c: 0x05a9, 0x59d: 0x05e1, + 0x59e: 0x0619, 0x59f: 0x0651, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308, + 0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008, 0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008, - 0x5b0: 0x0008, 0x5b1: 0x0008, 0x5b2: 0x0018, 0x5b3: 0x0018, 0x5b4: 0x0018, 0x5b5: 0x0018, - 0x5b6: 0x0018, 0x5b7: 0x0018, 0x5b8: 0x0018, 0x5b9: 0x0018, 0x5ba: 0x0018, 0x5bb: 0x0018, - 0x5bc: 0x0040, 0x5bd: 0x0040, 0x5be: 0x0040, 0x5bf: 0x0040, + 0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008, + 0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008, + 0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008, // Block 0x17, offset 0x5c0 - 0x5c0: 0x0040, 0x5c1: 0x1308, 0x5c2: 0x1308, 0x5c3: 0x1008, 0x5c4: 0x0040, 0x5c5: 0x0008, - 0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0040, - 0x5cc: 0x0040, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040, + 0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008, + 0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008, + 0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040, 0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008, 0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008, 0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008, 0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040, 0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008, - 0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0731, 0x5f4: 0x0040, 0x5f5: 0x0008, - 0x5f6: 0x0769, 0x5f7: 0x0040, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040, - 0x5fc: 0x1308, 0x5fd: 0x0040, 0x5fe: 0x1008, 0x5ff: 0x1008, + 0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040, + 0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040, + 0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008, // Block 0x18, offset 0x600 - 0x600: 0x1008, 0x601: 0x1308, 0x602: 0x1308, 0x603: 0x0040, 0x604: 0x0040, 0x605: 0x0040, - 0x606: 0x0040, 0x607: 0x1308, 0x608: 0x1308, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x1308, - 0x60c: 0x1308, 0x60d: 0x1b08, 0x60e: 0x0040, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x1308, - 0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x0040, - 0x618: 0x0040, 0x619: 0x07a1, 0x61a: 0x07d9, 0x61b: 0x0811, 0x61c: 0x0008, 0x61d: 0x0040, - 0x61e: 0x0849, 0x61f: 0x0040, 0x620: 0x0040, 0x621: 0x0040, 0x622: 0x0040, 0x623: 0x0040, + 0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040, + 0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008, + 0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040, + 0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008, + 0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0689, 0x61d: 0x06c1, + 0x61e: 0x0040, 0x61f: 0x06f9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308, 0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008, 0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008, - 0x630: 0x1308, 0x631: 0x1308, 0x632: 0x0008, 0x633: 0x0008, 0x634: 0x0008, 0x635: 0x1308, - 0x636: 0x0040, 0x637: 0x0040, 0x638: 0x0040, 0x639: 0x0040, 0x63a: 0x0040, 0x63b: 0x0040, - 0x63c: 0x0040, 0x63d: 0x0040, 0x63e: 0x0040, 0x63f: 0x0040, + 0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018, + 0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018, + 0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x0040, 0x63f: 0x0040, // Block 0x19, offset 0x640 - 0x640: 0x0040, 0x641: 0x1308, 0x642: 0x1308, 0x643: 0x1008, 0x644: 0x0040, 0x645: 0x0008, - 0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0008, - 0x64c: 0x0008, 0x64d: 0x0008, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0008, + 0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008, + 0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040, + 0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040, 0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008, 0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008, 0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008, 0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040, 0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008, - 0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0008, 0x674: 0x0040, 0x675: 0x0008, - 0x676: 0x0008, 0x677: 0x0008, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040, - 0x67c: 0x1308, 0x67d: 0x0008, 0x67e: 0x1008, 0x67f: 0x1008, + 0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0731, 0x674: 0x0040, 0x675: 0x0008, + 0x676: 0x0769, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040, + 0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008, // Block 0x1a, offset 0x680 - 0x680: 0x1008, 0x681: 0x1308, 0x682: 0x1308, 0x683: 0x1308, 0x684: 0x1308, 0x685: 0x1308, - 0x686: 0x0040, 0x687: 0x1308, 0x688: 0x1308, 0x689: 0x1008, 0x68a: 0x0040, 0x68b: 0x1008, - 0x68c: 0x1008, 0x68d: 0x1b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0008, 0x691: 0x0040, + 0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040, + 0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308, + 0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308, 0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040, - 0x698: 0x0040, 0x699: 0x0040, 0x69a: 0x0040, 0x69b: 0x0040, 0x69c: 0x0040, 0x69d: 0x0040, - 0x69e: 0x0040, 0x69f: 0x0040, 0x6a0: 0x0008, 0x6a1: 0x0008, 0x6a2: 0x1308, 0x6a3: 0x1308, + 0x698: 0x0040, 0x699: 0x07a1, 0x69a: 0x07d9, 0x69b: 0x0811, 0x69c: 0x0008, 0x69d: 0x0040, + 0x69e: 0x0849, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040, 0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008, 0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008, - 0x6b0: 0x0018, 0x6b1: 0x0018, 0x6b2: 0x0040, 0x6b3: 0x0040, 0x6b4: 0x0040, 0x6b5: 0x0040, - 0x6b6: 0x0040, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0008, 0x6ba: 0x0040, 0x6bb: 0x0040, + 0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308, + 0x6b6: 0x0040, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040, 0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040, // Block 0x1b, offset 0x6c0 - 0x6c0: 0x0040, 0x6c1: 0x1308, 0x6c2: 0x1008, 0x6c3: 0x1008, 0x6c4: 0x0040, 0x6c5: 0x0008, + 0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008, 0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008, - 0x6cc: 0x0008, 0x6cd: 0x0040, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0040, + 0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008, 0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008, 0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008, 0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008, @@ -889,1457 +889,1490 @@ var idnaValues = [8000]uint16{ 0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008, 0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008, 0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040, - 0x6fc: 0x1308, 0x6fd: 0x0008, 0x6fe: 0x1008, 0x6ff: 0x1308, + 0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008, // Block 0x1c, offset 0x700 - 0x700: 0x1008, 0x701: 0x1308, 0x702: 0x1308, 0x703: 0x1308, 0x704: 0x1308, 0x705: 0x0040, - 0x706: 0x0040, 0x707: 0x1008, 0x708: 0x1008, 0x709: 0x0040, 0x70a: 0x0040, 0x70b: 0x1008, - 0x70c: 0x1008, 0x70d: 0x1b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0040, 0x711: 0x0040, - 0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x1308, 0x717: 0x1008, - 0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0881, 0x71d: 0x08b9, - 0x71e: 0x0040, 0x71f: 0x0008, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x1308, 0x723: 0x1308, + 0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308, + 0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008, + 0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040, + 0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040, + 0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040, + 0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308, 0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008, 0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008, - 0x730: 0x0018, 0x731: 0x0008, 0x732: 0x0018, 0x733: 0x0018, 0x734: 0x0018, 0x735: 0x0018, - 0x736: 0x0018, 0x737: 0x0018, 0x738: 0x0040, 0x739: 0x0040, 0x73a: 0x0040, 0x73b: 0x0040, - 0x73c: 0x0040, 0x73d: 0x0040, 0x73e: 0x0040, 0x73f: 0x0040, + 0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040, + 0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308, + 0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308, // Block 0x1d, offset 0x740 - 0x740: 0x0040, 0x741: 0x0040, 0x742: 0x1308, 0x743: 0x0008, 0x744: 0x0040, 0x745: 0x0008, - 0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0040, - 0x74c: 0x0040, 0x74d: 0x0040, 0x74e: 0x0008, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040, - 0x752: 0x0008, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0040, 0x757: 0x0040, - 0x758: 0x0040, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0040, 0x75c: 0x0008, 0x75d: 0x0040, - 0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0040, 0x761: 0x0040, 0x762: 0x0040, 0x763: 0x0008, - 0x764: 0x0008, 0x765: 0x0040, 0x766: 0x0040, 0x767: 0x0040, 0x768: 0x0008, 0x769: 0x0008, - 0x76a: 0x0008, 0x76b: 0x0040, 0x76c: 0x0040, 0x76d: 0x0040, 0x76e: 0x0008, 0x76f: 0x0008, - 0x770: 0x0008, 0x771: 0x0008, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0008, 0x775: 0x0008, + 0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008, + 0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008, + 0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040, + 0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008, + 0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008, + 0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008, + 0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040, + 0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008, + 0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008, 0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040, - 0x77c: 0x0040, 0x77d: 0x0040, 0x77e: 0x1008, 0x77f: 0x1008, + 0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308, // Block 0x1e, offset 0x780 - 0x780: 0x1308, 0x781: 0x1008, 0x782: 0x1008, 0x783: 0x1008, 0x784: 0x1008, 0x785: 0x0040, - 0x786: 0x1308, 0x787: 0x1308, 0x788: 0x1308, 0x789: 0x0040, 0x78a: 0x1308, 0x78b: 0x1308, - 0x78c: 0x1308, 0x78d: 0x1b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040, - 0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x1308, 0x796: 0x1308, 0x797: 0x0040, - 0x798: 0x0008, 0x799: 0x0008, 0x79a: 0x0008, 0x79b: 0x0040, 0x79c: 0x0040, 0x79d: 0x0040, - 0x79e: 0x0040, 0x79f: 0x0040, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x1308, 0x7a3: 0x1308, + 0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040, + 0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008, + 0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040, + 0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x0040, 0x796: 0x3308, 0x797: 0x3008, + 0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x0881, 0x79d: 0x08b9, + 0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308, 0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008, 0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008, - 0x7b0: 0x0040, 0x7b1: 0x0040, 0x7b2: 0x0040, 0x7b3: 0x0040, 0x7b4: 0x0040, 0x7b5: 0x0040, - 0x7b6: 0x0040, 0x7b7: 0x0040, 0x7b8: 0x0018, 0x7b9: 0x0018, 0x7ba: 0x0018, 0x7bb: 0x0018, - 0x7bc: 0x0018, 0x7bd: 0x0018, 0x7be: 0x0018, 0x7bf: 0x0018, + 0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018, + 0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040, + 0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040, // Block 0x1f, offset 0x7c0 - 0x7c0: 0x0008, 0x7c1: 0x1308, 0x7c2: 0x1008, 0x7c3: 0x1008, 0x7c4: 0x0040, 0x7c5: 0x0008, - 0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0008, - 0x7cc: 0x0008, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040, - 0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0008, 0x7d7: 0x0008, - 0x7d8: 0x0008, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0008, 0x7dc: 0x0008, 0x7dd: 0x0008, - 0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0008, 0x7e1: 0x0008, 0x7e2: 0x0008, 0x7e3: 0x0008, - 0x7e4: 0x0008, 0x7e5: 0x0008, 0x7e6: 0x0008, 0x7e7: 0x0008, 0x7e8: 0x0008, 0x7e9: 0x0040, - 0x7ea: 0x0008, 0x7eb: 0x0008, 0x7ec: 0x0008, 0x7ed: 0x0008, 0x7ee: 0x0008, 0x7ef: 0x0008, - 0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0040, 0x7f5: 0x0008, + 0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008, + 0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040, + 0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040, + 0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040, + 0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040, + 0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008, + 0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008, + 0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008, + 0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008, 0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040, - 0x7fc: 0x1308, 0x7fd: 0x0008, 0x7fe: 0x1008, 0x7ff: 0x1308, + 0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008, // Block 0x20, offset 0x800 - 0x800: 0x1008, 0x801: 0x1008, 0x802: 0x1008, 0x803: 0x1008, 0x804: 0x1008, 0x805: 0x0040, - 0x806: 0x1308, 0x807: 0x1008, 0x808: 0x1008, 0x809: 0x0040, 0x80a: 0x1008, 0x80b: 0x1008, - 0x80c: 0x1308, 0x80d: 0x1b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040, - 0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x1008, 0x816: 0x1008, 0x817: 0x0040, - 0x818: 0x0040, 0x819: 0x0040, 0x81a: 0x0040, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040, - 0x81e: 0x0008, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x1308, 0x823: 0x1308, + 0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040, + 0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308, + 0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040, + 0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040, + 0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040, + 0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308, 0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008, 0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008, - 0x830: 0x0040, 0x831: 0x0008, 0x832: 0x0008, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040, - 0x836: 0x0040, 0x837: 0x0040, 0x838: 0x0040, 0x839: 0x0040, 0x83a: 0x0040, 0x83b: 0x0040, - 0x83c: 0x0040, 0x83d: 0x0040, 0x83e: 0x0040, 0x83f: 0x0040, + 0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040, + 0x836: 0x0040, 0x837: 0x0040, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018, + 0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018, // Block 0x21, offset 0x840 - 0x840: 0x1008, 0x841: 0x1308, 0x842: 0x1308, 0x843: 0x1308, 0x844: 0x1308, 0x845: 0x0040, - 0x846: 0x1008, 0x847: 0x1008, 0x848: 0x1008, 0x849: 0x0040, 0x84a: 0x1008, 0x84b: 0x1008, - 0x84c: 0x1008, 0x84d: 0x1b08, 0x84e: 0x0008, 0x84f: 0x0018, 0x850: 0x0040, 0x851: 0x0040, - 0x852: 0x0040, 0x853: 0x0040, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x1008, - 0x858: 0x0018, 0x859: 0x0018, 0x85a: 0x0018, 0x85b: 0x0018, 0x85c: 0x0018, 0x85d: 0x0018, - 0x85e: 0x0018, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x1308, 0x863: 0x1308, - 0x864: 0x0040, 0x865: 0x0040, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0008, + 0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0040, 0x845: 0x0008, + 0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008, + 0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040, + 0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008, + 0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008, + 0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008, + 0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040, 0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008, - 0x870: 0x0018, 0x871: 0x0018, 0x872: 0x0018, 0x873: 0x0018, 0x874: 0x0018, 0x875: 0x0018, - 0x876: 0x0018, 0x877: 0x0018, 0x878: 0x0018, 0x879: 0x0018, 0x87a: 0x0008, 0x87b: 0x0008, - 0x87c: 0x0008, 0x87d: 0x0008, 0x87e: 0x0008, 0x87f: 0x0008, + 0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008, + 0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040, + 0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308, // Block 0x22, offset 0x880 - 0x880: 0x0040, 0x881: 0x0008, 0x882: 0x0008, 0x883: 0x0040, 0x884: 0x0008, 0x885: 0x0040, - 0x886: 0x0040, 0x887: 0x0008, 0x888: 0x0008, 0x889: 0x0040, 0x88a: 0x0008, 0x88b: 0x0040, - 0x88c: 0x0040, 0x88d: 0x0008, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040, - 0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0008, 0x895: 0x0008, 0x896: 0x0008, 0x897: 0x0008, - 0x898: 0x0040, 0x899: 0x0008, 0x89a: 0x0008, 0x89b: 0x0008, 0x89c: 0x0008, 0x89d: 0x0008, - 0x89e: 0x0008, 0x89f: 0x0008, 0x8a0: 0x0040, 0x8a1: 0x0008, 0x8a2: 0x0008, 0x8a3: 0x0008, - 0x8a4: 0x0040, 0x8a5: 0x0008, 0x8a6: 0x0040, 0x8a7: 0x0008, 0x8a8: 0x0040, 0x8a9: 0x0040, - 0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0040, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008, - 0x8b0: 0x0008, 0x8b1: 0x1308, 0x8b2: 0x0008, 0x8b3: 0x0929, 0x8b4: 0x1308, 0x8b5: 0x1308, - 0x8b6: 0x1308, 0x8b7: 0x1308, 0x8b8: 0x1308, 0x8b9: 0x1308, 0x8ba: 0x0040, 0x8bb: 0x1308, - 0x8bc: 0x1308, 0x8bd: 0x0008, 0x8be: 0x0040, 0x8bf: 0x0040, + 0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040, + 0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008, + 0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040, + 0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040, + 0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040, + 0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308, + 0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008, + 0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008, + 0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040, + 0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040, + 0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040, // Block 0x23, offset 0x8c0 - 0x8c0: 0x0008, 0x8c1: 0x0008, 0x8c2: 0x0008, 0x8c3: 0x09d1, 0x8c4: 0x0008, 0x8c5: 0x0008, - 0x8c6: 0x0008, 0x8c7: 0x0008, 0x8c8: 0x0040, 0x8c9: 0x0008, 0x8ca: 0x0008, 0x8cb: 0x0008, - 0x8cc: 0x0008, 0x8cd: 0x0a09, 0x8ce: 0x0008, 0x8cf: 0x0008, 0x8d0: 0x0008, 0x8d1: 0x0008, - 0x8d2: 0x0a41, 0x8d3: 0x0008, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x0a79, - 0x8d8: 0x0008, 0x8d9: 0x0008, 0x8da: 0x0008, 0x8db: 0x0008, 0x8dc: 0x0ab1, 0x8dd: 0x0008, - 0x8de: 0x0008, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x0008, 0x8e3: 0x0008, - 0x8e4: 0x0008, 0x8e5: 0x0008, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0ae9, - 0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0040, 0x8ee: 0x0040, 0x8ef: 0x0040, - 0x8f0: 0x0040, 0x8f1: 0x1308, 0x8f2: 0x1308, 0x8f3: 0x0b21, 0x8f4: 0x1308, 0x8f5: 0x0b59, - 0x8f6: 0x0b91, 0x8f7: 0x0bc9, 0x8f8: 0x0c19, 0x8f9: 0x0c51, 0x8fa: 0x1308, 0x8fb: 0x1308, - 0x8fc: 0x1308, 0x8fd: 0x1308, 0x8fe: 0x1308, 0x8ff: 0x1008, + 0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040, + 0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008, + 0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040, + 0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008, + 0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018, + 0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308, + 0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008, + 0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008, + 0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018, + 0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008, + 0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008, // Block 0x24, offset 0x900 - 0x900: 0x1308, 0x901: 0x0ca1, 0x902: 0x1308, 0x903: 0x1308, 0x904: 0x1b08, 0x905: 0x0018, - 0x906: 0x1308, 0x907: 0x1308, 0x908: 0x0008, 0x909: 0x0008, 0x90a: 0x0008, 0x90b: 0x0008, - 0x90c: 0x0008, 0x90d: 0x1308, 0x90e: 0x1308, 0x90f: 0x1308, 0x910: 0x1308, 0x911: 0x1308, - 0x912: 0x1308, 0x913: 0x0cd9, 0x914: 0x1308, 0x915: 0x1308, 0x916: 0x1308, 0x917: 0x1308, - 0x918: 0x0040, 0x919: 0x1308, 0x91a: 0x1308, 0x91b: 0x1308, 0x91c: 0x1308, 0x91d: 0x0d11, - 0x91e: 0x1308, 0x91f: 0x1308, 0x920: 0x1308, 0x921: 0x1308, 0x922: 0x0d49, 0x923: 0x1308, - 0x924: 0x1308, 0x925: 0x1308, 0x926: 0x1308, 0x927: 0x0d81, 0x928: 0x1308, 0x929: 0x1308, - 0x92a: 0x1308, 0x92b: 0x1308, 0x92c: 0x0db9, 0x92d: 0x1308, 0x92e: 0x1308, 0x92f: 0x1308, - 0x930: 0x1308, 0x931: 0x1308, 0x932: 0x1308, 0x933: 0x1308, 0x934: 0x1308, 0x935: 0x1308, - 0x936: 0x1308, 0x937: 0x1308, 0x938: 0x1308, 0x939: 0x0df1, 0x93a: 0x1308, 0x93b: 0x1308, - 0x93c: 0x1308, 0x93d: 0x0040, 0x93e: 0x0018, 0x93f: 0x0018, + 0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040, + 0x906: 0x0040, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0040, 0x90a: 0x0008, 0x90b: 0x0040, + 0x90c: 0x0040, 0x90d: 0x0008, 0x90e: 0x0040, 0x90f: 0x0040, 0x910: 0x0040, 0x911: 0x0040, + 0x912: 0x0040, 0x913: 0x0040, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008, + 0x918: 0x0040, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008, + 0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0040, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008, + 0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0040, 0x929: 0x0040, + 0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0040, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008, + 0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x0929, 0x934: 0x3308, 0x935: 0x3308, + 0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x0040, 0x93b: 0x3308, + 0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040, // Block 0x25, offset 0x940 - 0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x0008, 0x944: 0x0008, 0x945: 0x0008, - 0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0008, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008, - 0x94c: 0x0008, 0x94d: 0x0008, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008, - 0x952: 0x0008, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0008, - 0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0008, 0x95d: 0x0008, + 0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x09d1, 0x944: 0x0008, 0x945: 0x0008, + 0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008, + 0x94c: 0x0008, 0x94d: 0x0a09, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008, + 0x952: 0x0a41, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0a79, + 0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0ab1, 0x95d: 0x0008, 0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008, - 0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0008, - 0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0039, 0x96d: 0x0ed1, 0x96e: 0x0ee9, 0x96f: 0x0008, - 0x970: 0x0ef9, 0x971: 0x0f09, 0x972: 0x0f19, 0x973: 0x0f31, 0x974: 0x0249, 0x975: 0x0f41, - 0x976: 0x0259, 0x977: 0x0f51, 0x978: 0x0359, 0x979: 0x0f61, 0x97a: 0x0f71, 0x97b: 0x0008, - 0x97c: 0x00d9, 0x97d: 0x0f81, 0x97e: 0x0f99, 0x97f: 0x0269, + 0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0ae9, + 0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040, + 0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0b21, 0x974: 0x3308, 0x975: 0x0b59, + 0x976: 0x0b91, 0x977: 0x0bc9, 0x978: 0x0c19, 0x979: 0x0c51, 0x97a: 0x3308, 0x97b: 0x3308, + 0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008, // Block 0x26, offset 0x980 - 0x980: 0x0fa9, 0x981: 0x0fb9, 0x982: 0x0279, 0x983: 0x0039, 0x984: 0x0fc9, 0x985: 0x0fe1, - 0x986: 0x059d, 0x987: 0x0ee9, 0x988: 0x0ef9, 0x989: 0x0f09, 0x98a: 0x0ff9, 0x98b: 0x1011, - 0x98c: 0x1029, 0x98d: 0x0f31, 0x98e: 0x0008, 0x98f: 0x0f51, 0x990: 0x0f61, 0x991: 0x1041, - 0x992: 0x00d9, 0x993: 0x1059, 0x994: 0x05b5, 0x995: 0x05b5, 0x996: 0x0f99, 0x997: 0x0fa9, - 0x998: 0x0fb9, 0x999: 0x059d, 0x99a: 0x1071, 0x99b: 0x1089, 0x99c: 0x05cd, 0x99d: 0x1099, - 0x99e: 0x10b1, 0x99f: 0x10c9, 0x9a0: 0x10e1, 0x9a1: 0x10f9, 0x9a2: 0x0f41, 0x9a3: 0x0269, - 0x9a4: 0x0fb9, 0x9a5: 0x1089, 0x9a6: 0x1099, 0x9a7: 0x10b1, 0x9a8: 0x1111, 0x9a9: 0x10e1, - 0x9aa: 0x10f9, 0x9ab: 0x0008, 0x9ac: 0x0008, 0x9ad: 0x0008, 0x9ae: 0x0008, 0x9af: 0x0008, - 0x9b0: 0x0008, 0x9b1: 0x0008, 0x9b2: 0x0008, 0x9b3: 0x0008, 0x9b4: 0x0008, 0x9b5: 0x0008, - 0x9b6: 0x0008, 0x9b7: 0x0008, 0x9b8: 0x1129, 0x9b9: 0x0008, 0x9ba: 0x0008, 0x9bb: 0x0008, - 0x9bc: 0x0008, 0x9bd: 0x0008, 0x9be: 0x0008, 0x9bf: 0x0008, + 0x980: 0x3308, 0x981: 0x0ca1, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018, + 0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008, + 0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308, + 0x992: 0x3308, 0x993: 0x0cd9, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308, + 0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0d11, + 0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0d49, 0x9a3: 0x3308, + 0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0d81, 0x9a8: 0x3308, 0x9a9: 0x3308, + 0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0db9, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308, + 0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308, + 0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x0df1, 0x9ba: 0x3308, 0x9bb: 0x3308, + 0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018, // Block 0x27, offset 0x9c0 0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008, 0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008, 0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008, 0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008, - 0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x1141, 0x9dc: 0x1159, 0x9dd: 0x1169, - 0x9de: 0x1181, 0x9df: 0x1029, 0x9e0: 0x1199, 0x9e1: 0x11a9, 0x9e2: 0x11c1, 0x9e3: 0x11d9, - 0x9e4: 0x11f1, 0x9e5: 0x1209, 0x9e6: 0x1221, 0x9e7: 0x05e5, 0x9e8: 0x1239, 0x9e9: 0x1251, - 0x9ea: 0xe17d, 0x9eb: 0x1269, 0x9ec: 0x1281, 0x9ed: 0x1299, 0x9ee: 0x12b1, 0x9ef: 0x12c9, - 0x9f0: 0x12e1, 0x9f1: 0x12f9, 0x9f2: 0x1311, 0x9f3: 0x1329, 0x9f4: 0x1341, 0x9f5: 0x1359, - 0x9f6: 0x1371, 0x9f7: 0x1389, 0x9f8: 0x05fd, 0x9f9: 0x13a1, 0x9fa: 0x13b9, 0x9fb: 0x13d1, - 0x9fc: 0x13e1, 0x9fd: 0x13f9, 0x9fe: 0x1411, 0x9ff: 0x1429, + 0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008, + 0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008, + 0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008, + 0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0039, 0x9ed: 0x0ed1, 0x9ee: 0x0ee9, 0x9ef: 0x0008, + 0x9f0: 0x0ef9, 0x9f1: 0x0f09, 0x9f2: 0x0f19, 0x9f3: 0x0f31, 0x9f4: 0x0249, 0x9f5: 0x0f41, + 0x9f6: 0x0259, 0x9f7: 0x0f51, 0x9f8: 0x0359, 0x9f9: 0x0f61, 0x9fa: 0x0f71, 0x9fb: 0x0008, + 0x9fc: 0x00d9, 0x9fd: 0x0f81, 0x9fe: 0x0f99, 0x9ff: 0x0269, // Block 0x28, offset 0xa00 - 0xa00: 0xe00d, 0xa01: 0x0008, 0xa02: 0xe00d, 0xa03: 0x0008, 0xa04: 0xe00d, 0xa05: 0x0008, - 0xa06: 0xe00d, 0xa07: 0x0008, 0xa08: 0xe00d, 0xa09: 0x0008, 0xa0a: 0xe00d, 0xa0b: 0x0008, - 0xa0c: 0xe00d, 0xa0d: 0x0008, 0xa0e: 0xe00d, 0xa0f: 0x0008, 0xa10: 0xe00d, 0xa11: 0x0008, - 0xa12: 0xe00d, 0xa13: 0x0008, 0xa14: 0xe00d, 0xa15: 0x0008, 0xa16: 0xe00d, 0xa17: 0x0008, - 0xa18: 0xe00d, 0xa19: 0x0008, 0xa1a: 0xe00d, 0xa1b: 0x0008, 0xa1c: 0xe00d, 0xa1d: 0x0008, - 0xa1e: 0xe00d, 0xa1f: 0x0008, 0xa20: 0xe00d, 0xa21: 0x0008, 0xa22: 0xe00d, 0xa23: 0x0008, - 0xa24: 0xe00d, 0xa25: 0x0008, 0xa26: 0xe00d, 0xa27: 0x0008, 0xa28: 0xe00d, 0xa29: 0x0008, - 0xa2a: 0xe00d, 0xa2b: 0x0008, 0xa2c: 0xe00d, 0xa2d: 0x0008, 0xa2e: 0xe00d, 0xa2f: 0x0008, - 0xa30: 0xe00d, 0xa31: 0x0008, 0xa32: 0xe00d, 0xa33: 0x0008, 0xa34: 0xe00d, 0xa35: 0x0008, - 0xa36: 0xe00d, 0xa37: 0x0008, 0xa38: 0xe00d, 0xa39: 0x0008, 0xa3a: 0xe00d, 0xa3b: 0x0008, - 0xa3c: 0xe00d, 0xa3d: 0x0008, 0xa3e: 0xe00d, 0xa3f: 0x0008, + 0xa00: 0x0fa9, 0xa01: 0x0fb9, 0xa02: 0x0279, 0xa03: 0x0039, 0xa04: 0x0fc9, 0xa05: 0x0fe1, + 0xa06: 0x059d, 0xa07: 0x0ee9, 0xa08: 0x0ef9, 0xa09: 0x0f09, 0xa0a: 0x0ff9, 0xa0b: 0x1011, + 0xa0c: 0x1029, 0xa0d: 0x0f31, 0xa0e: 0x0008, 0xa0f: 0x0f51, 0xa10: 0x0f61, 0xa11: 0x1041, + 0xa12: 0x00d9, 0xa13: 0x1059, 0xa14: 0x05b5, 0xa15: 0x05b5, 0xa16: 0x0f99, 0xa17: 0x0fa9, + 0xa18: 0x0fb9, 0xa19: 0x059d, 0xa1a: 0x1071, 0xa1b: 0x1089, 0xa1c: 0x05cd, 0xa1d: 0x1099, + 0xa1e: 0x10b1, 0xa1f: 0x10c9, 0xa20: 0x10e1, 0xa21: 0x10f9, 0xa22: 0x0f41, 0xa23: 0x0269, + 0xa24: 0x0fb9, 0xa25: 0x1089, 0xa26: 0x1099, 0xa27: 0x10b1, 0xa28: 0x1111, 0xa29: 0x10e1, + 0xa2a: 0x10f9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008, + 0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008, + 0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x1129, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008, + 0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008, // Block 0x29, offset 0xa40 - 0xa40: 0xe00d, 0xa41: 0x0008, 0xa42: 0xe00d, 0xa43: 0x0008, 0xa44: 0xe00d, 0xa45: 0x0008, - 0xa46: 0xe00d, 0xa47: 0x0008, 0xa48: 0xe00d, 0xa49: 0x0008, 0xa4a: 0xe00d, 0xa4b: 0x0008, - 0xa4c: 0xe00d, 0xa4d: 0x0008, 0xa4e: 0xe00d, 0xa4f: 0x0008, 0xa50: 0xe00d, 0xa51: 0x0008, - 0xa52: 0xe00d, 0xa53: 0x0008, 0xa54: 0xe00d, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008, - 0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0615, 0xa5b: 0x0635, 0xa5c: 0x0008, 0xa5d: 0x0008, - 0xa5e: 0x1441, 0xa5f: 0x0008, 0xa60: 0xe00d, 0xa61: 0x0008, 0xa62: 0xe00d, 0xa63: 0x0008, - 0xa64: 0xe00d, 0xa65: 0x0008, 0xa66: 0xe00d, 0xa67: 0x0008, 0xa68: 0xe00d, 0xa69: 0x0008, - 0xa6a: 0xe00d, 0xa6b: 0x0008, 0xa6c: 0xe00d, 0xa6d: 0x0008, 0xa6e: 0xe00d, 0xa6f: 0x0008, - 0xa70: 0xe00d, 0xa71: 0x0008, 0xa72: 0xe00d, 0xa73: 0x0008, 0xa74: 0xe00d, 0xa75: 0x0008, - 0xa76: 0xe00d, 0xa77: 0x0008, 0xa78: 0xe00d, 0xa79: 0x0008, 0xa7a: 0xe00d, 0xa7b: 0x0008, - 0xa7c: 0xe00d, 0xa7d: 0x0008, 0xa7e: 0xe00d, 0xa7f: 0x0008, + 0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008, + 0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008, + 0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008, + 0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008, + 0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x1141, 0xa5c: 0x1159, 0xa5d: 0x1169, + 0xa5e: 0x1181, 0xa5f: 0x1029, 0xa60: 0x1199, 0xa61: 0x11a9, 0xa62: 0x11c1, 0xa63: 0x11d9, + 0xa64: 0x11f1, 0xa65: 0x1209, 0xa66: 0x1221, 0xa67: 0x05e5, 0xa68: 0x1239, 0xa69: 0x1251, + 0xa6a: 0xe17d, 0xa6b: 0x1269, 0xa6c: 0x1281, 0xa6d: 0x1299, 0xa6e: 0x12b1, 0xa6f: 0x12c9, + 0xa70: 0x12e1, 0xa71: 0x12f9, 0xa72: 0x1311, 0xa73: 0x1329, 0xa74: 0x1341, 0xa75: 0x1359, + 0xa76: 0x1371, 0xa77: 0x1389, 0xa78: 0x05fd, 0xa79: 0x13a1, 0xa7a: 0x13b9, 0xa7b: 0x13d1, + 0xa7c: 0x13e1, 0xa7d: 0x13f9, 0xa7e: 0x1411, 0xa7f: 0x1429, // Block 0x2a, offset 0xa80 - 0xa80: 0x0008, 0xa81: 0x0008, 0xa82: 0x0008, 0xa83: 0x0008, 0xa84: 0x0008, 0xa85: 0x0008, - 0xa86: 0x0040, 0xa87: 0x0040, 0xa88: 0xe045, 0xa89: 0xe045, 0xa8a: 0xe045, 0xa8b: 0xe045, - 0xa8c: 0xe045, 0xa8d: 0xe045, 0xa8e: 0x0040, 0xa8f: 0x0040, 0xa90: 0x0008, 0xa91: 0x0008, - 0xa92: 0x0008, 0xa93: 0x0008, 0xa94: 0x0008, 0xa95: 0x0008, 0xa96: 0x0008, 0xa97: 0x0008, - 0xa98: 0x0040, 0xa99: 0xe045, 0xa9a: 0x0040, 0xa9b: 0xe045, 0xa9c: 0x0040, 0xa9d: 0xe045, - 0xa9e: 0x0040, 0xa9f: 0xe045, 0xaa0: 0x0008, 0xaa1: 0x0008, 0xaa2: 0x0008, 0xaa3: 0x0008, - 0xaa4: 0x0008, 0xaa5: 0x0008, 0xaa6: 0x0008, 0xaa7: 0x0008, 0xaa8: 0xe045, 0xaa9: 0xe045, - 0xaaa: 0xe045, 0xaab: 0xe045, 0xaac: 0xe045, 0xaad: 0xe045, 0xaae: 0xe045, 0xaaf: 0xe045, - 0xab0: 0x0008, 0xab1: 0x1459, 0xab2: 0x0008, 0xab3: 0x1471, 0xab4: 0x0008, 0xab5: 0x1489, - 0xab6: 0x0008, 0xab7: 0x14a1, 0xab8: 0x0008, 0xab9: 0x14b9, 0xaba: 0x0008, 0xabb: 0x14d1, - 0xabc: 0x0008, 0xabd: 0x14e9, 0xabe: 0x0040, 0xabf: 0x0040, + 0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008, + 0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008, + 0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008, + 0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008, + 0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008, + 0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008, + 0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008, + 0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008, + 0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008, + 0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008, + 0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008, // Block 0x2b, offset 0xac0 - 0xac0: 0x1501, 0xac1: 0x1531, 0xac2: 0x1561, 0xac3: 0x1591, 0xac4: 0x15c1, 0xac5: 0x15f1, - 0xac6: 0x1621, 0xac7: 0x1651, 0xac8: 0x1501, 0xac9: 0x1531, 0xaca: 0x1561, 0xacb: 0x1591, - 0xacc: 0x15c1, 0xacd: 0x15f1, 0xace: 0x1621, 0xacf: 0x1651, 0xad0: 0x1681, 0xad1: 0x16b1, - 0xad2: 0x16e1, 0xad3: 0x1711, 0xad4: 0x1741, 0xad5: 0x1771, 0xad6: 0x17a1, 0xad7: 0x17d1, - 0xad8: 0x1681, 0xad9: 0x16b1, 0xada: 0x16e1, 0xadb: 0x1711, 0xadc: 0x1741, 0xadd: 0x1771, - 0xade: 0x17a1, 0xadf: 0x17d1, 0xae0: 0x1801, 0xae1: 0x1831, 0xae2: 0x1861, 0xae3: 0x1891, - 0xae4: 0x18c1, 0xae5: 0x18f1, 0xae6: 0x1921, 0xae7: 0x1951, 0xae8: 0x1801, 0xae9: 0x1831, - 0xaea: 0x1861, 0xaeb: 0x1891, 0xaec: 0x18c1, 0xaed: 0x18f1, 0xaee: 0x1921, 0xaef: 0x1951, - 0xaf0: 0x0008, 0xaf1: 0x0008, 0xaf2: 0x1981, 0xaf3: 0x19b1, 0xaf4: 0x19d9, 0xaf5: 0x0040, - 0xaf6: 0x0008, 0xaf7: 0x1a01, 0xaf8: 0xe045, 0xaf9: 0xe045, 0xafa: 0x064d, 0xafb: 0x1459, - 0xafc: 0x19b1, 0xafd: 0x0666, 0xafe: 0x1a31, 0xaff: 0x0686, + 0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008, + 0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008, + 0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008, + 0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008, + 0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x0615, 0xadb: 0x0635, 0xadc: 0x0008, 0xadd: 0x0008, + 0xade: 0x1441, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008, + 0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008, + 0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008, + 0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008, + 0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008, + 0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008, // Block 0x2c, offset 0xb00 - 0xb00: 0x06a6, 0xb01: 0x1a4a, 0xb02: 0x1a79, 0xb03: 0x1aa9, 0xb04: 0x1ad1, 0xb05: 0x0040, - 0xb06: 0x0008, 0xb07: 0x1af9, 0xb08: 0x06c5, 0xb09: 0x1471, 0xb0a: 0x06dd, 0xb0b: 0x1489, - 0xb0c: 0x1aa9, 0xb0d: 0x1b2a, 0xb0e: 0x1b5a, 0xb0f: 0x1b8a, 0xb10: 0x0008, 0xb11: 0x0008, - 0xb12: 0x0008, 0xb13: 0x1bb9, 0xb14: 0x0040, 0xb15: 0x0040, 0xb16: 0x0008, 0xb17: 0x0008, - 0xb18: 0xe045, 0xb19: 0xe045, 0xb1a: 0x06f5, 0xb1b: 0x14a1, 0xb1c: 0x0040, 0xb1d: 0x1bd2, - 0xb1e: 0x1c02, 0xb1f: 0x1c32, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x1c61, + 0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008, + 0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045, + 0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008, + 0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008, + 0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045, + 0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008, 0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045, - 0xb2a: 0x070d, 0xb2b: 0x14d1, 0xb2c: 0xe04d, 0xb2d: 0x1c7a, 0xb2e: 0x03d2, 0xb2f: 0x1caa, - 0xb30: 0x0040, 0xb31: 0x0040, 0xb32: 0x1cb9, 0xb33: 0x1ce9, 0xb34: 0x1d11, 0xb35: 0x0040, - 0xb36: 0x0008, 0xb37: 0x1d39, 0xb38: 0x0725, 0xb39: 0x14b9, 0xb3a: 0x0515, 0xb3b: 0x14e9, - 0xb3c: 0x1ce9, 0xb3d: 0x073e, 0xb3e: 0x075e, 0xb3f: 0x0040, + 0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045, + 0xb30: 0x0008, 0xb31: 0x1459, 0xb32: 0x0008, 0xb33: 0x1471, 0xb34: 0x0008, 0xb35: 0x1489, + 0xb36: 0x0008, 0xb37: 0x14a1, 0xb38: 0x0008, 0xb39: 0x14b9, 0xb3a: 0x0008, 0xb3b: 0x14d1, + 0xb3c: 0x0008, 0xb3d: 0x14e9, 0xb3e: 0x0040, 0xb3f: 0x0040, // Block 0x2d, offset 0xb40 - 0xb40: 0x000a, 0xb41: 0x000a, 0xb42: 0x000a, 0xb43: 0x000a, 0xb44: 0x000a, 0xb45: 0x000a, - 0xb46: 0x000a, 0xb47: 0x000a, 0xb48: 0x000a, 0xb49: 0x000a, 0xb4a: 0x000a, 0xb4b: 0x03c0, - 0xb4c: 0x0003, 0xb4d: 0x0003, 0xb4e: 0x0340, 0xb4f: 0x0340, 0xb50: 0x0018, 0xb51: 0xe00d, - 0xb52: 0x0018, 0xb53: 0x0018, 0xb54: 0x0018, 0xb55: 0x0018, 0xb56: 0x0018, 0xb57: 0x077e, - 0xb58: 0x0018, 0xb59: 0x0018, 0xb5a: 0x0018, 0xb5b: 0x0018, 0xb5c: 0x0018, 0xb5d: 0x0018, - 0xb5e: 0x0018, 0xb5f: 0x0018, 0xb60: 0x0018, 0xb61: 0x0018, 0xb62: 0x0018, 0xb63: 0x0018, - 0xb64: 0x0040, 0xb65: 0x0040, 0xb66: 0x0040, 0xb67: 0x0018, 0xb68: 0x0040, 0xb69: 0x0040, - 0xb6a: 0x0340, 0xb6b: 0x0340, 0xb6c: 0x0340, 0xb6d: 0x0340, 0xb6e: 0x0340, 0xb6f: 0x000a, - 0xb70: 0x0018, 0xb71: 0x0018, 0xb72: 0x0018, 0xb73: 0x1d69, 0xb74: 0x1da1, 0xb75: 0x0018, - 0xb76: 0x1df1, 0xb77: 0x1e29, 0xb78: 0x0018, 0xb79: 0x0018, 0xb7a: 0x0018, 0xb7b: 0x0018, - 0xb7c: 0x1e7a, 0xb7d: 0x0018, 0xb7e: 0x079e, 0xb7f: 0x0018, + 0xb40: 0x1501, 0xb41: 0x1531, 0xb42: 0x1561, 0xb43: 0x1591, 0xb44: 0x15c1, 0xb45: 0x15f1, + 0xb46: 0x1621, 0xb47: 0x1651, 0xb48: 0x1501, 0xb49: 0x1531, 0xb4a: 0x1561, 0xb4b: 0x1591, + 0xb4c: 0x15c1, 0xb4d: 0x15f1, 0xb4e: 0x1621, 0xb4f: 0x1651, 0xb50: 0x1681, 0xb51: 0x16b1, + 0xb52: 0x16e1, 0xb53: 0x1711, 0xb54: 0x1741, 0xb55: 0x1771, 0xb56: 0x17a1, 0xb57: 0x17d1, + 0xb58: 0x1681, 0xb59: 0x16b1, 0xb5a: 0x16e1, 0xb5b: 0x1711, 0xb5c: 0x1741, 0xb5d: 0x1771, + 0xb5e: 0x17a1, 0xb5f: 0x17d1, 0xb60: 0x1801, 0xb61: 0x1831, 0xb62: 0x1861, 0xb63: 0x1891, + 0xb64: 0x18c1, 0xb65: 0x18f1, 0xb66: 0x1921, 0xb67: 0x1951, 0xb68: 0x1801, 0xb69: 0x1831, + 0xb6a: 0x1861, 0xb6b: 0x1891, 0xb6c: 0x18c1, 0xb6d: 0x18f1, 0xb6e: 0x1921, 0xb6f: 0x1951, + 0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x1981, 0xb73: 0x19b1, 0xb74: 0x19d9, 0xb75: 0x0040, + 0xb76: 0x0008, 0xb77: 0x1a01, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x064d, 0xb7b: 0x1459, + 0xb7c: 0x19b1, 0xb7d: 0x0666, 0xb7e: 0x1a31, 0xb7f: 0x0686, // Block 0x2e, offset 0xb80 - 0xb80: 0x0018, 0xb81: 0x0018, 0xb82: 0x0018, 0xb83: 0x0018, 0xb84: 0x0018, 0xb85: 0x0018, - 0xb86: 0x0018, 0xb87: 0x1e92, 0xb88: 0x1eaa, 0xb89: 0x1ec2, 0xb8a: 0x0018, 0xb8b: 0x0018, - 0xb8c: 0x0018, 0xb8d: 0x0018, 0xb8e: 0x0018, 0xb8f: 0x0018, 0xb90: 0x0018, 0xb91: 0x0018, - 0xb92: 0x0018, 0xb93: 0x0018, 0xb94: 0x0018, 0xb95: 0x0018, 0xb96: 0x0018, 0xb97: 0x1ed9, - 0xb98: 0x0018, 0xb99: 0x0018, 0xb9a: 0x0018, 0xb9b: 0x0018, 0xb9c: 0x0018, 0xb9d: 0x0018, - 0xb9e: 0x0018, 0xb9f: 0x000a, 0xba0: 0x03c0, 0xba1: 0x0340, 0xba2: 0x0340, 0xba3: 0x0340, - 0xba4: 0x03c0, 0xba5: 0x0040, 0xba6: 0x0040, 0xba7: 0x0040, 0xba8: 0x0040, 0xba9: 0x0040, - 0xbaa: 0x0340, 0xbab: 0x0340, 0xbac: 0x0340, 0xbad: 0x0340, 0xbae: 0x0340, 0xbaf: 0x0340, - 0xbb0: 0x1f41, 0xbb1: 0x0f41, 0xbb2: 0x0040, 0xbb3: 0x0040, 0xbb4: 0x1f51, 0xbb5: 0x1f61, - 0xbb6: 0x1f71, 0xbb7: 0x1f81, 0xbb8: 0x1f91, 0xbb9: 0x1fa1, 0xbba: 0x1fb2, 0xbbb: 0x07bd, - 0xbbc: 0x1fc2, 0xbbd: 0x1fd2, 0xbbe: 0x1fe2, 0xbbf: 0x0f71, + 0xb80: 0x06a6, 0xb81: 0x1a4a, 0xb82: 0x1a79, 0xb83: 0x1aa9, 0xb84: 0x1ad1, 0xb85: 0x0040, + 0xb86: 0x0008, 0xb87: 0x1af9, 0xb88: 0x06c5, 0xb89: 0x1471, 0xb8a: 0x06dd, 0xb8b: 0x1489, + 0xb8c: 0x1aa9, 0xb8d: 0x1b2a, 0xb8e: 0x1b5a, 0xb8f: 0x1b8a, 0xb90: 0x0008, 0xb91: 0x0008, + 0xb92: 0x0008, 0xb93: 0x1bb9, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008, + 0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x06f5, 0xb9b: 0x14a1, 0xb9c: 0x0040, 0xb9d: 0x1bd2, + 0xb9e: 0x1c02, 0xb9f: 0x1c32, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x1c61, + 0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045, + 0xbaa: 0x070d, 0xbab: 0x14d1, 0xbac: 0xe04d, 0xbad: 0x1c7a, 0xbae: 0x03d2, 0xbaf: 0x1caa, + 0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x1cb9, 0xbb3: 0x1ce9, 0xbb4: 0x1d11, 0xbb5: 0x0040, + 0xbb6: 0x0008, 0xbb7: 0x1d39, 0xbb8: 0x0725, 0xbb9: 0x14b9, 0xbba: 0x0515, 0xbbb: 0x14e9, + 0xbbc: 0x1ce9, 0xbbd: 0x073e, 0xbbe: 0x075e, 0xbbf: 0x0040, // Block 0x2f, offset 0xbc0 - 0xbc0: 0x1f41, 0xbc1: 0x00c9, 0xbc2: 0x0069, 0xbc3: 0x0079, 0xbc4: 0x1f51, 0xbc5: 0x1f61, - 0xbc6: 0x1f71, 0xbc7: 0x1f81, 0xbc8: 0x1f91, 0xbc9: 0x1fa1, 0xbca: 0x1fb2, 0xbcb: 0x07d5, - 0xbcc: 0x1fc2, 0xbcd: 0x1fd2, 0xbce: 0x1fe2, 0xbcf: 0x0040, 0xbd0: 0x0039, 0xbd1: 0x0f09, - 0xbd2: 0x00d9, 0xbd3: 0x0369, 0xbd4: 0x0ff9, 0xbd5: 0x0249, 0xbd6: 0x0f51, 0xbd7: 0x0359, - 0xbd8: 0x0f61, 0xbd9: 0x0f71, 0xbda: 0x0f99, 0xbdb: 0x01d9, 0xbdc: 0x0fa9, 0xbdd: 0x0040, - 0xbde: 0x0040, 0xbdf: 0x0040, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018, - 0xbe4: 0x0018, 0xbe5: 0x0018, 0xbe6: 0x0018, 0xbe7: 0x0018, 0xbe8: 0x1ff1, 0xbe9: 0x0018, - 0xbea: 0x0018, 0xbeb: 0x0018, 0xbec: 0x0018, 0xbed: 0x0018, 0xbee: 0x0018, 0xbef: 0x0018, - 0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x0018, 0xbf4: 0x0018, 0xbf5: 0x0018, - 0xbf6: 0x0018, 0xbf7: 0x0018, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018, - 0xbfc: 0x0018, 0xbfd: 0x0018, 0xbfe: 0x0018, 0xbff: 0x0040, + 0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a, + 0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0, + 0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d, + 0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x077e, + 0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018, + 0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018, + 0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040, + 0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a, + 0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x1d69, 0xbf4: 0x1da1, 0xbf5: 0x0018, + 0xbf6: 0x1df1, 0xbf7: 0x1e29, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018, + 0xbfc: 0x1e7a, 0xbfd: 0x0018, 0xbfe: 0x079e, 0xbff: 0x0018, // Block 0x30, offset 0xc00 - 0xc00: 0x07ee, 0xc01: 0x080e, 0xc02: 0x1159, 0xc03: 0x082d, 0xc04: 0x0018, 0xc05: 0x084e, - 0xc06: 0x086e, 0xc07: 0x1011, 0xc08: 0x0018, 0xc09: 0x088d, 0xc0a: 0x0f31, 0xc0b: 0x0249, - 0xc0c: 0x0249, 0xc0d: 0x0249, 0xc0e: 0x0249, 0xc0f: 0x2009, 0xc10: 0x0f41, 0xc11: 0x0f41, - 0xc12: 0x0359, 0xc13: 0x0359, 0xc14: 0x0018, 0xc15: 0x0f71, 0xc16: 0x2021, 0xc17: 0x0018, - 0xc18: 0x0018, 0xc19: 0x0f99, 0xc1a: 0x2039, 0xc1b: 0x0269, 0xc1c: 0x0269, 0xc1d: 0x0269, - 0xc1e: 0x0018, 0xc1f: 0x0018, 0xc20: 0x2049, 0xc21: 0x08ad, 0xc22: 0x2061, 0xc23: 0x0018, - 0xc24: 0x13d1, 0xc25: 0x0018, 0xc26: 0x2079, 0xc27: 0x0018, 0xc28: 0x13d1, 0xc29: 0x0018, - 0xc2a: 0x0f51, 0xc2b: 0x2091, 0xc2c: 0x0ee9, 0xc2d: 0x1159, 0xc2e: 0x0018, 0xc2f: 0x0f09, - 0xc30: 0x0f09, 0xc31: 0x1199, 0xc32: 0x0040, 0xc33: 0x0f61, 0xc34: 0x00d9, 0xc35: 0x20a9, - 0xc36: 0x20c1, 0xc37: 0x20d9, 0xc38: 0x20f1, 0xc39: 0x0f41, 0xc3a: 0x0018, 0xc3b: 0x08cd, - 0xc3c: 0x2109, 0xc3d: 0x10b1, 0xc3e: 0x10b1, 0xc3f: 0x2109, + 0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018, + 0xc06: 0x0018, 0xc07: 0x1e92, 0xc08: 0x1eaa, 0xc09: 0x1ec2, 0xc0a: 0x0018, 0xc0b: 0x0018, + 0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018, + 0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x1ed9, + 0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018, + 0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340, + 0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040, + 0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340, + 0xc30: 0x1f41, 0xc31: 0x0f41, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x1f51, 0xc35: 0x1f61, + 0xc36: 0x1f71, 0xc37: 0x1f81, 0xc38: 0x1f91, 0xc39: 0x1fa1, 0xc3a: 0x1fb2, 0xc3b: 0x07bd, + 0xc3c: 0x1fc2, 0xc3d: 0x1fd2, 0xc3e: 0x1fe2, 0xc3f: 0x0f71, // Block 0x31, offset 0xc40 - 0xc40: 0x08ed, 0xc41: 0x0018, 0xc42: 0x0018, 0xc43: 0x0018, 0xc44: 0x0018, 0xc45: 0x0ef9, - 0xc46: 0x0ef9, 0xc47: 0x0f09, 0xc48: 0x0f41, 0xc49: 0x0259, 0xc4a: 0x0018, 0xc4b: 0x0018, - 0xc4c: 0x0018, 0xc4d: 0x0018, 0xc4e: 0x0008, 0xc4f: 0x0018, 0xc50: 0x2121, 0xc51: 0x2151, - 0xc52: 0x2181, 0xc53: 0x21b9, 0xc54: 0x21e9, 0xc55: 0x2219, 0xc56: 0x2249, 0xc57: 0x2279, - 0xc58: 0x22a9, 0xc59: 0x22d9, 0xc5a: 0x2309, 0xc5b: 0x2339, 0xc5c: 0x2369, 0xc5d: 0x2399, - 0xc5e: 0x23c9, 0xc5f: 0x23f9, 0xc60: 0x0f41, 0xc61: 0x2421, 0xc62: 0x0905, 0xc63: 0x2439, - 0xc64: 0x1089, 0xc65: 0x2451, 0xc66: 0x0925, 0xc67: 0x2469, 0xc68: 0x2491, 0xc69: 0x0369, - 0xc6a: 0x24a9, 0xc6b: 0x0945, 0xc6c: 0x0359, 0xc6d: 0x1159, 0xc6e: 0x0ef9, 0xc6f: 0x0f61, - 0xc70: 0x0f41, 0xc71: 0x2421, 0xc72: 0x0965, 0xc73: 0x2439, 0xc74: 0x1089, 0xc75: 0x2451, - 0xc76: 0x0985, 0xc77: 0x2469, 0xc78: 0x2491, 0xc79: 0x0369, 0xc7a: 0x24a9, 0xc7b: 0x09a5, - 0xc7c: 0x0359, 0xc7d: 0x1159, 0xc7e: 0x0ef9, 0xc7f: 0x0f61, + 0xc40: 0x1f41, 0xc41: 0x00c9, 0xc42: 0x0069, 0xc43: 0x0079, 0xc44: 0x1f51, 0xc45: 0x1f61, + 0xc46: 0x1f71, 0xc47: 0x1f81, 0xc48: 0x1f91, 0xc49: 0x1fa1, 0xc4a: 0x1fb2, 0xc4b: 0x07d5, + 0xc4c: 0x1fc2, 0xc4d: 0x1fd2, 0xc4e: 0x1fe2, 0xc4f: 0x0040, 0xc50: 0x0039, 0xc51: 0x0f09, + 0xc52: 0x00d9, 0xc53: 0x0369, 0xc54: 0x0ff9, 0xc55: 0x0249, 0xc56: 0x0f51, 0xc57: 0x0359, + 0xc58: 0x0f61, 0xc59: 0x0f71, 0xc5a: 0x0f99, 0xc5b: 0x01d9, 0xc5c: 0x0fa9, 0xc5d: 0x0040, + 0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018, + 0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x1ff1, 0xc69: 0x0018, + 0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018, + 0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018, + 0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018, + 0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018, // Block 0x32, offset 0xc80 - 0xc80: 0x0018, 0xc81: 0x0018, 0xc82: 0x0018, 0xc83: 0x0018, 0xc84: 0x0018, 0xc85: 0x0018, - 0xc86: 0x0018, 0xc87: 0x0018, 0xc88: 0x0018, 0xc89: 0x0018, 0xc8a: 0x0018, 0xc8b: 0x0040, - 0xc8c: 0x0040, 0xc8d: 0x0040, 0xc8e: 0x0040, 0xc8f: 0x0040, 0xc90: 0x0040, 0xc91: 0x0040, - 0xc92: 0x0040, 0xc93: 0x0040, 0xc94: 0x0040, 0xc95: 0x0040, 0xc96: 0x0040, 0xc97: 0x0040, - 0xc98: 0x0040, 0xc99: 0x0040, 0xc9a: 0x0040, 0xc9b: 0x0040, 0xc9c: 0x0040, 0xc9d: 0x0040, - 0xc9e: 0x0040, 0xc9f: 0x0040, 0xca0: 0x00c9, 0xca1: 0x0069, 0xca2: 0x0079, 0xca3: 0x1f51, - 0xca4: 0x1f61, 0xca5: 0x1f71, 0xca6: 0x1f81, 0xca7: 0x1f91, 0xca8: 0x1fa1, 0xca9: 0x2601, - 0xcaa: 0x2619, 0xcab: 0x2631, 0xcac: 0x2649, 0xcad: 0x2661, 0xcae: 0x2679, 0xcaf: 0x2691, - 0xcb0: 0x26a9, 0xcb1: 0x26c1, 0xcb2: 0x26d9, 0xcb3: 0x26f1, 0xcb4: 0x0a06, 0xcb5: 0x0a26, - 0xcb6: 0x0a46, 0xcb7: 0x0a66, 0xcb8: 0x0a86, 0xcb9: 0x0aa6, 0xcba: 0x0ac6, 0xcbb: 0x0ae6, - 0xcbc: 0x0b06, 0xcbd: 0x270a, 0xcbe: 0x2732, 0xcbf: 0x275a, + 0xc80: 0x07ee, 0xc81: 0x080e, 0xc82: 0x1159, 0xc83: 0x082d, 0xc84: 0x0018, 0xc85: 0x084e, + 0xc86: 0x086e, 0xc87: 0x1011, 0xc88: 0x0018, 0xc89: 0x088d, 0xc8a: 0x0f31, 0xc8b: 0x0249, + 0xc8c: 0x0249, 0xc8d: 0x0249, 0xc8e: 0x0249, 0xc8f: 0x2009, 0xc90: 0x0f41, 0xc91: 0x0f41, + 0xc92: 0x0359, 0xc93: 0x0359, 0xc94: 0x0018, 0xc95: 0x0f71, 0xc96: 0x2021, 0xc97: 0x0018, + 0xc98: 0x0018, 0xc99: 0x0f99, 0xc9a: 0x2039, 0xc9b: 0x0269, 0xc9c: 0x0269, 0xc9d: 0x0269, + 0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x2049, 0xca1: 0x08ad, 0xca2: 0x2061, 0xca3: 0x0018, + 0xca4: 0x13d1, 0xca5: 0x0018, 0xca6: 0x2079, 0xca7: 0x0018, 0xca8: 0x13d1, 0xca9: 0x0018, + 0xcaa: 0x0f51, 0xcab: 0x2091, 0xcac: 0x0ee9, 0xcad: 0x1159, 0xcae: 0x0018, 0xcaf: 0x0f09, + 0xcb0: 0x0f09, 0xcb1: 0x1199, 0xcb2: 0x0040, 0xcb3: 0x0f61, 0xcb4: 0x00d9, 0xcb5: 0x20a9, + 0xcb6: 0x20c1, 0xcb7: 0x20d9, 0xcb8: 0x20f1, 0xcb9: 0x0f41, 0xcba: 0x0018, 0xcbb: 0x08cd, + 0xcbc: 0x2109, 0xcbd: 0x10b1, 0xcbe: 0x10b1, 0xcbf: 0x2109, // Block 0x33, offset 0xcc0 - 0xcc0: 0x2782, 0xcc1: 0x27aa, 0xcc2: 0x27d2, 0xcc3: 0x27fa, 0xcc4: 0x2822, 0xcc5: 0x284a, - 0xcc6: 0x2872, 0xcc7: 0x289a, 0xcc8: 0x0040, 0xcc9: 0x0040, 0xcca: 0x0040, 0xccb: 0x0040, - 0xccc: 0x0040, 0xccd: 0x0040, 0xcce: 0x0040, 0xccf: 0x0040, 0xcd0: 0x0040, 0xcd1: 0x0040, - 0xcd2: 0x0040, 0xcd3: 0x0040, 0xcd4: 0x0040, 0xcd5: 0x0040, 0xcd6: 0x0040, 0xcd7: 0x0040, - 0xcd8: 0x0040, 0xcd9: 0x0040, 0xcda: 0x0040, 0xcdb: 0x0040, 0xcdc: 0x0b26, 0xcdd: 0x0b46, - 0xcde: 0x0b66, 0xcdf: 0x0b86, 0xce0: 0x0ba6, 0xce1: 0x0bc6, 0xce2: 0x0be6, 0xce3: 0x0c06, - 0xce4: 0x0c26, 0xce5: 0x0c46, 0xce6: 0x0c66, 0xce7: 0x0c86, 0xce8: 0x0ca6, 0xce9: 0x0cc6, - 0xcea: 0x0ce6, 0xceb: 0x0d06, 0xcec: 0x0d26, 0xced: 0x0d46, 0xcee: 0x0d66, 0xcef: 0x0d86, - 0xcf0: 0x0da6, 0xcf1: 0x0dc6, 0xcf2: 0x0de6, 0xcf3: 0x0e06, 0xcf4: 0x0e26, 0xcf5: 0x0e46, - 0xcf6: 0x0039, 0xcf7: 0x0ee9, 0xcf8: 0x1159, 0xcf9: 0x0ef9, 0xcfa: 0x0f09, 0xcfb: 0x1199, - 0xcfc: 0x0f31, 0xcfd: 0x0249, 0xcfe: 0x0f41, 0xcff: 0x0259, + 0xcc0: 0x08ed, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0ef9, + 0xcc6: 0x0ef9, 0xcc7: 0x0f09, 0xcc8: 0x0f41, 0xcc9: 0x0259, 0xcca: 0x0018, 0xccb: 0x0018, + 0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x2121, 0xcd1: 0x2151, + 0xcd2: 0x2181, 0xcd3: 0x21b9, 0xcd4: 0x21e9, 0xcd5: 0x2219, 0xcd6: 0x2249, 0xcd7: 0x2279, + 0xcd8: 0x22a9, 0xcd9: 0x22d9, 0xcda: 0x2309, 0xcdb: 0x2339, 0xcdc: 0x2369, 0xcdd: 0x2399, + 0xcde: 0x23c9, 0xcdf: 0x23f9, 0xce0: 0x0f41, 0xce1: 0x2421, 0xce2: 0x0905, 0xce3: 0x2439, + 0xce4: 0x1089, 0xce5: 0x2451, 0xce6: 0x0925, 0xce7: 0x2469, 0xce8: 0x2491, 0xce9: 0x0369, + 0xcea: 0x24a9, 0xceb: 0x0945, 0xcec: 0x0359, 0xced: 0x1159, 0xcee: 0x0ef9, 0xcef: 0x0f61, + 0xcf0: 0x0f41, 0xcf1: 0x2421, 0xcf2: 0x0965, 0xcf3: 0x2439, 0xcf4: 0x1089, 0xcf5: 0x2451, + 0xcf6: 0x0985, 0xcf7: 0x2469, 0xcf8: 0x2491, 0xcf9: 0x0369, 0xcfa: 0x24a9, 0xcfb: 0x09a5, + 0xcfc: 0x0359, 0xcfd: 0x1159, 0xcfe: 0x0ef9, 0xcff: 0x0f61, // Block 0x34, offset 0xd00 - 0xd00: 0x0f51, 0xd01: 0x0359, 0xd02: 0x0f61, 0xd03: 0x0f71, 0xd04: 0x00d9, 0xd05: 0x0f99, - 0xd06: 0x2039, 0xd07: 0x0269, 0xd08: 0x01d9, 0xd09: 0x0fa9, 0xd0a: 0x0fb9, 0xd0b: 0x1089, - 0xd0c: 0x0279, 0xd0d: 0x0369, 0xd0e: 0x0289, 0xd0f: 0x13d1, 0xd10: 0x0039, 0xd11: 0x0ee9, - 0xd12: 0x1159, 0xd13: 0x0ef9, 0xd14: 0x0f09, 0xd15: 0x1199, 0xd16: 0x0f31, 0xd17: 0x0249, - 0xd18: 0x0f41, 0xd19: 0x0259, 0xd1a: 0x0f51, 0xd1b: 0x0359, 0xd1c: 0x0f61, 0xd1d: 0x0f71, - 0xd1e: 0x00d9, 0xd1f: 0x0f99, 0xd20: 0x2039, 0xd21: 0x0269, 0xd22: 0x01d9, 0xd23: 0x0fa9, - 0xd24: 0x0fb9, 0xd25: 0x1089, 0xd26: 0x0279, 0xd27: 0x0369, 0xd28: 0x0289, 0xd29: 0x13d1, - 0xd2a: 0x1f41, 0xd2b: 0x0018, 0xd2c: 0x0018, 0xd2d: 0x0018, 0xd2e: 0x0018, 0xd2f: 0x0018, - 0xd30: 0x0018, 0xd31: 0x0018, 0xd32: 0x0018, 0xd33: 0x0018, 0xd34: 0x0018, 0xd35: 0x0018, - 0xd36: 0x0018, 0xd37: 0x0018, 0xd38: 0x0018, 0xd39: 0x0018, 0xd3a: 0x0018, 0xd3b: 0x0018, - 0xd3c: 0x0018, 0xd3d: 0x0018, 0xd3e: 0x0018, 0xd3f: 0x0018, + 0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018, + 0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040, + 0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040, + 0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040, + 0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040, + 0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x00c9, 0xd21: 0x0069, 0xd22: 0x0079, 0xd23: 0x1f51, + 0xd24: 0x1f61, 0xd25: 0x1f71, 0xd26: 0x1f81, 0xd27: 0x1f91, 0xd28: 0x1fa1, 0xd29: 0x2601, + 0xd2a: 0x2619, 0xd2b: 0x2631, 0xd2c: 0x2649, 0xd2d: 0x2661, 0xd2e: 0x2679, 0xd2f: 0x2691, + 0xd30: 0x26a9, 0xd31: 0x26c1, 0xd32: 0x26d9, 0xd33: 0x26f1, 0xd34: 0x0a06, 0xd35: 0x0a26, + 0xd36: 0x0a46, 0xd37: 0x0a66, 0xd38: 0x0a86, 0xd39: 0x0aa6, 0xd3a: 0x0ac6, 0xd3b: 0x0ae6, + 0xd3c: 0x0b06, 0xd3d: 0x270a, 0xd3e: 0x2732, 0xd3f: 0x275a, // Block 0x35, offset 0xd40 - 0xd40: 0x0008, 0xd41: 0x0008, 0xd42: 0x0008, 0xd43: 0x0008, 0xd44: 0x0008, 0xd45: 0x0008, - 0xd46: 0x0008, 0xd47: 0x0008, 0xd48: 0x0008, 0xd49: 0x0008, 0xd4a: 0x0008, 0xd4b: 0x0008, - 0xd4c: 0x0008, 0xd4d: 0x0008, 0xd4e: 0x0008, 0xd4f: 0x0008, 0xd50: 0x0008, 0xd51: 0x0008, - 0xd52: 0x0008, 0xd53: 0x0008, 0xd54: 0x0008, 0xd55: 0x0008, 0xd56: 0x0008, 0xd57: 0x0008, - 0xd58: 0x0008, 0xd59: 0x0008, 0xd5a: 0x0008, 0xd5b: 0x0008, 0xd5c: 0x0008, 0xd5d: 0x0008, - 0xd5e: 0x0008, 0xd5f: 0x0040, 0xd60: 0xe00d, 0xd61: 0x0008, 0xd62: 0x2971, 0xd63: 0x0ebd, - 0xd64: 0x2989, 0xd65: 0x0008, 0xd66: 0x0008, 0xd67: 0xe07d, 0xd68: 0x0008, 0xd69: 0xe01d, - 0xd6a: 0x0008, 0xd6b: 0xe03d, 0xd6c: 0x0008, 0xd6d: 0x0fe1, 0xd6e: 0x1281, 0xd6f: 0x0fc9, - 0xd70: 0x1141, 0xd71: 0x0008, 0xd72: 0xe00d, 0xd73: 0x0008, 0xd74: 0x0008, 0xd75: 0xe01d, - 0xd76: 0x0008, 0xd77: 0x0008, 0xd78: 0x0008, 0xd79: 0x0008, 0xd7a: 0x0008, 0xd7b: 0x0008, - 0xd7c: 0x0259, 0xd7d: 0x1089, 0xd7e: 0x29a1, 0xd7f: 0x29b9, + 0xd40: 0x2782, 0xd41: 0x27aa, 0xd42: 0x27d2, 0xd43: 0x27fa, 0xd44: 0x2822, 0xd45: 0x284a, + 0xd46: 0x2872, 0xd47: 0x289a, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040, + 0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040, + 0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040, + 0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b26, 0xd5d: 0x0b46, + 0xd5e: 0x0b66, 0xd5f: 0x0b86, 0xd60: 0x0ba6, 0xd61: 0x0bc6, 0xd62: 0x0be6, 0xd63: 0x0c06, + 0xd64: 0x0c26, 0xd65: 0x0c46, 0xd66: 0x0c66, 0xd67: 0x0c86, 0xd68: 0x0ca6, 0xd69: 0x0cc6, + 0xd6a: 0x0ce6, 0xd6b: 0x0d06, 0xd6c: 0x0d26, 0xd6d: 0x0d46, 0xd6e: 0x0d66, 0xd6f: 0x0d86, + 0xd70: 0x0da6, 0xd71: 0x0dc6, 0xd72: 0x0de6, 0xd73: 0x0e06, 0xd74: 0x0e26, 0xd75: 0x0e46, + 0xd76: 0x0039, 0xd77: 0x0ee9, 0xd78: 0x1159, 0xd79: 0x0ef9, 0xd7a: 0x0f09, 0xd7b: 0x1199, + 0xd7c: 0x0f31, 0xd7d: 0x0249, 0xd7e: 0x0f41, 0xd7f: 0x0259, // Block 0x36, offset 0xd80 - 0xd80: 0xe00d, 0xd81: 0x0008, 0xd82: 0xe00d, 0xd83: 0x0008, 0xd84: 0xe00d, 0xd85: 0x0008, - 0xd86: 0xe00d, 0xd87: 0x0008, 0xd88: 0xe00d, 0xd89: 0x0008, 0xd8a: 0xe00d, 0xd8b: 0x0008, - 0xd8c: 0xe00d, 0xd8d: 0x0008, 0xd8e: 0xe00d, 0xd8f: 0x0008, 0xd90: 0xe00d, 0xd91: 0x0008, - 0xd92: 0xe00d, 0xd93: 0x0008, 0xd94: 0xe00d, 0xd95: 0x0008, 0xd96: 0xe00d, 0xd97: 0x0008, - 0xd98: 0xe00d, 0xd99: 0x0008, 0xd9a: 0xe00d, 0xd9b: 0x0008, 0xd9c: 0xe00d, 0xd9d: 0x0008, - 0xd9e: 0xe00d, 0xd9f: 0x0008, 0xda0: 0xe00d, 0xda1: 0x0008, 0xda2: 0xe00d, 0xda3: 0x0008, - 0xda4: 0x0008, 0xda5: 0x0018, 0xda6: 0x0018, 0xda7: 0x0018, 0xda8: 0x0018, 0xda9: 0x0018, - 0xdaa: 0x0018, 0xdab: 0xe03d, 0xdac: 0x0008, 0xdad: 0xe01d, 0xdae: 0x0008, 0xdaf: 0x1308, - 0xdb0: 0x1308, 0xdb1: 0x1308, 0xdb2: 0xe00d, 0xdb3: 0x0008, 0xdb4: 0x0040, 0xdb5: 0x0040, - 0xdb6: 0x0040, 0xdb7: 0x0040, 0xdb8: 0x0040, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018, + 0xd80: 0x0f51, 0xd81: 0x0359, 0xd82: 0x0f61, 0xd83: 0x0f71, 0xd84: 0x00d9, 0xd85: 0x0f99, + 0xd86: 0x2039, 0xd87: 0x0269, 0xd88: 0x01d9, 0xd89: 0x0fa9, 0xd8a: 0x0fb9, 0xd8b: 0x1089, + 0xd8c: 0x0279, 0xd8d: 0x0369, 0xd8e: 0x0289, 0xd8f: 0x13d1, 0xd90: 0x0039, 0xd91: 0x0ee9, + 0xd92: 0x1159, 0xd93: 0x0ef9, 0xd94: 0x0f09, 0xd95: 0x1199, 0xd96: 0x0f31, 0xd97: 0x0249, + 0xd98: 0x0f41, 0xd99: 0x0259, 0xd9a: 0x0f51, 0xd9b: 0x0359, 0xd9c: 0x0f61, 0xd9d: 0x0f71, + 0xd9e: 0x00d9, 0xd9f: 0x0f99, 0xda0: 0x2039, 0xda1: 0x0269, 0xda2: 0x01d9, 0xda3: 0x0fa9, + 0xda4: 0x0fb9, 0xda5: 0x1089, 0xda6: 0x0279, 0xda7: 0x0369, 0xda8: 0x0289, 0xda9: 0x13d1, + 0xdaa: 0x1f41, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018, + 0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018, + 0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018, 0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018, // Block 0x37, offset 0xdc0 - 0xdc0: 0x26fd, 0xdc1: 0x271d, 0xdc2: 0x273d, 0xdc3: 0x275d, 0xdc4: 0x277d, 0xdc5: 0x279d, - 0xdc6: 0x27bd, 0xdc7: 0x27dd, 0xdc8: 0x27fd, 0xdc9: 0x281d, 0xdca: 0x283d, 0xdcb: 0x285d, - 0xdcc: 0x287d, 0xdcd: 0x289d, 0xdce: 0x28bd, 0xdcf: 0x28dd, 0xdd0: 0x28fd, 0xdd1: 0x291d, - 0xdd2: 0x293d, 0xdd3: 0x295d, 0xdd4: 0x297d, 0xdd5: 0x299d, 0xdd6: 0x0040, 0xdd7: 0x0040, - 0xdd8: 0x0040, 0xdd9: 0x0040, 0xdda: 0x0040, 0xddb: 0x0040, 0xddc: 0x0040, 0xddd: 0x0040, - 0xdde: 0x0040, 0xddf: 0x0040, 0xde0: 0x0040, 0xde1: 0x0040, 0xde2: 0x0040, 0xde3: 0x0040, - 0xde4: 0x0040, 0xde5: 0x0040, 0xde6: 0x0040, 0xde7: 0x0040, 0xde8: 0x0040, 0xde9: 0x0040, - 0xdea: 0x0040, 0xdeb: 0x0040, 0xdec: 0x0040, 0xded: 0x0040, 0xdee: 0x0040, 0xdef: 0x0040, - 0xdf0: 0x0040, 0xdf1: 0x0040, 0xdf2: 0x0040, 0xdf3: 0x0040, 0xdf4: 0x0040, 0xdf5: 0x0040, - 0xdf6: 0x0040, 0xdf7: 0x0040, 0xdf8: 0x0040, 0xdf9: 0x0040, 0xdfa: 0x0040, 0xdfb: 0x0040, - 0xdfc: 0x0040, 0xdfd: 0x0040, 0xdfe: 0x0040, 0xdff: 0x0040, + 0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008, + 0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008, + 0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008, + 0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008, + 0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008, + 0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x2971, 0xde3: 0x0ebd, + 0xde4: 0x2989, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d, + 0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0fe1, 0xdee: 0x1281, 0xdef: 0x0fc9, + 0xdf0: 0x1141, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d, + 0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008, + 0xdfc: 0x0259, 0xdfd: 0x1089, 0xdfe: 0x29a1, 0xdff: 0x29b9, // Block 0x38, offset 0xe00 - 0xe00: 0x000a, 0xe01: 0x0018, 0xe02: 0x29d1, 0xe03: 0x0018, 0xe04: 0x0018, 0xe05: 0x0008, - 0xe06: 0x0008, 0xe07: 0x0008, 0xe08: 0x0018, 0xe09: 0x0018, 0xe0a: 0x0018, 0xe0b: 0x0018, - 0xe0c: 0x0018, 0xe0d: 0x0018, 0xe0e: 0x0018, 0xe0f: 0x0018, 0xe10: 0x0018, 0xe11: 0x0018, - 0xe12: 0x0018, 0xe13: 0x0018, 0xe14: 0x0018, 0xe15: 0x0018, 0xe16: 0x0018, 0xe17: 0x0018, - 0xe18: 0x0018, 0xe19: 0x0018, 0xe1a: 0x0018, 0xe1b: 0x0018, 0xe1c: 0x0018, 0xe1d: 0x0018, - 0xe1e: 0x0018, 0xe1f: 0x0018, 0xe20: 0x0018, 0xe21: 0x0018, 0xe22: 0x0018, 0xe23: 0x0018, - 0xe24: 0x0018, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018, - 0xe2a: 0x1308, 0xe2b: 0x1308, 0xe2c: 0x1308, 0xe2d: 0x1308, 0xe2e: 0x1018, 0xe2f: 0x1018, - 0xe30: 0x0018, 0xe31: 0x0018, 0xe32: 0x0018, 0xe33: 0x0018, 0xe34: 0x0018, 0xe35: 0x0018, - 0xe36: 0xe125, 0xe37: 0x0018, 0xe38: 0x29bd, 0xe39: 0x29dd, 0xe3a: 0x29fd, 0xe3b: 0x0018, - 0xe3c: 0x0008, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018, + 0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008, + 0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008, + 0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008, + 0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008, + 0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008, + 0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008, + 0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018, + 0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308, + 0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040, + 0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018, + 0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018, // Block 0x39, offset 0xe40 - 0xe40: 0x2b3d, 0xe41: 0x2b5d, 0xe42: 0x2b7d, 0xe43: 0x2b9d, 0xe44: 0x2bbd, 0xe45: 0x2bdd, - 0xe46: 0x2bdd, 0xe47: 0x2bdd, 0xe48: 0x2bfd, 0xe49: 0x2bfd, 0xe4a: 0x2bfd, 0xe4b: 0x2bfd, - 0xe4c: 0x2c1d, 0xe4d: 0x2c1d, 0xe4e: 0x2c1d, 0xe4f: 0x2c3d, 0xe50: 0x2c5d, 0xe51: 0x2c5d, - 0xe52: 0x2a7d, 0xe53: 0x2a7d, 0xe54: 0x2c5d, 0xe55: 0x2c5d, 0xe56: 0x2c7d, 0xe57: 0x2c7d, - 0xe58: 0x2c5d, 0xe59: 0x2c5d, 0xe5a: 0x2a7d, 0xe5b: 0x2a7d, 0xe5c: 0x2c5d, 0xe5d: 0x2c5d, - 0xe5e: 0x2c3d, 0xe5f: 0x2c3d, 0xe60: 0x2c9d, 0xe61: 0x2c9d, 0xe62: 0x2cbd, 0xe63: 0x2cbd, - 0xe64: 0x0040, 0xe65: 0x2cdd, 0xe66: 0x2cfd, 0xe67: 0x2d1d, 0xe68: 0x2d1d, 0xe69: 0x2d3d, - 0xe6a: 0x2d5d, 0xe6b: 0x2d7d, 0xe6c: 0x2d9d, 0xe6d: 0x2dbd, 0xe6e: 0x2ddd, 0xe6f: 0x2dfd, - 0xe70: 0x2e1d, 0xe71: 0x2e3d, 0xe72: 0x2e3d, 0xe73: 0x2e5d, 0xe74: 0x2e7d, 0xe75: 0x2e7d, - 0xe76: 0x2e9d, 0xe77: 0x2ebd, 0xe78: 0x2e5d, 0xe79: 0x2edd, 0xe7a: 0x2efd, 0xe7b: 0x2edd, - 0xe7c: 0x2e5d, 0xe7d: 0x2f1d, 0xe7e: 0x2f3d, 0xe7f: 0x2f5d, + 0xe40: 0x26fd, 0xe41: 0x271d, 0xe42: 0x273d, 0xe43: 0x275d, 0xe44: 0x277d, 0xe45: 0x279d, + 0xe46: 0x27bd, 0xe47: 0x27dd, 0xe48: 0x27fd, 0xe49: 0x281d, 0xe4a: 0x283d, 0xe4b: 0x285d, + 0xe4c: 0x287d, 0xe4d: 0x289d, 0xe4e: 0x28bd, 0xe4f: 0x28dd, 0xe50: 0x28fd, 0xe51: 0x291d, + 0xe52: 0x293d, 0xe53: 0x295d, 0xe54: 0x297d, 0xe55: 0x299d, 0xe56: 0x0040, 0xe57: 0x0040, + 0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040, + 0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040, + 0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040, + 0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040, + 0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040, + 0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040, + 0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040, // Block 0x3a, offset 0xe80 - 0xe80: 0x2f7d, 0xe81: 0x2f9d, 0xe82: 0x2cfd, 0xe83: 0x2cdd, 0xe84: 0x2fbd, 0xe85: 0x2fdd, - 0xe86: 0x2ffd, 0xe87: 0x301d, 0xe88: 0x303d, 0xe89: 0x305d, 0xe8a: 0x307d, 0xe8b: 0x309d, - 0xe8c: 0x30bd, 0xe8d: 0x30dd, 0xe8e: 0x30fd, 0xe8f: 0x0040, 0xe90: 0x0018, 0xe91: 0x0018, - 0xe92: 0x311d, 0xe93: 0x313d, 0xe94: 0x315d, 0xe95: 0x317d, 0xe96: 0x319d, 0xe97: 0x31bd, - 0xe98: 0x31dd, 0xe99: 0x31fd, 0xe9a: 0x321d, 0xe9b: 0x323d, 0xe9c: 0x315d, 0xe9d: 0x325d, - 0xe9e: 0x327d, 0xe9f: 0x329d, 0xea0: 0x0008, 0xea1: 0x0008, 0xea2: 0x0008, 0xea3: 0x0008, - 0xea4: 0x0008, 0xea5: 0x0008, 0xea6: 0x0008, 0xea7: 0x0008, 0xea8: 0x0008, 0xea9: 0x0008, - 0xeaa: 0x0008, 0xeab: 0x0008, 0xeac: 0x0008, 0xead: 0x0008, 0xeae: 0x0008, 0xeaf: 0x0008, - 0xeb0: 0x0008, 0xeb1: 0x0008, 0xeb2: 0x0008, 0xeb3: 0x0008, 0xeb4: 0x0008, 0xeb5: 0x0008, - 0xeb6: 0x0008, 0xeb7: 0x0008, 0xeb8: 0x0008, 0xeb9: 0x0008, 0xeba: 0x0008, 0xebb: 0x0040, - 0xebc: 0x0040, 0xebd: 0x0040, 0xebe: 0x0040, 0xebf: 0x0040, + 0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x29d1, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008, + 0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018, + 0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018, + 0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018, + 0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018, + 0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018, + 0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018, + 0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018, + 0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018, + 0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29bd, 0xeb9: 0x29dd, 0xeba: 0x29fd, 0xebb: 0x0018, + 0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018, // Block 0x3b, offset 0xec0 - 0xec0: 0x36a2, 0xec1: 0x36d2, 0xec2: 0x3702, 0xec3: 0x3732, 0xec4: 0x32bd, 0xec5: 0x32dd, - 0xec6: 0x32fd, 0xec7: 0x331d, 0xec8: 0x0018, 0xec9: 0x0018, 0xeca: 0x0018, 0xecb: 0x0018, - 0xecc: 0x0018, 0xecd: 0x0018, 0xece: 0x0018, 0xecf: 0x0018, 0xed0: 0x333d, 0xed1: 0x3761, - 0xed2: 0x3779, 0xed3: 0x3791, 0xed4: 0x37a9, 0xed5: 0x37c1, 0xed6: 0x37d9, 0xed7: 0x37f1, - 0xed8: 0x3809, 0xed9: 0x3821, 0xeda: 0x3839, 0xedb: 0x3851, 0xedc: 0x3869, 0xedd: 0x3881, - 0xede: 0x3899, 0xedf: 0x38b1, 0xee0: 0x335d, 0xee1: 0x337d, 0xee2: 0x339d, 0xee3: 0x33bd, - 0xee4: 0x33dd, 0xee5: 0x33dd, 0xee6: 0x33fd, 0xee7: 0x341d, 0xee8: 0x343d, 0xee9: 0x345d, - 0xeea: 0x347d, 0xeeb: 0x349d, 0xeec: 0x34bd, 0xeed: 0x34dd, 0xeee: 0x34fd, 0xeef: 0x351d, - 0xef0: 0x353d, 0xef1: 0x355d, 0xef2: 0x357d, 0xef3: 0x359d, 0xef4: 0x35bd, 0xef5: 0x35dd, - 0xef6: 0x35fd, 0xef7: 0x361d, 0xef8: 0x363d, 0xef9: 0x365d, 0xefa: 0x367d, 0xefb: 0x369d, - 0xefc: 0x38c9, 0xefd: 0x3901, 0xefe: 0x36bd, 0xeff: 0x0018, + 0xec0: 0x2b3d, 0xec1: 0x2b5d, 0xec2: 0x2b7d, 0xec3: 0x2b9d, 0xec4: 0x2bbd, 0xec5: 0x2bdd, + 0xec6: 0x2bdd, 0xec7: 0x2bdd, 0xec8: 0x2bfd, 0xec9: 0x2bfd, 0xeca: 0x2bfd, 0xecb: 0x2bfd, + 0xecc: 0x2c1d, 0xecd: 0x2c1d, 0xece: 0x2c1d, 0xecf: 0x2c3d, 0xed0: 0x2c5d, 0xed1: 0x2c5d, + 0xed2: 0x2a7d, 0xed3: 0x2a7d, 0xed4: 0x2c5d, 0xed5: 0x2c5d, 0xed6: 0x2c7d, 0xed7: 0x2c7d, + 0xed8: 0x2c5d, 0xed9: 0x2c5d, 0xeda: 0x2a7d, 0xedb: 0x2a7d, 0xedc: 0x2c5d, 0xedd: 0x2c5d, + 0xede: 0x2c3d, 0xedf: 0x2c3d, 0xee0: 0x2c9d, 0xee1: 0x2c9d, 0xee2: 0x2cbd, 0xee3: 0x2cbd, + 0xee4: 0x0040, 0xee5: 0x2cdd, 0xee6: 0x2cfd, 0xee7: 0x2d1d, 0xee8: 0x2d1d, 0xee9: 0x2d3d, + 0xeea: 0x2d5d, 0xeeb: 0x2d7d, 0xeec: 0x2d9d, 0xeed: 0x2dbd, 0xeee: 0x2ddd, 0xeef: 0x2dfd, + 0xef0: 0x2e1d, 0xef1: 0x2e3d, 0xef2: 0x2e3d, 0xef3: 0x2e5d, 0xef4: 0x2e7d, 0xef5: 0x2e7d, + 0xef6: 0x2e9d, 0xef7: 0x2ebd, 0xef8: 0x2e5d, 0xef9: 0x2edd, 0xefa: 0x2efd, 0xefb: 0x2edd, + 0xefc: 0x2e5d, 0xefd: 0x2f1d, 0xefe: 0x2f3d, 0xeff: 0x2f5d, // Block 0x3c, offset 0xf00 - 0xf00: 0x36dd, 0xf01: 0x36fd, 0xf02: 0x371d, 0xf03: 0x373d, 0xf04: 0x375d, 0xf05: 0x377d, - 0xf06: 0x379d, 0xf07: 0x37bd, 0xf08: 0x37dd, 0xf09: 0x37fd, 0xf0a: 0x381d, 0xf0b: 0x383d, - 0xf0c: 0x385d, 0xf0d: 0x387d, 0xf0e: 0x389d, 0xf0f: 0x38bd, 0xf10: 0x38dd, 0xf11: 0x38fd, - 0xf12: 0x391d, 0xf13: 0x393d, 0xf14: 0x395d, 0xf15: 0x397d, 0xf16: 0x399d, 0xf17: 0x39bd, - 0xf18: 0x39dd, 0xf19: 0x39fd, 0xf1a: 0x3a1d, 0xf1b: 0x3a3d, 0xf1c: 0x3a5d, 0xf1d: 0x3a7d, - 0xf1e: 0x3a9d, 0xf1f: 0x3abd, 0xf20: 0x3add, 0xf21: 0x3afd, 0xf22: 0x3b1d, 0xf23: 0x3b3d, - 0xf24: 0x3b5d, 0xf25: 0x3b7d, 0xf26: 0x127d, 0xf27: 0x3b9d, 0xf28: 0x3bbd, 0xf29: 0x3bdd, - 0xf2a: 0x3bfd, 0xf2b: 0x3c1d, 0xf2c: 0x3c3d, 0xf2d: 0x3c5d, 0xf2e: 0x239d, 0xf2f: 0x3c7d, - 0xf30: 0x3c9d, 0xf31: 0x3939, 0xf32: 0x3951, 0xf33: 0x3969, 0xf34: 0x3981, 0xf35: 0x3999, - 0xf36: 0x39b1, 0xf37: 0x39c9, 0xf38: 0x39e1, 0xf39: 0x39f9, 0xf3a: 0x3a11, 0xf3b: 0x3a29, - 0xf3c: 0x3a41, 0xf3d: 0x3a59, 0xf3e: 0x3a71, 0xf3f: 0x3a89, + 0xf00: 0x2f7d, 0xf01: 0x2f9d, 0xf02: 0x2cfd, 0xf03: 0x2cdd, 0xf04: 0x2fbd, 0xf05: 0x2fdd, + 0xf06: 0x2ffd, 0xf07: 0x301d, 0xf08: 0x303d, 0xf09: 0x305d, 0xf0a: 0x307d, 0xf0b: 0x309d, + 0xf0c: 0x30bd, 0xf0d: 0x30dd, 0xf0e: 0x30fd, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018, + 0xf12: 0x311d, 0xf13: 0x313d, 0xf14: 0x315d, 0xf15: 0x317d, 0xf16: 0x319d, 0xf17: 0x31bd, + 0xf18: 0x31dd, 0xf19: 0x31fd, 0xf1a: 0x321d, 0xf1b: 0x323d, 0xf1c: 0x315d, 0xf1d: 0x325d, + 0xf1e: 0x327d, 0xf1f: 0x329d, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008, + 0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008, + 0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008, + 0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008, + 0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0040, + 0xf3c: 0x0040, 0xf3d: 0x0040, 0xf3e: 0x0040, 0xf3f: 0x0040, // Block 0x3d, offset 0xf40 - 0xf40: 0x3aa1, 0xf41: 0x3ac9, 0xf42: 0x3af1, 0xf43: 0x3b19, 0xf44: 0x3b41, 0xf45: 0x3b69, - 0xf46: 0x3b91, 0xf47: 0x3bb9, 0xf48: 0x3be1, 0xf49: 0x3c09, 0xf4a: 0x3c39, 0xf4b: 0x3c69, - 0xf4c: 0x3c99, 0xf4d: 0x3cbd, 0xf4e: 0x3cb1, 0xf4f: 0x3cdd, 0xf50: 0x3cfd, 0xf51: 0x3d15, - 0xf52: 0x3d2d, 0xf53: 0x3d45, 0xf54: 0x3d5d, 0xf55: 0x3d5d, 0xf56: 0x3d45, 0xf57: 0x3d75, - 0xf58: 0x07bd, 0xf59: 0x3d8d, 0xf5a: 0x3da5, 0xf5b: 0x3dbd, 0xf5c: 0x3dd5, 0xf5d: 0x3ded, - 0xf5e: 0x3e05, 0xf5f: 0x3e1d, 0xf60: 0x3e35, 0xf61: 0x3e4d, 0xf62: 0x3e65, 0xf63: 0x3e7d, - 0xf64: 0x3e95, 0xf65: 0x3e95, 0xf66: 0x3ead, 0xf67: 0x3ead, 0xf68: 0x3ec5, 0xf69: 0x3ec5, - 0xf6a: 0x3edd, 0xf6b: 0x3ef5, 0xf6c: 0x3f0d, 0xf6d: 0x3f25, 0xf6e: 0x3f3d, 0xf6f: 0x3f3d, - 0xf70: 0x3f55, 0xf71: 0x3f55, 0xf72: 0x3f55, 0xf73: 0x3f6d, 0xf74: 0x3f85, 0xf75: 0x3f9d, - 0xf76: 0x3fb5, 0xf77: 0x3f9d, 0xf78: 0x3fcd, 0xf79: 0x3fe5, 0xf7a: 0x3f6d, 0xf7b: 0x3ffd, - 0xf7c: 0x4015, 0xf7d: 0x4015, 0xf7e: 0x4015, 0xf7f: 0x0040, + 0xf40: 0x36a2, 0xf41: 0x36d2, 0xf42: 0x3702, 0xf43: 0x3732, 0xf44: 0x32bd, 0xf45: 0x32dd, + 0xf46: 0x32fd, 0xf47: 0x331d, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018, + 0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x333d, 0xf51: 0x3761, + 0xf52: 0x3779, 0xf53: 0x3791, 0xf54: 0x37a9, 0xf55: 0x37c1, 0xf56: 0x37d9, 0xf57: 0x37f1, + 0xf58: 0x3809, 0xf59: 0x3821, 0xf5a: 0x3839, 0xf5b: 0x3851, 0xf5c: 0x3869, 0xf5d: 0x3881, + 0xf5e: 0x3899, 0xf5f: 0x38b1, 0xf60: 0x335d, 0xf61: 0x337d, 0xf62: 0x339d, 0xf63: 0x33bd, + 0xf64: 0x33dd, 0xf65: 0x33dd, 0xf66: 0x33fd, 0xf67: 0x341d, 0xf68: 0x343d, 0xf69: 0x345d, + 0xf6a: 0x347d, 0xf6b: 0x349d, 0xf6c: 0x34bd, 0xf6d: 0x34dd, 0xf6e: 0x34fd, 0xf6f: 0x351d, + 0xf70: 0x353d, 0xf71: 0x355d, 0xf72: 0x357d, 0xf73: 0x359d, 0xf74: 0x35bd, 0xf75: 0x35dd, + 0xf76: 0x35fd, 0xf77: 0x361d, 0xf78: 0x363d, 0xf79: 0x365d, 0xf7a: 0x367d, 0xf7b: 0x369d, + 0xf7c: 0x38c9, 0xf7d: 0x3901, 0xf7e: 0x36bd, 0xf7f: 0x0018, // Block 0x3e, offset 0xf80 - 0xf80: 0x3cc9, 0xf81: 0x3d31, 0xf82: 0x3d99, 0xf83: 0x3e01, 0xf84: 0x3e51, 0xf85: 0x3eb9, - 0xf86: 0x3f09, 0xf87: 0x3f59, 0xf88: 0x3fd9, 0xf89: 0x4041, 0xf8a: 0x4091, 0xf8b: 0x40e1, - 0xf8c: 0x4131, 0xf8d: 0x4199, 0xf8e: 0x4201, 0xf8f: 0x4251, 0xf90: 0x42a1, 0xf91: 0x42d9, - 0xf92: 0x4329, 0xf93: 0x4391, 0xf94: 0x43f9, 0xf95: 0x4431, 0xf96: 0x44b1, 0xf97: 0x4549, - 0xf98: 0x45c9, 0xf99: 0x4619, 0xf9a: 0x4699, 0xf9b: 0x4719, 0xf9c: 0x4781, 0xf9d: 0x47d1, - 0xf9e: 0x4821, 0xf9f: 0x4871, 0xfa0: 0x48d9, 0xfa1: 0x4959, 0xfa2: 0x49c1, 0xfa3: 0x4a11, - 0xfa4: 0x4a61, 0xfa5: 0x4ab1, 0xfa6: 0x4ae9, 0xfa7: 0x4b21, 0xfa8: 0x4b59, 0xfa9: 0x4b91, - 0xfaa: 0x4be1, 0xfab: 0x4c31, 0xfac: 0x4cb1, 0xfad: 0x4d01, 0xfae: 0x4d69, 0xfaf: 0x4de9, - 0xfb0: 0x4e39, 0xfb1: 0x4e71, 0xfb2: 0x4ea9, 0xfb3: 0x4f29, 0xfb4: 0x4f91, 0xfb5: 0x5011, - 0xfb6: 0x5061, 0xfb7: 0x50e1, 0xfb8: 0x5119, 0xfb9: 0x5169, 0xfba: 0x51b9, 0xfbb: 0x5209, - 0xfbc: 0x5259, 0xfbd: 0x52a9, 0xfbe: 0x5311, 0xfbf: 0x5361, + 0xf80: 0x36dd, 0xf81: 0x36fd, 0xf82: 0x371d, 0xf83: 0x373d, 0xf84: 0x375d, 0xf85: 0x377d, + 0xf86: 0x379d, 0xf87: 0x37bd, 0xf88: 0x37dd, 0xf89: 0x37fd, 0xf8a: 0x381d, 0xf8b: 0x383d, + 0xf8c: 0x385d, 0xf8d: 0x387d, 0xf8e: 0x389d, 0xf8f: 0x38bd, 0xf90: 0x38dd, 0xf91: 0x38fd, + 0xf92: 0x391d, 0xf93: 0x393d, 0xf94: 0x395d, 0xf95: 0x397d, 0xf96: 0x399d, 0xf97: 0x39bd, + 0xf98: 0x39dd, 0xf99: 0x39fd, 0xf9a: 0x3a1d, 0xf9b: 0x3a3d, 0xf9c: 0x3a5d, 0xf9d: 0x3a7d, + 0xf9e: 0x3a9d, 0xf9f: 0x3abd, 0xfa0: 0x3add, 0xfa1: 0x3afd, 0xfa2: 0x3b1d, 0xfa3: 0x3b3d, + 0xfa4: 0x3b5d, 0xfa5: 0x3b7d, 0xfa6: 0x127d, 0xfa7: 0x3b9d, 0xfa8: 0x3bbd, 0xfa9: 0x3bdd, + 0xfaa: 0x3bfd, 0xfab: 0x3c1d, 0xfac: 0x3c3d, 0xfad: 0x3c5d, 0xfae: 0x239d, 0xfaf: 0x3c7d, + 0xfb0: 0x3c9d, 0xfb1: 0x3939, 0xfb2: 0x3951, 0xfb3: 0x3969, 0xfb4: 0x3981, 0xfb5: 0x3999, + 0xfb6: 0x39b1, 0xfb7: 0x39c9, 0xfb8: 0x39e1, 0xfb9: 0x39f9, 0xfba: 0x3a11, 0xfbb: 0x3a29, + 0xfbc: 0x3a41, 0xfbd: 0x3a59, 0xfbe: 0x3a71, 0xfbf: 0x3a89, // Block 0x3f, offset 0xfc0 - 0xfc0: 0x5399, 0xfc1: 0x53e9, 0xfc2: 0x5439, 0xfc3: 0x5489, 0xfc4: 0x54f1, 0xfc5: 0x5541, - 0xfc6: 0x5591, 0xfc7: 0x55e1, 0xfc8: 0x5661, 0xfc9: 0x56c9, 0xfca: 0x5701, 0xfcb: 0x5781, - 0xfcc: 0x57b9, 0xfcd: 0x5821, 0xfce: 0x5889, 0xfcf: 0x58d9, 0xfd0: 0x5929, 0xfd1: 0x5979, - 0xfd2: 0x59e1, 0xfd3: 0x5a19, 0xfd4: 0x5a69, 0xfd5: 0x5ad1, 0xfd6: 0x5b09, 0xfd7: 0x5b89, - 0xfd8: 0x5bd9, 0xfd9: 0x5c01, 0xfda: 0x5c29, 0xfdb: 0x5c51, 0xfdc: 0x5c79, 0xfdd: 0x5ca1, - 0xfde: 0x5cc9, 0xfdf: 0x5cf1, 0xfe0: 0x5d19, 0xfe1: 0x5d41, 0xfe2: 0x5d69, 0xfe3: 0x5d99, - 0xfe4: 0x5dc9, 0xfe5: 0x5df9, 0xfe6: 0x5e29, 0xfe7: 0x5e59, 0xfe8: 0x5e89, 0xfe9: 0x5eb9, - 0xfea: 0x5ee9, 0xfeb: 0x5f19, 0xfec: 0x5f49, 0xfed: 0x5f79, 0xfee: 0x5fa9, 0xfef: 0x5fd9, - 0xff0: 0x6009, 0xff1: 0x402d, 0xff2: 0x6039, 0xff3: 0x6051, 0xff4: 0x404d, 0xff5: 0x6069, - 0xff6: 0x6081, 0xff7: 0x6099, 0xff8: 0x406d, 0xff9: 0x406d, 0xffa: 0x60b1, 0xffb: 0x60c9, - 0xffc: 0x6101, 0xffd: 0x6139, 0xffe: 0x6171, 0xfff: 0x61a9, + 0xfc0: 0x3aa1, 0xfc1: 0x3ac9, 0xfc2: 0x3af1, 0xfc3: 0x3b19, 0xfc4: 0x3b41, 0xfc5: 0x3b69, + 0xfc6: 0x3b91, 0xfc7: 0x3bb9, 0xfc8: 0x3be1, 0xfc9: 0x3c09, 0xfca: 0x3c39, 0xfcb: 0x3c69, + 0xfcc: 0x3c99, 0xfcd: 0x3cbd, 0xfce: 0x3cb1, 0xfcf: 0x3cdd, 0xfd0: 0x3cfd, 0xfd1: 0x3d15, + 0xfd2: 0x3d2d, 0xfd3: 0x3d45, 0xfd4: 0x3d5d, 0xfd5: 0x3d5d, 0xfd6: 0x3d45, 0xfd7: 0x3d75, + 0xfd8: 0x07bd, 0xfd9: 0x3d8d, 0xfda: 0x3da5, 0xfdb: 0x3dbd, 0xfdc: 0x3dd5, 0xfdd: 0x3ded, + 0xfde: 0x3e05, 0xfdf: 0x3e1d, 0xfe0: 0x3e35, 0xfe1: 0x3e4d, 0xfe2: 0x3e65, 0xfe3: 0x3e7d, + 0xfe4: 0x3e95, 0xfe5: 0x3e95, 0xfe6: 0x3ead, 0xfe7: 0x3ead, 0xfe8: 0x3ec5, 0xfe9: 0x3ec5, + 0xfea: 0x3edd, 0xfeb: 0x3ef5, 0xfec: 0x3f0d, 0xfed: 0x3f25, 0xfee: 0x3f3d, 0xfef: 0x3f3d, + 0xff0: 0x3f55, 0xff1: 0x3f55, 0xff2: 0x3f55, 0xff3: 0x3f6d, 0xff4: 0x3f85, 0xff5: 0x3f9d, + 0xff6: 0x3fb5, 0xff7: 0x3f9d, 0xff8: 0x3fcd, 0xff9: 0x3fe5, 0xffa: 0x3f6d, 0xffb: 0x3ffd, + 0xffc: 0x4015, 0xffd: 0x4015, 0xffe: 0x4015, 0xfff: 0x0040, // Block 0x40, offset 0x1000 - 0x1000: 0x6211, 0x1001: 0x6229, 0x1002: 0x408d, 0x1003: 0x6241, 0x1004: 0x6259, 0x1005: 0x6271, - 0x1006: 0x6289, 0x1007: 0x62a1, 0x1008: 0x40ad, 0x1009: 0x62b9, 0x100a: 0x62e1, 0x100b: 0x62f9, - 0x100c: 0x40cd, 0x100d: 0x40cd, 0x100e: 0x6311, 0x100f: 0x6329, 0x1010: 0x6341, 0x1011: 0x40ed, - 0x1012: 0x410d, 0x1013: 0x412d, 0x1014: 0x414d, 0x1015: 0x416d, 0x1016: 0x6359, 0x1017: 0x6371, - 0x1018: 0x6389, 0x1019: 0x63a1, 0x101a: 0x63b9, 0x101b: 0x418d, 0x101c: 0x63d1, 0x101d: 0x63e9, - 0x101e: 0x6401, 0x101f: 0x41ad, 0x1020: 0x41cd, 0x1021: 0x6419, 0x1022: 0x41ed, 0x1023: 0x420d, - 0x1024: 0x422d, 0x1025: 0x6431, 0x1026: 0x424d, 0x1027: 0x6449, 0x1028: 0x6479, 0x1029: 0x6211, - 0x102a: 0x426d, 0x102b: 0x428d, 0x102c: 0x42ad, 0x102d: 0x42cd, 0x102e: 0x64b1, 0x102f: 0x64f1, - 0x1030: 0x6539, 0x1031: 0x6551, 0x1032: 0x42ed, 0x1033: 0x6569, 0x1034: 0x6581, 0x1035: 0x6599, - 0x1036: 0x430d, 0x1037: 0x65b1, 0x1038: 0x65c9, 0x1039: 0x65b1, 0x103a: 0x65e1, 0x103b: 0x65f9, - 0x103c: 0x432d, 0x103d: 0x6611, 0x103e: 0x6629, 0x103f: 0x6611, + 0x1000: 0x3cc9, 0x1001: 0x3d31, 0x1002: 0x3d99, 0x1003: 0x3e01, 0x1004: 0x3e51, 0x1005: 0x3eb9, + 0x1006: 0x3f09, 0x1007: 0x3f59, 0x1008: 0x3fd9, 0x1009: 0x4041, 0x100a: 0x4091, 0x100b: 0x40e1, + 0x100c: 0x4131, 0x100d: 0x4199, 0x100e: 0x4201, 0x100f: 0x4251, 0x1010: 0x42a1, 0x1011: 0x42d9, + 0x1012: 0x4329, 0x1013: 0x4391, 0x1014: 0x43f9, 0x1015: 0x4431, 0x1016: 0x44b1, 0x1017: 0x4549, + 0x1018: 0x45c9, 0x1019: 0x4619, 0x101a: 0x4699, 0x101b: 0x4719, 0x101c: 0x4781, 0x101d: 0x47d1, + 0x101e: 0x4821, 0x101f: 0x4871, 0x1020: 0x48d9, 0x1021: 0x4959, 0x1022: 0x49c1, 0x1023: 0x4a11, + 0x1024: 0x4a61, 0x1025: 0x4ab1, 0x1026: 0x4ae9, 0x1027: 0x4b21, 0x1028: 0x4b59, 0x1029: 0x4b91, + 0x102a: 0x4be1, 0x102b: 0x4c31, 0x102c: 0x4cb1, 0x102d: 0x4d01, 0x102e: 0x4d69, 0x102f: 0x4de9, + 0x1030: 0x4e39, 0x1031: 0x4e71, 0x1032: 0x4ea9, 0x1033: 0x4f29, 0x1034: 0x4f91, 0x1035: 0x5011, + 0x1036: 0x5061, 0x1037: 0x50e1, 0x1038: 0x5119, 0x1039: 0x5169, 0x103a: 0x51b9, 0x103b: 0x5209, + 0x103c: 0x5259, 0x103d: 0x52a9, 0x103e: 0x5311, 0x103f: 0x5361, // Block 0x41, offset 0x1040 - 0x1040: 0x434d, 0x1041: 0x436d, 0x1042: 0x0040, 0x1043: 0x6641, 0x1044: 0x6659, 0x1045: 0x6671, - 0x1046: 0x6689, 0x1047: 0x0040, 0x1048: 0x66c1, 0x1049: 0x66d9, 0x104a: 0x66f1, 0x104b: 0x6709, - 0x104c: 0x6721, 0x104d: 0x6739, 0x104e: 0x6401, 0x104f: 0x6751, 0x1050: 0x6769, 0x1051: 0x6781, - 0x1052: 0x438d, 0x1053: 0x6799, 0x1054: 0x6289, 0x1055: 0x43ad, 0x1056: 0x43cd, 0x1057: 0x67b1, - 0x1058: 0x0040, 0x1059: 0x43ed, 0x105a: 0x67c9, 0x105b: 0x67e1, 0x105c: 0x67f9, 0x105d: 0x6811, - 0x105e: 0x6829, 0x105f: 0x6859, 0x1060: 0x6889, 0x1061: 0x68b1, 0x1062: 0x68d9, 0x1063: 0x6901, - 0x1064: 0x6929, 0x1065: 0x6951, 0x1066: 0x6979, 0x1067: 0x69a1, 0x1068: 0x69c9, 0x1069: 0x69f1, - 0x106a: 0x6a21, 0x106b: 0x6a51, 0x106c: 0x6a81, 0x106d: 0x6ab1, 0x106e: 0x6ae1, 0x106f: 0x6b11, - 0x1070: 0x6b41, 0x1071: 0x6b71, 0x1072: 0x6ba1, 0x1073: 0x6bd1, 0x1074: 0x6c01, 0x1075: 0x6c31, - 0x1076: 0x6c61, 0x1077: 0x6c91, 0x1078: 0x6cc1, 0x1079: 0x6cf1, 0x107a: 0x6d21, 0x107b: 0x6d51, - 0x107c: 0x6d81, 0x107d: 0x6db1, 0x107e: 0x6de1, 0x107f: 0x440d, + 0x1040: 0x5399, 0x1041: 0x53e9, 0x1042: 0x5439, 0x1043: 0x5489, 0x1044: 0x54f1, 0x1045: 0x5541, + 0x1046: 0x5591, 0x1047: 0x55e1, 0x1048: 0x5661, 0x1049: 0x56c9, 0x104a: 0x5701, 0x104b: 0x5781, + 0x104c: 0x57b9, 0x104d: 0x5821, 0x104e: 0x5889, 0x104f: 0x58d9, 0x1050: 0x5929, 0x1051: 0x5979, + 0x1052: 0x59e1, 0x1053: 0x5a19, 0x1054: 0x5a69, 0x1055: 0x5ad1, 0x1056: 0x5b09, 0x1057: 0x5b89, + 0x1058: 0x5bd9, 0x1059: 0x5c01, 0x105a: 0x5c29, 0x105b: 0x5c51, 0x105c: 0x5c79, 0x105d: 0x5ca1, + 0x105e: 0x5cc9, 0x105f: 0x5cf1, 0x1060: 0x5d19, 0x1061: 0x5d41, 0x1062: 0x5d69, 0x1063: 0x5d99, + 0x1064: 0x5dc9, 0x1065: 0x5df9, 0x1066: 0x5e29, 0x1067: 0x5e59, 0x1068: 0x5e89, 0x1069: 0x5eb9, + 0x106a: 0x5ee9, 0x106b: 0x5f19, 0x106c: 0x5f49, 0x106d: 0x5f79, 0x106e: 0x5fa9, 0x106f: 0x5fd9, + 0x1070: 0x6009, 0x1071: 0x402d, 0x1072: 0x6039, 0x1073: 0x6051, 0x1074: 0x404d, 0x1075: 0x6069, + 0x1076: 0x6081, 0x1077: 0x6099, 0x1078: 0x406d, 0x1079: 0x406d, 0x107a: 0x60b1, 0x107b: 0x60c9, + 0x107c: 0x6101, 0x107d: 0x6139, 0x107e: 0x6171, 0x107f: 0x61a9, // Block 0x42, offset 0x1080 - 0x1080: 0xe00d, 0x1081: 0x0008, 0x1082: 0xe00d, 0x1083: 0x0008, 0x1084: 0xe00d, 0x1085: 0x0008, - 0x1086: 0xe00d, 0x1087: 0x0008, 0x1088: 0xe00d, 0x1089: 0x0008, 0x108a: 0xe00d, 0x108b: 0x0008, - 0x108c: 0xe00d, 0x108d: 0x0008, 0x108e: 0xe00d, 0x108f: 0x0008, 0x1090: 0xe00d, 0x1091: 0x0008, - 0x1092: 0xe00d, 0x1093: 0x0008, 0x1094: 0xe00d, 0x1095: 0x0008, 0x1096: 0xe00d, 0x1097: 0x0008, - 0x1098: 0xe00d, 0x1099: 0x0008, 0x109a: 0xe00d, 0x109b: 0x0008, 0x109c: 0xe00d, 0x109d: 0x0008, - 0x109e: 0xe00d, 0x109f: 0x0008, 0x10a0: 0xe00d, 0x10a1: 0x0008, 0x10a2: 0xe00d, 0x10a3: 0x0008, - 0x10a4: 0xe00d, 0x10a5: 0x0008, 0x10a6: 0xe00d, 0x10a7: 0x0008, 0x10a8: 0xe00d, 0x10a9: 0x0008, - 0x10aa: 0xe00d, 0x10ab: 0x0008, 0x10ac: 0xe00d, 0x10ad: 0x0008, 0x10ae: 0x0008, 0x10af: 0x1308, - 0x10b0: 0x1318, 0x10b1: 0x1318, 0x10b2: 0x1318, 0x10b3: 0x0018, 0x10b4: 0x1308, 0x10b5: 0x1308, - 0x10b6: 0x1308, 0x10b7: 0x1308, 0x10b8: 0x1308, 0x10b9: 0x1308, 0x10ba: 0x1308, 0x10bb: 0x1308, - 0x10bc: 0x1308, 0x10bd: 0x1308, 0x10be: 0x0018, 0x10bf: 0x0008, + 0x1080: 0x6211, 0x1081: 0x6229, 0x1082: 0x408d, 0x1083: 0x6241, 0x1084: 0x6259, 0x1085: 0x6271, + 0x1086: 0x6289, 0x1087: 0x62a1, 0x1088: 0x40ad, 0x1089: 0x62b9, 0x108a: 0x62e1, 0x108b: 0x62f9, + 0x108c: 0x40cd, 0x108d: 0x40cd, 0x108e: 0x6311, 0x108f: 0x6329, 0x1090: 0x6341, 0x1091: 0x40ed, + 0x1092: 0x410d, 0x1093: 0x412d, 0x1094: 0x414d, 0x1095: 0x416d, 0x1096: 0x6359, 0x1097: 0x6371, + 0x1098: 0x6389, 0x1099: 0x63a1, 0x109a: 0x63b9, 0x109b: 0x418d, 0x109c: 0x63d1, 0x109d: 0x63e9, + 0x109e: 0x6401, 0x109f: 0x41ad, 0x10a0: 0x41cd, 0x10a1: 0x6419, 0x10a2: 0x41ed, 0x10a3: 0x420d, + 0x10a4: 0x422d, 0x10a5: 0x6431, 0x10a6: 0x424d, 0x10a7: 0x6449, 0x10a8: 0x6479, 0x10a9: 0x6211, + 0x10aa: 0x426d, 0x10ab: 0x428d, 0x10ac: 0x42ad, 0x10ad: 0x42cd, 0x10ae: 0x64b1, 0x10af: 0x64f1, + 0x10b0: 0x6539, 0x10b1: 0x6551, 0x10b2: 0x42ed, 0x10b3: 0x6569, 0x10b4: 0x6581, 0x10b5: 0x6599, + 0x10b6: 0x430d, 0x10b7: 0x65b1, 0x10b8: 0x65c9, 0x10b9: 0x65b1, 0x10ba: 0x65e1, 0x10bb: 0x65f9, + 0x10bc: 0x432d, 0x10bd: 0x6611, 0x10be: 0x6629, 0x10bf: 0x6611, // Block 0x43, offset 0x10c0 - 0x10c0: 0xe00d, 0x10c1: 0x0008, 0x10c2: 0xe00d, 0x10c3: 0x0008, 0x10c4: 0xe00d, 0x10c5: 0x0008, - 0x10c6: 0xe00d, 0x10c7: 0x0008, 0x10c8: 0xe00d, 0x10c9: 0x0008, 0x10ca: 0xe00d, 0x10cb: 0x0008, - 0x10cc: 0xe00d, 0x10cd: 0x0008, 0x10ce: 0xe00d, 0x10cf: 0x0008, 0x10d0: 0xe00d, 0x10d1: 0x0008, - 0x10d2: 0xe00d, 0x10d3: 0x0008, 0x10d4: 0xe00d, 0x10d5: 0x0008, 0x10d6: 0xe00d, 0x10d7: 0x0008, - 0x10d8: 0xe00d, 0x10d9: 0x0008, 0x10da: 0xe00d, 0x10db: 0x0008, 0x10dc: 0x0ea1, 0x10dd: 0x6e11, - 0x10de: 0x1308, 0x10df: 0x1308, 0x10e0: 0x0008, 0x10e1: 0x0008, 0x10e2: 0x0008, 0x10e3: 0x0008, - 0x10e4: 0x0008, 0x10e5: 0x0008, 0x10e6: 0x0008, 0x10e7: 0x0008, 0x10e8: 0x0008, 0x10e9: 0x0008, - 0x10ea: 0x0008, 0x10eb: 0x0008, 0x10ec: 0x0008, 0x10ed: 0x0008, 0x10ee: 0x0008, 0x10ef: 0x0008, - 0x10f0: 0x0008, 0x10f1: 0x0008, 0x10f2: 0x0008, 0x10f3: 0x0008, 0x10f4: 0x0008, 0x10f5: 0x0008, - 0x10f6: 0x0008, 0x10f7: 0x0008, 0x10f8: 0x0008, 0x10f9: 0x0008, 0x10fa: 0x0008, 0x10fb: 0x0008, - 0x10fc: 0x0008, 0x10fd: 0x0008, 0x10fe: 0x0008, 0x10ff: 0x0008, + 0x10c0: 0x434d, 0x10c1: 0x436d, 0x10c2: 0x0040, 0x10c3: 0x6641, 0x10c4: 0x6659, 0x10c5: 0x6671, + 0x10c6: 0x6689, 0x10c7: 0x0040, 0x10c8: 0x66c1, 0x10c9: 0x66d9, 0x10ca: 0x66f1, 0x10cb: 0x6709, + 0x10cc: 0x6721, 0x10cd: 0x6739, 0x10ce: 0x6401, 0x10cf: 0x6751, 0x10d0: 0x6769, 0x10d1: 0x6781, + 0x10d2: 0x438d, 0x10d3: 0x6799, 0x10d4: 0x6289, 0x10d5: 0x43ad, 0x10d6: 0x43cd, 0x10d7: 0x67b1, + 0x10d8: 0x0040, 0x10d9: 0x43ed, 0x10da: 0x67c9, 0x10db: 0x67e1, 0x10dc: 0x67f9, 0x10dd: 0x6811, + 0x10de: 0x6829, 0x10df: 0x6859, 0x10e0: 0x6889, 0x10e1: 0x68b1, 0x10e2: 0x68d9, 0x10e3: 0x6901, + 0x10e4: 0x6929, 0x10e5: 0x6951, 0x10e6: 0x6979, 0x10e7: 0x69a1, 0x10e8: 0x69c9, 0x10e9: 0x69f1, + 0x10ea: 0x6a21, 0x10eb: 0x6a51, 0x10ec: 0x6a81, 0x10ed: 0x6ab1, 0x10ee: 0x6ae1, 0x10ef: 0x6b11, + 0x10f0: 0x6b41, 0x10f1: 0x6b71, 0x10f2: 0x6ba1, 0x10f3: 0x6bd1, 0x10f4: 0x6c01, 0x10f5: 0x6c31, + 0x10f6: 0x6c61, 0x10f7: 0x6c91, 0x10f8: 0x6cc1, 0x10f9: 0x6cf1, 0x10fa: 0x6d21, 0x10fb: 0x6d51, + 0x10fc: 0x6d81, 0x10fd: 0x6db1, 0x10fe: 0x6de1, 0x10ff: 0x440d, // Block 0x44, offset 0x1100 - 0x1100: 0x0018, 0x1101: 0x0018, 0x1102: 0x0018, 0x1103: 0x0018, 0x1104: 0x0018, 0x1105: 0x0018, - 0x1106: 0x0018, 0x1107: 0x0018, 0x1108: 0x0018, 0x1109: 0x0018, 0x110a: 0x0018, 0x110b: 0x0018, - 0x110c: 0x0018, 0x110d: 0x0018, 0x110e: 0x0018, 0x110f: 0x0018, 0x1110: 0x0018, 0x1111: 0x0018, - 0x1112: 0x0018, 0x1113: 0x0018, 0x1114: 0x0018, 0x1115: 0x0018, 0x1116: 0x0018, 0x1117: 0x0008, - 0x1118: 0x0008, 0x1119: 0x0008, 0x111a: 0x0008, 0x111b: 0x0008, 0x111c: 0x0008, 0x111d: 0x0008, - 0x111e: 0x0008, 0x111f: 0x0008, 0x1120: 0x0018, 0x1121: 0x0018, 0x1122: 0xe00d, 0x1123: 0x0008, + 0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008, + 0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008, + 0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008, + 0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008, + 0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0xe00d, 0x111d: 0x0008, + 0x111e: 0xe00d, 0x111f: 0x0008, 0x1120: 0xe00d, 0x1121: 0x0008, 0x1122: 0xe00d, 0x1123: 0x0008, 0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008, - 0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0xe00d, 0x112f: 0x0008, - 0x1130: 0x0008, 0x1131: 0x0008, 0x1132: 0xe00d, 0x1133: 0x0008, 0x1134: 0xe00d, 0x1135: 0x0008, - 0x1136: 0xe00d, 0x1137: 0x0008, 0x1138: 0xe00d, 0x1139: 0x0008, 0x113a: 0xe00d, 0x113b: 0x0008, - 0x113c: 0xe00d, 0x113d: 0x0008, 0x113e: 0xe00d, 0x113f: 0x0008, + 0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x3308, + 0x1130: 0x3318, 0x1131: 0x3318, 0x1132: 0x3318, 0x1133: 0x0018, 0x1134: 0x3308, 0x1135: 0x3308, + 0x1136: 0x3308, 0x1137: 0x3308, 0x1138: 0x3308, 0x1139: 0x3308, 0x113a: 0x3308, 0x113b: 0x3308, + 0x113c: 0x3308, 0x113d: 0x3308, 0x113e: 0x0018, 0x113f: 0x0008, // Block 0x45, offset 0x1140 0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008, 0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008, 0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008, 0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008, - 0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0xe00d, 0x115d: 0x0008, - 0x115e: 0xe00d, 0x115f: 0x0008, 0x1160: 0xe00d, 0x1161: 0x0008, 0x1162: 0xe00d, 0x1163: 0x0008, - 0x1164: 0xe00d, 0x1165: 0x0008, 0x1166: 0xe00d, 0x1167: 0x0008, 0x1168: 0xe00d, 0x1169: 0x0008, - 0x116a: 0xe00d, 0x116b: 0x0008, 0x116c: 0xe00d, 0x116d: 0x0008, 0x116e: 0xe00d, 0x116f: 0x0008, - 0x1170: 0xe0fd, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008, - 0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0xe01d, 0x117a: 0x0008, 0x117b: 0xe03d, - 0x117c: 0x0008, 0x117d: 0x442d, 0x117e: 0xe00d, 0x117f: 0x0008, + 0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0x0ea1, 0x115d: 0x6e11, + 0x115e: 0x3308, 0x115f: 0x3308, 0x1160: 0x0008, 0x1161: 0x0008, 0x1162: 0x0008, 0x1163: 0x0008, + 0x1164: 0x0008, 0x1165: 0x0008, 0x1166: 0x0008, 0x1167: 0x0008, 0x1168: 0x0008, 0x1169: 0x0008, + 0x116a: 0x0008, 0x116b: 0x0008, 0x116c: 0x0008, 0x116d: 0x0008, 0x116e: 0x0008, 0x116f: 0x0008, + 0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008, + 0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0x0008, 0x117a: 0x0008, 0x117b: 0x0008, + 0x117c: 0x0008, 0x117d: 0x0008, 0x117e: 0x0008, 0x117f: 0x0008, // Block 0x46, offset 0x1180 - 0x1180: 0xe00d, 0x1181: 0x0008, 0x1182: 0xe00d, 0x1183: 0x0008, 0x1184: 0xe00d, 0x1185: 0x0008, - 0x1186: 0xe00d, 0x1187: 0x0008, 0x1188: 0x0008, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0xe03d, - 0x118c: 0x0008, 0x118d: 0x11d9, 0x118e: 0x0008, 0x118f: 0x0008, 0x1190: 0xe00d, 0x1191: 0x0008, - 0x1192: 0xe00d, 0x1193: 0x0008, 0x1194: 0x0008, 0x1195: 0x0008, 0x1196: 0xe00d, 0x1197: 0x0008, - 0x1198: 0xe00d, 0x1199: 0x0008, 0x119a: 0xe00d, 0x119b: 0x0008, 0x119c: 0xe00d, 0x119d: 0x0008, - 0x119e: 0xe00d, 0x119f: 0x0008, 0x11a0: 0xe00d, 0x11a1: 0x0008, 0x11a2: 0xe00d, 0x11a3: 0x0008, + 0x1180: 0x0018, 0x1181: 0x0018, 0x1182: 0x0018, 0x1183: 0x0018, 0x1184: 0x0018, 0x1185: 0x0018, + 0x1186: 0x0018, 0x1187: 0x0018, 0x1188: 0x0018, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0x0018, + 0x118c: 0x0018, 0x118d: 0x0018, 0x118e: 0x0018, 0x118f: 0x0018, 0x1190: 0x0018, 0x1191: 0x0018, + 0x1192: 0x0018, 0x1193: 0x0018, 0x1194: 0x0018, 0x1195: 0x0018, 0x1196: 0x0018, 0x1197: 0x0008, + 0x1198: 0x0008, 0x1199: 0x0008, 0x119a: 0x0008, 0x119b: 0x0008, 0x119c: 0x0008, 0x119d: 0x0008, + 0x119e: 0x0008, 0x119f: 0x0008, 0x11a0: 0x0018, 0x11a1: 0x0018, 0x11a2: 0xe00d, 0x11a3: 0x0008, 0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008, - 0x11aa: 0x6e29, 0x11ab: 0x1029, 0x11ac: 0x11c1, 0x11ad: 0x6e41, 0x11ae: 0x1221, 0x11af: 0x0040, - 0x11b0: 0x6e59, 0x11b1: 0x6e71, 0x11b2: 0x1239, 0x11b3: 0x444d, 0x11b4: 0xe00d, 0x11b5: 0x0008, - 0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0x0040, 0x11b9: 0x0040, 0x11ba: 0x0040, 0x11bb: 0x0040, - 0x11bc: 0x0040, 0x11bd: 0x0040, 0x11be: 0x0040, 0x11bf: 0x0040, + 0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008, + 0x11b0: 0x0008, 0x11b1: 0x0008, 0x11b2: 0xe00d, 0x11b3: 0x0008, 0x11b4: 0xe00d, 0x11b5: 0x0008, + 0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008, + 0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008, // Block 0x47, offset 0x11c0 - 0x11c0: 0x64d5, 0x11c1: 0x64f5, 0x11c2: 0x6515, 0x11c3: 0x6535, 0x11c4: 0x6555, 0x11c5: 0x6575, - 0x11c6: 0x6595, 0x11c7: 0x65b5, 0x11c8: 0x65d5, 0x11c9: 0x65f5, 0x11ca: 0x6615, 0x11cb: 0x6635, - 0x11cc: 0x6655, 0x11cd: 0x6675, 0x11ce: 0x0008, 0x11cf: 0x0008, 0x11d0: 0x6695, 0x11d1: 0x0008, - 0x11d2: 0x66b5, 0x11d3: 0x0008, 0x11d4: 0x0008, 0x11d5: 0x66d5, 0x11d6: 0x66f5, 0x11d7: 0x6715, - 0x11d8: 0x6735, 0x11d9: 0x6755, 0x11da: 0x6775, 0x11db: 0x6795, 0x11dc: 0x67b5, 0x11dd: 0x67d5, - 0x11de: 0x67f5, 0x11df: 0x0008, 0x11e0: 0x6815, 0x11e1: 0x0008, 0x11e2: 0x6835, 0x11e3: 0x0008, - 0x11e4: 0x0008, 0x11e5: 0x6855, 0x11e6: 0x6875, 0x11e7: 0x0008, 0x11e8: 0x0008, 0x11e9: 0x0008, - 0x11ea: 0x6895, 0x11eb: 0x68b5, 0x11ec: 0x68d5, 0x11ed: 0x68f5, 0x11ee: 0x6915, 0x11ef: 0x6935, - 0x11f0: 0x6955, 0x11f1: 0x6975, 0x11f2: 0x6995, 0x11f3: 0x69b5, 0x11f4: 0x69d5, 0x11f5: 0x69f5, - 0x11f6: 0x6a15, 0x11f7: 0x6a35, 0x11f8: 0x6a55, 0x11f9: 0x6a75, 0x11fa: 0x6a95, 0x11fb: 0x6ab5, - 0x11fc: 0x6ad5, 0x11fd: 0x6af5, 0x11fe: 0x6b15, 0x11ff: 0x6b35, + 0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008, + 0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0xe00d, 0x11c9: 0x0008, 0x11ca: 0xe00d, 0x11cb: 0x0008, + 0x11cc: 0xe00d, 0x11cd: 0x0008, 0x11ce: 0xe00d, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008, + 0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0xe00d, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008, + 0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008, + 0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008, + 0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008, + 0x11ea: 0xe00d, 0x11eb: 0x0008, 0x11ec: 0xe00d, 0x11ed: 0x0008, 0x11ee: 0xe00d, 0x11ef: 0x0008, + 0x11f0: 0xe0fd, 0x11f1: 0x0008, 0x11f2: 0x0008, 0x11f3: 0x0008, 0x11f4: 0x0008, 0x11f5: 0x0008, + 0x11f6: 0x0008, 0x11f7: 0x0008, 0x11f8: 0x0008, 0x11f9: 0xe01d, 0x11fa: 0x0008, 0x11fb: 0xe03d, + 0x11fc: 0x0008, 0x11fd: 0x442d, 0x11fe: 0xe00d, 0x11ff: 0x0008, // Block 0x48, offset 0x1200 - 0x1200: 0x7a95, 0x1201: 0x7ab5, 0x1202: 0x7ad5, 0x1203: 0x7af5, 0x1204: 0x7b15, 0x1205: 0x7b35, - 0x1206: 0x7b55, 0x1207: 0x7b75, 0x1208: 0x7b95, 0x1209: 0x7bb5, 0x120a: 0x7bd5, 0x120b: 0x7bf5, - 0x120c: 0x7c15, 0x120d: 0x7c35, 0x120e: 0x7c55, 0x120f: 0x6ec9, 0x1210: 0x6ef1, 0x1211: 0x6f19, - 0x1212: 0x7c75, 0x1213: 0x7c95, 0x1214: 0x7cb5, 0x1215: 0x6f41, 0x1216: 0x6f69, 0x1217: 0x6f91, - 0x1218: 0x7cd5, 0x1219: 0x7cf5, 0x121a: 0x0040, 0x121b: 0x0040, 0x121c: 0x0040, 0x121d: 0x0040, - 0x121e: 0x0040, 0x121f: 0x0040, 0x1220: 0x0040, 0x1221: 0x0040, 0x1222: 0x0040, 0x1223: 0x0040, - 0x1224: 0x0040, 0x1225: 0x0040, 0x1226: 0x0040, 0x1227: 0x0040, 0x1228: 0x0040, 0x1229: 0x0040, - 0x122a: 0x0040, 0x122b: 0x0040, 0x122c: 0x0040, 0x122d: 0x0040, 0x122e: 0x0040, 0x122f: 0x0040, - 0x1230: 0x0040, 0x1231: 0x0040, 0x1232: 0x0040, 0x1233: 0x0040, 0x1234: 0x0040, 0x1235: 0x0040, - 0x1236: 0x0040, 0x1237: 0x0040, 0x1238: 0x0040, 0x1239: 0x0040, 0x123a: 0x0040, 0x123b: 0x0040, + 0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0xe00d, 0x1205: 0x0008, + 0x1206: 0xe00d, 0x1207: 0x0008, 0x1208: 0x0008, 0x1209: 0x0018, 0x120a: 0x0018, 0x120b: 0xe03d, + 0x120c: 0x0008, 0x120d: 0x11d9, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0xe00d, 0x1211: 0x0008, + 0x1212: 0xe00d, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008, + 0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0xe00d, 0x121b: 0x0008, 0x121c: 0xe00d, 0x121d: 0x0008, + 0x121e: 0xe00d, 0x121f: 0x0008, 0x1220: 0xe00d, 0x1221: 0x0008, 0x1222: 0xe00d, 0x1223: 0x0008, + 0x1224: 0xe00d, 0x1225: 0x0008, 0x1226: 0xe00d, 0x1227: 0x0008, 0x1228: 0xe00d, 0x1229: 0x0008, + 0x122a: 0x6e29, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e41, 0x122e: 0x1221, 0x122f: 0x0040, + 0x1230: 0x6e59, 0x1231: 0x6e71, 0x1232: 0x1239, 0x1233: 0x444d, 0x1234: 0xe00d, 0x1235: 0x0008, + 0x1236: 0xe00d, 0x1237: 0x0008, 0x1238: 0x0040, 0x1239: 0x0040, 0x123a: 0x0040, 0x123b: 0x0040, 0x123c: 0x0040, 0x123d: 0x0040, 0x123e: 0x0040, 0x123f: 0x0040, // Block 0x49, offset 0x1240 - 0x1240: 0x6fb9, 0x1241: 0x6fd1, 0x1242: 0x6fe9, 0x1243: 0x7d15, 0x1244: 0x7d35, 0x1245: 0x7001, - 0x1246: 0x7001, 0x1247: 0x0040, 0x1248: 0x0040, 0x1249: 0x0040, 0x124a: 0x0040, 0x124b: 0x0040, - 0x124c: 0x0040, 0x124d: 0x0040, 0x124e: 0x0040, 0x124f: 0x0040, 0x1250: 0x0040, 0x1251: 0x0040, - 0x1252: 0x0040, 0x1253: 0x7019, 0x1254: 0x7041, 0x1255: 0x7069, 0x1256: 0x7091, 0x1257: 0x70b9, - 0x1258: 0x0040, 0x1259: 0x0040, 0x125a: 0x0040, 0x125b: 0x0040, 0x125c: 0x0040, 0x125d: 0x70e1, - 0x125e: 0x1308, 0x125f: 0x7109, 0x1260: 0x7131, 0x1261: 0x20a9, 0x1262: 0x20f1, 0x1263: 0x7149, - 0x1264: 0x7161, 0x1265: 0x7179, 0x1266: 0x7191, 0x1267: 0x71a9, 0x1268: 0x71c1, 0x1269: 0x1fb2, - 0x126a: 0x71d9, 0x126b: 0x7201, 0x126c: 0x7229, 0x126d: 0x7261, 0x126e: 0x7299, 0x126f: 0x72c1, - 0x1270: 0x72e9, 0x1271: 0x7311, 0x1272: 0x7339, 0x1273: 0x7361, 0x1274: 0x7389, 0x1275: 0x73b1, - 0x1276: 0x73d9, 0x1277: 0x0040, 0x1278: 0x7401, 0x1279: 0x7429, 0x127a: 0x7451, 0x127b: 0x7479, - 0x127c: 0x74a1, 0x127d: 0x0040, 0x127e: 0x74c9, 0x127f: 0x0040, + 0x1240: 0x64d5, 0x1241: 0x64f5, 0x1242: 0x6515, 0x1243: 0x6535, 0x1244: 0x6555, 0x1245: 0x6575, + 0x1246: 0x6595, 0x1247: 0x65b5, 0x1248: 0x65d5, 0x1249: 0x65f5, 0x124a: 0x6615, 0x124b: 0x6635, + 0x124c: 0x6655, 0x124d: 0x6675, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x6695, 0x1251: 0x0008, + 0x1252: 0x66b5, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x66d5, 0x1256: 0x66f5, 0x1257: 0x6715, + 0x1258: 0x6735, 0x1259: 0x6755, 0x125a: 0x6775, 0x125b: 0x6795, 0x125c: 0x67b5, 0x125d: 0x67d5, + 0x125e: 0x67f5, 0x125f: 0x0008, 0x1260: 0x6815, 0x1261: 0x0008, 0x1262: 0x6835, 0x1263: 0x0008, + 0x1264: 0x0008, 0x1265: 0x6855, 0x1266: 0x6875, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008, + 0x126a: 0x6895, 0x126b: 0x68b5, 0x126c: 0x68d5, 0x126d: 0x68f5, 0x126e: 0x6915, 0x126f: 0x6935, + 0x1270: 0x6955, 0x1271: 0x6975, 0x1272: 0x6995, 0x1273: 0x69b5, 0x1274: 0x69d5, 0x1275: 0x69f5, + 0x1276: 0x6a15, 0x1277: 0x6a35, 0x1278: 0x6a55, 0x1279: 0x6a75, 0x127a: 0x6a95, 0x127b: 0x6ab5, + 0x127c: 0x6ad5, 0x127d: 0x6af5, 0x127e: 0x6b15, 0x127f: 0x6b35, // Block 0x4a, offset 0x1280 - 0x1280: 0x74f1, 0x1281: 0x7519, 0x1282: 0x0040, 0x1283: 0x7541, 0x1284: 0x7569, 0x1285: 0x0040, - 0x1286: 0x7591, 0x1287: 0x75b9, 0x1288: 0x75e1, 0x1289: 0x7609, 0x128a: 0x7631, 0x128b: 0x7659, - 0x128c: 0x7681, 0x128d: 0x76a9, 0x128e: 0x76d1, 0x128f: 0x76f9, 0x1290: 0x7721, 0x1291: 0x7721, - 0x1292: 0x7739, 0x1293: 0x7739, 0x1294: 0x7739, 0x1295: 0x7739, 0x1296: 0x7751, 0x1297: 0x7751, - 0x1298: 0x7751, 0x1299: 0x7751, 0x129a: 0x7769, 0x129b: 0x7769, 0x129c: 0x7769, 0x129d: 0x7769, - 0x129e: 0x7781, 0x129f: 0x7781, 0x12a0: 0x7781, 0x12a1: 0x7781, 0x12a2: 0x7799, 0x12a3: 0x7799, - 0x12a4: 0x7799, 0x12a5: 0x7799, 0x12a6: 0x77b1, 0x12a7: 0x77b1, 0x12a8: 0x77b1, 0x12a9: 0x77b1, - 0x12aa: 0x77c9, 0x12ab: 0x77c9, 0x12ac: 0x77c9, 0x12ad: 0x77c9, 0x12ae: 0x77e1, 0x12af: 0x77e1, - 0x12b0: 0x77e1, 0x12b1: 0x77e1, 0x12b2: 0x77f9, 0x12b3: 0x77f9, 0x12b4: 0x77f9, 0x12b5: 0x77f9, - 0x12b6: 0x7811, 0x12b7: 0x7811, 0x12b8: 0x7811, 0x12b9: 0x7811, 0x12ba: 0x7829, 0x12bb: 0x7829, - 0x12bc: 0x7829, 0x12bd: 0x7829, 0x12be: 0x7841, 0x12bf: 0x7841, + 0x1280: 0x7a95, 0x1281: 0x7ab5, 0x1282: 0x7ad5, 0x1283: 0x7af5, 0x1284: 0x7b15, 0x1285: 0x7b35, + 0x1286: 0x7b55, 0x1287: 0x7b75, 0x1288: 0x7b95, 0x1289: 0x7bb5, 0x128a: 0x7bd5, 0x128b: 0x7bf5, + 0x128c: 0x7c15, 0x128d: 0x7c35, 0x128e: 0x7c55, 0x128f: 0x6ec9, 0x1290: 0x6ef1, 0x1291: 0x6f19, + 0x1292: 0x7c75, 0x1293: 0x7c95, 0x1294: 0x7cb5, 0x1295: 0x6f41, 0x1296: 0x6f69, 0x1297: 0x6f91, + 0x1298: 0x7cd5, 0x1299: 0x7cf5, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040, + 0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040, + 0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040, + 0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040, + 0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040, + 0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040, + 0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040, // Block 0x4b, offset 0x12c0 - 0x12c0: 0x7841, 0x12c1: 0x7841, 0x12c2: 0x7859, 0x12c3: 0x7859, 0x12c4: 0x7871, 0x12c5: 0x7871, - 0x12c6: 0x7889, 0x12c7: 0x7889, 0x12c8: 0x78a1, 0x12c9: 0x78a1, 0x12ca: 0x78b9, 0x12cb: 0x78b9, - 0x12cc: 0x78d1, 0x12cd: 0x78d1, 0x12ce: 0x78e9, 0x12cf: 0x78e9, 0x12d0: 0x78e9, 0x12d1: 0x78e9, - 0x12d2: 0x7901, 0x12d3: 0x7901, 0x12d4: 0x7901, 0x12d5: 0x7901, 0x12d6: 0x7919, 0x12d7: 0x7919, - 0x12d8: 0x7919, 0x12d9: 0x7919, 0x12da: 0x7931, 0x12db: 0x7931, 0x12dc: 0x7931, 0x12dd: 0x7931, - 0x12de: 0x7949, 0x12df: 0x7949, 0x12e0: 0x7961, 0x12e1: 0x7961, 0x12e2: 0x7961, 0x12e3: 0x7961, - 0x12e4: 0x7979, 0x12e5: 0x7979, 0x12e6: 0x7991, 0x12e7: 0x7991, 0x12e8: 0x7991, 0x12e9: 0x7991, - 0x12ea: 0x79a9, 0x12eb: 0x79a9, 0x12ec: 0x79a9, 0x12ed: 0x79a9, 0x12ee: 0x79c1, 0x12ef: 0x79c1, - 0x12f0: 0x79d9, 0x12f1: 0x79d9, 0x12f2: 0x0018, 0x12f3: 0x0018, 0x12f4: 0x0018, 0x12f5: 0x0018, - 0x12f6: 0x0018, 0x12f7: 0x0018, 0x12f8: 0x0018, 0x12f9: 0x0018, 0x12fa: 0x0018, 0x12fb: 0x0018, - 0x12fc: 0x0018, 0x12fd: 0x0018, 0x12fe: 0x0018, 0x12ff: 0x0018, + 0x12c0: 0x6fb9, 0x12c1: 0x6fd1, 0x12c2: 0x6fe9, 0x12c3: 0x7d15, 0x12c4: 0x7d35, 0x12c5: 0x7001, + 0x12c6: 0x7001, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040, + 0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040, + 0x12d2: 0x0040, 0x12d3: 0x7019, 0x12d4: 0x7041, 0x12d5: 0x7069, 0x12d6: 0x7091, 0x12d7: 0x70b9, + 0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x70e1, + 0x12de: 0x3308, 0x12df: 0x7109, 0x12e0: 0x7131, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7149, + 0x12e4: 0x7161, 0x12e5: 0x7179, 0x12e6: 0x7191, 0x12e7: 0x71a9, 0x12e8: 0x71c1, 0x12e9: 0x1fb2, + 0x12ea: 0x71d9, 0x12eb: 0x7201, 0x12ec: 0x7229, 0x12ed: 0x7261, 0x12ee: 0x7299, 0x12ef: 0x72c1, + 0x12f0: 0x72e9, 0x12f1: 0x7311, 0x12f2: 0x7339, 0x12f3: 0x7361, 0x12f4: 0x7389, 0x12f5: 0x73b1, + 0x12f6: 0x73d9, 0x12f7: 0x0040, 0x12f8: 0x7401, 0x12f9: 0x7429, 0x12fa: 0x7451, 0x12fb: 0x7479, + 0x12fc: 0x74a1, 0x12fd: 0x0040, 0x12fe: 0x74c9, 0x12ff: 0x0040, // Block 0x4c, offset 0x1300 - 0x1300: 0x0018, 0x1301: 0x0018, 0x1302: 0x0040, 0x1303: 0x0040, 0x1304: 0x0040, 0x1305: 0x0040, - 0x1306: 0x0040, 0x1307: 0x0040, 0x1308: 0x0040, 0x1309: 0x0040, 0x130a: 0x0040, 0x130b: 0x0040, - 0x130c: 0x0040, 0x130d: 0x0040, 0x130e: 0x0040, 0x130f: 0x0040, 0x1310: 0x0040, 0x1311: 0x0040, - 0x1312: 0x0040, 0x1313: 0x79f1, 0x1314: 0x79f1, 0x1315: 0x79f1, 0x1316: 0x79f1, 0x1317: 0x7a09, - 0x1318: 0x7a09, 0x1319: 0x7a21, 0x131a: 0x7a21, 0x131b: 0x7a39, 0x131c: 0x7a39, 0x131d: 0x0479, - 0x131e: 0x7a51, 0x131f: 0x7a51, 0x1320: 0x7a69, 0x1321: 0x7a69, 0x1322: 0x7a81, 0x1323: 0x7a81, - 0x1324: 0x7a99, 0x1325: 0x7a99, 0x1326: 0x7a99, 0x1327: 0x7a99, 0x1328: 0x7ab1, 0x1329: 0x7ab1, - 0x132a: 0x7ac9, 0x132b: 0x7ac9, 0x132c: 0x7af1, 0x132d: 0x7af1, 0x132e: 0x7b19, 0x132f: 0x7b19, - 0x1330: 0x7b41, 0x1331: 0x7b41, 0x1332: 0x7b69, 0x1333: 0x7b69, 0x1334: 0x7b91, 0x1335: 0x7b91, - 0x1336: 0x7bb9, 0x1337: 0x7bb9, 0x1338: 0x7bb9, 0x1339: 0x7be1, 0x133a: 0x7be1, 0x133b: 0x7be1, - 0x133c: 0x7c09, 0x133d: 0x7c09, 0x133e: 0x7c09, 0x133f: 0x7c09, + 0x1300: 0x74f1, 0x1301: 0x7519, 0x1302: 0x0040, 0x1303: 0x7541, 0x1304: 0x7569, 0x1305: 0x0040, + 0x1306: 0x7591, 0x1307: 0x75b9, 0x1308: 0x75e1, 0x1309: 0x7609, 0x130a: 0x7631, 0x130b: 0x7659, + 0x130c: 0x7681, 0x130d: 0x76a9, 0x130e: 0x76d1, 0x130f: 0x76f9, 0x1310: 0x7721, 0x1311: 0x7721, + 0x1312: 0x7739, 0x1313: 0x7739, 0x1314: 0x7739, 0x1315: 0x7739, 0x1316: 0x7751, 0x1317: 0x7751, + 0x1318: 0x7751, 0x1319: 0x7751, 0x131a: 0x7769, 0x131b: 0x7769, 0x131c: 0x7769, 0x131d: 0x7769, + 0x131e: 0x7781, 0x131f: 0x7781, 0x1320: 0x7781, 0x1321: 0x7781, 0x1322: 0x7799, 0x1323: 0x7799, + 0x1324: 0x7799, 0x1325: 0x7799, 0x1326: 0x77b1, 0x1327: 0x77b1, 0x1328: 0x77b1, 0x1329: 0x77b1, + 0x132a: 0x77c9, 0x132b: 0x77c9, 0x132c: 0x77c9, 0x132d: 0x77c9, 0x132e: 0x77e1, 0x132f: 0x77e1, + 0x1330: 0x77e1, 0x1331: 0x77e1, 0x1332: 0x77f9, 0x1333: 0x77f9, 0x1334: 0x77f9, 0x1335: 0x77f9, + 0x1336: 0x7811, 0x1337: 0x7811, 0x1338: 0x7811, 0x1339: 0x7811, 0x133a: 0x7829, 0x133b: 0x7829, + 0x133c: 0x7829, 0x133d: 0x7829, 0x133e: 0x7841, 0x133f: 0x7841, // Block 0x4d, offset 0x1340 - 0x1340: 0x85f9, 0x1341: 0x8621, 0x1342: 0x8649, 0x1343: 0x8671, 0x1344: 0x8699, 0x1345: 0x86c1, - 0x1346: 0x86e9, 0x1347: 0x8711, 0x1348: 0x8739, 0x1349: 0x8761, 0x134a: 0x8789, 0x134b: 0x87b1, - 0x134c: 0x87d9, 0x134d: 0x8801, 0x134e: 0x8829, 0x134f: 0x8851, 0x1350: 0x8879, 0x1351: 0x88a1, - 0x1352: 0x88c9, 0x1353: 0x88f1, 0x1354: 0x8919, 0x1355: 0x8941, 0x1356: 0x8969, 0x1357: 0x8991, - 0x1358: 0x89b9, 0x1359: 0x89e1, 0x135a: 0x8a09, 0x135b: 0x8a31, 0x135c: 0x8a59, 0x135d: 0x8a81, - 0x135e: 0x8aaa, 0x135f: 0x8ada, 0x1360: 0x8b0a, 0x1361: 0x8b3a, 0x1362: 0x8b6a, 0x1363: 0x8b9a, - 0x1364: 0x8bc9, 0x1365: 0x8bf1, 0x1366: 0x7c71, 0x1367: 0x8c19, 0x1368: 0x7be1, 0x1369: 0x7c99, - 0x136a: 0x8c41, 0x136b: 0x8c69, 0x136c: 0x7d39, 0x136d: 0x8c91, 0x136e: 0x7d61, 0x136f: 0x7d89, - 0x1370: 0x8cb9, 0x1371: 0x8ce1, 0x1372: 0x7e29, 0x1373: 0x8d09, 0x1374: 0x7e51, 0x1375: 0x7e79, - 0x1376: 0x8d31, 0x1377: 0x8d59, 0x1378: 0x7ec9, 0x1379: 0x8d81, 0x137a: 0x7ef1, 0x137b: 0x7f19, - 0x137c: 0x83a1, 0x137d: 0x83c9, 0x137e: 0x8441, 0x137f: 0x8469, + 0x1340: 0x7841, 0x1341: 0x7841, 0x1342: 0x7859, 0x1343: 0x7859, 0x1344: 0x7871, 0x1345: 0x7871, + 0x1346: 0x7889, 0x1347: 0x7889, 0x1348: 0x78a1, 0x1349: 0x78a1, 0x134a: 0x78b9, 0x134b: 0x78b9, + 0x134c: 0x78d1, 0x134d: 0x78d1, 0x134e: 0x78e9, 0x134f: 0x78e9, 0x1350: 0x78e9, 0x1351: 0x78e9, + 0x1352: 0x7901, 0x1353: 0x7901, 0x1354: 0x7901, 0x1355: 0x7901, 0x1356: 0x7919, 0x1357: 0x7919, + 0x1358: 0x7919, 0x1359: 0x7919, 0x135a: 0x7931, 0x135b: 0x7931, 0x135c: 0x7931, 0x135d: 0x7931, + 0x135e: 0x7949, 0x135f: 0x7949, 0x1360: 0x7961, 0x1361: 0x7961, 0x1362: 0x7961, 0x1363: 0x7961, + 0x1364: 0x7979, 0x1365: 0x7979, 0x1366: 0x7991, 0x1367: 0x7991, 0x1368: 0x7991, 0x1369: 0x7991, + 0x136a: 0x79a9, 0x136b: 0x79a9, 0x136c: 0x79a9, 0x136d: 0x79a9, 0x136e: 0x79c1, 0x136f: 0x79c1, + 0x1370: 0x79d9, 0x1371: 0x79d9, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818, + 0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818, + 0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818, // Block 0x4e, offset 0x1380 - 0x1380: 0x8491, 0x1381: 0x8531, 0x1382: 0x8559, 0x1383: 0x8581, 0x1384: 0x85a9, 0x1385: 0x8649, - 0x1386: 0x8671, 0x1387: 0x8699, 0x1388: 0x8da9, 0x1389: 0x8739, 0x138a: 0x8dd1, 0x138b: 0x8df9, - 0x138c: 0x8829, 0x138d: 0x8e21, 0x138e: 0x8851, 0x138f: 0x8879, 0x1390: 0x8a81, 0x1391: 0x8e49, - 0x1392: 0x8e71, 0x1393: 0x89b9, 0x1394: 0x8e99, 0x1395: 0x89e1, 0x1396: 0x8a09, 0x1397: 0x7c21, - 0x1398: 0x7c49, 0x1399: 0x8ec1, 0x139a: 0x7c71, 0x139b: 0x8ee9, 0x139c: 0x7cc1, 0x139d: 0x7ce9, - 0x139e: 0x7d11, 0x139f: 0x7d39, 0x13a0: 0x8f11, 0x13a1: 0x7db1, 0x13a2: 0x7dd9, 0x13a3: 0x7e01, - 0x13a4: 0x7e29, 0x13a5: 0x8f39, 0x13a6: 0x7ec9, 0x13a7: 0x7f41, 0x13a8: 0x7f69, 0x13a9: 0x7f91, - 0x13aa: 0x7fb9, 0x13ab: 0x7fe1, 0x13ac: 0x8031, 0x13ad: 0x8059, 0x13ae: 0x8081, 0x13af: 0x80a9, - 0x13b0: 0x80d1, 0x13b1: 0x80f9, 0x13b2: 0x8f61, 0x13b3: 0x8121, 0x13b4: 0x8149, 0x13b5: 0x8171, - 0x13b6: 0x8199, 0x13b7: 0x81c1, 0x13b8: 0x81e9, 0x13b9: 0x8239, 0x13ba: 0x8261, 0x13bb: 0x8289, - 0x13bc: 0x82b1, 0x13bd: 0x82d9, 0x13be: 0x8301, 0x13bf: 0x8329, + 0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0040, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040, + 0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040, + 0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040, + 0x1392: 0x0040, 0x1393: 0x79f1, 0x1394: 0x79f1, 0x1395: 0x79f1, 0x1396: 0x79f1, 0x1397: 0x7a09, + 0x1398: 0x7a09, 0x1399: 0x7a21, 0x139a: 0x7a21, 0x139b: 0x7a39, 0x139c: 0x7a39, 0x139d: 0x0479, + 0x139e: 0x7a51, 0x139f: 0x7a51, 0x13a0: 0x7a69, 0x13a1: 0x7a69, 0x13a2: 0x7a81, 0x13a3: 0x7a81, + 0x13a4: 0x7a99, 0x13a5: 0x7a99, 0x13a6: 0x7a99, 0x13a7: 0x7a99, 0x13a8: 0x7ab1, 0x13a9: 0x7ab1, + 0x13aa: 0x7ac9, 0x13ab: 0x7ac9, 0x13ac: 0x7af1, 0x13ad: 0x7af1, 0x13ae: 0x7b19, 0x13af: 0x7b19, + 0x13b0: 0x7b41, 0x13b1: 0x7b41, 0x13b2: 0x7b69, 0x13b3: 0x7b69, 0x13b4: 0x7b91, 0x13b5: 0x7b91, + 0x13b6: 0x7bb9, 0x13b7: 0x7bb9, 0x13b8: 0x7bb9, 0x13b9: 0x7be1, 0x13ba: 0x7be1, 0x13bb: 0x7be1, + 0x13bc: 0x7c09, 0x13bd: 0x7c09, 0x13be: 0x7c09, 0x13bf: 0x7c09, // Block 0x4f, offset 0x13c0 - 0x13c0: 0x8351, 0x13c1: 0x8379, 0x13c2: 0x83f1, 0x13c3: 0x8419, 0x13c4: 0x84b9, 0x13c5: 0x84e1, - 0x13c6: 0x8509, 0x13c7: 0x8531, 0x13c8: 0x8559, 0x13c9: 0x85d1, 0x13ca: 0x85f9, 0x13cb: 0x8621, - 0x13cc: 0x8649, 0x13cd: 0x8f89, 0x13ce: 0x86c1, 0x13cf: 0x86e9, 0x13d0: 0x8711, 0x13d1: 0x8739, - 0x13d2: 0x87b1, 0x13d3: 0x87d9, 0x13d4: 0x8801, 0x13d5: 0x8829, 0x13d6: 0x8fb1, 0x13d7: 0x88a1, - 0x13d8: 0x88c9, 0x13d9: 0x8fd9, 0x13da: 0x8941, 0x13db: 0x8969, 0x13dc: 0x8991, 0x13dd: 0x89b9, - 0x13de: 0x9001, 0x13df: 0x7c71, 0x13e0: 0x8ee9, 0x13e1: 0x7d39, 0x13e2: 0x8f11, 0x13e3: 0x7e29, - 0x13e4: 0x8f39, 0x13e5: 0x7ec9, 0x13e6: 0x9029, 0x13e7: 0x80d1, 0x13e8: 0x9051, 0x13e9: 0x9079, - 0x13ea: 0x90a1, 0x13eb: 0x8531, 0x13ec: 0x8559, 0x13ed: 0x8649, 0x13ee: 0x8829, 0x13ef: 0x8fb1, - 0x13f0: 0x89b9, 0x13f1: 0x9001, 0x13f2: 0x90c9, 0x13f3: 0x9101, 0x13f4: 0x9139, 0x13f5: 0x9171, - 0x13f6: 0x9199, 0x13f7: 0x91c1, 0x13f8: 0x91e9, 0x13f9: 0x9211, 0x13fa: 0x9239, 0x13fb: 0x9261, - 0x13fc: 0x9289, 0x13fd: 0x92b1, 0x13fe: 0x92d9, 0x13ff: 0x9301, + 0x13c0: 0x85f9, 0x13c1: 0x8621, 0x13c2: 0x8649, 0x13c3: 0x8671, 0x13c4: 0x8699, 0x13c5: 0x86c1, + 0x13c6: 0x86e9, 0x13c7: 0x8711, 0x13c8: 0x8739, 0x13c9: 0x8761, 0x13ca: 0x8789, 0x13cb: 0x87b1, + 0x13cc: 0x87d9, 0x13cd: 0x8801, 0x13ce: 0x8829, 0x13cf: 0x8851, 0x13d0: 0x8879, 0x13d1: 0x88a1, + 0x13d2: 0x88c9, 0x13d3: 0x88f1, 0x13d4: 0x8919, 0x13d5: 0x8941, 0x13d6: 0x8969, 0x13d7: 0x8991, + 0x13d8: 0x89b9, 0x13d9: 0x89e1, 0x13da: 0x8a09, 0x13db: 0x8a31, 0x13dc: 0x8a59, 0x13dd: 0x8a81, + 0x13de: 0x8aaa, 0x13df: 0x8ada, 0x13e0: 0x8b0a, 0x13e1: 0x8b3a, 0x13e2: 0x8b6a, 0x13e3: 0x8b9a, + 0x13e4: 0x8bc9, 0x13e5: 0x8bf1, 0x13e6: 0x7c71, 0x13e7: 0x8c19, 0x13e8: 0x7be1, 0x13e9: 0x7c99, + 0x13ea: 0x8c41, 0x13eb: 0x8c69, 0x13ec: 0x7d39, 0x13ed: 0x8c91, 0x13ee: 0x7d61, 0x13ef: 0x7d89, + 0x13f0: 0x8cb9, 0x13f1: 0x8ce1, 0x13f2: 0x7e29, 0x13f3: 0x8d09, 0x13f4: 0x7e51, 0x13f5: 0x7e79, + 0x13f6: 0x8d31, 0x13f7: 0x8d59, 0x13f8: 0x7ec9, 0x13f9: 0x8d81, 0x13fa: 0x7ef1, 0x13fb: 0x7f19, + 0x13fc: 0x83a1, 0x13fd: 0x83c9, 0x13fe: 0x8441, 0x13ff: 0x8469, // Block 0x50, offset 0x1400 - 0x1400: 0x9329, 0x1401: 0x9351, 0x1402: 0x9379, 0x1403: 0x93a1, 0x1404: 0x93c9, 0x1405: 0x93f1, - 0x1406: 0x9419, 0x1407: 0x9441, 0x1408: 0x9469, 0x1409: 0x9491, 0x140a: 0x94b9, 0x140b: 0x94e1, - 0x140c: 0x9079, 0x140d: 0x9509, 0x140e: 0x9531, 0x140f: 0x9559, 0x1410: 0x9581, 0x1411: 0x9171, - 0x1412: 0x9199, 0x1413: 0x91c1, 0x1414: 0x91e9, 0x1415: 0x9211, 0x1416: 0x9239, 0x1417: 0x9261, - 0x1418: 0x9289, 0x1419: 0x92b1, 0x141a: 0x92d9, 0x141b: 0x9301, 0x141c: 0x9329, 0x141d: 0x9351, - 0x141e: 0x9379, 0x141f: 0x93a1, 0x1420: 0x93c9, 0x1421: 0x93f1, 0x1422: 0x9419, 0x1423: 0x9441, - 0x1424: 0x9469, 0x1425: 0x9491, 0x1426: 0x94b9, 0x1427: 0x94e1, 0x1428: 0x9079, 0x1429: 0x9509, - 0x142a: 0x9531, 0x142b: 0x9559, 0x142c: 0x9581, 0x142d: 0x9491, 0x142e: 0x94b9, 0x142f: 0x94e1, - 0x1430: 0x9079, 0x1431: 0x9051, 0x1432: 0x90a1, 0x1433: 0x8211, 0x1434: 0x8059, 0x1435: 0x8081, - 0x1436: 0x80a9, 0x1437: 0x9491, 0x1438: 0x94b9, 0x1439: 0x94e1, 0x143a: 0x8211, 0x143b: 0x8239, - 0x143c: 0x95a9, 0x143d: 0x95a9, 0x143e: 0x0018, 0x143f: 0x0018, + 0x1400: 0x8491, 0x1401: 0x8531, 0x1402: 0x8559, 0x1403: 0x8581, 0x1404: 0x85a9, 0x1405: 0x8649, + 0x1406: 0x8671, 0x1407: 0x8699, 0x1408: 0x8da9, 0x1409: 0x8739, 0x140a: 0x8dd1, 0x140b: 0x8df9, + 0x140c: 0x8829, 0x140d: 0x8e21, 0x140e: 0x8851, 0x140f: 0x8879, 0x1410: 0x8a81, 0x1411: 0x8e49, + 0x1412: 0x8e71, 0x1413: 0x89b9, 0x1414: 0x8e99, 0x1415: 0x89e1, 0x1416: 0x8a09, 0x1417: 0x7c21, + 0x1418: 0x7c49, 0x1419: 0x8ec1, 0x141a: 0x7c71, 0x141b: 0x8ee9, 0x141c: 0x7cc1, 0x141d: 0x7ce9, + 0x141e: 0x7d11, 0x141f: 0x7d39, 0x1420: 0x8f11, 0x1421: 0x7db1, 0x1422: 0x7dd9, 0x1423: 0x7e01, + 0x1424: 0x7e29, 0x1425: 0x8f39, 0x1426: 0x7ec9, 0x1427: 0x7f41, 0x1428: 0x7f69, 0x1429: 0x7f91, + 0x142a: 0x7fb9, 0x142b: 0x7fe1, 0x142c: 0x8031, 0x142d: 0x8059, 0x142e: 0x8081, 0x142f: 0x80a9, + 0x1430: 0x80d1, 0x1431: 0x80f9, 0x1432: 0x8f61, 0x1433: 0x8121, 0x1434: 0x8149, 0x1435: 0x8171, + 0x1436: 0x8199, 0x1437: 0x81c1, 0x1438: 0x81e9, 0x1439: 0x8239, 0x143a: 0x8261, 0x143b: 0x8289, + 0x143c: 0x82b1, 0x143d: 0x82d9, 0x143e: 0x8301, 0x143f: 0x8329, // Block 0x51, offset 0x1440 - 0x1440: 0x0040, 0x1441: 0x0040, 0x1442: 0x0040, 0x1443: 0x0040, 0x1444: 0x0040, 0x1445: 0x0040, - 0x1446: 0x0040, 0x1447: 0x0040, 0x1448: 0x0040, 0x1449: 0x0040, 0x144a: 0x0040, 0x144b: 0x0040, - 0x144c: 0x0040, 0x144d: 0x0040, 0x144e: 0x0040, 0x144f: 0x0040, 0x1450: 0x95d1, 0x1451: 0x9609, - 0x1452: 0x9609, 0x1453: 0x9641, 0x1454: 0x9679, 0x1455: 0x96b1, 0x1456: 0x96e9, 0x1457: 0x9721, - 0x1458: 0x9759, 0x1459: 0x9759, 0x145a: 0x9791, 0x145b: 0x97c9, 0x145c: 0x9801, 0x145d: 0x9839, - 0x145e: 0x9871, 0x145f: 0x98a9, 0x1460: 0x98a9, 0x1461: 0x98e1, 0x1462: 0x9919, 0x1463: 0x9919, - 0x1464: 0x9951, 0x1465: 0x9951, 0x1466: 0x9989, 0x1467: 0x99c1, 0x1468: 0x99c1, 0x1469: 0x99f9, - 0x146a: 0x9a31, 0x146b: 0x9a31, 0x146c: 0x9a69, 0x146d: 0x9a69, 0x146e: 0x9aa1, 0x146f: 0x9ad9, - 0x1470: 0x9ad9, 0x1471: 0x9b11, 0x1472: 0x9b11, 0x1473: 0x9b49, 0x1474: 0x9b81, 0x1475: 0x9bb9, - 0x1476: 0x9bf1, 0x1477: 0x9bf1, 0x1478: 0x9c29, 0x1479: 0x9c61, 0x147a: 0x9c99, 0x147b: 0x9cd1, - 0x147c: 0x9d09, 0x147d: 0x9d09, 0x147e: 0x9d41, 0x147f: 0x9d79, + 0x1440: 0x8351, 0x1441: 0x8379, 0x1442: 0x83f1, 0x1443: 0x8419, 0x1444: 0x84b9, 0x1445: 0x84e1, + 0x1446: 0x8509, 0x1447: 0x8531, 0x1448: 0x8559, 0x1449: 0x85d1, 0x144a: 0x85f9, 0x144b: 0x8621, + 0x144c: 0x8649, 0x144d: 0x8f89, 0x144e: 0x86c1, 0x144f: 0x86e9, 0x1450: 0x8711, 0x1451: 0x8739, + 0x1452: 0x87b1, 0x1453: 0x87d9, 0x1454: 0x8801, 0x1455: 0x8829, 0x1456: 0x8fb1, 0x1457: 0x88a1, + 0x1458: 0x88c9, 0x1459: 0x8fd9, 0x145a: 0x8941, 0x145b: 0x8969, 0x145c: 0x8991, 0x145d: 0x89b9, + 0x145e: 0x9001, 0x145f: 0x7c71, 0x1460: 0x8ee9, 0x1461: 0x7d39, 0x1462: 0x8f11, 0x1463: 0x7e29, + 0x1464: 0x8f39, 0x1465: 0x7ec9, 0x1466: 0x9029, 0x1467: 0x80d1, 0x1468: 0x9051, 0x1469: 0x9079, + 0x146a: 0x90a1, 0x146b: 0x8531, 0x146c: 0x8559, 0x146d: 0x8649, 0x146e: 0x8829, 0x146f: 0x8fb1, + 0x1470: 0x89b9, 0x1471: 0x9001, 0x1472: 0x90c9, 0x1473: 0x9101, 0x1474: 0x9139, 0x1475: 0x9171, + 0x1476: 0x9199, 0x1477: 0x91c1, 0x1478: 0x91e9, 0x1479: 0x9211, 0x147a: 0x9239, 0x147b: 0x9261, + 0x147c: 0x9289, 0x147d: 0x92b1, 0x147e: 0x92d9, 0x147f: 0x9301, // Block 0x52, offset 0x1480 - 0x1480: 0xa949, 0x1481: 0xa981, 0x1482: 0xa9b9, 0x1483: 0xa8a1, 0x1484: 0x9bb9, 0x1485: 0x9989, - 0x1486: 0xa9f1, 0x1487: 0xaa29, 0x1488: 0x0040, 0x1489: 0x0040, 0x148a: 0x0040, 0x148b: 0x0040, - 0x148c: 0x0040, 0x148d: 0x0040, 0x148e: 0x0040, 0x148f: 0x0040, 0x1490: 0x0040, 0x1491: 0x0040, - 0x1492: 0x0040, 0x1493: 0x0040, 0x1494: 0x0040, 0x1495: 0x0040, 0x1496: 0x0040, 0x1497: 0x0040, - 0x1498: 0x0040, 0x1499: 0x0040, 0x149a: 0x0040, 0x149b: 0x0040, 0x149c: 0x0040, 0x149d: 0x0040, - 0x149e: 0x0040, 0x149f: 0x0040, 0x14a0: 0x0040, 0x14a1: 0x0040, 0x14a2: 0x0040, 0x14a3: 0x0040, - 0x14a4: 0x0040, 0x14a5: 0x0040, 0x14a6: 0x0040, 0x14a7: 0x0040, 0x14a8: 0x0040, 0x14a9: 0x0040, - 0x14aa: 0x0040, 0x14ab: 0x0040, 0x14ac: 0x0040, 0x14ad: 0x0040, 0x14ae: 0x0040, 0x14af: 0x0040, - 0x14b0: 0xaa61, 0x14b1: 0xaa99, 0x14b2: 0xaad1, 0x14b3: 0xab19, 0x14b4: 0xab61, 0x14b5: 0xaba9, - 0x14b6: 0xabf1, 0x14b7: 0xac39, 0x14b8: 0xac81, 0x14b9: 0xacc9, 0x14ba: 0xad02, 0x14bb: 0xae12, - 0x14bc: 0xae91, 0x14bd: 0x0018, 0x14be: 0x0040, 0x14bf: 0x0040, + 0x1480: 0x9329, 0x1481: 0x9351, 0x1482: 0x9379, 0x1483: 0x93a1, 0x1484: 0x93c9, 0x1485: 0x93f1, + 0x1486: 0x9419, 0x1487: 0x9441, 0x1488: 0x9469, 0x1489: 0x9491, 0x148a: 0x94b9, 0x148b: 0x94e1, + 0x148c: 0x9079, 0x148d: 0x9509, 0x148e: 0x9531, 0x148f: 0x9559, 0x1490: 0x9581, 0x1491: 0x9171, + 0x1492: 0x9199, 0x1493: 0x91c1, 0x1494: 0x91e9, 0x1495: 0x9211, 0x1496: 0x9239, 0x1497: 0x9261, + 0x1498: 0x9289, 0x1499: 0x92b1, 0x149a: 0x92d9, 0x149b: 0x9301, 0x149c: 0x9329, 0x149d: 0x9351, + 0x149e: 0x9379, 0x149f: 0x93a1, 0x14a0: 0x93c9, 0x14a1: 0x93f1, 0x14a2: 0x9419, 0x14a3: 0x9441, + 0x14a4: 0x9469, 0x14a5: 0x9491, 0x14a6: 0x94b9, 0x14a7: 0x94e1, 0x14a8: 0x9079, 0x14a9: 0x9509, + 0x14aa: 0x9531, 0x14ab: 0x9559, 0x14ac: 0x9581, 0x14ad: 0x9491, 0x14ae: 0x94b9, 0x14af: 0x94e1, + 0x14b0: 0x9079, 0x14b1: 0x9051, 0x14b2: 0x90a1, 0x14b3: 0x8211, 0x14b4: 0x8059, 0x14b5: 0x8081, + 0x14b6: 0x80a9, 0x14b7: 0x9491, 0x14b8: 0x94b9, 0x14b9: 0x94e1, 0x14ba: 0x8211, 0x14bb: 0x8239, + 0x14bc: 0x95a9, 0x14bd: 0x95a9, 0x14be: 0x0018, 0x14bf: 0x0018, // Block 0x53, offset 0x14c0 - 0x14c0: 0x13c0, 0x14c1: 0x13c0, 0x14c2: 0x13c0, 0x14c3: 0x13c0, 0x14c4: 0x13c0, 0x14c5: 0x13c0, - 0x14c6: 0x13c0, 0x14c7: 0x13c0, 0x14c8: 0x13c0, 0x14c9: 0x13c0, 0x14ca: 0x13c0, 0x14cb: 0x13c0, - 0x14cc: 0x13c0, 0x14cd: 0x13c0, 0x14ce: 0x13c0, 0x14cf: 0x13c0, 0x14d0: 0xaeda, 0x14d1: 0x7d55, - 0x14d2: 0x0040, 0x14d3: 0xaeea, 0x14d4: 0x03c2, 0x14d5: 0xaefa, 0x14d6: 0xaf0a, 0x14d7: 0x7d75, - 0x14d8: 0x7d95, 0x14d9: 0x0040, 0x14da: 0x0040, 0x14db: 0x0040, 0x14dc: 0x0040, 0x14dd: 0x0040, - 0x14de: 0x0040, 0x14df: 0x0040, 0x14e0: 0x1308, 0x14e1: 0x1308, 0x14e2: 0x1308, 0x14e3: 0x1308, - 0x14e4: 0x1308, 0x14e5: 0x1308, 0x14e6: 0x1308, 0x14e7: 0x1308, 0x14e8: 0x1308, 0x14e9: 0x1308, - 0x14ea: 0x1308, 0x14eb: 0x1308, 0x14ec: 0x1308, 0x14ed: 0x1308, 0x14ee: 0x1308, 0x14ef: 0x1308, - 0x14f0: 0x0040, 0x14f1: 0x7db5, 0x14f2: 0x7dd5, 0x14f3: 0xaf1a, 0x14f4: 0xaf1a, 0x14f5: 0x1fd2, - 0x14f6: 0x1fe2, 0x14f7: 0xaf2a, 0x14f8: 0xaf3a, 0x14f9: 0x7df5, 0x14fa: 0x7e15, 0x14fb: 0x7e35, - 0x14fc: 0x7df5, 0x14fd: 0x7e55, 0x14fe: 0x7e75, 0x14ff: 0x7e55, + 0x14c0: 0x0040, 0x14c1: 0x0040, 0x14c2: 0x0040, 0x14c3: 0x0040, 0x14c4: 0x0040, 0x14c5: 0x0040, + 0x14c6: 0x0040, 0x14c7: 0x0040, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040, + 0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x95d1, 0x14d1: 0x9609, + 0x14d2: 0x9609, 0x14d3: 0x9641, 0x14d4: 0x9679, 0x14d5: 0x96b1, 0x14d6: 0x96e9, 0x14d7: 0x9721, + 0x14d8: 0x9759, 0x14d9: 0x9759, 0x14da: 0x9791, 0x14db: 0x97c9, 0x14dc: 0x9801, 0x14dd: 0x9839, + 0x14de: 0x9871, 0x14df: 0x98a9, 0x14e0: 0x98a9, 0x14e1: 0x98e1, 0x14e2: 0x9919, 0x14e3: 0x9919, + 0x14e4: 0x9951, 0x14e5: 0x9951, 0x14e6: 0x9989, 0x14e7: 0x99c1, 0x14e8: 0x99c1, 0x14e9: 0x99f9, + 0x14ea: 0x9a31, 0x14eb: 0x9a31, 0x14ec: 0x9a69, 0x14ed: 0x9a69, 0x14ee: 0x9aa1, 0x14ef: 0x9ad9, + 0x14f0: 0x9ad9, 0x14f1: 0x9b11, 0x14f2: 0x9b11, 0x14f3: 0x9b49, 0x14f4: 0x9b81, 0x14f5: 0x9bb9, + 0x14f6: 0x9bf1, 0x14f7: 0x9bf1, 0x14f8: 0x9c29, 0x14f9: 0x9c61, 0x14fa: 0x9c99, 0x14fb: 0x9cd1, + 0x14fc: 0x9d09, 0x14fd: 0x9d09, 0x14fe: 0x9d41, 0x14ff: 0x9d79, // Block 0x54, offset 0x1500 - 0x1500: 0x7e95, 0x1501: 0x7eb5, 0x1502: 0x7ed5, 0x1503: 0x7eb5, 0x1504: 0x7ef5, 0x1505: 0x0018, - 0x1506: 0x0018, 0x1507: 0xaf4a, 0x1508: 0xaf5a, 0x1509: 0x7f16, 0x150a: 0x7f36, 0x150b: 0x7f56, - 0x150c: 0x7f76, 0x150d: 0xaf1a, 0x150e: 0xaf1a, 0x150f: 0xaf1a, 0x1510: 0xaeda, 0x1511: 0x7f95, - 0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x03c2, 0x1515: 0xaeea, 0x1516: 0xaf0a, 0x1517: 0xaefa, - 0x1518: 0x7fb5, 0x1519: 0x1fd2, 0x151a: 0x1fe2, 0x151b: 0xaf2a, 0x151c: 0xaf3a, 0x151d: 0x7e95, - 0x151e: 0x7ef5, 0x151f: 0xaf6a, 0x1520: 0xaf7a, 0x1521: 0xaf8a, 0x1522: 0x1fb2, 0x1523: 0xaf99, - 0x1524: 0xafaa, 0x1525: 0xafba, 0x1526: 0x1fc2, 0x1527: 0x0040, 0x1528: 0xafca, 0x1529: 0xafda, - 0x152a: 0xafea, 0x152b: 0xaffa, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040, - 0x1530: 0x7fd6, 0x1531: 0xb009, 0x1532: 0x7ff6, 0x1533: 0x0008, 0x1534: 0x8016, 0x1535: 0x0040, - 0x1536: 0x8036, 0x1537: 0xb031, 0x1538: 0x8056, 0x1539: 0xb059, 0x153a: 0x8076, 0x153b: 0xb081, - 0x153c: 0x8096, 0x153d: 0xb0a9, 0x153e: 0x80b6, 0x153f: 0xb0d1, + 0x1500: 0xa949, 0x1501: 0xa981, 0x1502: 0xa9b9, 0x1503: 0xa8a1, 0x1504: 0x9bb9, 0x1505: 0x9989, + 0x1506: 0xa9f1, 0x1507: 0xaa29, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040, + 0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0040, 0x1510: 0x0040, 0x1511: 0x0040, + 0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040, + 0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040, + 0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040, + 0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040, + 0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040, + 0x1530: 0xaa61, 0x1531: 0xaa99, 0x1532: 0xaad1, 0x1533: 0xab19, 0x1534: 0xab61, 0x1535: 0xaba9, + 0x1536: 0xabf1, 0x1537: 0xac39, 0x1538: 0xac81, 0x1539: 0xacc9, 0x153a: 0xad02, 0x153b: 0xae12, + 0x153c: 0xae91, 0x153d: 0x0018, 0x153e: 0x0040, 0x153f: 0x0040, // Block 0x55, offset 0x1540 - 0x1540: 0xb0f9, 0x1541: 0xb111, 0x1542: 0xb111, 0x1543: 0xb129, 0x1544: 0xb129, 0x1545: 0xb141, - 0x1546: 0xb141, 0x1547: 0xb159, 0x1548: 0xb159, 0x1549: 0xb171, 0x154a: 0xb171, 0x154b: 0xb171, - 0x154c: 0xb171, 0x154d: 0xb189, 0x154e: 0xb189, 0x154f: 0xb1a1, 0x1550: 0xb1a1, 0x1551: 0xb1a1, - 0x1552: 0xb1a1, 0x1553: 0xb1b9, 0x1554: 0xb1b9, 0x1555: 0xb1d1, 0x1556: 0xb1d1, 0x1557: 0xb1d1, - 0x1558: 0xb1d1, 0x1559: 0xb1e9, 0x155a: 0xb1e9, 0x155b: 0xb1e9, 0x155c: 0xb1e9, 0x155d: 0xb201, - 0x155e: 0xb201, 0x155f: 0xb201, 0x1560: 0xb201, 0x1561: 0xb219, 0x1562: 0xb219, 0x1563: 0xb219, - 0x1564: 0xb219, 0x1565: 0xb231, 0x1566: 0xb231, 0x1567: 0xb231, 0x1568: 0xb231, 0x1569: 0xb249, - 0x156a: 0xb249, 0x156b: 0xb261, 0x156c: 0xb261, 0x156d: 0xb279, 0x156e: 0xb279, 0x156f: 0xb291, - 0x1570: 0xb291, 0x1571: 0xb2a9, 0x1572: 0xb2a9, 0x1573: 0xb2a9, 0x1574: 0xb2a9, 0x1575: 0xb2c1, - 0x1576: 0xb2c1, 0x1577: 0xb2c1, 0x1578: 0xb2c1, 0x1579: 0xb2d9, 0x157a: 0xb2d9, 0x157b: 0xb2d9, - 0x157c: 0xb2d9, 0x157d: 0xb2f1, 0x157e: 0xb2f1, 0x157f: 0xb2f1, + 0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0, + 0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0, + 0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0xaeda, 0x1551: 0x7d55, + 0x1552: 0x0040, 0x1553: 0xaeea, 0x1554: 0x03c2, 0x1555: 0xaefa, 0x1556: 0xaf0a, 0x1557: 0x7d75, + 0x1558: 0x7d95, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040, + 0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308, + 0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308, + 0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308, + 0x1570: 0x0040, 0x1571: 0x7db5, 0x1572: 0x7dd5, 0x1573: 0xaf1a, 0x1574: 0xaf1a, 0x1575: 0x1fd2, + 0x1576: 0x1fe2, 0x1577: 0xaf2a, 0x1578: 0xaf3a, 0x1579: 0x7df5, 0x157a: 0x7e15, 0x157b: 0x7e35, + 0x157c: 0x7df5, 0x157d: 0x7e55, 0x157e: 0x7e75, 0x157f: 0x7e55, // Block 0x56, offset 0x1580 - 0x1580: 0xb2f1, 0x1581: 0xb309, 0x1582: 0xb309, 0x1583: 0xb309, 0x1584: 0xb309, 0x1585: 0xb321, - 0x1586: 0xb321, 0x1587: 0xb321, 0x1588: 0xb321, 0x1589: 0xb339, 0x158a: 0xb339, 0x158b: 0xb339, - 0x158c: 0xb339, 0x158d: 0xb351, 0x158e: 0xb351, 0x158f: 0xb351, 0x1590: 0xb351, 0x1591: 0xb369, - 0x1592: 0xb369, 0x1593: 0xb369, 0x1594: 0xb369, 0x1595: 0xb381, 0x1596: 0xb381, 0x1597: 0xb381, - 0x1598: 0xb381, 0x1599: 0xb399, 0x159a: 0xb399, 0x159b: 0xb399, 0x159c: 0xb399, 0x159d: 0xb3b1, - 0x159e: 0xb3b1, 0x159f: 0xb3b1, 0x15a0: 0xb3b1, 0x15a1: 0xb3c9, 0x15a2: 0xb3c9, 0x15a3: 0xb3c9, - 0x15a4: 0xb3c9, 0x15a5: 0xb3e1, 0x15a6: 0xb3e1, 0x15a7: 0xb3e1, 0x15a8: 0xb3e1, 0x15a9: 0xb3f9, - 0x15aa: 0xb3f9, 0x15ab: 0xb3f9, 0x15ac: 0xb3f9, 0x15ad: 0xb411, 0x15ae: 0xb411, 0x15af: 0x7ab1, - 0x15b0: 0x7ab1, 0x15b1: 0xb429, 0x15b2: 0xb429, 0x15b3: 0xb429, 0x15b4: 0xb429, 0x15b5: 0xb441, - 0x15b6: 0xb441, 0x15b7: 0xb469, 0x15b8: 0xb469, 0x15b9: 0xb491, 0x15ba: 0xb491, 0x15bb: 0xb4b9, - 0x15bc: 0xb4b9, 0x15bd: 0x0040, 0x15be: 0x0040, 0x15bf: 0x03c0, + 0x1580: 0x7e95, 0x1581: 0x7eb5, 0x1582: 0x7ed5, 0x1583: 0x7eb5, 0x1584: 0x7ef5, 0x1585: 0x0018, + 0x1586: 0x0018, 0x1587: 0xaf4a, 0x1588: 0xaf5a, 0x1589: 0x7f16, 0x158a: 0x7f36, 0x158b: 0x7f56, + 0x158c: 0x7f76, 0x158d: 0xaf1a, 0x158e: 0xaf1a, 0x158f: 0xaf1a, 0x1590: 0xaeda, 0x1591: 0x7f95, + 0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaeea, 0x1596: 0xaf0a, 0x1597: 0xaefa, + 0x1598: 0x7fb5, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf2a, 0x159c: 0xaf3a, 0x159d: 0x7e95, + 0x159e: 0x7ef5, 0x159f: 0xaf6a, 0x15a0: 0xaf7a, 0x15a1: 0xaf8a, 0x15a2: 0x1fb2, 0x15a3: 0xaf99, + 0x15a4: 0xafaa, 0x15a5: 0xafba, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xafca, 0x15a9: 0xafda, + 0x15aa: 0xafea, 0x15ab: 0xaffa, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040, + 0x15b0: 0x7fd6, 0x15b1: 0xb009, 0x15b2: 0x7ff6, 0x15b3: 0x0808, 0x15b4: 0x8016, 0x15b5: 0x0040, + 0x15b6: 0x8036, 0x15b7: 0xb031, 0x15b8: 0x8056, 0x15b9: 0xb059, 0x15ba: 0x8076, 0x15bb: 0xb081, + 0x15bc: 0x8096, 0x15bd: 0xb0a9, 0x15be: 0x80b6, 0x15bf: 0xb0d1, // Block 0x57, offset 0x15c0 - 0x15c0: 0x0040, 0x15c1: 0xaefa, 0x15c2: 0xb4e2, 0x15c3: 0xaf6a, 0x15c4: 0xafda, 0x15c5: 0xafea, - 0x15c6: 0xaf7a, 0x15c7: 0xb4f2, 0x15c8: 0x1fd2, 0x15c9: 0x1fe2, 0x15ca: 0xaf8a, 0x15cb: 0x1fb2, - 0x15cc: 0xaeda, 0x15cd: 0xaf99, 0x15ce: 0x29d1, 0x15cf: 0xb502, 0x15d0: 0x1f41, 0x15d1: 0x00c9, - 0x15d2: 0x0069, 0x15d3: 0x0079, 0x15d4: 0x1f51, 0x15d5: 0x1f61, 0x15d6: 0x1f71, 0x15d7: 0x1f81, - 0x15d8: 0x1f91, 0x15d9: 0x1fa1, 0x15da: 0xaeea, 0x15db: 0x03c2, 0x15dc: 0xafaa, 0x15dd: 0x1fc2, - 0x15de: 0xafba, 0x15df: 0xaf0a, 0x15e0: 0xaffa, 0x15e1: 0x0039, 0x15e2: 0x0ee9, 0x15e3: 0x1159, - 0x15e4: 0x0ef9, 0x15e5: 0x0f09, 0x15e6: 0x1199, 0x15e7: 0x0f31, 0x15e8: 0x0249, 0x15e9: 0x0f41, - 0x15ea: 0x0259, 0x15eb: 0x0f51, 0x15ec: 0x0359, 0x15ed: 0x0f61, 0x15ee: 0x0f71, 0x15ef: 0x00d9, - 0x15f0: 0x0f99, 0x15f1: 0x2039, 0x15f2: 0x0269, 0x15f3: 0x01d9, 0x15f4: 0x0fa9, 0x15f5: 0x0fb9, - 0x15f6: 0x1089, 0x15f7: 0x0279, 0x15f8: 0x0369, 0x15f9: 0x0289, 0x15fa: 0x13d1, 0x15fb: 0xaf4a, - 0x15fc: 0xafca, 0x15fd: 0xaf5a, 0x15fe: 0xb512, 0x15ff: 0xaf1a, + 0x15c0: 0xb0f9, 0x15c1: 0xb111, 0x15c2: 0xb111, 0x15c3: 0xb129, 0x15c4: 0xb129, 0x15c5: 0xb141, + 0x15c6: 0xb141, 0x15c7: 0xb159, 0x15c8: 0xb159, 0x15c9: 0xb171, 0x15ca: 0xb171, 0x15cb: 0xb171, + 0x15cc: 0xb171, 0x15cd: 0xb189, 0x15ce: 0xb189, 0x15cf: 0xb1a1, 0x15d0: 0xb1a1, 0x15d1: 0xb1a1, + 0x15d2: 0xb1a1, 0x15d3: 0xb1b9, 0x15d4: 0xb1b9, 0x15d5: 0xb1d1, 0x15d6: 0xb1d1, 0x15d7: 0xb1d1, + 0x15d8: 0xb1d1, 0x15d9: 0xb1e9, 0x15da: 0xb1e9, 0x15db: 0xb1e9, 0x15dc: 0xb1e9, 0x15dd: 0xb201, + 0x15de: 0xb201, 0x15df: 0xb201, 0x15e0: 0xb201, 0x15e1: 0xb219, 0x15e2: 0xb219, 0x15e3: 0xb219, + 0x15e4: 0xb219, 0x15e5: 0xb231, 0x15e6: 0xb231, 0x15e7: 0xb231, 0x15e8: 0xb231, 0x15e9: 0xb249, + 0x15ea: 0xb249, 0x15eb: 0xb261, 0x15ec: 0xb261, 0x15ed: 0xb279, 0x15ee: 0xb279, 0x15ef: 0xb291, + 0x15f0: 0xb291, 0x15f1: 0xb2a9, 0x15f2: 0xb2a9, 0x15f3: 0xb2a9, 0x15f4: 0xb2a9, 0x15f5: 0xb2c1, + 0x15f6: 0xb2c1, 0x15f7: 0xb2c1, 0x15f8: 0xb2c1, 0x15f9: 0xb2d9, 0x15fa: 0xb2d9, 0x15fb: 0xb2d9, + 0x15fc: 0xb2d9, 0x15fd: 0xb2f1, 0x15fe: 0xb2f1, 0x15ff: 0xb2f1, // Block 0x58, offset 0x1600 - 0x1600: 0x1caa, 0x1601: 0x0039, 0x1602: 0x0ee9, 0x1603: 0x1159, 0x1604: 0x0ef9, 0x1605: 0x0f09, - 0x1606: 0x1199, 0x1607: 0x0f31, 0x1608: 0x0249, 0x1609: 0x0f41, 0x160a: 0x0259, 0x160b: 0x0f51, - 0x160c: 0x0359, 0x160d: 0x0f61, 0x160e: 0x0f71, 0x160f: 0x00d9, 0x1610: 0x0f99, 0x1611: 0x2039, - 0x1612: 0x0269, 0x1613: 0x01d9, 0x1614: 0x0fa9, 0x1615: 0x0fb9, 0x1616: 0x1089, 0x1617: 0x0279, - 0x1618: 0x0369, 0x1619: 0x0289, 0x161a: 0x13d1, 0x161b: 0xaf2a, 0x161c: 0xb522, 0x161d: 0xaf3a, - 0x161e: 0xb532, 0x161f: 0x80d5, 0x1620: 0x80f5, 0x1621: 0x29d1, 0x1622: 0x8115, 0x1623: 0x8115, - 0x1624: 0x8135, 0x1625: 0x8155, 0x1626: 0x8175, 0x1627: 0x8195, 0x1628: 0x81b5, 0x1629: 0x81d5, - 0x162a: 0x81f5, 0x162b: 0x8215, 0x162c: 0x8235, 0x162d: 0x8255, 0x162e: 0x8275, 0x162f: 0x8295, - 0x1630: 0x82b5, 0x1631: 0x82d5, 0x1632: 0x82f5, 0x1633: 0x8315, 0x1634: 0x8335, 0x1635: 0x8355, - 0x1636: 0x8375, 0x1637: 0x8395, 0x1638: 0x83b5, 0x1639: 0x83d5, 0x163a: 0x83f5, 0x163b: 0x8415, - 0x163c: 0x81b5, 0x163d: 0x8435, 0x163e: 0x8455, 0x163f: 0x8215, + 0x1600: 0xb2f1, 0x1601: 0xb309, 0x1602: 0xb309, 0x1603: 0xb309, 0x1604: 0xb309, 0x1605: 0xb321, + 0x1606: 0xb321, 0x1607: 0xb321, 0x1608: 0xb321, 0x1609: 0xb339, 0x160a: 0xb339, 0x160b: 0xb339, + 0x160c: 0xb339, 0x160d: 0xb351, 0x160e: 0xb351, 0x160f: 0xb351, 0x1610: 0xb351, 0x1611: 0xb369, + 0x1612: 0xb369, 0x1613: 0xb369, 0x1614: 0xb369, 0x1615: 0xb381, 0x1616: 0xb381, 0x1617: 0xb381, + 0x1618: 0xb381, 0x1619: 0xb399, 0x161a: 0xb399, 0x161b: 0xb399, 0x161c: 0xb399, 0x161d: 0xb3b1, + 0x161e: 0xb3b1, 0x161f: 0xb3b1, 0x1620: 0xb3b1, 0x1621: 0xb3c9, 0x1622: 0xb3c9, 0x1623: 0xb3c9, + 0x1624: 0xb3c9, 0x1625: 0xb3e1, 0x1626: 0xb3e1, 0x1627: 0xb3e1, 0x1628: 0xb3e1, 0x1629: 0xb3f9, + 0x162a: 0xb3f9, 0x162b: 0xb3f9, 0x162c: 0xb3f9, 0x162d: 0xb411, 0x162e: 0xb411, 0x162f: 0x7ab1, + 0x1630: 0x7ab1, 0x1631: 0xb429, 0x1632: 0xb429, 0x1633: 0xb429, 0x1634: 0xb429, 0x1635: 0xb441, + 0x1636: 0xb441, 0x1637: 0xb469, 0x1638: 0xb469, 0x1639: 0xb491, 0x163a: 0xb491, 0x163b: 0xb4b9, + 0x163c: 0xb4b9, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0, // Block 0x59, offset 0x1640 - 0x1640: 0x8475, 0x1641: 0x8495, 0x1642: 0x84b5, 0x1643: 0x84d5, 0x1644: 0x84f5, 0x1645: 0x8515, - 0x1646: 0x8535, 0x1647: 0x8555, 0x1648: 0x84d5, 0x1649: 0x8575, 0x164a: 0x84d5, 0x164b: 0x8595, - 0x164c: 0x8595, 0x164d: 0x85b5, 0x164e: 0x85b5, 0x164f: 0x85d5, 0x1650: 0x8515, 0x1651: 0x85f5, - 0x1652: 0x8615, 0x1653: 0x85f5, 0x1654: 0x8635, 0x1655: 0x8615, 0x1656: 0x8655, 0x1657: 0x8655, - 0x1658: 0x8675, 0x1659: 0x8675, 0x165a: 0x8695, 0x165b: 0x8695, 0x165c: 0x8615, 0x165d: 0x8115, - 0x165e: 0x86b5, 0x165f: 0x86d5, 0x1660: 0x0040, 0x1661: 0x86f5, 0x1662: 0x8715, 0x1663: 0x8735, - 0x1664: 0x8755, 0x1665: 0x8735, 0x1666: 0x8775, 0x1667: 0x8795, 0x1668: 0x87b5, 0x1669: 0x87b5, - 0x166a: 0x87d5, 0x166b: 0x87d5, 0x166c: 0x87f5, 0x166d: 0x87f5, 0x166e: 0x87d5, 0x166f: 0x87d5, - 0x1670: 0x8815, 0x1671: 0x8835, 0x1672: 0x8855, 0x1673: 0x8875, 0x1674: 0x8895, 0x1675: 0x88b5, - 0x1676: 0x88b5, 0x1677: 0x88b5, 0x1678: 0x88d5, 0x1679: 0x88d5, 0x167a: 0x88d5, 0x167b: 0x88d5, - 0x167c: 0x87b5, 0x167d: 0x87b5, 0x167e: 0x87b5, 0x167f: 0x0040, + 0x1640: 0x0040, 0x1641: 0xaefa, 0x1642: 0xb4e2, 0x1643: 0xaf6a, 0x1644: 0xafda, 0x1645: 0xafea, + 0x1646: 0xaf7a, 0x1647: 0xb4f2, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xaf8a, 0x164b: 0x1fb2, + 0x164c: 0xaeda, 0x164d: 0xaf99, 0x164e: 0x29d1, 0x164f: 0xb502, 0x1650: 0x1f41, 0x1651: 0x00c9, + 0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81, + 0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaeea, 0x165b: 0x03c2, 0x165c: 0xafaa, 0x165d: 0x1fc2, + 0x165e: 0xafba, 0x165f: 0xaf0a, 0x1660: 0xaffa, 0x1661: 0x0039, 0x1662: 0x0ee9, 0x1663: 0x1159, + 0x1664: 0x0ef9, 0x1665: 0x0f09, 0x1666: 0x1199, 0x1667: 0x0f31, 0x1668: 0x0249, 0x1669: 0x0f41, + 0x166a: 0x0259, 0x166b: 0x0f51, 0x166c: 0x0359, 0x166d: 0x0f61, 0x166e: 0x0f71, 0x166f: 0x00d9, + 0x1670: 0x0f99, 0x1671: 0x2039, 0x1672: 0x0269, 0x1673: 0x01d9, 0x1674: 0x0fa9, 0x1675: 0x0fb9, + 0x1676: 0x1089, 0x1677: 0x0279, 0x1678: 0x0369, 0x1679: 0x0289, 0x167a: 0x13d1, 0x167b: 0xaf4a, + 0x167c: 0xafca, 0x167d: 0xaf5a, 0x167e: 0xb512, 0x167f: 0xaf1a, // Block 0x5a, offset 0x1680 - 0x1680: 0x0040, 0x1681: 0x0040, 0x1682: 0x8715, 0x1683: 0x86f5, 0x1684: 0x88f5, 0x1685: 0x86f5, - 0x1686: 0x8715, 0x1687: 0x86f5, 0x1688: 0x0040, 0x1689: 0x0040, 0x168a: 0x8915, 0x168b: 0x8715, - 0x168c: 0x8935, 0x168d: 0x88f5, 0x168e: 0x8935, 0x168f: 0x8715, 0x1690: 0x0040, 0x1691: 0x0040, - 0x1692: 0x8955, 0x1693: 0x8975, 0x1694: 0x8875, 0x1695: 0x8935, 0x1696: 0x88f5, 0x1697: 0x8935, - 0x1698: 0x0040, 0x1699: 0x0040, 0x169a: 0x8995, 0x169b: 0x89b5, 0x169c: 0x8995, 0x169d: 0x0040, - 0x169e: 0x0040, 0x169f: 0x0040, 0x16a0: 0xb541, 0x16a1: 0xb559, 0x16a2: 0xb571, 0x16a3: 0x89d6, - 0x16a4: 0xb589, 0x16a5: 0xb5a1, 0x16a6: 0x89f5, 0x16a7: 0x0040, 0x16a8: 0x8a15, 0x16a9: 0x8a35, - 0x16aa: 0x8a55, 0x16ab: 0x8a35, 0x16ac: 0x8a75, 0x16ad: 0x8a95, 0x16ae: 0x8ab5, 0x16af: 0x0040, - 0x16b0: 0x0040, 0x16b1: 0x0040, 0x16b2: 0x0040, 0x16b3: 0x0040, 0x16b4: 0x0040, 0x16b5: 0x0040, - 0x16b6: 0x0040, 0x16b7: 0x0040, 0x16b8: 0x0040, 0x16b9: 0x0340, 0x16ba: 0x0340, 0x16bb: 0x0340, - 0x16bc: 0x0040, 0x16bd: 0x0040, 0x16be: 0x0040, 0x16bf: 0x0040, + 0x1680: 0x1caa, 0x1681: 0x0039, 0x1682: 0x0ee9, 0x1683: 0x1159, 0x1684: 0x0ef9, 0x1685: 0x0f09, + 0x1686: 0x1199, 0x1687: 0x0f31, 0x1688: 0x0249, 0x1689: 0x0f41, 0x168a: 0x0259, 0x168b: 0x0f51, + 0x168c: 0x0359, 0x168d: 0x0f61, 0x168e: 0x0f71, 0x168f: 0x00d9, 0x1690: 0x0f99, 0x1691: 0x2039, + 0x1692: 0x0269, 0x1693: 0x01d9, 0x1694: 0x0fa9, 0x1695: 0x0fb9, 0x1696: 0x1089, 0x1697: 0x0279, + 0x1698: 0x0369, 0x1699: 0x0289, 0x169a: 0x13d1, 0x169b: 0xaf2a, 0x169c: 0xb522, 0x169d: 0xaf3a, + 0x169e: 0xb532, 0x169f: 0x80d5, 0x16a0: 0x80f5, 0x16a1: 0x29d1, 0x16a2: 0x8115, 0x16a3: 0x8115, + 0x16a4: 0x8135, 0x16a5: 0x8155, 0x16a6: 0x8175, 0x16a7: 0x8195, 0x16a8: 0x81b5, 0x16a9: 0x81d5, + 0x16aa: 0x81f5, 0x16ab: 0x8215, 0x16ac: 0x8235, 0x16ad: 0x8255, 0x16ae: 0x8275, 0x16af: 0x8295, + 0x16b0: 0x82b5, 0x16b1: 0x82d5, 0x16b2: 0x82f5, 0x16b3: 0x8315, 0x16b4: 0x8335, 0x16b5: 0x8355, + 0x16b6: 0x8375, 0x16b7: 0x8395, 0x16b8: 0x83b5, 0x16b9: 0x83d5, 0x16ba: 0x83f5, 0x16bb: 0x8415, + 0x16bc: 0x81b5, 0x16bd: 0x8435, 0x16be: 0x8455, 0x16bf: 0x8215, // Block 0x5b, offset 0x16c0 - 0x16c0: 0x0208, 0x16c1: 0x0208, 0x16c2: 0x0208, 0x16c3: 0x0208, 0x16c4: 0x0208, 0x16c5: 0x0408, - 0x16c6: 0x0008, 0x16c7: 0x0408, 0x16c8: 0x0018, 0x16c9: 0x0408, 0x16ca: 0x0408, 0x16cb: 0x0008, - 0x16cc: 0x0008, 0x16cd: 0x0108, 0x16ce: 0x0408, 0x16cf: 0x0408, 0x16d0: 0x0408, 0x16d1: 0x0408, - 0x16d2: 0x0408, 0x16d3: 0x0208, 0x16d4: 0x0208, 0x16d5: 0x0208, 0x16d6: 0x0208, 0x16d7: 0x0108, - 0x16d8: 0x0208, 0x16d9: 0x0208, 0x16da: 0x0208, 0x16db: 0x0208, 0x16dc: 0x0208, 0x16dd: 0x0408, - 0x16de: 0x0208, 0x16df: 0x0208, 0x16e0: 0x0208, 0x16e1: 0x0408, 0x16e2: 0x0008, 0x16e3: 0x0008, - 0x16e4: 0x0408, 0x16e5: 0x1308, 0x16e6: 0x1308, 0x16e7: 0x0040, 0x16e8: 0x0040, 0x16e9: 0x0040, - 0x16ea: 0x0040, 0x16eb: 0x0218, 0x16ec: 0x0218, 0x16ed: 0x0218, 0x16ee: 0x0218, 0x16ef: 0x0418, - 0x16f0: 0x0018, 0x16f1: 0x0018, 0x16f2: 0x0018, 0x16f3: 0x0018, 0x16f4: 0x0018, 0x16f5: 0x0018, - 0x16f6: 0x0018, 0x16f7: 0x0040, 0x16f8: 0x0040, 0x16f9: 0x0040, 0x16fa: 0x0040, 0x16fb: 0x0040, - 0x16fc: 0x0040, 0x16fd: 0x0040, 0x16fe: 0x0040, 0x16ff: 0x0040, + 0x16c0: 0x8475, 0x16c1: 0x8495, 0x16c2: 0x84b5, 0x16c3: 0x84d5, 0x16c4: 0x84f5, 0x16c5: 0x8515, + 0x16c6: 0x8535, 0x16c7: 0x8555, 0x16c8: 0x84d5, 0x16c9: 0x8575, 0x16ca: 0x84d5, 0x16cb: 0x8595, + 0x16cc: 0x8595, 0x16cd: 0x85b5, 0x16ce: 0x85b5, 0x16cf: 0x85d5, 0x16d0: 0x8515, 0x16d1: 0x85f5, + 0x16d2: 0x8615, 0x16d3: 0x85f5, 0x16d4: 0x8635, 0x16d5: 0x8615, 0x16d6: 0x8655, 0x16d7: 0x8655, + 0x16d8: 0x8675, 0x16d9: 0x8675, 0x16da: 0x8695, 0x16db: 0x8695, 0x16dc: 0x8615, 0x16dd: 0x8115, + 0x16de: 0x86b5, 0x16df: 0x86d5, 0x16e0: 0x0040, 0x16e1: 0x86f5, 0x16e2: 0x8715, 0x16e3: 0x8735, + 0x16e4: 0x8755, 0x16e5: 0x8735, 0x16e6: 0x8775, 0x16e7: 0x8795, 0x16e8: 0x87b5, 0x16e9: 0x87b5, + 0x16ea: 0x87d5, 0x16eb: 0x87d5, 0x16ec: 0x87f5, 0x16ed: 0x87f5, 0x16ee: 0x87d5, 0x16ef: 0x87d5, + 0x16f0: 0x8815, 0x16f1: 0x8835, 0x16f2: 0x8855, 0x16f3: 0x8875, 0x16f4: 0x8895, 0x16f5: 0x88b5, + 0x16f6: 0x88b5, 0x16f7: 0x88b5, 0x16f8: 0x88d5, 0x16f9: 0x88d5, 0x16fa: 0x88d5, 0x16fb: 0x88d5, + 0x16fc: 0x87b5, 0x16fd: 0x87b5, 0x16fe: 0x87b5, 0x16ff: 0x0040, // Block 0x5c, offset 0x1700 - 0x1700: 0x0208, 0x1701: 0x0408, 0x1702: 0x0208, 0x1703: 0x0408, 0x1704: 0x0408, 0x1705: 0x0408, - 0x1706: 0x0208, 0x1707: 0x0208, 0x1708: 0x0208, 0x1709: 0x0408, 0x170a: 0x0208, 0x170b: 0x0208, - 0x170c: 0x0408, 0x170d: 0x0208, 0x170e: 0x0408, 0x170f: 0x0408, 0x1710: 0x0208, 0x1711: 0x0408, - 0x1712: 0x0040, 0x1713: 0x0040, 0x1714: 0x0040, 0x1715: 0x0040, 0x1716: 0x0040, 0x1717: 0x0040, - 0x1718: 0x0040, 0x1719: 0x0018, 0x171a: 0x0018, 0x171b: 0x0018, 0x171c: 0x0018, 0x171d: 0x0040, - 0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0x0040, 0x1721: 0x0040, 0x1722: 0x0040, 0x1723: 0x0040, - 0x1724: 0x0040, 0x1725: 0x0040, 0x1726: 0x0040, 0x1727: 0x0040, 0x1728: 0x0040, 0x1729: 0x0418, - 0x172a: 0x0418, 0x172b: 0x0418, 0x172c: 0x0418, 0x172d: 0x0218, 0x172e: 0x0218, 0x172f: 0x0018, + 0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x8715, 0x1703: 0x86f5, 0x1704: 0x88f5, 0x1705: 0x86f5, + 0x1706: 0x8715, 0x1707: 0x86f5, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x8915, 0x170b: 0x8715, + 0x170c: 0x8935, 0x170d: 0x88f5, 0x170e: 0x8935, 0x170f: 0x8715, 0x1710: 0x0040, 0x1711: 0x0040, + 0x1712: 0x8955, 0x1713: 0x8975, 0x1714: 0x8875, 0x1715: 0x8935, 0x1716: 0x88f5, 0x1717: 0x8935, + 0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x8995, 0x171b: 0x89b5, 0x171c: 0x8995, 0x171d: 0x0040, + 0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0xb541, 0x1721: 0xb559, 0x1722: 0xb571, 0x1723: 0x89d6, + 0x1724: 0xb589, 0x1725: 0xb5a1, 0x1726: 0x89f5, 0x1727: 0x0040, 0x1728: 0x8a15, 0x1729: 0x8a35, + 0x172a: 0x8a55, 0x172b: 0x8a35, 0x172c: 0x8a75, 0x172d: 0x8a95, 0x172e: 0x8ab5, 0x172f: 0x0040, 0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040, - 0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0040, 0x173a: 0x0040, 0x173b: 0x0040, + 0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340, 0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040, // Block 0x5d, offset 0x1740 - 0x1740: 0x1308, 0x1741: 0x1308, 0x1742: 0x1008, 0x1743: 0x1008, 0x1744: 0x0040, 0x1745: 0x0008, - 0x1746: 0x0008, 0x1747: 0x0008, 0x1748: 0x0008, 0x1749: 0x0008, 0x174a: 0x0008, 0x174b: 0x0008, - 0x174c: 0x0008, 0x174d: 0x0040, 0x174e: 0x0040, 0x174f: 0x0008, 0x1750: 0x0008, 0x1751: 0x0040, - 0x1752: 0x0040, 0x1753: 0x0008, 0x1754: 0x0008, 0x1755: 0x0008, 0x1756: 0x0008, 0x1757: 0x0008, - 0x1758: 0x0008, 0x1759: 0x0008, 0x175a: 0x0008, 0x175b: 0x0008, 0x175c: 0x0008, 0x175d: 0x0008, - 0x175e: 0x0008, 0x175f: 0x0008, 0x1760: 0x0008, 0x1761: 0x0008, 0x1762: 0x0008, 0x1763: 0x0008, - 0x1764: 0x0008, 0x1765: 0x0008, 0x1766: 0x0008, 0x1767: 0x0008, 0x1768: 0x0008, 0x1769: 0x0040, - 0x176a: 0x0008, 0x176b: 0x0008, 0x176c: 0x0008, 0x176d: 0x0008, 0x176e: 0x0008, 0x176f: 0x0008, - 0x1770: 0x0008, 0x1771: 0x0040, 0x1772: 0x0008, 0x1773: 0x0008, 0x1774: 0x0040, 0x1775: 0x0008, - 0x1776: 0x0008, 0x1777: 0x0008, 0x1778: 0x0008, 0x1779: 0x0008, 0x177a: 0x0040, 0x177b: 0x0040, - 0x177c: 0x1308, 0x177d: 0x0008, 0x177e: 0x1008, 0x177f: 0x1008, + 0x1740: 0x0a08, 0x1741: 0x0a08, 0x1742: 0x0a08, 0x1743: 0x0a08, 0x1744: 0x0a08, 0x1745: 0x0c08, + 0x1746: 0x0808, 0x1747: 0x0c08, 0x1748: 0x0818, 0x1749: 0x0c08, 0x174a: 0x0c08, 0x174b: 0x0808, + 0x174c: 0x0808, 0x174d: 0x0908, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0c08, 0x1751: 0x0c08, + 0x1752: 0x0c08, 0x1753: 0x0a08, 0x1754: 0x0a08, 0x1755: 0x0a08, 0x1756: 0x0a08, 0x1757: 0x0908, + 0x1758: 0x0a08, 0x1759: 0x0a08, 0x175a: 0x0a08, 0x175b: 0x0a08, 0x175c: 0x0a08, 0x175d: 0x0c08, + 0x175e: 0x0a08, 0x175f: 0x0a08, 0x1760: 0x0a08, 0x1761: 0x0c08, 0x1762: 0x0808, 0x1763: 0x0808, + 0x1764: 0x0c08, 0x1765: 0x3308, 0x1766: 0x3308, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040, + 0x176a: 0x0040, 0x176b: 0x0a18, 0x176c: 0x0a18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0c18, + 0x1770: 0x0818, 0x1771: 0x0818, 0x1772: 0x0818, 0x1773: 0x0818, 0x1774: 0x0818, 0x1775: 0x0818, + 0x1776: 0x0818, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040, + 0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040, // Block 0x5e, offset 0x1780 - 0x1780: 0x1308, 0x1781: 0x1008, 0x1782: 0x1008, 0x1783: 0x1008, 0x1784: 0x1008, 0x1785: 0x0040, - 0x1786: 0x0040, 0x1787: 0x1008, 0x1788: 0x1008, 0x1789: 0x0040, 0x178a: 0x0040, 0x178b: 0x1008, - 0x178c: 0x1008, 0x178d: 0x1808, 0x178e: 0x0040, 0x178f: 0x0040, 0x1790: 0x0008, 0x1791: 0x0040, - 0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x1008, - 0x1798: 0x0040, 0x1799: 0x0040, 0x179a: 0x0040, 0x179b: 0x0040, 0x179c: 0x0040, 0x179d: 0x0008, - 0x179e: 0x0008, 0x179f: 0x0008, 0x17a0: 0x0008, 0x17a1: 0x0008, 0x17a2: 0x1008, 0x17a3: 0x1008, - 0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x1308, 0x17a7: 0x1308, 0x17a8: 0x1308, 0x17a9: 0x1308, - 0x17aa: 0x1308, 0x17ab: 0x1308, 0x17ac: 0x1308, 0x17ad: 0x0040, 0x17ae: 0x0040, 0x17af: 0x0040, - 0x17b0: 0x1308, 0x17b1: 0x1308, 0x17b2: 0x1308, 0x17b3: 0x1308, 0x17b4: 0x1308, 0x17b5: 0x0040, + 0x1780: 0x0a08, 0x1781: 0x0c08, 0x1782: 0x0a08, 0x1783: 0x0c08, 0x1784: 0x0c08, 0x1785: 0x0c08, + 0x1786: 0x0a08, 0x1787: 0x0a08, 0x1788: 0x0a08, 0x1789: 0x0c08, 0x178a: 0x0a08, 0x178b: 0x0a08, + 0x178c: 0x0c08, 0x178d: 0x0a08, 0x178e: 0x0c08, 0x178f: 0x0c08, 0x1790: 0x0a08, 0x1791: 0x0c08, + 0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x0040, + 0x1798: 0x0040, 0x1799: 0x0818, 0x179a: 0x0818, 0x179b: 0x0818, 0x179c: 0x0818, 0x179d: 0x0040, + 0x179e: 0x0040, 0x179f: 0x0040, 0x17a0: 0x0040, 0x17a1: 0x0040, 0x17a2: 0x0040, 0x17a3: 0x0040, + 0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x0040, 0x17a7: 0x0040, 0x17a8: 0x0040, 0x17a9: 0x0c18, + 0x17aa: 0x0c18, 0x17ab: 0x0c18, 0x17ac: 0x0c18, 0x17ad: 0x0a18, 0x17ae: 0x0a18, 0x17af: 0x0818, + 0x17b0: 0x0040, 0x17b1: 0x0040, 0x17b2: 0x0040, 0x17b3: 0x0040, 0x17b4: 0x0040, 0x17b5: 0x0040, 0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040, 0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040, // Block 0x5f, offset 0x17c0 - 0x17c0: 0x0039, 0x17c1: 0x0ee9, 0x17c2: 0x1159, 0x17c3: 0x0ef9, 0x17c4: 0x0f09, 0x17c5: 0x1199, - 0x17c6: 0x0f31, 0x17c7: 0x0249, 0x17c8: 0x0f41, 0x17c9: 0x0259, 0x17ca: 0x0f51, 0x17cb: 0x0359, - 0x17cc: 0x0f61, 0x17cd: 0x0f71, 0x17ce: 0x00d9, 0x17cf: 0x0f99, 0x17d0: 0x2039, 0x17d1: 0x0269, - 0x17d2: 0x01d9, 0x17d3: 0x0fa9, 0x17d4: 0x0fb9, 0x17d5: 0x1089, 0x17d6: 0x0279, 0x17d7: 0x0369, - 0x17d8: 0x0289, 0x17d9: 0x13d1, 0x17da: 0x0039, 0x17db: 0x0ee9, 0x17dc: 0x1159, 0x17dd: 0x0ef9, - 0x17de: 0x0f09, 0x17df: 0x1199, 0x17e0: 0x0f31, 0x17e1: 0x0249, 0x17e2: 0x0f41, 0x17e3: 0x0259, - 0x17e4: 0x0f51, 0x17e5: 0x0359, 0x17e6: 0x0f61, 0x17e7: 0x0f71, 0x17e8: 0x00d9, 0x17e9: 0x0f99, - 0x17ea: 0x2039, 0x17eb: 0x0269, 0x17ec: 0x01d9, 0x17ed: 0x0fa9, 0x17ee: 0x0fb9, 0x17ef: 0x1089, - 0x17f0: 0x0279, 0x17f1: 0x0369, 0x17f2: 0x0289, 0x17f3: 0x13d1, 0x17f4: 0x0039, 0x17f5: 0x0ee9, - 0x17f6: 0x1159, 0x17f7: 0x0ef9, 0x17f8: 0x0f09, 0x17f9: 0x1199, 0x17fa: 0x0f31, 0x17fb: 0x0249, - 0x17fc: 0x0f41, 0x17fd: 0x0259, 0x17fe: 0x0f51, 0x17ff: 0x0359, + 0x17c0: 0x3308, 0x17c1: 0x3308, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x0040, 0x17c5: 0x0008, + 0x17c6: 0x0008, 0x17c7: 0x0008, 0x17c8: 0x0008, 0x17c9: 0x0008, 0x17ca: 0x0008, 0x17cb: 0x0008, + 0x17cc: 0x0008, 0x17cd: 0x0040, 0x17ce: 0x0040, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0040, + 0x17d2: 0x0040, 0x17d3: 0x0008, 0x17d4: 0x0008, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0008, + 0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008, + 0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008, + 0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0040, + 0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008, + 0x17f0: 0x0008, 0x17f1: 0x0040, 0x17f2: 0x0008, 0x17f3: 0x0008, 0x17f4: 0x0040, 0x17f5: 0x0008, + 0x17f6: 0x0008, 0x17f7: 0x0008, 0x17f8: 0x0008, 0x17f9: 0x0008, 0x17fa: 0x0040, 0x17fb: 0x0040, + 0x17fc: 0x3308, 0x17fd: 0x0008, 0x17fe: 0x3008, 0x17ff: 0x3008, // Block 0x60, offset 0x1800 - 0x1800: 0x0f61, 0x1801: 0x0f71, 0x1802: 0x00d9, 0x1803: 0x0f99, 0x1804: 0x2039, 0x1805: 0x0269, - 0x1806: 0x01d9, 0x1807: 0x0fa9, 0x1808: 0x0fb9, 0x1809: 0x1089, 0x180a: 0x0279, 0x180b: 0x0369, - 0x180c: 0x0289, 0x180d: 0x13d1, 0x180e: 0x0039, 0x180f: 0x0ee9, 0x1810: 0x1159, 0x1811: 0x0ef9, - 0x1812: 0x0f09, 0x1813: 0x1199, 0x1814: 0x0f31, 0x1815: 0x0040, 0x1816: 0x0f41, 0x1817: 0x0259, - 0x1818: 0x0f51, 0x1819: 0x0359, 0x181a: 0x0f61, 0x181b: 0x0f71, 0x181c: 0x00d9, 0x181d: 0x0f99, - 0x181e: 0x2039, 0x181f: 0x0269, 0x1820: 0x01d9, 0x1821: 0x0fa9, 0x1822: 0x0fb9, 0x1823: 0x1089, - 0x1824: 0x0279, 0x1825: 0x0369, 0x1826: 0x0289, 0x1827: 0x13d1, 0x1828: 0x0039, 0x1829: 0x0ee9, - 0x182a: 0x1159, 0x182b: 0x0ef9, 0x182c: 0x0f09, 0x182d: 0x1199, 0x182e: 0x0f31, 0x182f: 0x0249, - 0x1830: 0x0f41, 0x1831: 0x0259, 0x1832: 0x0f51, 0x1833: 0x0359, 0x1834: 0x0f61, 0x1835: 0x0f71, - 0x1836: 0x00d9, 0x1837: 0x0f99, 0x1838: 0x2039, 0x1839: 0x0269, 0x183a: 0x01d9, 0x183b: 0x0fa9, - 0x183c: 0x0fb9, 0x183d: 0x1089, 0x183e: 0x0279, 0x183f: 0x0369, + 0x1800: 0x3308, 0x1801: 0x3008, 0x1802: 0x3008, 0x1803: 0x3008, 0x1804: 0x3008, 0x1805: 0x0040, + 0x1806: 0x0040, 0x1807: 0x3008, 0x1808: 0x3008, 0x1809: 0x0040, 0x180a: 0x0040, 0x180b: 0x3008, + 0x180c: 0x3008, 0x180d: 0x3808, 0x180e: 0x0040, 0x180f: 0x0040, 0x1810: 0x0008, 0x1811: 0x0040, + 0x1812: 0x0040, 0x1813: 0x0040, 0x1814: 0x0040, 0x1815: 0x0040, 0x1816: 0x0040, 0x1817: 0x3008, + 0x1818: 0x0040, 0x1819: 0x0040, 0x181a: 0x0040, 0x181b: 0x0040, 0x181c: 0x0040, 0x181d: 0x0008, + 0x181e: 0x0008, 0x181f: 0x0008, 0x1820: 0x0008, 0x1821: 0x0008, 0x1822: 0x3008, 0x1823: 0x3008, + 0x1824: 0x0040, 0x1825: 0x0040, 0x1826: 0x3308, 0x1827: 0x3308, 0x1828: 0x3308, 0x1829: 0x3308, + 0x182a: 0x3308, 0x182b: 0x3308, 0x182c: 0x3308, 0x182d: 0x0040, 0x182e: 0x0040, 0x182f: 0x0040, + 0x1830: 0x3308, 0x1831: 0x3308, 0x1832: 0x3308, 0x1833: 0x3308, 0x1834: 0x3308, 0x1835: 0x0040, + 0x1836: 0x0040, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040, + 0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040, // Block 0x61, offset 0x1840 - 0x1840: 0x0289, 0x1841: 0x13d1, 0x1842: 0x0039, 0x1843: 0x0ee9, 0x1844: 0x1159, 0x1845: 0x0ef9, - 0x1846: 0x0f09, 0x1847: 0x1199, 0x1848: 0x0f31, 0x1849: 0x0249, 0x184a: 0x0f41, 0x184b: 0x0259, - 0x184c: 0x0f51, 0x184d: 0x0359, 0x184e: 0x0f61, 0x184f: 0x0f71, 0x1850: 0x00d9, 0x1851: 0x0f99, - 0x1852: 0x2039, 0x1853: 0x0269, 0x1854: 0x01d9, 0x1855: 0x0fa9, 0x1856: 0x0fb9, 0x1857: 0x1089, - 0x1858: 0x0279, 0x1859: 0x0369, 0x185a: 0x0289, 0x185b: 0x13d1, 0x185c: 0x0039, 0x185d: 0x0040, - 0x185e: 0x1159, 0x185f: 0x0ef9, 0x1860: 0x0040, 0x1861: 0x0040, 0x1862: 0x0f31, 0x1863: 0x0040, - 0x1864: 0x0040, 0x1865: 0x0259, 0x1866: 0x0f51, 0x1867: 0x0040, 0x1868: 0x0040, 0x1869: 0x0f71, - 0x186a: 0x00d9, 0x186b: 0x0f99, 0x186c: 0x2039, 0x186d: 0x0040, 0x186e: 0x01d9, 0x186f: 0x0fa9, - 0x1870: 0x0fb9, 0x1871: 0x1089, 0x1872: 0x0279, 0x1873: 0x0369, 0x1874: 0x0289, 0x1875: 0x13d1, - 0x1876: 0x0039, 0x1877: 0x0ee9, 0x1878: 0x1159, 0x1879: 0x0ef9, 0x187a: 0x0040, 0x187b: 0x1199, - 0x187c: 0x0040, 0x187d: 0x0249, 0x187e: 0x0f41, 0x187f: 0x0259, + 0x1840: 0x0039, 0x1841: 0x0ee9, 0x1842: 0x1159, 0x1843: 0x0ef9, 0x1844: 0x0f09, 0x1845: 0x1199, + 0x1846: 0x0f31, 0x1847: 0x0249, 0x1848: 0x0f41, 0x1849: 0x0259, 0x184a: 0x0f51, 0x184b: 0x0359, + 0x184c: 0x0f61, 0x184d: 0x0f71, 0x184e: 0x00d9, 0x184f: 0x0f99, 0x1850: 0x2039, 0x1851: 0x0269, + 0x1852: 0x01d9, 0x1853: 0x0fa9, 0x1854: 0x0fb9, 0x1855: 0x1089, 0x1856: 0x0279, 0x1857: 0x0369, + 0x1858: 0x0289, 0x1859: 0x13d1, 0x185a: 0x0039, 0x185b: 0x0ee9, 0x185c: 0x1159, 0x185d: 0x0ef9, + 0x185e: 0x0f09, 0x185f: 0x1199, 0x1860: 0x0f31, 0x1861: 0x0249, 0x1862: 0x0f41, 0x1863: 0x0259, + 0x1864: 0x0f51, 0x1865: 0x0359, 0x1866: 0x0f61, 0x1867: 0x0f71, 0x1868: 0x00d9, 0x1869: 0x0f99, + 0x186a: 0x2039, 0x186b: 0x0269, 0x186c: 0x01d9, 0x186d: 0x0fa9, 0x186e: 0x0fb9, 0x186f: 0x1089, + 0x1870: 0x0279, 0x1871: 0x0369, 0x1872: 0x0289, 0x1873: 0x13d1, 0x1874: 0x0039, 0x1875: 0x0ee9, + 0x1876: 0x1159, 0x1877: 0x0ef9, 0x1878: 0x0f09, 0x1879: 0x1199, 0x187a: 0x0f31, 0x187b: 0x0249, + 0x187c: 0x0f41, 0x187d: 0x0259, 0x187e: 0x0f51, 0x187f: 0x0359, // Block 0x62, offset 0x1880 - 0x1880: 0x0f51, 0x1881: 0x0359, 0x1882: 0x0f61, 0x1883: 0x0f71, 0x1884: 0x0040, 0x1885: 0x0f99, - 0x1886: 0x2039, 0x1887: 0x0269, 0x1888: 0x01d9, 0x1889: 0x0fa9, 0x188a: 0x0fb9, 0x188b: 0x1089, - 0x188c: 0x0279, 0x188d: 0x0369, 0x188e: 0x0289, 0x188f: 0x13d1, 0x1890: 0x0039, 0x1891: 0x0ee9, - 0x1892: 0x1159, 0x1893: 0x0ef9, 0x1894: 0x0f09, 0x1895: 0x1199, 0x1896: 0x0f31, 0x1897: 0x0249, - 0x1898: 0x0f41, 0x1899: 0x0259, 0x189a: 0x0f51, 0x189b: 0x0359, 0x189c: 0x0f61, 0x189d: 0x0f71, - 0x189e: 0x00d9, 0x189f: 0x0f99, 0x18a0: 0x2039, 0x18a1: 0x0269, 0x18a2: 0x01d9, 0x18a3: 0x0fa9, - 0x18a4: 0x0fb9, 0x18a5: 0x1089, 0x18a6: 0x0279, 0x18a7: 0x0369, 0x18a8: 0x0289, 0x18a9: 0x13d1, - 0x18aa: 0x0039, 0x18ab: 0x0ee9, 0x18ac: 0x1159, 0x18ad: 0x0ef9, 0x18ae: 0x0f09, 0x18af: 0x1199, - 0x18b0: 0x0f31, 0x18b1: 0x0249, 0x18b2: 0x0f41, 0x18b3: 0x0259, 0x18b4: 0x0f51, 0x18b5: 0x0359, - 0x18b6: 0x0f61, 0x18b7: 0x0f71, 0x18b8: 0x00d9, 0x18b9: 0x0f99, 0x18ba: 0x2039, 0x18bb: 0x0269, - 0x18bc: 0x01d9, 0x18bd: 0x0fa9, 0x18be: 0x0fb9, 0x18bf: 0x1089, + 0x1880: 0x0f61, 0x1881: 0x0f71, 0x1882: 0x00d9, 0x1883: 0x0f99, 0x1884: 0x2039, 0x1885: 0x0269, + 0x1886: 0x01d9, 0x1887: 0x0fa9, 0x1888: 0x0fb9, 0x1889: 0x1089, 0x188a: 0x0279, 0x188b: 0x0369, + 0x188c: 0x0289, 0x188d: 0x13d1, 0x188e: 0x0039, 0x188f: 0x0ee9, 0x1890: 0x1159, 0x1891: 0x0ef9, + 0x1892: 0x0f09, 0x1893: 0x1199, 0x1894: 0x0f31, 0x1895: 0x0040, 0x1896: 0x0f41, 0x1897: 0x0259, + 0x1898: 0x0f51, 0x1899: 0x0359, 0x189a: 0x0f61, 0x189b: 0x0f71, 0x189c: 0x00d9, 0x189d: 0x0f99, + 0x189e: 0x2039, 0x189f: 0x0269, 0x18a0: 0x01d9, 0x18a1: 0x0fa9, 0x18a2: 0x0fb9, 0x18a3: 0x1089, + 0x18a4: 0x0279, 0x18a5: 0x0369, 0x18a6: 0x0289, 0x18a7: 0x13d1, 0x18a8: 0x0039, 0x18a9: 0x0ee9, + 0x18aa: 0x1159, 0x18ab: 0x0ef9, 0x18ac: 0x0f09, 0x18ad: 0x1199, 0x18ae: 0x0f31, 0x18af: 0x0249, + 0x18b0: 0x0f41, 0x18b1: 0x0259, 0x18b2: 0x0f51, 0x18b3: 0x0359, 0x18b4: 0x0f61, 0x18b5: 0x0f71, + 0x18b6: 0x00d9, 0x18b7: 0x0f99, 0x18b8: 0x2039, 0x18b9: 0x0269, 0x18ba: 0x01d9, 0x18bb: 0x0fa9, + 0x18bc: 0x0fb9, 0x18bd: 0x1089, 0x18be: 0x0279, 0x18bf: 0x0369, // Block 0x63, offset 0x18c0 - 0x18c0: 0x0279, 0x18c1: 0x0369, 0x18c2: 0x0289, 0x18c3: 0x13d1, 0x18c4: 0x0039, 0x18c5: 0x0ee9, - 0x18c6: 0x0040, 0x18c7: 0x0ef9, 0x18c8: 0x0f09, 0x18c9: 0x1199, 0x18ca: 0x0f31, 0x18cb: 0x0040, - 0x18cc: 0x0040, 0x18cd: 0x0259, 0x18ce: 0x0f51, 0x18cf: 0x0359, 0x18d0: 0x0f61, 0x18d1: 0x0f71, - 0x18d2: 0x00d9, 0x18d3: 0x0f99, 0x18d4: 0x2039, 0x18d5: 0x0040, 0x18d6: 0x01d9, 0x18d7: 0x0fa9, - 0x18d8: 0x0fb9, 0x18d9: 0x1089, 0x18da: 0x0279, 0x18db: 0x0369, 0x18dc: 0x0289, 0x18dd: 0x0040, - 0x18de: 0x0039, 0x18df: 0x0ee9, 0x18e0: 0x1159, 0x18e1: 0x0ef9, 0x18e2: 0x0f09, 0x18e3: 0x1199, - 0x18e4: 0x0f31, 0x18e5: 0x0249, 0x18e6: 0x0f41, 0x18e7: 0x0259, 0x18e8: 0x0f51, 0x18e9: 0x0359, - 0x18ea: 0x0f61, 0x18eb: 0x0f71, 0x18ec: 0x00d9, 0x18ed: 0x0f99, 0x18ee: 0x2039, 0x18ef: 0x0269, - 0x18f0: 0x01d9, 0x18f1: 0x0fa9, 0x18f2: 0x0fb9, 0x18f3: 0x1089, 0x18f4: 0x0279, 0x18f5: 0x0369, - 0x18f6: 0x0289, 0x18f7: 0x13d1, 0x18f8: 0x0039, 0x18f9: 0x0ee9, 0x18fa: 0x0040, 0x18fb: 0x0ef9, - 0x18fc: 0x0f09, 0x18fd: 0x1199, 0x18fe: 0x0f31, 0x18ff: 0x0040, + 0x18c0: 0x0289, 0x18c1: 0x13d1, 0x18c2: 0x0039, 0x18c3: 0x0ee9, 0x18c4: 0x1159, 0x18c5: 0x0ef9, + 0x18c6: 0x0f09, 0x18c7: 0x1199, 0x18c8: 0x0f31, 0x18c9: 0x0249, 0x18ca: 0x0f41, 0x18cb: 0x0259, + 0x18cc: 0x0f51, 0x18cd: 0x0359, 0x18ce: 0x0f61, 0x18cf: 0x0f71, 0x18d0: 0x00d9, 0x18d1: 0x0f99, + 0x18d2: 0x2039, 0x18d3: 0x0269, 0x18d4: 0x01d9, 0x18d5: 0x0fa9, 0x18d6: 0x0fb9, 0x18d7: 0x1089, + 0x18d8: 0x0279, 0x18d9: 0x0369, 0x18da: 0x0289, 0x18db: 0x13d1, 0x18dc: 0x0039, 0x18dd: 0x0040, + 0x18de: 0x1159, 0x18df: 0x0ef9, 0x18e0: 0x0040, 0x18e1: 0x0040, 0x18e2: 0x0f31, 0x18e3: 0x0040, + 0x18e4: 0x0040, 0x18e5: 0x0259, 0x18e6: 0x0f51, 0x18e7: 0x0040, 0x18e8: 0x0040, 0x18e9: 0x0f71, + 0x18ea: 0x00d9, 0x18eb: 0x0f99, 0x18ec: 0x2039, 0x18ed: 0x0040, 0x18ee: 0x01d9, 0x18ef: 0x0fa9, + 0x18f0: 0x0fb9, 0x18f1: 0x1089, 0x18f2: 0x0279, 0x18f3: 0x0369, 0x18f4: 0x0289, 0x18f5: 0x13d1, + 0x18f6: 0x0039, 0x18f7: 0x0ee9, 0x18f8: 0x1159, 0x18f9: 0x0ef9, 0x18fa: 0x0040, 0x18fb: 0x1199, + 0x18fc: 0x0040, 0x18fd: 0x0249, 0x18fe: 0x0f41, 0x18ff: 0x0259, // Block 0x64, offset 0x1900 - 0x1900: 0x0f41, 0x1901: 0x0259, 0x1902: 0x0f51, 0x1903: 0x0359, 0x1904: 0x0f61, 0x1905: 0x0040, - 0x1906: 0x00d9, 0x1907: 0x0040, 0x1908: 0x0040, 0x1909: 0x0040, 0x190a: 0x01d9, 0x190b: 0x0fa9, - 0x190c: 0x0fb9, 0x190d: 0x1089, 0x190e: 0x0279, 0x190f: 0x0369, 0x1910: 0x0289, 0x1911: 0x0040, - 0x1912: 0x0039, 0x1913: 0x0ee9, 0x1914: 0x1159, 0x1915: 0x0ef9, 0x1916: 0x0f09, 0x1917: 0x1199, - 0x1918: 0x0f31, 0x1919: 0x0249, 0x191a: 0x0f41, 0x191b: 0x0259, 0x191c: 0x0f51, 0x191d: 0x0359, - 0x191e: 0x0f61, 0x191f: 0x0f71, 0x1920: 0x00d9, 0x1921: 0x0f99, 0x1922: 0x2039, 0x1923: 0x0269, - 0x1924: 0x01d9, 0x1925: 0x0fa9, 0x1926: 0x0fb9, 0x1927: 0x1089, 0x1928: 0x0279, 0x1929: 0x0369, - 0x192a: 0x0289, 0x192b: 0x13d1, 0x192c: 0x0039, 0x192d: 0x0ee9, 0x192e: 0x1159, 0x192f: 0x0ef9, - 0x1930: 0x0f09, 0x1931: 0x1199, 0x1932: 0x0f31, 0x1933: 0x0249, 0x1934: 0x0f41, 0x1935: 0x0259, - 0x1936: 0x0f51, 0x1937: 0x0359, 0x1938: 0x0f61, 0x1939: 0x0f71, 0x193a: 0x00d9, 0x193b: 0x0f99, - 0x193c: 0x2039, 0x193d: 0x0269, 0x193e: 0x01d9, 0x193f: 0x0fa9, + 0x1900: 0x0f51, 0x1901: 0x0359, 0x1902: 0x0f61, 0x1903: 0x0f71, 0x1904: 0x0040, 0x1905: 0x0f99, + 0x1906: 0x2039, 0x1907: 0x0269, 0x1908: 0x01d9, 0x1909: 0x0fa9, 0x190a: 0x0fb9, 0x190b: 0x1089, + 0x190c: 0x0279, 0x190d: 0x0369, 0x190e: 0x0289, 0x190f: 0x13d1, 0x1910: 0x0039, 0x1911: 0x0ee9, + 0x1912: 0x1159, 0x1913: 0x0ef9, 0x1914: 0x0f09, 0x1915: 0x1199, 0x1916: 0x0f31, 0x1917: 0x0249, + 0x1918: 0x0f41, 0x1919: 0x0259, 0x191a: 0x0f51, 0x191b: 0x0359, 0x191c: 0x0f61, 0x191d: 0x0f71, + 0x191e: 0x00d9, 0x191f: 0x0f99, 0x1920: 0x2039, 0x1921: 0x0269, 0x1922: 0x01d9, 0x1923: 0x0fa9, + 0x1924: 0x0fb9, 0x1925: 0x1089, 0x1926: 0x0279, 0x1927: 0x0369, 0x1928: 0x0289, 0x1929: 0x13d1, + 0x192a: 0x0039, 0x192b: 0x0ee9, 0x192c: 0x1159, 0x192d: 0x0ef9, 0x192e: 0x0f09, 0x192f: 0x1199, + 0x1930: 0x0f31, 0x1931: 0x0249, 0x1932: 0x0f41, 0x1933: 0x0259, 0x1934: 0x0f51, 0x1935: 0x0359, + 0x1936: 0x0f61, 0x1937: 0x0f71, 0x1938: 0x00d9, 0x1939: 0x0f99, 0x193a: 0x2039, 0x193b: 0x0269, + 0x193c: 0x01d9, 0x193d: 0x0fa9, 0x193e: 0x0fb9, 0x193f: 0x1089, // Block 0x65, offset 0x1940 - 0x1940: 0x0fb9, 0x1941: 0x1089, 0x1942: 0x0279, 0x1943: 0x0369, 0x1944: 0x0289, 0x1945: 0x13d1, - 0x1946: 0x0039, 0x1947: 0x0ee9, 0x1948: 0x1159, 0x1949: 0x0ef9, 0x194a: 0x0f09, 0x194b: 0x1199, - 0x194c: 0x0f31, 0x194d: 0x0249, 0x194e: 0x0f41, 0x194f: 0x0259, 0x1950: 0x0f51, 0x1951: 0x0359, - 0x1952: 0x0f61, 0x1953: 0x0f71, 0x1954: 0x00d9, 0x1955: 0x0f99, 0x1956: 0x2039, 0x1957: 0x0269, - 0x1958: 0x01d9, 0x1959: 0x0fa9, 0x195a: 0x0fb9, 0x195b: 0x1089, 0x195c: 0x0279, 0x195d: 0x0369, - 0x195e: 0x0289, 0x195f: 0x13d1, 0x1960: 0x0039, 0x1961: 0x0ee9, 0x1962: 0x1159, 0x1963: 0x0ef9, - 0x1964: 0x0f09, 0x1965: 0x1199, 0x1966: 0x0f31, 0x1967: 0x0249, 0x1968: 0x0f41, 0x1969: 0x0259, - 0x196a: 0x0f51, 0x196b: 0x0359, 0x196c: 0x0f61, 0x196d: 0x0f71, 0x196e: 0x00d9, 0x196f: 0x0f99, - 0x1970: 0x2039, 0x1971: 0x0269, 0x1972: 0x01d9, 0x1973: 0x0fa9, 0x1974: 0x0fb9, 0x1975: 0x1089, - 0x1976: 0x0279, 0x1977: 0x0369, 0x1978: 0x0289, 0x1979: 0x13d1, 0x197a: 0x0039, 0x197b: 0x0ee9, - 0x197c: 0x1159, 0x197d: 0x0ef9, 0x197e: 0x0f09, 0x197f: 0x1199, + 0x1940: 0x0279, 0x1941: 0x0369, 0x1942: 0x0289, 0x1943: 0x13d1, 0x1944: 0x0039, 0x1945: 0x0ee9, + 0x1946: 0x0040, 0x1947: 0x0ef9, 0x1948: 0x0f09, 0x1949: 0x1199, 0x194a: 0x0f31, 0x194b: 0x0040, + 0x194c: 0x0040, 0x194d: 0x0259, 0x194e: 0x0f51, 0x194f: 0x0359, 0x1950: 0x0f61, 0x1951: 0x0f71, + 0x1952: 0x00d9, 0x1953: 0x0f99, 0x1954: 0x2039, 0x1955: 0x0040, 0x1956: 0x01d9, 0x1957: 0x0fa9, + 0x1958: 0x0fb9, 0x1959: 0x1089, 0x195a: 0x0279, 0x195b: 0x0369, 0x195c: 0x0289, 0x195d: 0x0040, + 0x195e: 0x0039, 0x195f: 0x0ee9, 0x1960: 0x1159, 0x1961: 0x0ef9, 0x1962: 0x0f09, 0x1963: 0x1199, + 0x1964: 0x0f31, 0x1965: 0x0249, 0x1966: 0x0f41, 0x1967: 0x0259, 0x1968: 0x0f51, 0x1969: 0x0359, + 0x196a: 0x0f61, 0x196b: 0x0f71, 0x196c: 0x00d9, 0x196d: 0x0f99, 0x196e: 0x2039, 0x196f: 0x0269, + 0x1970: 0x01d9, 0x1971: 0x0fa9, 0x1972: 0x0fb9, 0x1973: 0x1089, 0x1974: 0x0279, 0x1975: 0x0369, + 0x1976: 0x0289, 0x1977: 0x13d1, 0x1978: 0x0039, 0x1979: 0x0ee9, 0x197a: 0x0040, 0x197b: 0x0ef9, + 0x197c: 0x0f09, 0x197d: 0x1199, 0x197e: 0x0f31, 0x197f: 0x0040, // Block 0x66, offset 0x1980 - 0x1980: 0x0f31, 0x1981: 0x0249, 0x1982: 0x0f41, 0x1983: 0x0259, 0x1984: 0x0f51, 0x1985: 0x0359, - 0x1986: 0x0f61, 0x1987: 0x0f71, 0x1988: 0x00d9, 0x1989: 0x0f99, 0x198a: 0x2039, 0x198b: 0x0269, - 0x198c: 0x01d9, 0x198d: 0x0fa9, 0x198e: 0x0fb9, 0x198f: 0x1089, 0x1990: 0x0279, 0x1991: 0x0369, - 0x1992: 0x0289, 0x1993: 0x13d1, 0x1994: 0x0039, 0x1995: 0x0ee9, 0x1996: 0x1159, 0x1997: 0x0ef9, - 0x1998: 0x0f09, 0x1999: 0x1199, 0x199a: 0x0f31, 0x199b: 0x0249, 0x199c: 0x0f41, 0x199d: 0x0259, - 0x199e: 0x0f51, 0x199f: 0x0359, 0x19a0: 0x0f61, 0x19a1: 0x0f71, 0x19a2: 0x00d9, 0x19a3: 0x0f99, - 0x19a4: 0x2039, 0x19a5: 0x0269, 0x19a6: 0x01d9, 0x19a7: 0x0fa9, 0x19a8: 0x0fb9, 0x19a9: 0x1089, - 0x19aa: 0x0279, 0x19ab: 0x0369, 0x19ac: 0x0289, 0x19ad: 0x13d1, 0x19ae: 0x0039, 0x19af: 0x0ee9, - 0x19b0: 0x1159, 0x19b1: 0x0ef9, 0x19b2: 0x0f09, 0x19b3: 0x1199, 0x19b4: 0x0f31, 0x19b5: 0x0249, - 0x19b6: 0x0f41, 0x19b7: 0x0259, 0x19b8: 0x0f51, 0x19b9: 0x0359, 0x19ba: 0x0f61, 0x19bb: 0x0f71, - 0x19bc: 0x00d9, 0x19bd: 0x0f99, 0x19be: 0x2039, 0x19bf: 0x0269, + 0x1980: 0x0f41, 0x1981: 0x0259, 0x1982: 0x0f51, 0x1983: 0x0359, 0x1984: 0x0f61, 0x1985: 0x0040, + 0x1986: 0x00d9, 0x1987: 0x0040, 0x1988: 0x0040, 0x1989: 0x0040, 0x198a: 0x01d9, 0x198b: 0x0fa9, + 0x198c: 0x0fb9, 0x198d: 0x1089, 0x198e: 0x0279, 0x198f: 0x0369, 0x1990: 0x0289, 0x1991: 0x0040, + 0x1992: 0x0039, 0x1993: 0x0ee9, 0x1994: 0x1159, 0x1995: 0x0ef9, 0x1996: 0x0f09, 0x1997: 0x1199, + 0x1998: 0x0f31, 0x1999: 0x0249, 0x199a: 0x0f41, 0x199b: 0x0259, 0x199c: 0x0f51, 0x199d: 0x0359, + 0x199e: 0x0f61, 0x199f: 0x0f71, 0x19a0: 0x00d9, 0x19a1: 0x0f99, 0x19a2: 0x2039, 0x19a3: 0x0269, + 0x19a4: 0x01d9, 0x19a5: 0x0fa9, 0x19a6: 0x0fb9, 0x19a7: 0x1089, 0x19a8: 0x0279, 0x19a9: 0x0369, + 0x19aa: 0x0289, 0x19ab: 0x13d1, 0x19ac: 0x0039, 0x19ad: 0x0ee9, 0x19ae: 0x1159, 0x19af: 0x0ef9, + 0x19b0: 0x0f09, 0x19b1: 0x1199, 0x19b2: 0x0f31, 0x19b3: 0x0249, 0x19b4: 0x0f41, 0x19b5: 0x0259, + 0x19b6: 0x0f51, 0x19b7: 0x0359, 0x19b8: 0x0f61, 0x19b9: 0x0f71, 0x19ba: 0x00d9, 0x19bb: 0x0f99, + 0x19bc: 0x2039, 0x19bd: 0x0269, 0x19be: 0x01d9, 0x19bf: 0x0fa9, // Block 0x67, offset 0x19c0 - 0x19c0: 0x01d9, 0x19c1: 0x0fa9, 0x19c2: 0x0fb9, 0x19c3: 0x1089, 0x19c4: 0x0279, 0x19c5: 0x0369, - 0x19c6: 0x0289, 0x19c7: 0x13d1, 0x19c8: 0x0039, 0x19c9: 0x0ee9, 0x19ca: 0x1159, 0x19cb: 0x0ef9, - 0x19cc: 0x0f09, 0x19cd: 0x1199, 0x19ce: 0x0f31, 0x19cf: 0x0249, 0x19d0: 0x0f41, 0x19d1: 0x0259, - 0x19d2: 0x0f51, 0x19d3: 0x0359, 0x19d4: 0x0f61, 0x19d5: 0x0f71, 0x19d6: 0x00d9, 0x19d7: 0x0f99, - 0x19d8: 0x2039, 0x19d9: 0x0269, 0x19da: 0x01d9, 0x19db: 0x0fa9, 0x19dc: 0x0fb9, 0x19dd: 0x1089, - 0x19de: 0x0279, 0x19df: 0x0369, 0x19e0: 0x0289, 0x19e1: 0x13d1, 0x19e2: 0x0039, 0x19e3: 0x0ee9, - 0x19e4: 0x1159, 0x19e5: 0x0ef9, 0x19e6: 0x0f09, 0x19e7: 0x1199, 0x19e8: 0x0f31, 0x19e9: 0x0249, - 0x19ea: 0x0f41, 0x19eb: 0x0259, 0x19ec: 0x0f51, 0x19ed: 0x0359, 0x19ee: 0x0f61, 0x19ef: 0x0f71, - 0x19f0: 0x00d9, 0x19f1: 0x0f99, 0x19f2: 0x2039, 0x19f3: 0x0269, 0x19f4: 0x01d9, 0x19f5: 0x0fa9, - 0x19f6: 0x0fb9, 0x19f7: 0x1089, 0x19f8: 0x0279, 0x19f9: 0x0369, 0x19fa: 0x0289, 0x19fb: 0x13d1, - 0x19fc: 0x0039, 0x19fd: 0x0ee9, 0x19fe: 0x1159, 0x19ff: 0x0ef9, + 0x19c0: 0x0fb9, 0x19c1: 0x1089, 0x19c2: 0x0279, 0x19c3: 0x0369, 0x19c4: 0x0289, 0x19c5: 0x13d1, + 0x19c6: 0x0039, 0x19c7: 0x0ee9, 0x19c8: 0x1159, 0x19c9: 0x0ef9, 0x19ca: 0x0f09, 0x19cb: 0x1199, + 0x19cc: 0x0f31, 0x19cd: 0x0249, 0x19ce: 0x0f41, 0x19cf: 0x0259, 0x19d0: 0x0f51, 0x19d1: 0x0359, + 0x19d2: 0x0f61, 0x19d3: 0x0f71, 0x19d4: 0x00d9, 0x19d5: 0x0f99, 0x19d6: 0x2039, 0x19d7: 0x0269, + 0x19d8: 0x01d9, 0x19d9: 0x0fa9, 0x19da: 0x0fb9, 0x19db: 0x1089, 0x19dc: 0x0279, 0x19dd: 0x0369, + 0x19de: 0x0289, 0x19df: 0x13d1, 0x19e0: 0x0039, 0x19e1: 0x0ee9, 0x19e2: 0x1159, 0x19e3: 0x0ef9, + 0x19e4: 0x0f09, 0x19e5: 0x1199, 0x19e6: 0x0f31, 0x19e7: 0x0249, 0x19e8: 0x0f41, 0x19e9: 0x0259, + 0x19ea: 0x0f51, 0x19eb: 0x0359, 0x19ec: 0x0f61, 0x19ed: 0x0f71, 0x19ee: 0x00d9, 0x19ef: 0x0f99, + 0x19f0: 0x2039, 0x19f1: 0x0269, 0x19f2: 0x01d9, 0x19f3: 0x0fa9, 0x19f4: 0x0fb9, 0x19f5: 0x1089, + 0x19f6: 0x0279, 0x19f7: 0x0369, 0x19f8: 0x0289, 0x19f9: 0x13d1, 0x19fa: 0x0039, 0x19fb: 0x0ee9, + 0x19fc: 0x1159, 0x19fd: 0x0ef9, 0x19fe: 0x0f09, 0x19ff: 0x1199, // Block 0x68, offset 0x1a00 - 0x1a00: 0x0f09, 0x1a01: 0x1199, 0x1a02: 0x0f31, 0x1a03: 0x0249, 0x1a04: 0x0f41, 0x1a05: 0x0259, - 0x1a06: 0x0f51, 0x1a07: 0x0359, 0x1a08: 0x0f61, 0x1a09: 0x0f71, 0x1a0a: 0x00d9, 0x1a0b: 0x0f99, - 0x1a0c: 0x2039, 0x1a0d: 0x0269, 0x1a0e: 0x01d9, 0x1a0f: 0x0fa9, 0x1a10: 0x0fb9, 0x1a11: 0x1089, - 0x1a12: 0x0279, 0x1a13: 0x0369, 0x1a14: 0x0289, 0x1a15: 0x13d1, 0x1a16: 0x0039, 0x1a17: 0x0ee9, - 0x1a18: 0x1159, 0x1a19: 0x0ef9, 0x1a1a: 0x0f09, 0x1a1b: 0x1199, 0x1a1c: 0x0f31, 0x1a1d: 0x0249, - 0x1a1e: 0x0f41, 0x1a1f: 0x0259, 0x1a20: 0x0f51, 0x1a21: 0x0359, 0x1a22: 0x0f61, 0x1a23: 0x0f71, - 0x1a24: 0x00d9, 0x1a25: 0x0f99, 0x1a26: 0x2039, 0x1a27: 0x0269, 0x1a28: 0x01d9, 0x1a29: 0x0fa9, - 0x1a2a: 0x0fb9, 0x1a2b: 0x1089, 0x1a2c: 0x0279, 0x1a2d: 0x0369, 0x1a2e: 0x0289, 0x1a2f: 0x13d1, - 0x1a30: 0x0039, 0x1a31: 0x0ee9, 0x1a32: 0x1159, 0x1a33: 0x0ef9, 0x1a34: 0x0f09, 0x1a35: 0x1199, - 0x1a36: 0x0f31, 0x1a37: 0x0249, 0x1a38: 0x0f41, 0x1a39: 0x0259, 0x1a3a: 0x0f51, 0x1a3b: 0x0359, - 0x1a3c: 0x0f61, 0x1a3d: 0x0f71, 0x1a3e: 0x00d9, 0x1a3f: 0x0f99, + 0x1a00: 0x0f31, 0x1a01: 0x0249, 0x1a02: 0x0f41, 0x1a03: 0x0259, 0x1a04: 0x0f51, 0x1a05: 0x0359, + 0x1a06: 0x0f61, 0x1a07: 0x0f71, 0x1a08: 0x00d9, 0x1a09: 0x0f99, 0x1a0a: 0x2039, 0x1a0b: 0x0269, + 0x1a0c: 0x01d9, 0x1a0d: 0x0fa9, 0x1a0e: 0x0fb9, 0x1a0f: 0x1089, 0x1a10: 0x0279, 0x1a11: 0x0369, + 0x1a12: 0x0289, 0x1a13: 0x13d1, 0x1a14: 0x0039, 0x1a15: 0x0ee9, 0x1a16: 0x1159, 0x1a17: 0x0ef9, + 0x1a18: 0x0f09, 0x1a19: 0x1199, 0x1a1a: 0x0f31, 0x1a1b: 0x0249, 0x1a1c: 0x0f41, 0x1a1d: 0x0259, + 0x1a1e: 0x0f51, 0x1a1f: 0x0359, 0x1a20: 0x0f61, 0x1a21: 0x0f71, 0x1a22: 0x00d9, 0x1a23: 0x0f99, + 0x1a24: 0x2039, 0x1a25: 0x0269, 0x1a26: 0x01d9, 0x1a27: 0x0fa9, 0x1a28: 0x0fb9, 0x1a29: 0x1089, + 0x1a2a: 0x0279, 0x1a2b: 0x0369, 0x1a2c: 0x0289, 0x1a2d: 0x13d1, 0x1a2e: 0x0039, 0x1a2f: 0x0ee9, + 0x1a30: 0x1159, 0x1a31: 0x0ef9, 0x1a32: 0x0f09, 0x1a33: 0x1199, 0x1a34: 0x0f31, 0x1a35: 0x0249, + 0x1a36: 0x0f41, 0x1a37: 0x0259, 0x1a38: 0x0f51, 0x1a39: 0x0359, 0x1a3a: 0x0f61, 0x1a3b: 0x0f71, + 0x1a3c: 0x00d9, 0x1a3d: 0x0f99, 0x1a3e: 0x2039, 0x1a3f: 0x0269, // Block 0x69, offset 0x1a40 - 0x1a40: 0x2039, 0x1a41: 0x0269, 0x1a42: 0x01d9, 0x1a43: 0x0fa9, 0x1a44: 0x0fb9, 0x1a45: 0x1089, - 0x1a46: 0x0279, 0x1a47: 0x0369, 0x1a48: 0x0289, 0x1a49: 0x13d1, 0x1a4a: 0x0039, 0x1a4b: 0x0ee9, - 0x1a4c: 0x1159, 0x1a4d: 0x0ef9, 0x1a4e: 0x0f09, 0x1a4f: 0x1199, 0x1a50: 0x0f31, 0x1a51: 0x0249, - 0x1a52: 0x0f41, 0x1a53: 0x0259, 0x1a54: 0x0f51, 0x1a55: 0x0359, 0x1a56: 0x0f61, 0x1a57: 0x0f71, - 0x1a58: 0x00d9, 0x1a59: 0x0f99, 0x1a5a: 0x2039, 0x1a5b: 0x0269, 0x1a5c: 0x01d9, 0x1a5d: 0x0fa9, - 0x1a5e: 0x0fb9, 0x1a5f: 0x1089, 0x1a60: 0x0279, 0x1a61: 0x0369, 0x1a62: 0x0289, 0x1a63: 0x13d1, - 0x1a64: 0xba81, 0x1a65: 0xba99, 0x1a66: 0x0040, 0x1a67: 0x0040, 0x1a68: 0xbab1, 0x1a69: 0x1099, - 0x1a6a: 0x10b1, 0x1a6b: 0x10c9, 0x1a6c: 0xbac9, 0x1a6d: 0xbae1, 0x1a6e: 0xbaf9, 0x1a6f: 0x1429, - 0x1a70: 0x1a31, 0x1a71: 0xbb11, 0x1a72: 0xbb29, 0x1a73: 0xbb41, 0x1a74: 0xbb59, 0x1a75: 0xbb71, - 0x1a76: 0xbb89, 0x1a77: 0x2109, 0x1a78: 0x1111, 0x1a79: 0x1429, 0x1a7a: 0xbba1, 0x1a7b: 0xbbb9, - 0x1a7c: 0xbbd1, 0x1a7d: 0x10e1, 0x1a7e: 0x10f9, 0x1a7f: 0xbbe9, + 0x1a40: 0x01d9, 0x1a41: 0x0fa9, 0x1a42: 0x0fb9, 0x1a43: 0x1089, 0x1a44: 0x0279, 0x1a45: 0x0369, + 0x1a46: 0x0289, 0x1a47: 0x13d1, 0x1a48: 0x0039, 0x1a49: 0x0ee9, 0x1a4a: 0x1159, 0x1a4b: 0x0ef9, + 0x1a4c: 0x0f09, 0x1a4d: 0x1199, 0x1a4e: 0x0f31, 0x1a4f: 0x0249, 0x1a50: 0x0f41, 0x1a51: 0x0259, + 0x1a52: 0x0f51, 0x1a53: 0x0359, 0x1a54: 0x0f61, 0x1a55: 0x0f71, 0x1a56: 0x00d9, 0x1a57: 0x0f99, + 0x1a58: 0x2039, 0x1a59: 0x0269, 0x1a5a: 0x01d9, 0x1a5b: 0x0fa9, 0x1a5c: 0x0fb9, 0x1a5d: 0x1089, + 0x1a5e: 0x0279, 0x1a5f: 0x0369, 0x1a60: 0x0289, 0x1a61: 0x13d1, 0x1a62: 0x0039, 0x1a63: 0x0ee9, + 0x1a64: 0x1159, 0x1a65: 0x0ef9, 0x1a66: 0x0f09, 0x1a67: 0x1199, 0x1a68: 0x0f31, 0x1a69: 0x0249, + 0x1a6a: 0x0f41, 0x1a6b: 0x0259, 0x1a6c: 0x0f51, 0x1a6d: 0x0359, 0x1a6e: 0x0f61, 0x1a6f: 0x0f71, + 0x1a70: 0x00d9, 0x1a71: 0x0f99, 0x1a72: 0x2039, 0x1a73: 0x0269, 0x1a74: 0x01d9, 0x1a75: 0x0fa9, + 0x1a76: 0x0fb9, 0x1a77: 0x1089, 0x1a78: 0x0279, 0x1a79: 0x0369, 0x1a7a: 0x0289, 0x1a7b: 0x13d1, + 0x1a7c: 0x0039, 0x1a7d: 0x0ee9, 0x1a7e: 0x1159, 0x1a7f: 0x0ef9, // Block 0x6a, offset 0x1a80 - 0x1a80: 0x2079, 0x1a81: 0xbc01, 0x1a82: 0xbab1, 0x1a83: 0x1099, 0x1a84: 0x10b1, 0x1a85: 0x10c9, - 0x1a86: 0xbac9, 0x1a87: 0xbae1, 0x1a88: 0xbaf9, 0x1a89: 0x1429, 0x1a8a: 0x1a31, 0x1a8b: 0xbb11, - 0x1a8c: 0xbb29, 0x1a8d: 0xbb41, 0x1a8e: 0xbb59, 0x1a8f: 0xbb71, 0x1a90: 0xbb89, 0x1a91: 0x2109, - 0x1a92: 0x1111, 0x1a93: 0xbba1, 0x1a94: 0xbba1, 0x1a95: 0xbbb9, 0x1a96: 0xbbd1, 0x1a97: 0x10e1, - 0x1a98: 0x10f9, 0x1a99: 0xbbe9, 0x1a9a: 0x2079, 0x1a9b: 0xbc21, 0x1a9c: 0xbac9, 0x1a9d: 0x1429, - 0x1a9e: 0xbb11, 0x1a9f: 0x10e1, 0x1aa0: 0x1111, 0x1aa1: 0x2109, 0x1aa2: 0xbab1, 0x1aa3: 0x1099, - 0x1aa4: 0x10b1, 0x1aa5: 0x10c9, 0x1aa6: 0xbac9, 0x1aa7: 0xbae1, 0x1aa8: 0xbaf9, 0x1aa9: 0x1429, - 0x1aaa: 0x1a31, 0x1aab: 0xbb11, 0x1aac: 0xbb29, 0x1aad: 0xbb41, 0x1aae: 0xbb59, 0x1aaf: 0xbb71, - 0x1ab0: 0xbb89, 0x1ab1: 0x2109, 0x1ab2: 0x1111, 0x1ab3: 0x1429, 0x1ab4: 0xbba1, 0x1ab5: 0xbbb9, - 0x1ab6: 0xbbd1, 0x1ab7: 0x10e1, 0x1ab8: 0x10f9, 0x1ab9: 0xbbe9, 0x1aba: 0x2079, 0x1abb: 0xbc01, - 0x1abc: 0xbab1, 0x1abd: 0x1099, 0x1abe: 0x10b1, 0x1abf: 0x10c9, + 0x1a80: 0x0f09, 0x1a81: 0x1199, 0x1a82: 0x0f31, 0x1a83: 0x0249, 0x1a84: 0x0f41, 0x1a85: 0x0259, + 0x1a86: 0x0f51, 0x1a87: 0x0359, 0x1a88: 0x0f61, 0x1a89: 0x0f71, 0x1a8a: 0x00d9, 0x1a8b: 0x0f99, + 0x1a8c: 0x2039, 0x1a8d: 0x0269, 0x1a8e: 0x01d9, 0x1a8f: 0x0fa9, 0x1a90: 0x0fb9, 0x1a91: 0x1089, + 0x1a92: 0x0279, 0x1a93: 0x0369, 0x1a94: 0x0289, 0x1a95: 0x13d1, 0x1a96: 0x0039, 0x1a97: 0x0ee9, + 0x1a98: 0x1159, 0x1a99: 0x0ef9, 0x1a9a: 0x0f09, 0x1a9b: 0x1199, 0x1a9c: 0x0f31, 0x1a9d: 0x0249, + 0x1a9e: 0x0f41, 0x1a9f: 0x0259, 0x1aa0: 0x0f51, 0x1aa1: 0x0359, 0x1aa2: 0x0f61, 0x1aa3: 0x0f71, + 0x1aa4: 0x00d9, 0x1aa5: 0x0f99, 0x1aa6: 0x2039, 0x1aa7: 0x0269, 0x1aa8: 0x01d9, 0x1aa9: 0x0fa9, + 0x1aaa: 0x0fb9, 0x1aab: 0x1089, 0x1aac: 0x0279, 0x1aad: 0x0369, 0x1aae: 0x0289, 0x1aaf: 0x13d1, + 0x1ab0: 0x0039, 0x1ab1: 0x0ee9, 0x1ab2: 0x1159, 0x1ab3: 0x0ef9, 0x1ab4: 0x0f09, 0x1ab5: 0x1199, + 0x1ab6: 0x0f31, 0x1ab7: 0x0249, 0x1ab8: 0x0f41, 0x1ab9: 0x0259, 0x1aba: 0x0f51, 0x1abb: 0x0359, + 0x1abc: 0x0f61, 0x1abd: 0x0f71, 0x1abe: 0x00d9, 0x1abf: 0x0f99, // Block 0x6b, offset 0x1ac0 - 0x1ac0: 0xbac9, 0x1ac1: 0xbae1, 0x1ac2: 0xbaf9, 0x1ac3: 0x1429, 0x1ac4: 0x1a31, 0x1ac5: 0xbb11, - 0x1ac6: 0xbb29, 0x1ac7: 0xbb41, 0x1ac8: 0xbb59, 0x1ac9: 0xbb71, 0x1aca: 0xbb89, 0x1acb: 0x2109, - 0x1acc: 0x1111, 0x1acd: 0xbba1, 0x1ace: 0xbba1, 0x1acf: 0xbbb9, 0x1ad0: 0xbbd1, 0x1ad1: 0x10e1, - 0x1ad2: 0x10f9, 0x1ad3: 0xbbe9, 0x1ad4: 0x2079, 0x1ad5: 0xbc21, 0x1ad6: 0xbac9, 0x1ad7: 0x1429, - 0x1ad8: 0xbb11, 0x1ad9: 0x10e1, 0x1ada: 0x1111, 0x1adb: 0x2109, 0x1adc: 0xbab1, 0x1add: 0x1099, - 0x1ade: 0x10b1, 0x1adf: 0x10c9, 0x1ae0: 0xbac9, 0x1ae1: 0xbae1, 0x1ae2: 0xbaf9, 0x1ae3: 0x1429, - 0x1ae4: 0x1a31, 0x1ae5: 0xbb11, 0x1ae6: 0xbb29, 0x1ae7: 0xbb41, 0x1ae8: 0xbb59, 0x1ae9: 0xbb71, - 0x1aea: 0xbb89, 0x1aeb: 0x2109, 0x1aec: 0x1111, 0x1aed: 0x1429, 0x1aee: 0xbba1, 0x1aef: 0xbbb9, - 0x1af0: 0xbbd1, 0x1af1: 0x10e1, 0x1af2: 0x10f9, 0x1af3: 0xbbe9, 0x1af4: 0x2079, 0x1af5: 0xbc01, - 0x1af6: 0xbab1, 0x1af7: 0x1099, 0x1af8: 0x10b1, 0x1af9: 0x10c9, 0x1afa: 0xbac9, 0x1afb: 0xbae1, - 0x1afc: 0xbaf9, 0x1afd: 0x1429, 0x1afe: 0x1a31, 0x1aff: 0xbb11, + 0x1ac0: 0x2039, 0x1ac1: 0x0269, 0x1ac2: 0x01d9, 0x1ac3: 0x0fa9, 0x1ac4: 0x0fb9, 0x1ac5: 0x1089, + 0x1ac6: 0x0279, 0x1ac7: 0x0369, 0x1ac8: 0x0289, 0x1ac9: 0x13d1, 0x1aca: 0x0039, 0x1acb: 0x0ee9, + 0x1acc: 0x1159, 0x1acd: 0x0ef9, 0x1ace: 0x0f09, 0x1acf: 0x1199, 0x1ad0: 0x0f31, 0x1ad1: 0x0249, + 0x1ad2: 0x0f41, 0x1ad3: 0x0259, 0x1ad4: 0x0f51, 0x1ad5: 0x0359, 0x1ad6: 0x0f61, 0x1ad7: 0x0f71, + 0x1ad8: 0x00d9, 0x1ad9: 0x0f99, 0x1ada: 0x2039, 0x1adb: 0x0269, 0x1adc: 0x01d9, 0x1add: 0x0fa9, + 0x1ade: 0x0fb9, 0x1adf: 0x1089, 0x1ae0: 0x0279, 0x1ae1: 0x0369, 0x1ae2: 0x0289, 0x1ae3: 0x13d1, + 0x1ae4: 0xba81, 0x1ae5: 0xba99, 0x1ae6: 0x0040, 0x1ae7: 0x0040, 0x1ae8: 0xbab1, 0x1ae9: 0x1099, + 0x1aea: 0x10b1, 0x1aeb: 0x10c9, 0x1aec: 0xbac9, 0x1aed: 0xbae1, 0x1aee: 0xbaf9, 0x1aef: 0x1429, + 0x1af0: 0x1a31, 0x1af1: 0xbb11, 0x1af2: 0xbb29, 0x1af3: 0xbb41, 0x1af4: 0xbb59, 0x1af5: 0xbb71, + 0x1af6: 0xbb89, 0x1af7: 0x2109, 0x1af8: 0x1111, 0x1af9: 0x1429, 0x1afa: 0xbba1, 0x1afb: 0xbbb9, + 0x1afc: 0xbbd1, 0x1afd: 0x10e1, 0x1afe: 0x10f9, 0x1aff: 0xbbe9, // Block 0x6c, offset 0x1b00 - 0x1b00: 0xbb29, 0x1b01: 0xbb41, 0x1b02: 0xbb59, 0x1b03: 0xbb71, 0x1b04: 0xbb89, 0x1b05: 0x2109, - 0x1b06: 0x1111, 0x1b07: 0xbba1, 0x1b08: 0xbba1, 0x1b09: 0xbbb9, 0x1b0a: 0xbbd1, 0x1b0b: 0x10e1, - 0x1b0c: 0x10f9, 0x1b0d: 0xbbe9, 0x1b0e: 0x2079, 0x1b0f: 0xbc21, 0x1b10: 0xbac9, 0x1b11: 0x1429, - 0x1b12: 0xbb11, 0x1b13: 0x10e1, 0x1b14: 0x1111, 0x1b15: 0x2109, 0x1b16: 0xbab1, 0x1b17: 0x1099, - 0x1b18: 0x10b1, 0x1b19: 0x10c9, 0x1b1a: 0xbac9, 0x1b1b: 0xbae1, 0x1b1c: 0xbaf9, 0x1b1d: 0x1429, - 0x1b1e: 0x1a31, 0x1b1f: 0xbb11, 0x1b20: 0xbb29, 0x1b21: 0xbb41, 0x1b22: 0xbb59, 0x1b23: 0xbb71, - 0x1b24: 0xbb89, 0x1b25: 0x2109, 0x1b26: 0x1111, 0x1b27: 0x1429, 0x1b28: 0xbba1, 0x1b29: 0xbbb9, - 0x1b2a: 0xbbd1, 0x1b2b: 0x10e1, 0x1b2c: 0x10f9, 0x1b2d: 0xbbe9, 0x1b2e: 0x2079, 0x1b2f: 0xbc01, - 0x1b30: 0xbab1, 0x1b31: 0x1099, 0x1b32: 0x10b1, 0x1b33: 0x10c9, 0x1b34: 0xbac9, 0x1b35: 0xbae1, - 0x1b36: 0xbaf9, 0x1b37: 0x1429, 0x1b38: 0x1a31, 0x1b39: 0xbb11, 0x1b3a: 0xbb29, 0x1b3b: 0xbb41, - 0x1b3c: 0xbb59, 0x1b3d: 0xbb71, 0x1b3e: 0xbb89, 0x1b3f: 0x2109, + 0x1b00: 0x2079, 0x1b01: 0xbc01, 0x1b02: 0xbab1, 0x1b03: 0x1099, 0x1b04: 0x10b1, 0x1b05: 0x10c9, + 0x1b06: 0xbac9, 0x1b07: 0xbae1, 0x1b08: 0xbaf9, 0x1b09: 0x1429, 0x1b0a: 0x1a31, 0x1b0b: 0xbb11, + 0x1b0c: 0xbb29, 0x1b0d: 0xbb41, 0x1b0e: 0xbb59, 0x1b0f: 0xbb71, 0x1b10: 0xbb89, 0x1b11: 0x2109, + 0x1b12: 0x1111, 0x1b13: 0xbba1, 0x1b14: 0xbba1, 0x1b15: 0xbbb9, 0x1b16: 0xbbd1, 0x1b17: 0x10e1, + 0x1b18: 0x10f9, 0x1b19: 0xbbe9, 0x1b1a: 0x2079, 0x1b1b: 0xbc21, 0x1b1c: 0xbac9, 0x1b1d: 0x1429, + 0x1b1e: 0xbb11, 0x1b1f: 0x10e1, 0x1b20: 0x1111, 0x1b21: 0x2109, 0x1b22: 0xbab1, 0x1b23: 0x1099, + 0x1b24: 0x10b1, 0x1b25: 0x10c9, 0x1b26: 0xbac9, 0x1b27: 0xbae1, 0x1b28: 0xbaf9, 0x1b29: 0x1429, + 0x1b2a: 0x1a31, 0x1b2b: 0xbb11, 0x1b2c: 0xbb29, 0x1b2d: 0xbb41, 0x1b2e: 0xbb59, 0x1b2f: 0xbb71, + 0x1b30: 0xbb89, 0x1b31: 0x2109, 0x1b32: 0x1111, 0x1b33: 0x1429, 0x1b34: 0xbba1, 0x1b35: 0xbbb9, + 0x1b36: 0xbbd1, 0x1b37: 0x10e1, 0x1b38: 0x10f9, 0x1b39: 0xbbe9, 0x1b3a: 0x2079, 0x1b3b: 0xbc01, + 0x1b3c: 0xbab1, 0x1b3d: 0x1099, 0x1b3e: 0x10b1, 0x1b3f: 0x10c9, // Block 0x6d, offset 0x1b40 - 0x1b40: 0x1111, 0x1b41: 0xbba1, 0x1b42: 0xbba1, 0x1b43: 0xbbb9, 0x1b44: 0xbbd1, 0x1b45: 0x10e1, - 0x1b46: 0x10f9, 0x1b47: 0xbbe9, 0x1b48: 0x2079, 0x1b49: 0xbc21, 0x1b4a: 0xbac9, 0x1b4b: 0x1429, - 0x1b4c: 0xbb11, 0x1b4d: 0x10e1, 0x1b4e: 0x1111, 0x1b4f: 0x2109, 0x1b50: 0xbab1, 0x1b51: 0x1099, - 0x1b52: 0x10b1, 0x1b53: 0x10c9, 0x1b54: 0xbac9, 0x1b55: 0xbae1, 0x1b56: 0xbaf9, 0x1b57: 0x1429, - 0x1b58: 0x1a31, 0x1b59: 0xbb11, 0x1b5a: 0xbb29, 0x1b5b: 0xbb41, 0x1b5c: 0xbb59, 0x1b5d: 0xbb71, - 0x1b5e: 0xbb89, 0x1b5f: 0x2109, 0x1b60: 0x1111, 0x1b61: 0x1429, 0x1b62: 0xbba1, 0x1b63: 0xbbb9, - 0x1b64: 0xbbd1, 0x1b65: 0x10e1, 0x1b66: 0x10f9, 0x1b67: 0xbbe9, 0x1b68: 0x2079, 0x1b69: 0xbc01, - 0x1b6a: 0xbab1, 0x1b6b: 0x1099, 0x1b6c: 0x10b1, 0x1b6d: 0x10c9, 0x1b6e: 0xbac9, 0x1b6f: 0xbae1, - 0x1b70: 0xbaf9, 0x1b71: 0x1429, 0x1b72: 0x1a31, 0x1b73: 0xbb11, 0x1b74: 0xbb29, 0x1b75: 0xbb41, - 0x1b76: 0xbb59, 0x1b77: 0xbb71, 0x1b78: 0xbb89, 0x1b79: 0x2109, 0x1b7a: 0x1111, 0x1b7b: 0xbba1, - 0x1b7c: 0xbba1, 0x1b7d: 0xbbb9, 0x1b7e: 0xbbd1, 0x1b7f: 0x10e1, + 0x1b40: 0xbac9, 0x1b41: 0xbae1, 0x1b42: 0xbaf9, 0x1b43: 0x1429, 0x1b44: 0x1a31, 0x1b45: 0xbb11, + 0x1b46: 0xbb29, 0x1b47: 0xbb41, 0x1b48: 0xbb59, 0x1b49: 0xbb71, 0x1b4a: 0xbb89, 0x1b4b: 0x2109, + 0x1b4c: 0x1111, 0x1b4d: 0xbba1, 0x1b4e: 0xbba1, 0x1b4f: 0xbbb9, 0x1b50: 0xbbd1, 0x1b51: 0x10e1, + 0x1b52: 0x10f9, 0x1b53: 0xbbe9, 0x1b54: 0x2079, 0x1b55: 0xbc21, 0x1b56: 0xbac9, 0x1b57: 0x1429, + 0x1b58: 0xbb11, 0x1b59: 0x10e1, 0x1b5a: 0x1111, 0x1b5b: 0x2109, 0x1b5c: 0xbab1, 0x1b5d: 0x1099, + 0x1b5e: 0x10b1, 0x1b5f: 0x10c9, 0x1b60: 0xbac9, 0x1b61: 0xbae1, 0x1b62: 0xbaf9, 0x1b63: 0x1429, + 0x1b64: 0x1a31, 0x1b65: 0xbb11, 0x1b66: 0xbb29, 0x1b67: 0xbb41, 0x1b68: 0xbb59, 0x1b69: 0xbb71, + 0x1b6a: 0xbb89, 0x1b6b: 0x2109, 0x1b6c: 0x1111, 0x1b6d: 0x1429, 0x1b6e: 0xbba1, 0x1b6f: 0xbbb9, + 0x1b70: 0xbbd1, 0x1b71: 0x10e1, 0x1b72: 0x10f9, 0x1b73: 0xbbe9, 0x1b74: 0x2079, 0x1b75: 0xbc01, + 0x1b76: 0xbab1, 0x1b77: 0x1099, 0x1b78: 0x10b1, 0x1b79: 0x10c9, 0x1b7a: 0xbac9, 0x1b7b: 0xbae1, + 0x1b7c: 0xbaf9, 0x1b7d: 0x1429, 0x1b7e: 0x1a31, 0x1b7f: 0xbb11, // Block 0x6e, offset 0x1b80 - 0x1b80: 0x10f9, 0x1b81: 0xbbe9, 0x1b82: 0x2079, 0x1b83: 0xbc21, 0x1b84: 0xbac9, 0x1b85: 0x1429, - 0x1b86: 0xbb11, 0x1b87: 0x10e1, 0x1b88: 0x1111, 0x1b89: 0x2109, 0x1b8a: 0xbc41, 0x1b8b: 0xbc41, - 0x1b8c: 0x0040, 0x1b8d: 0x0040, 0x1b8e: 0x1f41, 0x1b8f: 0x00c9, 0x1b90: 0x0069, 0x1b91: 0x0079, - 0x1b92: 0x1f51, 0x1b93: 0x1f61, 0x1b94: 0x1f71, 0x1b95: 0x1f81, 0x1b96: 0x1f91, 0x1b97: 0x1fa1, - 0x1b98: 0x1f41, 0x1b99: 0x00c9, 0x1b9a: 0x0069, 0x1b9b: 0x0079, 0x1b9c: 0x1f51, 0x1b9d: 0x1f61, - 0x1b9e: 0x1f71, 0x1b9f: 0x1f81, 0x1ba0: 0x1f91, 0x1ba1: 0x1fa1, 0x1ba2: 0x1f41, 0x1ba3: 0x00c9, - 0x1ba4: 0x0069, 0x1ba5: 0x0079, 0x1ba6: 0x1f51, 0x1ba7: 0x1f61, 0x1ba8: 0x1f71, 0x1ba9: 0x1f81, - 0x1baa: 0x1f91, 0x1bab: 0x1fa1, 0x1bac: 0x1f41, 0x1bad: 0x00c9, 0x1bae: 0x0069, 0x1baf: 0x0079, - 0x1bb0: 0x1f51, 0x1bb1: 0x1f61, 0x1bb2: 0x1f71, 0x1bb3: 0x1f81, 0x1bb4: 0x1f91, 0x1bb5: 0x1fa1, - 0x1bb6: 0x1f41, 0x1bb7: 0x00c9, 0x1bb8: 0x0069, 0x1bb9: 0x0079, 0x1bba: 0x1f51, 0x1bbb: 0x1f61, - 0x1bbc: 0x1f71, 0x1bbd: 0x1f81, 0x1bbe: 0x1f91, 0x1bbf: 0x1fa1, + 0x1b80: 0xbb29, 0x1b81: 0xbb41, 0x1b82: 0xbb59, 0x1b83: 0xbb71, 0x1b84: 0xbb89, 0x1b85: 0x2109, + 0x1b86: 0x1111, 0x1b87: 0xbba1, 0x1b88: 0xbba1, 0x1b89: 0xbbb9, 0x1b8a: 0xbbd1, 0x1b8b: 0x10e1, + 0x1b8c: 0x10f9, 0x1b8d: 0xbbe9, 0x1b8e: 0x2079, 0x1b8f: 0xbc21, 0x1b90: 0xbac9, 0x1b91: 0x1429, + 0x1b92: 0xbb11, 0x1b93: 0x10e1, 0x1b94: 0x1111, 0x1b95: 0x2109, 0x1b96: 0xbab1, 0x1b97: 0x1099, + 0x1b98: 0x10b1, 0x1b99: 0x10c9, 0x1b9a: 0xbac9, 0x1b9b: 0xbae1, 0x1b9c: 0xbaf9, 0x1b9d: 0x1429, + 0x1b9e: 0x1a31, 0x1b9f: 0xbb11, 0x1ba0: 0xbb29, 0x1ba1: 0xbb41, 0x1ba2: 0xbb59, 0x1ba3: 0xbb71, + 0x1ba4: 0xbb89, 0x1ba5: 0x2109, 0x1ba6: 0x1111, 0x1ba7: 0x1429, 0x1ba8: 0xbba1, 0x1ba9: 0xbbb9, + 0x1baa: 0xbbd1, 0x1bab: 0x10e1, 0x1bac: 0x10f9, 0x1bad: 0xbbe9, 0x1bae: 0x2079, 0x1baf: 0xbc01, + 0x1bb0: 0xbab1, 0x1bb1: 0x1099, 0x1bb2: 0x10b1, 0x1bb3: 0x10c9, 0x1bb4: 0xbac9, 0x1bb5: 0xbae1, + 0x1bb6: 0xbaf9, 0x1bb7: 0x1429, 0x1bb8: 0x1a31, 0x1bb9: 0xbb11, 0x1bba: 0xbb29, 0x1bbb: 0xbb41, + 0x1bbc: 0xbb59, 0x1bbd: 0xbb71, 0x1bbe: 0xbb89, 0x1bbf: 0x2109, // Block 0x6f, offset 0x1bc0 - 0x1bc0: 0xe115, 0x1bc1: 0xe115, 0x1bc2: 0xe135, 0x1bc3: 0xe135, 0x1bc4: 0xe115, 0x1bc5: 0xe115, - 0x1bc6: 0xe175, 0x1bc7: 0xe175, 0x1bc8: 0xe115, 0x1bc9: 0xe115, 0x1bca: 0xe135, 0x1bcb: 0xe135, - 0x1bcc: 0xe115, 0x1bcd: 0xe115, 0x1bce: 0xe1f5, 0x1bcf: 0xe1f5, 0x1bd0: 0xe115, 0x1bd1: 0xe115, - 0x1bd2: 0xe135, 0x1bd3: 0xe135, 0x1bd4: 0xe115, 0x1bd5: 0xe115, 0x1bd6: 0xe175, 0x1bd7: 0xe175, - 0x1bd8: 0xe115, 0x1bd9: 0xe115, 0x1bda: 0xe135, 0x1bdb: 0xe135, 0x1bdc: 0xe115, 0x1bdd: 0xe115, - 0x1bde: 0x8b05, 0x1bdf: 0x8b05, 0x1be0: 0x04b5, 0x1be1: 0x04b5, 0x1be2: 0x0208, 0x1be3: 0x0208, - 0x1be4: 0x0208, 0x1be5: 0x0208, 0x1be6: 0x0208, 0x1be7: 0x0208, 0x1be8: 0x0208, 0x1be9: 0x0208, - 0x1bea: 0x0208, 0x1beb: 0x0208, 0x1bec: 0x0208, 0x1bed: 0x0208, 0x1bee: 0x0208, 0x1bef: 0x0208, - 0x1bf0: 0x0208, 0x1bf1: 0x0208, 0x1bf2: 0x0208, 0x1bf3: 0x0208, 0x1bf4: 0x0208, 0x1bf5: 0x0208, - 0x1bf6: 0x0208, 0x1bf7: 0x0208, 0x1bf8: 0x0208, 0x1bf9: 0x0208, 0x1bfa: 0x0208, 0x1bfb: 0x0208, - 0x1bfc: 0x0208, 0x1bfd: 0x0208, 0x1bfe: 0x0208, 0x1bff: 0x0208, + 0x1bc0: 0x1111, 0x1bc1: 0xbba1, 0x1bc2: 0xbba1, 0x1bc3: 0xbbb9, 0x1bc4: 0xbbd1, 0x1bc5: 0x10e1, + 0x1bc6: 0x10f9, 0x1bc7: 0xbbe9, 0x1bc8: 0x2079, 0x1bc9: 0xbc21, 0x1bca: 0xbac9, 0x1bcb: 0x1429, + 0x1bcc: 0xbb11, 0x1bcd: 0x10e1, 0x1bce: 0x1111, 0x1bcf: 0x2109, 0x1bd0: 0xbab1, 0x1bd1: 0x1099, + 0x1bd2: 0x10b1, 0x1bd3: 0x10c9, 0x1bd4: 0xbac9, 0x1bd5: 0xbae1, 0x1bd6: 0xbaf9, 0x1bd7: 0x1429, + 0x1bd8: 0x1a31, 0x1bd9: 0xbb11, 0x1bda: 0xbb29, 0x1bdb: 0xbb41, 0x1bdc: 0xbb59, 0x1bdd: 0xbb71, + 0x1bde: 0xbb89, 0x1bdf: 0x2109, 0x1be0: 0x1111, 0x1be1: 0x1429, 0x1be2: 0xbba1, 0x1be3: 0xbbb9, + 0x1be4: 0xbbd1, 0x1be5: 0x10e1, 0x1be6: 0x10f9, 0x1be7: 0xbbe9, 0x1be8: 0x2079, 0x1be9: 0xbc01, + 0x1bea: 0xbab1, 0x1beb: 0x1099, 0x1bec: 0x10b1, 0x1bed: 0x10c9, 0x1bee: 0xbac9, 0x1bef: 0xbae1, + 0x1bf0: 0xbaf9, 0x1bf1: 0x1429, 0x1bf2: 0x1a31, 0x1bf3: 0xbb11, 0x1bf4: 0xbb29, 0x1bf5: 0xbb41, + 0x1bf6: 0xbb59, 0x1bf7: 0xbb71, 0x1bf8: 0xbb89, 0x1bf9: 0x2109, 0x1bfa: 0x1111, 0x1bfb: 0xbba1, + 0x1bfc: 0xbba1, 0x1bfd: 0xbbb9, 0x1bfe: 0xbbd1, 0x1bff: 0x10e1, // Block 0x70, offset 0x1c00 - 0x1c00: 0xb189, 0x1c01: 0xb1a1, 0x1c02: 0xb201, 0x1c03: 0xb249, 0x1c04: 0x0040, 0x1c05: 0xb411, - 0x1c06: 0xb291, 0x1c07: 0xb219, 0x1c08: 0xb309, 0x1c09: 0xb429, 0x1c0a: 0xb399, 0x1c0b: 0xb3b1, - 0x1c0c: 0xb3c9, 0x1c0d: 0xb3e1, 0x1c0e: 0xb2a9, 0x1c0f: 0xb339, 0x1c10: 0xb369, 0x1c11: 0xb2d9, - 0x1c12: 0xb381, 0x1c13: 0xb279, 0x1c14: 0xb2c1, 0x1c15: 0xb1d1, 0x1c16: 0xb1e9, 0x1c17: 0xb231, - 0x1c18: 0xb261, 0x1c19: 0xb2f1, 0x1c1a: 0xb321, 0x1c1b: 0xb351, 0x1c1c: 0xbc59, 0x1c1d: 0x7949, - 0x1c1e: 0xbc71, 0x1c1f: 0xbc89, 0x1c20: 0x0040, 0x1c21: 0xb1a1, 0x1c22: 0xb201, 0x1c23: 0x0040, - 0x1c24: 0xb3f9, 0x1c25: 0x0040, 0x1c26: 0x0040, 0x1c27: 0xb219, 0x1c28: 0x0040, 0x1c29: 0xb429, - 0x1c2a: 0xb399, 0x1c2b: 0xb3b1, 0x1c2c: 0xb3c9, 0x1c2d: 0xb3e1, 0x1c2e: 0xb2a9, 0x1c2f: 0xb339, - 0x1c30: 0xb369, 0x1c31: 0xb2d9, 0x1c32: 0xb381, 0x1c33: 0x0040, 0x1c34: 0xb2c1, 0x1c35: 0xb1d1, - 0x1c36: 0xb1e9, 0x1c37: 0xb231, 0x1c38: 0x0040, 0x1c39: 0xb2f1, 0x1c3a: 0x0040, 0x1c3b: 0xb351, - 0x1c3c: 0x0040, 0x1c3d: 0x0040, 0x1c3e: 0x0040, 0x1c3f: 0x0040, + 0x1c00: 0x10f9, 0x1c01: 0xbbe9, 0x1c02: 0x2079, 0x1c03: 0xbc21, 0x1c04: 0xbac9, 0x1c05: 0x1429, + 0x1c06: 0xbb11, 0x1c07: 0x10e1, 0x1c08: 0x1111, 0x1c09: 0x2109, 0x1c0a: 0xbc41, 0x1c0b: 0xbc41, + 0x1c0c: 0x0040, 0x1c0d: 0x0040, 0x1c0e: 0x1f41, 0x1c0f: 0x00c9, 0x1c10: 0x0069, 0x1c11: 0x0079, + 0x1c12: 0x1f51, 0x1c13: 0x1f61, 0x1c14: 0x1f71, 0x1c15: 0x1f81, 0x1c16: 0x1f91, 0x1c17: 0x1fa1, + 0x1c18: 0x1f41, 0x1c19: 0x00c9, 0x1c1a: 0x0069, 0x1c1b: 0x0079, 0x1c1c: 0x1f51, 0x1c1d: 0x1f61, + 0x1c1e: 0x1f71, 0x1c1f: 0x1f81, 0x1c20: 0x1f91, 0x1c21: 0x1fa1, 0x1c22: 0x1f41, 0x1c23: 0x00c9, + 0x1c24: 0x0069, 0x1c25: 0x0079, 0x1c26: 0x1f51, 0x1c27: 0x1f61, 0x1c28: 0x1f71, 0x1c29: 0x1f81, + 0x1c2a: 0x1f91, 0x1c2b: 0x1fa1, 0x1c2c: 0x1f41, 0x1c2d: 0x00c9, 0x1c2e: 0x0069, 0x1c2f: 0x0079, + 0x1c30: 0x1f51, 0x1c31: 0x1f61, 0x1c32: 0x1f71, 0x1c33: 0x1f81, 0x1c34: 0x1f91, 0x1c35: 0x1fa1, + 0x1c36: 0x1f41, 0x1c37: 0x00c9, 0x1c38: 0x0069, 0x1c39: 0x0079, 0x1c3a: 0x1f51, 0x1c3b: 0x1f61, + 0x1c3c: 0x1f71, 0x1c3d: 0x1f81, 0x1c3e: 0x1f91, 0x1c3f: 0x1fa1, // Block 0x71, offset 0x1c40 - 0x1c40: 0x0040, 0x1c41: 0x0040, 0x1c42: 0xb201, 0x1c43: 0x0040, 0x1c44: 0x0040, 0x1c45: 0x0040, - 0x1c46: 0x0040, 0x1c47: 0xb219, 0x1c48: 0x0040, 0x1c49: 0xb429, 0x1c4a: 0x0040, 0x1c4b: 0xb3b1, - 0x1c4c: 0x0040, 0x1c4d: 0xb3e1, 0x1c4e: 0xb2a9, 0x1c4f: 0xb339, 0x1c50: 0x0040, 0x1c51: 0xb2d9, - 0x1c52: 0xb381, 0x1c53: 0x0040, 0x1c54: 0xb2c1, 0x1c55: 0x0040, 0x1c56: 0x0040, 0x1c57: 0xb231, - 0x1c58: 0x0040, 0x1c59: 0xb2f1, 0x1c5a: 0x0040, 0x1c5b: 0xb351, 0x1c5c: 0x0040, 0x1c5d: 0x7949, - 0x1c5e: 0x0040, 0x1c5f: 0xbc89, 0x1c60: 0x0040, 0x1c61: 0xb1a1, 0x1c62: 0xb201, 0x1c63: 0x0040, - 0x1c64: 0xb3f9, 0x1c65: 0x0040, 0x1c66: 0x0040, 0x1c67: 0xb219, 0x1c68: 0xb309, 0x1c69: 0xb429, - 0x1c6a: 0xb399, 0x1c6b: 0x0040, 0x1c6c: 0xb3c9, 0x1c6d: 0xb3e1, 0x1c6e: 0xb2a9, 0x1c6f: 0xb339, - 0x1c70: 0xb369, 0x1c71: 0xb2d9, 0x1c72: 0xb381, 0x1c73: 0x0040, 0x1c74: 0xb2c1, 0x1c75: 0xb1d1, - 0x1c76: 0xb1e9, 0x1c77: 0xb231, 0x1c78: 0x0040, 0x1c79: 0xb2f1, 0x1c7a: 0xb321, 0x1c7b: 0xb351, - 0x1c7c: 0xbc59, 0x1c7d: 0x0040, 0x1c7e: 0xbc71, 0x1c7f: 0x0040, + 0x1c40: 0xe115, 0x1c41: 0xe115, 0x1c42: 0xe135, 0x1c43: 0xe135, 0x1c44: 0xe115, 0x1c45: 0xe115, + 0x1c46: 0xe175, 0x1c47: 0xe175, 0x1c48: 0xe115, 0x1c49: 0xe115, 0x1c4a: 0xe135, 0x1c4b: 0xe135, + 0x1c4c: 0xe115, 0x1c4d: 0xe115, 0x1c4e: 0xe1f5, 0x1c4f: 0xe1f5, 0x1c50: 0xe115, 0x1c51: 0xe115, + 0x1c52: 0xe135, 0x1c53: 0xe135, 0x1c54: 0xe115, 0x1c55: 0xe115, 0x1c56: 0xe175, 0x1c57: 0xe175, + 0x1c58: 0xe115, 0x1c59: 0xe115, 0x1c5a: 0xe135, 0x1c5b: 0xe135, 0x1c5c: 0xe115, 0x1c5d: 0xe115, + 0x1c5e: 0x8b05, 0x1c5f: 0x8b05, 0x1c60: 0x04b5, 0x1c61: 0x04b5, 0x1c62: 0x0a08, 0x1c63: 0x0a08, + 0x1c64: 0x0a08, 0x1c65: 0x0a08, 0x1c66: 0x0a08, 0x1c67: 0x0a08, 0x1c68: 0x0a08, 0x1c69: 0x0a08, + 0x1c6a: 0x0a08, 0x1c6b: 0x0a08, 0x1c6c: 0x0a08, 0x1c6d: 0x0a08, 0x1c6e: 0x0a08, 0x1c6f: 0x0a08, + 0x1c70: 0x0a08, 0x1c71: 0x0a08, 0x1c72: 0x0a08, 0x1c73: 0x0a08, 0x1c74: 0x0a08, 0x1c75: 0x0a08, + 0x1c76: 0x0a08, 0x1c77: 0x0a08, 0x1c78: 0x0a08, 0x1c79: 0x0a08, 0x1c7a: 0x0a08, 0x1c7b: 0x0a08, + 0x1c7c: 0x0a08, 0x1c7d: 0x0a08, 0x1c7e: 0x0a08, 0x1c7f: 0x0a08, // Block 0x72, offset 0x1c80 - 0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0xb3f9, 0x1c85: 0xb411, - 0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0x0040, 0x1c8b: 0xb3b1, + 0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0x0040, 0x1c85: 0xb411, + 0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0xb399, 0x1c8b: 0xb3b1, 0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9, 0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231, - 0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0x0040, 0x1c9d: 0x0040, - 0x1c9e: 0x0040, 0x1c9f: 0x0040, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0xb249, - 0x1ca4: 0x0040, 0x1ca5: 0xb411, 0x1ca6: 0xb291, 0x1ca7: 0xb219, 0x1ca8: 0xb309, 0x1ca9: 0xb429, - 0x1caa: 0x0040, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339, - 0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0xb279, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1, - 0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0xb261, 0x1cb9: 0xb2f1, 0x1cba: 0xb321, 0x1cbb: 0xb351, + 0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0xbc59, 0x1c9d: 0x7949, + 0x1c9e: 0xbc71, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040, + 0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0x0040, 0x1ca9: 0xb429, + 0x1caa: 0xb399, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339, + 0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1, + 0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0x0040, 0x1cbb: 0xb351, 0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040, // Block 0x73, offset 0x1cc0 - 0x1cc0: 0x0040, 0x1cc1: 0xbca2, 0x1cc2: 0xbcba, 0x1cc3: 0xbcd2, 0x1cc4: 0xbcea, 0x1cc5: 0xbd02, - 0x1cc6: 0xbd1a, 0x1cc7: 0xbd32, 0x1cc8: 0xbd4a, 0x1cc9: 0xbd62, 0x1cca: 0xbd7a, 0x1ccb: 0x0018, - 0x1ccc: 0x0018, 0x1ccd: 0x0040, 0x1cce: 0x0040, 0x1ccf: 0x0040, 0x1cd0: 0xbd92, 0x1cd1: 0xbdb2, - 0x1cd2: 0xbdd2, 0x1cd3: 0xbdf2, 0x1cd4: 0xbe12, 0x1cd5: 0xbe32, 0x1cd6: 0xbe52, 0x1cd7: 0xbe72, - 0x1cd8: 0xbe92, 0x1cd9: 0xbeb2, 0x1cda: 0xbed2, 0x1cdb: 0xbef2, 0x1cdc: 0xbf12, 0x1cdd: 0xbf32, - 0x1cde: 0xbf52, 0x1cdf: 0xbf72, 0x1ce0: 0xbf92, 0x1ce1: 0xbfb2, 0x1ce2: 0xbfd2, 0x1ce3: 0xbff2, - 0x1ce4: 0xc012, 0x1ce5: 0xc032, 0x1ce6: 0xc052, 0x1ce7: 0xc072, 0x1ce8: 0xc092, 0x1ce9: 0xc0b2, - 0x1cea: 0xc0d1, 0x1ceb: 0x1159, 0x1cec: 0x0269, 0x1ced: 0x6671, 0x1cee: 0xc111, 0x1cef: 0x0040, - 0x1cf0: 0x0039, 0x1cf1: 0x0ee9, 0x1cf2: 0x1159, 0x1cf3: 0x0ef9, 0x1cf4: 0x0f09, 0x1cf5: 0x1199, - 0x1cf6: 0x0f31, 0x1cf7: 0x0249, 0x1cf8: 0x0f41, 0x1cf9: 0x0259, 0x1cfa: 0x0f51, 0x1cfb: 0x0359, - 0x1cfc: 0x0f61, 0x1cfd: 0x0f71, 0x1cfe: 0x00d9, 0x1cff: 0x0f99, + 0x1cc0: 0x0040, 0x1cc1: 0x0040, 0x1cc2: 0xb201, 0x1cc3: 0x0040, 0x1cc4: 0x0040, 0x1cc5: 0x0040, + 0x1cc6: 0x0040, 0x1cc7: 0xb219, 0x1cc8: 0x0040, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1, + 0x1ccc: 0x0040, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0x0040, 0x1cd1: 0xb2d9, + 0x1cd2: 0xb381, 0x1cd3: 0x0040, 0x1cd4: 0xb2c1, 0x1cd5: 0x0040, 0x1cd6: 0x0040, 0x1cd7: 0xb231, + 0x1cd8: 0x0040, 0x1cd9: 0xb2f1, 0x1cda: 0x0040, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x7949, + 0x1cde: 0x0040, 0x1cdf: 0xbc89, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0x0040, + 0x1ce4: 0xb3f9, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429, + 0x1cea: 0xb399, 0x1ceb: 0x0040, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339, + 0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0x0040, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1, + 0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0x0040, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351, + 0x1cfc: 0xbc59, 0x1cfd: 0x0040, 0x1cfe: 0xbc71, 0x1cff: 0x0040, // Block 0x74, offset 0x1d00 - 0x1d00: 0x2039, 0x1d01: 0x0269, 0x1d02: 0x01d9, 0x1d03: 0x0fa9, 0x1d04: 0x0fb9, 0x1d05: 0x1089, - 0x1d06: 0x0279, 0x1d07: 0x0369, 0x1d08: 0x0289, 0x1d09: 0x13d1, 0x1d0a: 0xc129, 0x1d0b: 0x65b1, - 0x1d0c: 0xc141, 0x1d0d: 0x1441, 0x1d0e: 0xc159, 0x1d0f: 0xc179, 0x1d10: 0x0018, 0x1d11: 0x0018, - 0x1d12: 0x0018, 0x1d13: 0x0018, 0x1d14: 0x0018, 0x1d15: 0x0018, 0x1d16: 0x0018, 0x1d17: 0x0018, - 0x1d18: 0x0018, 0x1d19: 0x0018, 0x1d1a: 0x0018, 0x1d1b: 0x0018, 0x1d1c: 0x0018, 0x1d1d: 0x0018, - 0x1d1e: 0x0018, 0x1d1f: 0x0018, 0x1d20: 0x0018, 0x1d21: 0x0018, 0x1d22: 0x0018, 0x1d23: 0x0018, - 0x1d24: 0x0018, 0x1d25: 0x0018, 0x1d26: 0x0018, 0x1d27: 0x0018, 0x1d28: 0x0018, 0x1d29: 0x0018, - 0x1d2a: 0xc191, 0x1d2b: 0xc1a9, 0x1d2c: 0x0040, 0x1d2d: 0x0040, 0x1d2e: 0x0040, 0x1d2f: 0x0040, - 0x1d30: 0x0018, 0x1d31: 0x0018, 0x1d32: 0x0018, 0x1d33: 0x0018, 0x1d34: 0x0018, 0x1d35: 0x0018, - 0x1d36: 0x0018, 0x1d37: 0x0018, 0x1d38: 0x0018, 0x1d39: 0x0018, 0x1d3a: 0x0018, 0x1d3b: 0x0018, - 0x1d3c: 0x0018, 0x1d3d: 0x0018, 0x1d3e: 0x0018, 0x1d3f: 0x0018, + 0x1d00: 0xb189, 0x1d01: 0xb1a1, 0x1d02: 0xb201, 0x1d03: 0xb249, 0x1d04: 0xb3f9, 0x1d05: 0xb411, + 0x1d06: 0xb291, 0x1d07: 0xb219, 0x1d08: 0xb309, 0x1d09: 0xb429, 0x1d0a: 0x0040, 0x1d0b: 0xb3b1, + 0x1d0c: 0xb3c9, 0x1d0d: 0xb3e1, 0x1d0e: 0xb2a9, 0x1d0f: 0xb339, 0x1d10: 0xb369, 0x1d11: 0xb2d9, + 0x1d12: 0xb381, 0x1d13: 0xb279, 0x1d14: 0xb2c1, 0x1d15: 0xb1d1, 0x1d16: 0xb1e9, 0x1d17: 0xb231, + 0x1d18: 0xb261, 0x1d19: 0xb2f1, 0x1d1a: 0xb321, 0x1d1b: 0xb351, 0x1d1c: 0x0040, 0x1d1d: 0x0040, + 0x1d1e: 0x0040, 0x1d1f: 0x0040, 0x1d20: 0x0040, 0x1d21: 0xb1a1, 0x1d22: 0xb201, 0x1d23: 0xb249, + 0x1d24: 0x0040, 0x1d25: 0xb411, 0x1d26: 0xb291, 0x1d27: 0xb219, 0x1d28: 0xb309, 0x1d29: 0xb429, + 0x1d2a: 0x0040, 0x1d2b: 0xb3b1, 0x1d2c: 0xb3c9, 0x1d2d: 0xb3e1, 0x1d2e: 0xb2a9, 0x1d2f: 0xb339, + 0x1d30: 0xb369, 0x1d31: 0xb2d9, 0x1d32: 0xb381, 0x1d33: 0xb279, 0x1d34: 0xb2c1, 0x1d35: 0xb1d1, + 0x1d36: 0xb1e9, 0x1d37: 0xb231, 0x1d38: 0xb261, 0x1d39: 0xb2f1, 0x1d3a: 0xb321, 0x1d3b: 0xb351, + 0x1d3c: 0x0040, 0x1d3d: 0x0040, 0x1d3e: 0x0040, 0x1d3f: 0x0040, // Block 0x75, offset 0x1d40 - 0x1d40: 0xc1d9, 0x1d41: 0xc211, 0x1d42: 0xc249, 0x1d43: 0x0040, 0x1d44: 0x0040, 0x1d45: 0x0040, - 0x1d46: 0x0040, 0x1d47: 0x0040, 0x1d48: 0x0040, 0x1d49: 0x0040, 0x1d4a: 0x0040, 0x1d4b: 0x0040, - 0x1d4c: 0x0040, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xc269, 0x1d51: 0xc289, - 0x1d52: 0xc2a9, 0x1d53: 0xc2c9, 0x1d54: 0xc2e9, 0x1d55: 0xc309, 0x1d56: 0xc329, 0x1d57: 0xc349, - 0x1d58: 0xc369, 0x1d59: 0xc389, 0x1d5a: 0xc3a9, 0x1d5b: 0xc3c9, 0x1d5c: 0xc3e9, 0x1d5d: 0xc409, - 0x1d5e: 0xc429, 0x1d5f: 0xc449, 0x1d60: 0xc469, 0x1d61: 0xc489, 0x1d62: 0xc4a9, 0x1d63: 0xc4c9, - 0x1d64: 0xc4e9, 0x1d65: 0xc509, 0x1d66: 0xc529, 0x1d67: 0xc549, 0x1d68: 0xc569, 0x1d69: 0xc589, - 0x1d6a: 0xc5a9, 0x1d6b: 0xc5c9, 0x1d6c: 0xc5e9, 0x1d6d: 0xc609, 0x1d6e: 0xc629, 0x1d6f: 0xc649, - 0x1d70: 0xc669, 0x1d71: 0xc689, 0x1d72: 0xc6a9, 0x1d73: 0xc6c9, 0x1d74: 0xc6e9, 0x1d75: 0xc709, - 0x1d76: 0xc729, 0x1d77: 0xc749, 0x1d78: 0xc769, 0x1d79: 0xc789, 0x1d7a: 0xc7a9, 0x1d7b: 0xc7c9, - 0x1d7c: 0x0040, 0x1d7d: 0x0040, 0x1d7e: 0x0040, 0x1d7f: 0x0040, + 0x1d40: 0x0040, 0x1d41: 0xbca2, 0x1d42: 0xbcba, 0x1d43: 0xbcd2, 0x1d44: 0xbcea, 0x1d45: 0xbd02, + 0x1d46: 0xbd1a, 0x1d47: 0xbd32, 0x1d48: 0xbd4a, 0x1d49: 0xbd62, 0x1d4a: 0xbd7a, 0x1d4b: 0x0018, + 0x1d4c: 0x0018, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xbd92, 0x1d51: 0xbdb2, + 0x1d52: 0xbdd2, 0x1d53: 0xbdf2, 0x1d54: 0xbe12, 0x1d55: 0xbe32, 0x1d56: 0xbe52, 0x1d57: 0xbe72, + 0x1d58: 0xbe92, 0x1d59: 0xbeb2, 0x1d5a: 0xbed2, 0x1d5b: 0xbef2, 0x1d5c: 0xbf12, 0x1d5d: 0xbf32, + 0x1d5e: 0xbf52, 0x1d5f: 0xbf72, 0x1d60: 0xbf92, 0x1d61: 0xbfb2, 0x1d62: 0xbfd2, 0x1d63: 0xbff2, + 0x1d64: 0xc012, 0x1d65: 0xc032, 0x1d66: 0xc052, 0x1d67: 0xc072, 0x1d68: 0xc092, 0x1d69: 0xc0b2, + 0x1d6a: 0xc0d1, 0x1d6b: 0x1159, 0x1d6c: 0x0269, 0x1d6d: 0x6671, 0x1d6e: 0xc111, 0x1d6f: 0x0040, + 0x1d70: 0x0039, 0x1d71: 0x0ee9, 0x1d72: 0x1159, 0x1d73: 0x0ef9, 0x1d74: 0x0f09, 0x1d75: 0x1199, + 0x1d76: 0x0f31, 0x1d77: 0x0249, 0x1d78: 0x0f41, 0x1d79: 0x0259, 0x1d7a: 0x0f51, 0x1d7b: 0x0359, + 0x1d7c: 0x0f61, 0x1d7d: 0x0f71, 0x1d7e: 0x00d9, 0x1d7f: 0x0f99, // Block 0x76, offset 0x1d80 - 0x1d80: 0xcaf9, 0x1d81: 0xcb19, 0x1d82: 0xcb39, 0x1d83: 0x8b1d, 0x1d84: 0xcb59, 0x1d85: 0xcb79, - 0x1d86: 0xcb99, 0x1d87: 0xcbb9, 0x1d88: 0xcbd9, 0x1d89: 0xcbf9, 0x1d8a: 0xcc19, 0x1d8b: 0xcc39, - 0x1d8c: 0xcc59, 0x1d8d: 0x8b3d, 0x1d8e: 0xcc79, 0x1d8f: 0xcc99, 0x1d90: 0xccb9, 0x1d91: 0xccd9, - 0x1d92: 0x8b5d, 0x1d93: 0xccf9, 0x1d94: 0xcd19, 0x1d95: 0xc429, 0x1d96: 0x8b7d, 0x1d97: 0xcd39, - 0x1d98: 0xcd59, 0x1d99: 0xcd79, 0x1d9a: 0xcd99, 0x1d9b: 0xcdb9, 0x1d9c: 0x8b9d, 0x1d9d: 0xcdd9, - 0x1d9e: 0xcdf9, 0x1d9f: 0xce19, 0x1da0: 0xce39, 0x1da1: 0xce59, 0x1da2: 0xc789, 0x1da3: 0xce79, - 0x1da4: 0xce99, 0x1da5: 0xceb9, 0x1da6: 0xced9, 0x1da7: 0xcef9, 0x1da8: 0xcf19, 0x1da9: 0xcf39, - 0x1daa: 0xcf59, 0x1dab: 0xcf79, 0x1dac: 0xcf99, 0x1dad: 0xcfb9, 0x1dae: 0xcfd9, 0x1daf: 0xcff9, - 0x1db0: 0xd019, 0x1db1: 0xd039, 0x1db2: 0xd039, 0x1db3: 0xd039, 0x1db4: 0x8bbd, 0x1db5: 0xd059, - 0x1db6: 0xd079, 0x1db7: 0xd099, 0x1db8: 0x8bdd, 0x1db9: 0xd0b9, 0x1dba: 0xd0d9, 0x1dbb: 0xd0f9, - 0x1dbc: 0xd119, 0x1dbd: 0xd139, 0x1dbe: 0xd159, 0x1dbf: 0xd179, + 0x1d80: 0x2039, 0x1d81: 0x0269, 0x1d82: 0x01d9, 0x1d83: 0x0fa9, 0x1d84: 0x0fb9, 0x1d85: 0x1089, + 0x1d86: 0x0279, 0x1d87: 0x0369, 0x1d88: 0x0289, 0x1d89: 0x13d1, 0x1d8a: 0xc129, 0x1d8b: 0x65b1, + 0x1d8c: 0xc141, 0x1d8d: 0x1441, 0x1d8e: 0xc159, 0x1d8f: 0xc179, 0x1d90: 0x0018, 0x1d91: 0x0018, + 0x1d92: 0x0018, 0x1d93: 0x0018, 0x1d94: 0x0018, 0x1d95: 0x0018, 0x1d96: 0x0018, 0x1d97: 0x0018, + 0x1d98: 0x0018, 0x1d99: 0x0018, 0x1d9a: 0x0018, 0x1d9b: 0x0018, 0x1d9c: 0x0018, 0x1d9d: 0x0018, + 0x1d9e: 0x0018, 0x1d9f: 0x0018, 0x1da0: 0x0018, 0x1da1: 0x0018, 0x1da2: 0x0018, 0x1da3: 0x0018, + 0x1da4: 0x0018, 0x1da5: 0x0018, 0x1da6: 0x0018, 0x1da7: 0x0018, 0x1da8: 0x0018, 0x1da9: 0x0018, + 0x1daa: 0xc191, 0x1dab: 0xc1a9, 0x1dac: 0x0040, 0x1dad: 0x0040, 0x1dae: 0x0040, 0x1daf: 0x0040, + 0x1db0: 0x0018, 0x1db1: 0x0018, 0x1db2: 0x0018, 0x1db3: 0x0018, 0x1db4: 0x0018, 0x1db5: 0x0018, + 0x1db6: 0x0018, 0x1db7: 0x0018, 0x1db8: 0x0018, 0x1db9: 0x0018, 0x1dba: 0x0018, 0x1dbb: 0x0018, + 0x1dbc: 0x0018, 0x1dbd: 0x0018, 0x1dbe: 0x0018, 0x1dbf: 0x0018, // Block 0x77, offset 0x1dc0 - 0x1dc0: 0xd199, 0x1dc1: 0xd1b9, 0x1dc2: 0xd1d9, 0x1dc3: 0xd1f9, 0x1dc4: 0xd219, 0x1dc5: 0xd239, - 0x1dc6: 0xd239, 0x1dc7: 0xd259, 0x1dc8: 0xd279, 0x1dc9: 0xd299, 0x1dca: 0xd2b9, 0x1dcb: 0xd2d9, - 0x1dcc: 0xd2f9, 0x1dcd: 0xd319, 0x1dce: 0xd339, 0x1dcf: 0xd359, 0x1dd0: 0xd379, 0x1dd1: 0xd399, - 0x1dd2: 0xd3b9, 0x1dd3: 0xd3d9, 0x1dd4: 0xd3f9, 0x1dd5: 0xd419, 0x1dd6: 0xd439, 0x1dd7: 0xd459, - 0x1dd8: 0xd479, 0x1dd9: 0x8bfd, 0x1dda: 0xd499, 0x1ddb: 0xd4b9, 0x1ddc: 0xd4d9, 0x1ddd: 0xc309, - 0x1dde: 0xd4f9, 0x1ddf: 0xd519, 0x1de0: 0x8c1d, 0x1de1: 0x8c3d, 0x1de2: 0xd539, 0x1de3: 0xd559, - 0x1de4: 0xd579, 0x1de5: 0xd599, 0x1de6: 0xd5b9, 0x1de7: 0xd5d9, 0x1de8: 0x0040, 0x1de9: 0xd5f9, - 0x1dea: 0xd619, 0x1deb: 0xd619, 0x1dec: 0x8c5d, 0x1ded: 0xd639, 0x1dee: 0xd659, 0x1def: 0xd679, - 0x1df0: 0xd699, 0x1df1: 0x8c7d, 0x1df2: 0xd6b9, 0x1df3: 0xd6d9, 0x1df4: 0x0040, 0x1df5: 0xd6f9, - 0x1df6: 0xd719, 0x1df7: 0xd739, 0x1df8: 0xd759, 0x1df9: 0xd779, 0x1dfa: 0xd799, 0x1dfb: 0x8c9d, - 0x1dfc: 0xd7b9, 0x1dfd: 0x8cbd, 0x1dfe: 0xd7d9, 0x1dff: 0xd7f9, + 0x1dc0: 0xc1d9, 0x1dc1: 0xc211, 0x1dc2: 0xc249, 0x1dc3: 0x0040, 0x1dc4: 0x0040, 0x1dc5: 0x0040, + 0x1dc6: 0x0040, 0x1dc7: 0x0040, 0x1dc8: 0x0040, 0x1dc9: 0x0040, 0x1dca: 0x0040, 0x1dcb: 0x0040, + 0x1dcc: 0x0040, 0x1dcd: 0x0040, 0x1dce: 0x0040, 0x1dcf: 0x0040, 0x1dd0: 0xc269, 0x1dd1: 0xc289, + 0x1dd2: 0xc2a9, 0x1dd3: 0xc2c9, 0x1dd4: 0xc2e9, 0x1dd5: 0xc309, 0x1dd6: 0xc329, 0x1dd7: 0xc349, + 0x1dd8: 0xc369, 0x1dd9: 0xc389, 0x1dda: 0xc3a9, 0x1ddb: 0xc3c9, 0x1ddc: 0xc3e9, 0x1ddd: 0xc409, + 0x1dde: 0xc429, 0x1ddf: 0xc449, 0x1de0: 0xc469, 0x1de1: 0xc489, 0x1de2: 0xc4a9, 0x1de3: 0xc4c9, + 0x1de4: 0xc4e9, 0x1de5: 0xc509, 0x1de6: 0xc529, 0x1de7: 0xc549, 0x1de8: 0xc569, 0x1de9: 0xc589, + 0x1dea: 0xc5a9, 0x1deb: 0xc5c9, 0x1dec: 0xc5e9, 0x1ded: 0xc609, 0x1dee: 0xc629, 0x1def: 0xc649, + 0x1df0: 0xc669, 0x1df1: 0xc689, 0x1df2: 0xc6a9, 0x1df3: 0xc6c9, 0x1df4: 0xc6e9, 0x1df5: 0xc709, + 0x1df6: 0xc729, 0x1df7: 0xc749, 0x1df8: 0xc769, 0x1df9: 0xc789, 0x1dfa: 0xc7a9, 0x1dfb: 0xc7c9, + 0x1dfc: 0x0040, 0x1dfd: 0x0040, 0x1dfe: 0x0040, 0x1dff: 0x0040, // Block 0x78, offset 0x1e00 - 0x1e00: 0xd819, 0x1e01: 0xd839, 0x1e02: 0xd859, 0x1e03: 0xd879, 0x1e04: 0xd899, 0x1e05: 0xd8b9, - 0x1e06: 0xd8d9, 0x1e07: 0xd8f9, 0x1e08: 0xd919, 0x1e09: 0x8cdd, 0x1e0a: 0xd939, 0x1e0b: 0xd959, - 0x1e0c: 0xd979, 0x1e0d: 0xd999, 0x1e0e: 0xd9b9, 0x1e0f: 0x8cfd, 0x1e10: 0xd9d9, 0x1e11: 0x8d1d, - 0x1e12: 0x8d3d, 0x1e13: 0xd9f9, 0x1e14: 0xda19, 0x1e15: 0xda19, 0x1e16: 0xda39, 0x1e17: 0x8d5d, - 0x1e18: 0x8d7d, 0x1e19: 0xda59, 0x1e1a: 0xda79, 0x1e1b: 0xda99, 0x1e1c: 0xdab9, 0x1e1d: 0xdad9, - 0x1e1e: 0xdaf9, 0x1e1f: 0xdb19, 0x1e20: 0xdb39, 0x1e21: 0xdb59, 0x1e22: 0xdb79, 0x1e23: 0xdb99, - 0x1e24: 0x8d9d, 0x1e25: 0xdbb9, 0x1e26: 0xdbd9, 0x1e27: 0xdbf9, 0x1e28: 0xdc19, 0x1e29: 0xdbf9, - 0x1e2a: 0xdc39, 0x1e2b: 0xdc59, 0x1e2c: 0xdc79, 0x1e2d: 0xdc99, 0x1e2e: 0xdcb9, 0x1e2f: 0xdcd9, - 0x1e30: 0xdcf9, 0x1e31: 0xdd19, 0x1e32: 0xdd39, 0x1e33: 0xdd59, 0x1e34: 0xdd79, 0x1e35: 0xdd99, - 0x1e36: 0xddb9, 0x1e37: 0xddd9, 0x1e38: 0x8dbd, 0x1e39: 0xddf9, 0x1e3a: 0xde19, 0x1e3b: 0xde39, - 0x1e3c: 0xde59, 0x1e3d: 0xde79, 0x1e3e: 0x8ddd, 0x1e3f: 0xde99, + 0x1e00: 0xcaf9, 0x1e01: 0xcb19, 0x1e02: 0xcb39, 0x1e03: 0x8b1d, 0x1e04: 0xcb59, 0x1e05: 0xcb79, + 0x1e06: 0xcb99, 0x1e07: 0xcbb9, 0x1e08: 0xcbd9, 0x1e09: 0xcbf9, 0x1e0a: 0xcc19, 0x1e0b: 0xcc39, + 0x1e0c: 0xcc59, 0x1e0d: 0x8b3d, 0x1e0e: 0xcc79, 0x1e0f: 0xcc99, 0x1e10: 0xccb9, 0x1e11: 0xccd9, + 0x1e12: 0x8b5d, 0x1e13: 0xccf9, 0x1e14: 0xcd19, 0x1e15: 0xc429, 0x1e16: 0x8b7d, 0x1e17: 0xcd39, + 0x1e18: 0xcd59, 0x1e19: 0xcd79, 0x1e1a: 0xcd99, 0x1e1b: 0xcdb9, 0x1e1c: 0x8b9d, 0x1e1d: 0xcdd9, + 0x1e1e: 0xcdf9, 0x1e1f: 0xce19, 0x1e20: 0xce39, 0x1e21: 0xce59, 0x1e22: 0xc789, 0x1e23: 0xce79, + 0x1e24: 0xce99, 0x1e25: 0xceb9, 0x1e26: 0xced9, 0x1e27: 0xcef9, 0x1e28: 0xcf19, 0x1e29: 0xcf39, + 0x1e2a: 0xcf59, 0x1e2b: 0xcf79, 0x1e2c: 0xcf99, 0x1e2d: 0xcfb9, 0x1e2e: 0xcfd9, 0x1e2f: 0xcff9, + 0x1e30: 0xd019, 0x1e31: 0xd039, 0x1e32: 0xd039, 0x1e33: 0xd039, 0x1e34: 0x8bbd, 0x1e35: 0xd059, + 0x1e36: 0xd079, 0x1e37: 0xd099, 0x1e38: 0x8bdd, 0x1e39: 0xd0b9, 0x1e3a: 0xd0d9, 0x1e3b: 0xd0f9, + 0x1e3c: 0xd119, 0x1e3d: 0xd139, 0x1e3e: 0xd159, 0x1e3f: 0xd179, // Block 0x79, offset 0x1e40 - 0x1e40: 0xe599, 0x1e41: 0xe5b9, 0x1e42: 0xe5d9, 0x1e43: 0xe5f9, 0x1e44: 0xe619, 0x1e45: 0xe639, - 0x1e46: 0x8efd, 0x1e47: 0xe659, 0x1e48: 0xe679, 0x1e49: 0xe699, 0x1e4a: 0xe6b9, 0x1e4b: 0xe6d9, - 0x1e4c: 0xe6f9, 0x1e4d: 0x8f1d, 0x1e4e: 0xe719, 0x1e4f: 0xe739, 0x1e50: 0x8f3d, 0x1e51: 0x8f5d, - 0x1e52: 0xe759, 0x1e53: 0xe779, 0x1e54: 0xe799, 0x1e55: 0xe7b9, 0x1e56: 0xe7d9, 0x1e57: 0xe7f9, - 0x1e58: 0xe819, 0x1e59: 0xe839, 0x1e5a: 0xe859, 0x1e5b: 0x8f7d, 0x1e5c: 0xe879, 0x1e5d: 0x8f9d, - 0x1e5e: 0xe899, 0x1e5f: 0x0040, 0x1e60: 0xe8b9, 0x1e61: 0xe8d9, 0x1e62: 0xe8f9, 0x1e63: 0x8fbd, - 0x1e64: 0xe919, 0x1e65: 0xe939, 0x1e66: 0x8fdd, 0x1e67: 0x8ffd, 0x1e68: 0xe959, 0x1e69: 0xe979, - 0x1e6a: 0xe999, 0x1e6b: 0xe9b9, 0x1e6c: 0xe9d9, 0x1e6d: 0xe9d9, 0x1e6e: 0xe9f9, 0x1e6f: 0xea19, - 0x1e70: 0xea39, 0x1e71: 0xea59, 0x1e72: 0xea79, 0x1e73: 0xea99, 0x1e74: 0xeab9, 0x1e75: 0x901d, - 0x1e76: 0xead9, 0x1e77: 0x903d, 0x1e78: 0xeaf9, 0x1e79: 0x905d, 0x1e7a: 0xeb19, 0x1e7b: 0x907d, - 0x1e7c: 0x909d, 0x1e7d: 0x90bd, 0x1e7e: 0xeb39, 0x1e7f: 0xeb59, + 0x1e40: 0xd199, 0x1e41: 0xd1b9, 0x1e42: 0xd1d9, 0x1e43: 0xd1f9, 0x1e44: 0xd219, 0x1e45: 0xd239, + 0x1e46: 0xd239, 0x1e47: 0xd259, 0x1e48: 0xd279, 0x1e49: 0xd299, 0x1e4a: 0xd2b9, 0x1e4b: 0xd2d9, + 0x1e4c: 0xd2f9, 0x1e4d: 0xd319, 0x1e4e: 0xd339, 0x1e4f: 0xd359, 0x1e50: 0xd379, 0x1e51: 0xd399, + 0x1e52: 0xd3b9, 0x1e53: 0xd3d9, 0x1e54: 0xd3f9, 0x1e55: 0xd419, 0x1e56: 0xd439, 0x1e57: 0xd459, + 0x1e58: 0xd479, 0x1e59: 0x8bfd, 0x1e5a: 0xd499, 0x1e5b: 0xd4b9, 0x1e5c: 0xd4d9, 0x1e5d: 0xc309, + 0x1e5e: 0xd4f9, 0x1e5f: 0xd519, 0x1e60: 0x8c1d, 0x1e61: 0x8c3d, 0x1e62: 0xd539, 0x1e63: 0xd559, + 0x1e64: 0xd579, 0x1e65: 0xd599, 0x1e66: 0xd5b9, 0x1e67: 0xd5d9, 0x1e68: 0x2040, 0x1e69: 0xd5f9, + 0x1e6a: 0xd619, 0x1e6b: 0xd619, 0x1e6c: 0x8c5d, 0x1e6d: 0xd639, 0x1e6e: 0xd659, 0x1e6f: 0xd679, + 0x1e70: 0xd699, 0x1e71: 0x8c7d, 0x1e72: 0xd6b9, 0x1e73: 0xd6d9, 0x1e74: 0x2040, 0x1e75: 0xd6f9, + 0x1e76: 0xd719, 0x1e77: 0xd739, 0x1e78: 0xd759, 0x1e79: 0xd779, 0x1e7a: 0xd799, 0x1e7b: 0x8c9d, + 0x1e7c: 0xd7b9, 0x1e7d: 0x8cbd, 0x1e7e: 0xd7d9, 0x1e7f: 0xd7f9, // Block 0x7a, offset 0x1e80 - 0x1e80: 0xeb79, 0x1e81: 0x90dd, 0x1e82: 0x90fd, 0x1e83: 0x911d, 0x1e84: 0x913d, 0x1e85: 0xeb99, - 0x1e86: 0xebb9, 0x1e87: 0xebb9, 0x1e88: 0xebd9, 0x1e89: 0xebf9, 0x1e8a: 0xec19, 0x1e8b: 0xec39, - 0x1e8c: 0xec59, 0x1e8d: 0x915d, 0x1e8e: 0xec79, 0x1e8f: 0xec99, 0x1e90: 0xecb9, 0x1e91: 0xecd9, - 0x1e92: 0x917d, 0x1e93: 0xecf9, 0x1e94: 0x919d, 0x1e95: 0x91bd, 0x1e96: 0xed19, 0x1e97: 0xed39, - 0x1e98: 0xed59, 0x1e99: 0xed79, 0x1e9a: 0xed99, 0x1e9b: 0xedb9, 0x1e9c: 0x91dd, 0x1e9d: 0x91fd, - 0x1e9e: 0x921d, 0x1e9f: 0x0040, 0x1ea0: 0xedd9, 0x1ea1: 0x923d, 0x1ea2: 0xedf9, 0x1ea3: 0xee19, - 0x1ea4: 0xee39, 0x1ea5: 0x925d, 0x1ea6: 0xee59, 0x1ea7: 0xee79, 0x1ea8: 0xee99, 0x1ea9: 0xeeb9, - 0x1eaa: 0xeed9, 0x1eab: 0x927d, 0x1eac: 0xeef9, 0x1ead: 0xef19, 0x1eae: 0xef39, 0x1eaf: 0xef59, - 0x1eb0: 0xef79, 0x1eb1: 0xef99, 0x1eb2: 0x929d, 0x1eb3: 0x92bd, 0x1eb4: 0xefb9, 0x1eb5: 0x92dd, - 0x1eb6: 0xefd9, 0x1eb7: 0x92fd, 0x1eb8: 0xeff9, 0x1eb9: 0xf019, 0x1eba: 0xf039, 0x1ebb: 0x931d, - 0x1ebc: 0x933d, 0x1ebd: 0xf059, 0x1ebe: 0x935d, 0x1ebf: 0xf079, + 0x1e80: 0xd819, 0x1e81: 0xd839, 0x1e82: 0xd859, 0x1e83: 0xd879, 0x1e84: 0xd899, 0x1e85: 0xd8b9, + 0x1e86: 0xd8d9, 0x1e87: 0xd8f9, 0x1e88: 0xd919, 0x1e89: 0x8cdd, 0x1e8a: 0xd939, 0x1e8b: 0xd959, + 0x1e8c: 0xd979, 0x1e8d: 0xd999, 0x1e8e: 0xd9b9, 0x1e8f: 0x8cfd, 0x1e90: 0xd9d9, 0x1e91: 0x8d1d, + 0x1e92: 0x8d3d, 0x1e93: 0xd9f9, 0x1e94: 0xda19, 0x1e95: 0xda19, 0x1e96: 0xda39, 0x1e97: 0x8d5d, + 0x1e98: 0x8d7d, 0x1e99: 0xda59, 0x1e9a: 0xda79, 0x1e9b: 0xda99, 0x1e9c: 0xdab9, 0x1e9d: 0xdad9, + 0x1e9e: 0xdaf9, 0x1e9f: 0xdb19, 0x1ea0: 0xdb39, 0x1ea1: 0xdb59, 0x1ea2: 0xdb79, 0x1ea3: 0xdb99, + 0x1ea4: 0x8d9d, 0x1ea5: 0xdbb9, 0x1ea6: 0xdbd9, 0x1ea7: 0xdbf9, 0x1ea8: 0xdc19, 0x1ea9: 0xdbf9, + 0x1eaa: 0xdc39, 0x1eab: 0xdc59, 0x1eac: 0xdc79, 0x1ead: 0xdc99, 0x1eae: 0xdcb9, 0x1eaf: 0xdcd9, + 0x1eb0: 0xdcf9, 0x1eb1: 0xdd19, 0x1eb2: 0xdd39, 0x1eb3: 0xdd59, 0x1eb4: 0xdd79, 0x1eb5: 0xdd99, + 0x1eb6: 0xddb9, 0x1eb7: 0xddd9, 0x1eb8: 0x8dbd, 0x1eb9: 0xddf9, 0x1eba: 0xde19, 0x1ebb: 0xde39, + 0x1ebc: 0xde59, 0x1ebd: 0xde79, 0x1ebe: 0x8ddd, 0x1ebf: 0xde99, // Block 0x7b, offset 0x1ec0 - 0x1ec0: 0xf6b9, 0x1ec1: 0xf6d9, 0x1ec2: 0xf6f9, 0x1ec3: 0xf719, 0x1ec4: 0xf739, 0x1ec5: 0x951d, - 0x1ec6: 0xf759, 0x1ec7: 0xf779, 0x1ec8: 0xf799, 0x1ec9: 0xf7b9, 0x1eca: 0xf7d9, 0x1ecb: 0x953d, - 0x1ecc: 0x955d, 0x1ecd: 0xf7f9, 0x1ece: 0xf819, 0x1ecf: 0xf839, 0x1ed0: 0xf859, 0x1ed1: 0xf879, - 0x1ed2: 0xf899, 0x1ed3: 0x957d, 0x1ed4: 0xf8b9, 0x1ed5: 0xf8d9, 0x1ed6: 0xf8f9, 0x1ed7: 0xf919, - 0x1ed8: 0x959d, 0x1ed9: 0x95bd, 0x1eda: 0xf939, 0x1edb: 0xf959, 0x1edc: 0xf979, 0x1edd: 0x95dd, - 0x1ede: 0xf999, 0x1edf: 0xf9b9, 0x1ee0: 0x6815, 0x1ee1: 0x95fd, 0x1ee2: 0xf9d9, 0x1ee3: 0xf9f9, - 0x1ee4: 0xfa19, 0x1ee5: 0x961d, 0x1ee6: 0xfa39, 0x1ee7: 0xfa59, 0x1ee8: 0xfa79, 0x1ee9: 0xfa99, - 0x1eea: 0xfab9, 0x1eeb: 0xfad9, 0x1eec: 0xfaf9, 0x1eed: 0x963d, 0x1eee: 0xfb19, 0x1eef: 0xfb39, - 0x1ef0: 0xfb59, 0x1ef1: 0x965d, 0x1ef2: 0xfb79, 0x1ef3: 0xfb99, 0x1ef4: 0xfbb9, 0x1ef5: 0xfbd9, - 0x1ef6: 0x7b35, 0x1ef7: 0x967d, 0x1ef8: 0xfbf9, 0x1ef9: 0xfc19, 0x1efa: 0xfc39, 0x1efb: 0x969d, - 0x1efc: 0xfc59, 0x1efd: 0x96bd, 0x1efe: 0xfc79, 0x1eff: 0xfc79, + 0x1ec0: 0xe599, 0x1ec1: 0xe5b9, 0x1ec2: 0xe5d9, 0x1ec3: 0xe5f9, 0x1ec4: 0xe619, 0x1ec5: 0xe639, + 0x1ec6: 0x8efd, 0x1ec7: 0xe659, 0x1ec8: 0xe679, 0x1ec9: 0xe699, 0x1eca: 0xe6b9, 0x1ecb: 0xe6d9, + 0x1ecc: 0xe6f9, 0x1ecd: 0x8f1d, 0x1ece: 0xe719, 0x1ecf: 0xe739, 0x1ed0: 0x8f3d, 0x1ed1: 0x8f5d, + 0x1ed2: 0xe759, 0x1ed3: 0xe779, 0x1ed4: 0xe799, 0x1ed5: 0xe7b9, 0x1ed6: 0xe7d9, 0x1ed7: 0xe7f9, + 0x1ed8: 0xe819, 0x1ed9: 0xe839, 0x1eda: 0xe859, 0x1edb: 0x8f7d, 0x1edc: 0xe879, 0x1edd: 0x8f9d, + 0x1ede: 0xe899, 0x1edf: 0x2040, 0x1ee0: 0xe8b9, 0x1ee1: 0xe8d9, 0x1ee2: 0xe8f9, 0x1ee3: 0x8fbd, + 0x1ee4: 0xe919, 0x1ee5: 0xe939, 0x1ee6: 0x8fdd, 0x1ee7: 0x8ffd, 0x1ee8: 0xe959, 0x1ee9: 0xe979, + 0x1eea: 0xe999, 0x1eeb: 0xe9b9, 0x1eec: 0xe9d9, 0x1eed: 0xe9d9, 0x1eee: 0xe9f9, 0x1eef: 0xea19, + 0x1ef0: 0xea39, 0x1ef1: 0xea59, 0x1ef2: 0xea79, 0x1ef3: 0xea99, 0x1ef4: 0xeab9, 0x1ef5: 0x901d, + 0x1ef6: 0xead9, 0x1ef7: 0x903d, 0x1ef8: 0xeaf9, 0x1ef9: 0x905d, 0x1efa: 0xeb19, 0x1efb: 0x907d, + 0x1efc: 0x909d, 0x1efd: 0x90bd, 0x1efe: 0xeb39, 0x1eff: 0xeb59, // Block 0x7c, offset 0x1f00 - 0x1f00: 0xfc99, 0x1f01: 0x96dd, 0x1f02: 0xfcb9, 0x1f03: 0xfcd9, 0x1f04: 0xfcf9, 0x1f05: 0xfd19, - 0x1f06: 0xfd39, 0x1f07: 0xfd59, 0x1f08: 0xfd79, 0x1f09: 0x96fd, 0x1f0a: 0xfd99, 0x1f0b: 0xfdb9, - 0x1f0c: 0xfdd9, 0x1f0d: 0xfdf9, 0x1f0e: 0xfe19, 0x1f0f: 0xfe39, 0x1f10: 0x971d, 0x1f11: 0xfe59, - 0x1f12: 0x973d, 0x1f13: 0x975d, 0x1f14: 0x977d, 0x1f15: 0xfe79, 0x1f16: 0xfe99, 0x1f17: 0xfeb9, - 0x1f18: 0xfed9, 0x1f19: 0xfef9, 0x1f1a: 0xff19, 0x1f1b: 0xff39, 0x1f1c: 0xff59, 0x1f1d: 0x979d, - 0x1f1e: 0x0040, 0x1f1f: 0x0040, 0x1f20: 0x0040, 0x1f21: 0x0040, 0x1f22: 0x0040, 0x1f23: 0x0040, - 0x1f24: 0x0040, 0x1f25: 0x0040, 0x1f26: 0x0040, 0x1f27: 0x0040, 0x1f28: 0x0040, 0x1f29: 0x0040, - 0x1f2a: 0x0040, 0x1f2b: 0x0040, 0x1f2c: 0x0040, 0x1f2d: 0x0040, 0x1f2e: 0x0040, 0x1f2f: 0x0040, - 0x1f30: 0x0040, 0x1f31: 0x0040, 0x1f32: 0x0040, 0x1f33: 0x0040, 0x1f34: 0x0040, 0x1f35: 0x0040, - 0x1f36: 0x0040, 0x1f37: 0x0040, 0x1f38: 0x0040, 0x1f39: 0x0040, 0x1f3a: 0x0040, 0x1f3b: 0x0040, - 0x1f3c: 0x0040, 0x1f3d: 0x0040, 0x1f3e: 0x0040, 0x1f3f: 0x0040, + 0x1f00: 0xeb79, 0x1f01: 0x90dd, 0x1f02: 0x90fd, 0x1f03: 0x911d, 0x1f04: 0x913d, 0x1f05: 0xeb99, + 0x1f06: 0xebb9, 0x1f07: 0xebb9, 0x1f08: 0xebd9, 0x1f09: 0xebf9, 0x1f0a: 0xec19, 0x1f0b: 0xec39, + 0x1f0c: 0xec59, 0x1f0d: 0x915d, 0x1f0e: 0xec79, 0x1f0f: 0xec99, 0x1f10: 0xecb9, 0x1f11: 0xecd9, + 0x1f12: 0x917d, 0x1f13: 0xecf9, 0x1f14: 0x919d, 0x1f15: 0x91bd, 0x1f16: 0xed19, 0x1f17: 0xed39, + 0x1f18: 0xed59, 0x1f19: 0xed79, 0x1f1a: 0xed99, 0x1f1b: 0xedb9, 0x1f1c: 0x91dd, 0x1f1d: 0x91fd, + 0x1f1e: 0x921d, 0x1f1f: 0x2040, 0x1f20: 0xedd9, 0x1f21: 0x923d, 0x1f22: 0xedf9, 0x1f23: 0xee19, + 0x1f24: 0xee39, 0x1f25: 0x925d, 0x1f26: 0xee59, 0x1f27: 0xee79, 0x1f28: 0xee99, 0x1f29: 0xeeb9, + 0x1f2a: 0xeed9, 0x1f2b: 0x927d, 0x1f2c: 0xeef9, 0x1f2d: 0xef19, 0x1f2e: 0xef39, 0x1f2f: 0xef59, + 0x1f30: 0xef79, 0x1f31: 0xef99, 0x1f32: 0x929d, 0x1f33: 0x92bd, 0x1f34: 0xefb9, 0x1f35: 0x92dd, + 0x1f36: 0xefd9, 0x1f37: 0x92fd, 0x1f38: 0xeff9, 0x1f39: 0xf019, 0x1f3a: 0xf039, 0x1f3b: 0x931d, + 0x1f3c: 0x933d, 0x1f3d: 0xf059, 0x1f3e: 0x935d, 0x1f3f: 0xf079, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0xf6b9, 0x1f41: 0xf6d9, 0x1f42: 0xf6f9, 0x1f43: 0xf719, 0x1f44: 0xf739, 0x1f45: 0x951d, + 0x1f46: 0xf759, 0x1f47: 0xf779, 0x1f48: 0xf799, 0x1f49: 0xf7b9, 0x1f4a: 0xf7d9, 0x1f4b: 0x953d, + 0x1f4c: 0x955d, 0x1f4d: 0xf7f9, 0x1f4e: 0xf819, 0x1f4f: 0xf839, 0x1f50: 0xf859, 0x1f51: 0xf879, + 0x1f52: 0xf899, 0x1f53: 0x957d, 0x1f54: 0xf8b9, 0x1f55: 0xf8d9, 0x1f56: 0xf8f9, 0x1f57: 0xf919, + 0x1f58: 0x959d, 0x1f59: 0x95bd, 0x1f5a: 0xf939, 0x1f5b: 0xf959, 0x1f5c: 0xf979, 0x1f5d: 0x95dd, + 0x1f5e: 0xf999, 0x1f5f: 0xf9b9, 0x1f60: 0x6815, 0x1f61: 0x95fd, 0x1f62: 0xf9d9, 0x1f63: 0xf9f9, + 0x1f64: 0xfa19, 0x1f65: 0x961d, 0x1f66: 0xfa39, 0x1f67: 0xfa59, 0x1f68: 0xfa79, 0x1f69: 0xfa99, + 0x1f6a: 0xfab9, 0x1f6b: 0xfad9, 0x1f6c: 0xfaf9, 0x1f6d: 0x963d, 0x1f6e: 0xfb19, 0x1f6f: 0xfb39, + 0x1f70: 0xfb59, 0x1f71: 0x965d, 0x1f72: 0xfb79, 0x1f73: 0xfb99, 0x1f74: 0xfbb9, 0x1f75: 0xfbd9, + 0x1f76: 0x7b35, 0x1f77: 0x967d, 0x1f78: 0xfbf9, 0x1f79: 0xfc19, 0x1f7a: 0xfc39, 0x1f7b: 0x969d, + 0x1f7c: 0xfc59, 0x1f7d: 0x96bd, 0x1f7e: 0xfc79, 0x1f7f: 0xfc79, + // Block 0x7e, offset 0x1f80 + 0x1f80: 0xfc99, 0x1f81: 0x96dd, 0x1f82: 0xfcb9, 0x1f83: 0xfcd9, 0x1f84: 0xfcf9, 0x1f85: 0xfd19, + 0x1f86: 0xfd39, 0x1f87: 0xfd59, 0x1f88: 0xfd79, 0x1f89: 0x96fd, 0x1f8a: 0xfd99, 0x1f8b: 0xfdb9, + 0x1f8c: 0xfdd9, 0x1f8d: 0xfdf9, 0x1f8e: 0xfe19, 0x1f8f: 0xfe39, 0x1f90: 0x971d, 0x1f91: 0xfe59, + 0x1f92: 0x973d, 0x1f93: 0x975d, 0x1f94: 0x977d, 0x1f95: 0xfe79, 0x1f96: 0xfe99, 0x1f97: 0xfeb9, + 0x1f98: 0xfed9, 0x1f99: 0xfef9, 0x1f9a: 0xff19, 0x1f9b: 0xff39, 0x1f9c: 0xff59, 0x1f9d: 0x979d, + 0x1f9e: 0x0040, 0x1f9f: 0x0040, 0x1fa0: 0x0040, 0x1fa1: 0x0040, 0x1fa2: 0x0040, 0x1fa3: 0x0040, + 0x1fa4: 0x0040, 0x1fa5: 0x0040, 0x1fa6: 0x0040, 0x1fa7: 0x0040, 0x1fa8: 0x0040, 0x1fa9: 0x0040, + 0x1faa: 0x0040, 0x1fab: 0x0040, 0x1fac: 0x0040, 0x1fad: 0x0040, 0x1fae: 0x0040, 0x1faf: 0x0040, + 0x1fb0: 0x0040, 0x1fb1: 0x0040, 0x1fb2: 0x0040, 0x1fb3: 0x0040, 0x1fb4: 0x0040, 0x1fb5: 0x0040, + 0x1fb6: 0x0040, 0x1fb7: 0x0040, 0x1fb8: 0x0040, 0x1fb9: 0x0040, 0x1fba: 0x0040, 0x1fbb: 0x0040, + 0x1fbc: 0x0040, 0x1fbd: 0x0040, 0x1fbe: 0x0040, 0x1fbf: 0x0040, } -// idnaIndex: 35 blocks, 2240 entries, 4480 bytes +// idnaIndex: 36 blocks, 2304 entries, 4608 bytes // Block 0 is the zero block. -var idnaIndex = [2240]uint16{ +var idnaIndex = [2304]uint16{ // Block 0x0, offset 0x0 // Block 0x1, offset 0x40 // Block 0x2, offset 0x80 // Block 0x3, offset 0xc0 - 0xc2: 0x01, 0xc3: 0x7b, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05, - 0xc8: 0x06, 0xc9: 0x7c, 0xca: 0x7d, 0xcb: 0x07, 0xcc: 0x7e, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a, - 0xd0: 0x7f, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x80, 0xd6: 0x81, 0xd7: 0x82, - 0xd8: 0x0f, 0xd9: 0x83, 0xda: 0x84, 0xdb: 0x10, 0xdc: 0x11, 0xdd: 0x85, 0xde: 0x86, 0xdf: 0x87, + 0xc2: 0x01, 0xc3: 0x7d, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05, + 0xc8: 0x06, 0xc9: 0x7e, 0xca: 0x7f, 0xcb: 0x07, 0xcc: 0x80, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a, + 0xd0: 0x81, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x82, 0xd6: 0x83, 0xd7: 0x84, + 0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x85, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x86, 0xde: 0x87, 0xdf: 0x88, 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07, 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c, - 0xf0: 0x1c, 0xf1: 0x1d, 0xf2: 0x1d, 0xf3: 0x1f, 0xf4: 0x20, + 0xf0: 0x1d, 0xf1: 0x1e, 0xf2: 0x1e, 0xf3: 0x20, 0xf4: 0x21, // Block 0x4, offset 0x100 - 0x120: 0x88, 0x121: 0x89, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x12, 0x126: 0x13, 0x127: 0x14, - 0x128: 0x15, 0x129: 0x16, 0x12a: 0x17, 0x12b: 0x18, 0x12c: 0x19, 0x12d: 0x1a, 0x12e: 0x1b, 0x12f: 0x8d, - 0x130: 0x8e, 0x131: 0x1c, 0x132: 0x1d, 0x133: 0x1e, 0x134: 0x8f, 0x135: 0x1f, 0x136: 0x90, 0x137: 0x91, - 0x138: 0x92, 0x139: 0x93, 0x13a: 0x20, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x21, 0x13e: 0x22, 0x13f: 0x96, + 0x120: 0x89, 0x121: 0x13, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16, + 0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8d, + 0x130: 0x8e, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x8f, 0x135: 0x21, 0x136: 0x90, 0x137: 0x91, + 0x138: 0x92, 0x139: 0x93, 0x13a: 0x22, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x96, // Block 0x5, offset 0x140 - 0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9b, 0x147: 0x9b, - 0x148: 0x9d, 0x149: 0x9e, 0x14a: 0x9f, 0x14b: 0xa0, 0x14c: 0xa1, 0x14d: 0xa2, 0x14e: 0xa3, 0x14f: 0xa4, - 0x150: 0xa5, 0x151: 0x9d, 0x152: 0x9d, 0x153: 0x9d, 0x154: 0x9d, 0x155: 0x9d, 0x156: 0x9d, 0x157: 0x9d, - 0x158: 0x9d, 0x159: 0xa6, 0x15a: 0xa7, 0x15b: 0xa8, 0x15c: 0xa9, 0x15d: 0xaa, 0x15e: 0xab, 0x15f: 0xac, - 0x160: 0xad, 0x161: 0xae, 0x162: 0xaf, 0x163: 0xb0, 0x164: 0xb1, 0x165: 0xb2, 0x166: 0xb3, 0x167: 0xb4, - 0x168: 0xb5, 0x169: 0xb6, 0x16a: 0xb7, 0x16b: 0xb8, 0x16c: 0xb9, 0x16d: 0xba, 0x16e: 0xbb, 0x16f: 0xbc, - 0x170: 0xbd, 0x171: 0xbe, 0x172: 0xbf, 0x173: 0xc0, 0x174: 0x23, 0x175: 0x24, 0x176: 0x25, 0x177: 0xc1, - 0x178: 0x26, 0x179: 0x26, 0x17a: 0x27, 0x17b: 0x26, 0x17c: 0xc2, 0x17d: 0x28, 0x17e: 0x29, 0x17f: 0x2a, + 0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e, + 0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6, + 0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f, + 0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae, + 0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6, + 0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe, + 0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc3, + 0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc4, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c, // Block 0x6, offset 0x180 - 0x180: 0x2b, 0x181: 0x2c, 0x182: 0x2d, 0x183: 0xc3, 0x184: 0x2e, 0x185: 0x2f, 0x186: 0xc4, 0x187: 0x9b, - 0x188: 0xc5, 0x189: 0xc6, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc7, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0xc8, - 0x190: 0xc9, 0x191: 0x30, 0x192: 0x31, 0x193: 0x32, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b, + 0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc5, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc6, 0x187: 0x9b, + 0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0x9b, + 0x190: 0xca, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b, 0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b, 0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b, - 0x1a8: 0xca, 0x1a9: 0xcb, 0x1aa: 0x9b, 0x1ab: 0xcc, 0x1ac: 0x9b, 0x1ad: 0xcd, 0x1ae: 0xce, 0x1af: 0xcf, - 0x1b0: 0xd0, 0x1b1: 0x33, 0x1b2: 0x26, 0x1b3: 0x34, 0x1b4: 0xd1, 0x1b5: 0xd2, 0x1b6: 0xd3, 0x1b7: 0xd4, - 0x1b8: 0xd5, 0x1b9: 0xd6, 0x1ba: 0xd7, 0x1bb: 0xd8, 0x1bc: 0xd9, 0x1bd: 0xda, 0x1be: 0xdb, 0x1bf: 0x35, + 0x1a8: 0xcb, 0x1a9: 0xcc, 0x1aa: 0x9b, 0x1ab: 0xcd, 0x1ac: 0x9b, 0x1ad: 0xce, 0x1ae: 0xcf, 0x1af: 0xd0, + 0x1b0: 0xd1, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd2, 0x1b5: 0xd3, 0x1b6: 0xd4, 0x1b7: 0xd5, + 0x1b8: 0xd6, 0x1b9: 0xd7, 0x1ba: 0xd8, 0x1bb: 0xd9, 0x1bc: 0xda, 0x1bd: 0xdb, 0x1be: 0xdc, 0x1bf: 0x37, // Block 0x7, offset 0x1c0 - 0x1c0: 0x36, 0x1c1: 0xdc, 0x1c2: 0xdd, 0x1c3: 0xde, 0x1c4: 0xdf, 0x1c5: 0x37, 0x1c6: 0x38, 0x1c7: 0xe0, - 0x1c8: 0xe1, 0x1c9: 0x39, 0x1ca: 0x3a, 0x1cb: 0x3b, 0x1cc: 0x3c, 0x1cd: 0x3d, 0x1ce: 0x3e, 0x1cf: 0x3f, - 0x1d0: 0x9d, 0x1d1: 0x9d, 0x1d2: 0x9d, 0x1d3: 0x9d, 0x1d4: 0x9d, 0x1d5: 0x9d, 0x1d6: 0x9d, 0x1d7: 0x9d, - 0x1d8: 0x9d, 0x1d9: 0x9d, 0x1da: 0x9d, 0x1db: 0x9d, 0x1dc: 0x9d, 0x1dd: 0x9d, 0x1de: 0x9d, 0x1df: 0x9d, - 0x1e0: 0x9d, 0x1e1: 0x9d, 0x1e2: 0x9d, 0x1e3: 0x9d, 0x1e4: 0x9d, 0x1e5: 0x9d, 0x1e6: 0x9d, 0x1e7: 0x9d, - 0x1e8: 0x9d, 0x1e9: 0x9d, 0x1ea: 0x9d, 0x1eb: 0x9d, 0x1ec: 0x9d, 0x1ed: 0x9d, 0x1ee: 0x9d, 0x1ef: 0x9d, - 0x1f0: 0x9d, 0x1f1: 0x9d, 0x1f2: 0x9d, 0x1f3: 0x9d, 0x1f4: 0x9d, 0x1f5: 0x9d, 0x1f6: 0x9d, 0x1f7: 0x9d, - 0x1f8: 0x9d, 0x1f9: 0x9d, 0x1fa: 0x9d, 0x1fb: 0x9d, 0x1fc: 0x9d, 0x1fd: 0x9d, 0x1fe: 0x9d, 0x1ff: 0x9d, + 0x1c0: 0x38, 0x1c1: 0xdd, 0x1c2: 0xde, 0x1c3: 0xdf, 0x1c4: 0xe0, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe1, + 0x1c8: 0xe2, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41, + 0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f, + 0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f, + 0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f, + 0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f, + 0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f, + 0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f, // Block 0x8, offset 0x200 - 0x200: 0x9d, 0x201: 0x9d, 0x202: 0x9d, 0x203: 0x9d, 0x204: 0x9d, 0x205: 0x9d, 0x206: 0x9d, 0x207: 0x9d, - 0x208: 0x9d, 0x209: 0x9d, 0x20a: 0x9d, 0x20b: 0x9d, 0x20c: 0x9d, 0x20d: 0x9d, 0x20e: 0x9d, 0x20f: 0x9d, - 0x210: 0x9d, 0x211: 0x9d, 0x212: 0x9d, 0x213: 0x9d, 0x214: 0x9d, 0x215: 0x9d, 0x216: 0x9d, 0x217: 0x9d, - 0x218: 0x9d, 0x219: 0x9d, 0x21a: 0x9d, 0x21b: 0x9d, 0x21c: 0x9d, 0x21d: 0x9d, 0x21e: 0x9d, 0x21f: 0x9d, - 0x220: 0x9d, 0x221: 0x9d, 0x222: 0x9d, 0x223: 0x9d, 0x224: 0x9d, 0x225: 0x9d, 0x226: 0x9d, 0x227: 0x9d, - 0x228: 0x9d, 0x229: 0x9d, 0x22a: 0x9d, 0x22b: 0x9d, 0x22c: 0x9d, 0x22d: 0x9d, 0x22e: 0x9d, 0x22f: 0x9d, - 0x230: 0x9d, 0x231: 0x9d, 0x232: 0x9d, 0x233: 0x9d, 0x234: 0x9d, 0x235: 0x9d, 0x236: 0xb0, 0x237: 0x9b, - 0x238: 0x9d, 0x239: 0x9d, 0x23a: 0x9d, 0x23b: 0x9d, 0x23c: 0x9d, 0x23d: 0x9d, 0x23e: 0x9d, 0x23f: 0x9d, + 0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f, + 0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f, + 0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f, + 0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f, + 0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f, + 0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f, + 0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b, + 0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f, // Block 0x9, offset 0x240 - 0x240: 0x9d, 0x241: 0x9d, 0x242: 0x9d, 0x243: 0x9d, 0x244: 0x9d, 0x245: 0x9d, 0x246: 0x9d, 0x247: 0x9d, - 0x248: 0x9d, 0x249: 0x9d, 0x24a: 0x9d, 0x24b: 0x9d, 0x24c: 0x9d, 0x24d: 0x9d, 0x24e: 0x9d, 0x24f: 0x9d, - 0x250: 0x9d, 0x251: 0x9d, 0x252: 0x9d, 0x253: 0x9d, 0x254: 0x9d, 0x255: 0x9d, 0x256: 0x9d, 0x257: 0x9d, - 0x258: 0x9d, 0x259: 0x9d, 0x25a: 0x9d, 0x25b: 0x9d, 0x25c: 0x9d, 0x25d: 0x9d, 0x25e: 0x9d, 0x25f: 0x9d, - 0x260: 0x9d, 0x261: 0x9d, 0x262: 0x9d, 0x263: 0x9d, 0x264: 0x9d, 0x265: 0x9d, 0x266: 0x9d, 0x267: 0x9d, - 0x268: 0x9d, 0x269: 0x9d, 0x26a: 0x9d, 0x26b: 0x9d, 0x26c: 0x9d, 0x26d: 0x9d, 0x26e: 0x9d, 0x26f: 0x9d, - 0x270: 0x9d, 0x271: 0x9d, 0x272: 0x9d, 0x273: 0x9d, 0x274: 0x9d, 0x275: 0x9d, 0x276: 0x9d, 0x277: 0x9d, - 0x278: 0x9d, 0x279: 0x9d, 0x27a: 0x9d, 0x27b: 0x9d, 0x27c: 0x9d, 0x27d: 0x9d, 0x27e: 0x9d, 0x27f: 0x9d, + 0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f, + 0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f, + 0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f, + 0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f, + 0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f, + 0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f, + 0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f, + 0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f, // Block 0xa, offset 0x280 - 0x280: 0x9d, 0x281: 0x9d, 0x282: 0x9d, 0x283: 0x9d, 0x284: 0x9d, 0x285: 0x9d, 0x286: 0x9d, 0x287: 0x9d, - 0x288: 0x9d, 0x289: 0x9d, 0x28a: 0x9d, 0x28b: 0x9d, 0x28c: 0x9d, 0x28d: 0x9d, 0x28e: 0x9d, 0x28f: 0x9d, - 0x290: 0x9d, 0x291: 0x9d, 0x292: 0x9d, 0x293: 0x9d, 0x294: 0x9d, 0x295: 0x9d, 0x296: 0x9d, 0x297: 0x9d, - 0x298: 0x9d, 0x299: 0x9d, 0x29a: 0x9d, 0x29b: 0x9d, 0x29c: 0x9d, 0x29d: 0x9d, 0x29e: 0x9d, 0x29f: 0x9d, - 0x2a0: 0x9d, 0x2a1: 0x9d, 0x2a2: 0x9d, 0x2a3: 0x9d, 0x2a4: 0x9d, 0x2a5: 0x9d, 0x2a6: 0x9d, 0x2a7: 0x9d, - 0x2a8: 0x9d, 0x2a9: 0x9d, 0x2aa: 0x9d, 0x2ab: 0x9d, 0x2ac: 0x9d, 0x2ad: 0x9d, 0x2ae: 0x9d, 0x2af: 0x9d, - 0x2b0: 0x9d, 0x2b1: 0x9d, 0x2b2: 0x9d, 0x2b3: 0x9d, 0x2b4: 0x9d, 0x2b5: 0x9d, 0x2b6: 0x9d, 0x2b7: 0x9d, - 0x2b8: 0x9d, 0x2b9: 0x9d, 0x2ba: 0x9d, 0x2bb: 0x9d, 0x2bc: 0x9d, 0x2bd: 0x9d, 0x2be: 0x9d, 0x2bf: 0xe2, + 0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f, + 0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f, + 0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f, + 0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f, + 0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f, + 0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f, + 0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f, + 0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe3, // Block 0xb, offset 0x2c0 - 0x2c0: 0x9d, 0x2c1: 0x9d, 0x2c2: 0x9d, 0x2c3: 0x9d, 0x2c4: 0x9d, 0x2c5: 0x9d, 0x2c6: 0x9d, 0x2c7: 0x9d, - 0x2c8: 0x9d, 0x2c9: 0x9d, 0x2ca: 0x9d, 0x2cb: 0x9d, 0x2cc: 0x9d, 0x2cd: 0x9d, 0x2ce: 0x9d, 0x2cf: 0x9d, - 0x2d0: 0x9d, 0x2d1: 0x9d, 0x2d2: 0xe3, 0x2d3: 0xe4, 0x2d4: 0x9d, 0x2d5: 0x9d, 0x2d6: 0x9d, 0x2d7: 0x9d, - 0x2d8: 0xe5, 0x2d9: 0x40, 0x2da: 0x41, 0x2db: 0xe6, 0x2dc: 0x42, 0x2dd: 0x43, 0x2de: 0x44, 0x2df: 0xe7, - 0x2e0: 0xe8, 0x2e1: 0xe9, 0x2e2: 0xea, 0x2e3: 0xeb, 0x2e4: 0xec, 0x2e5: 0xed, 0x2e6: 0xee, 0x2e7: 0xef, - 0x2e8: 0xf0, 0x2e9: 0xf1, 0x2ea: 0xf2, 0x2eb: 0xf3, 0x2ec: 0xf4, 0x2ed: 0xf5, 0x2ee: 0xf6, 0x2ef: 0xf7, - 0x2f0: 0x9d, 0x2f1: 0x9d, 0x2f2: 0x9d, 0x2f3: 0x9d, 0x2f4: 0x9d, 0x2f5: 0x9d, 0x2f6: 0x9d, 0x2f7: 0x9d, - 0x2f8: 0x9d, 0x2f9: 0x9d, 0x2fa: 0x9d, 0x2fb: 0x9d, 0x2fc: 0x9d, 0x2fd: 0x9d, 0x2fe: 0x9d, 0x2ff: 0x9d, + 0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f, + 0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f, + 0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe4, 0x2d3: 0xe5, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f, + 0x2d8: 0xe6, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe7, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe8, + 0x2e0: 0xe9, 0x2e1: 0xea, 0x2e2: 0xeb, 0x2e3: 0xec, 0x2e4: 0xed, 0x2e5: 0xee, 0x2e6: 0xef, 0x2e7: 0xf0, + 0x2e8: 0xf1, 0x2e9: 0xf2, 0x2ea: 0xf3, 0x2eb: 0xf4, 0x2ec: 0xf5, 0x2ed: 0xf6, 0x2ee: 0xf7, 0x2ef: 0xf8, + 0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f, + 0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f, // Block 0xc, offset 0x300 - 0x300: 0x9d, 0x301: 0x9d, 0x302: 0x9d, 0x303: 0x9d, 0x304: 0x9d, 0x305: 0x9d, 0x306: 0x9d, 0x307: 0x9d, - 0x308: 0x9d, 0x309: 0x9d, 0x30a: 0x9d, 0x30b: 0x9d, 0x30c: 0x9d, 0x30d: 0x9d, 0x30e: 0x9d, 0x30f: 0x9d, - 0x310: 0x9d, 0x311: 0x9d, 0x312: 0x9d, 0x313: 0x9d, 0x314: 0x9d, 0x315: 0x9d, 0x316: 0x9d, 0x317: 0x9d, - 0x318: 0x9d, 0x319: 0x9d, 0x31a: 0x9d, 0x31b: 0x9d, 0x31c: 0x9d, 0x31d: 0x9d, 0x31e: 0xf8, 0x31f: 0xf9, + 0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f, + 0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f, + 0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f, + 0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xf9, 0x31f: 0xfa, // Block 0xd, offset 0x340 - 0x340: 0xb8, 0x341: 0xb8, 0x342: 0xb8, 0x343: 0xb8, 0x344: 0xb8, 0x345: 0xb8, 0x346: 0xb8, 0x347: 0xb8, - 0x348: 0xb8, 0x349: 0xb8, 0x34a: 0xb8, 0x34b: 0xb8, 0x34c: 0xb8, 0x34d: 0xb8, 0x34e: 0xb8, 0x34f: 0xb8, - 0x350: 0xb8, 0x351: 0xb8, 0x352: 0xb8, 0x353: 0xb8, 0x354: 0xb8, 0x355: 0xb8, 0x356: 0xb8, 0x357: 0xb8, - 0x358: 0xb8, 0x359: 0xb8, 0x35a: 0xb8, 0x35b: 0xb8, 0x35c: 0xb8, 0x35d: 0xb8, 0x35e: 0xb8, 0x35f: 0xb8, - 0x360: 0xb8, 0x361: 0xb8, 0x362: 0xb8, 0x363: 0xb8, 0x364: 0xb8, 0x365: 0xb8, 0x366: 0xb8, 0x367: 0xb8, - 0x368: 0xb8, 0x369: 0xb8, 0x36a: 0xb8, 0x36b: 0xb8, 0x36c: 0xb8, 0x36d: 0xb8, 0x36e: 0xb8, 0x36f: 0xb8, - 0x370: 0xb8, 0x371: 0xb8, 0x372: 0xb8, 0x373: 0xb8, 0x374: 0xb8, 0x375: 0xb8, 0x376: 0xb8, 0x377: 0xb8, - 0x378: 0xb8, 0x379: 0xb8, 0x37a: 0xb8, 0x37b: 0xb8, 0x37c: 0xb8, 0x37d: 0xb8, 0x37e: 0xb8, 0x37f: 0xb8, + 0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba, + 0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba, + 0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba, + 0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba, + 0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba, + 0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba, + 0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba, + 0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba, // Block 0xe, offset 0x380 - 0x380: 0xb8, 0x381: 0xb8, 0x382: 0xb8, 0x383: 0xb8, 0x384: 0xb8, 0x385: 0xb8, 0x386: 0xb8, 0x387: 0xb8, - 0x388: 0xb8, 0x389: 0xb8, 0x38a: 0xb8, 0x38b: 0xb8, 0x38c: 0xb8, 0x38d: 0xb8, 0x38e: 0xb8, 0x38f: 0xb8, - 0x390: 0xb8, 0x391: 0xb8, 0x392: 0xb8, 0x393: 0xb8, 0x394: 0xb8, 0x395: 0xb8, 0x396: 0xb8, 0x397: 0xb8, - 0x398: 0xb8, 0x399: 0xb8, 0x39a: 0xb8, 0x39b: 0xb8, 0x39c: 0xb8, 0x39d: 0xb8, 0x39e: 0xb8, 0x39f: 0xb8, - 0x3a0: 0xb8, 0x3a1: 0xb8, 0x3a2: 0xb8, 0x3a3: 0xb8, 0x3a4: 0xfa, 0x3a5: 0xfb, 0x3a6: 0xfc, 0x3a7: 0xfd, - 0x3a8: 0x45, 0x3a9: 0xfe, 0x3aa: 0xff, 0x3ab: 0x46, 0x3ac: 0x47, 0x3ad: 0x48, 0x3ae: 0x49, 0x3af: 0x4a, - 0x3b0: 0x100, 0x3b1: 0x4b, 0x3b2: 0x4c, 0x3b3: 0x4d, 0x3b4: 0x4e, 0x3b5: 0x4f, 0x3b6: 0x101, 0x3b7: 0x50, - 0x3b8: 0x51, 0x3b9: 0x52, 0x3ba: 0x53, 0x3bb: 0x54, 0x3bc: 0x55, 0x3bd: 0x56, 0x3be: 0x57, 0x3bf: 0x58, + 0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba, + 0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba, + 0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba, + 0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba, + 0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfb, 0x3a5: 0xfc, 0x3a6: 0xfd, 0x3a7: 0xfe, + 0x3a8: 0x47, 0x3a9: 0xff, 0x3aa: 0x100, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c, + 0x3b0: 0x101, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x102, 0x3b7: 0x52, + 0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a, // Block 0xf, offset 0x3c0 - 0x3c0: 0x102, 0x3c1: 0x103, 0x3c2: 0x9d, 0x3c3: 0x104, 0x3c4: 0x105, 0x3c5: 0x9b, 0x3c6: 0x106, 0x3c7: 0x107, - 0x3c8: 0xb8, 0x3c9: 0xb8, 0x3ca: 0x108, 0x3cb: 0x109, 0x3cc: 0x10a, 0x3cd: 0x10b, 0x3ce: 0x10c, 0x3cf: 0x10d, - 0x3d0: 0x10e, 0x3d1: 0x9d, 0x3d2: 0x10f, 0x3d3: 0x110, 0x3d4: 0x111, 0x3d5: 0x112, 0x3d6: 0xb8, 0x3d7: 0xb8, - 0x3d8: 0x9d, 0x3d9: 0x9d, 0x3da: 0x9d, 0x3db: 0x9d, 0x3dc: 0x113, 0x3dd: 0x114, 0x3de: 0xb8, 0x3df: 0xb8, - 0x3e0: 0x115, 0x3e1: 0x116, 0x3e2: 0x117, 0x3e3: 0x118, 0x3e4: 0x119, 0x3e5: 0xb8, 0x3e6: 0x11a, 0x3e7: 0x11b, - 0x3e8: 0x11c, 0x3e9: 0x11d, 0x3ea: 0x11e, 0x3eb: 0x59, 0x3ec: 0x11f, 0x3ed: 0x120, 0x3ee: 0x5a, 0x3ef: 0xb8, - 0x3f0: 0x9d, 0x3f1: 0x121, 0x3f2: 0x122, 0x3f3: 0x123, 0x3f4: 0xb8, 0x3f5: 0xb8, 0x3f6: 0xb8, 0x3f7: 0xb8, - 0x3f8: 0xb8, 0x3f9: 0x124, 0x3fa: 0xb8, 0x3fb: 0xb8, 0x3fc: 0xb8, 0x3fd: 0xb8, 0x3fe: 0xb8, 0x3ff: 0xb8, + 0x3c0: 0x103, 0x3c1: 0x104, 0x3c2: 0x9f, 0x3c3: 0x105, 0x3c4: 0x106, 0x3c5: 0x9b, 0x3c6: 0x107, 0x3c7: 0x108, + 0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x109, 0x3cb: 0x10a, 0x3cc: 0x10b, 0x3cd: 0x10c, 0x3ce: 0x10d, 0x3cf: 0x10e, + 0x3d0: 0x10f, 0x3d1: 0x9f, 0x3d2: 0x110, 0x3d3: 0x111, 0x3d4: 0x112, 0x3d5: 0x113, 0x3d6: 0xba, 0x3d7: 0xba, + 0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x114, 0x3dd: 0x115, 0x3de: 0xba, 0x3df: 0xba, + 0x3e0: 0x116, 0x3e1: 0x117, 0x3e2: 0x118, 0x3e3: 0x119, 0x3e4: 0x11a, 0x3e5: 0xba, 0x3e6: 0x11b, 0x3e7: 0x11c, + 0x3e8: 0x11d, 0x3e9: 0x11e, 0x3ea: 0x11f, 0x3eb: 0x5b, 0x3ec: 0x120, 0x3ed: 0x121, 0x3ee: 0x5c, 0x3ef: 0xba, + 0x3f0: 0x122, 0x3f1: 0x123, 0x3f2: 0x124, 0x3f3: 0x125, 0x3f4: 0xba, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba, + 0x3f8: 0xba, 0x3f9: 0x126, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0xba, 0x3fd: 0xba, 0x3fe: 0xba, 0x3ff: 0xba, // Block 0x10, offset 0x400 - 0x400: 0x125, 0x401: 0x126, 0x402: 0x127, 0x403: 0x128, 0x404: 0x129, 0x405: 0x12a, 0x406: 0x12b, 0x407: 0x12c, - 0x408: 0x12d, 0x409: 0xb8, 0x40a: 0x12e, 0x40b: 0x12f, 0x40c: 0x5b, 0x40d: 0x5c, 0x40e: 0xb8, 0x40f: 0xb8, - 0x410: 0x130, 0x411: 0x131, 0x412: 0x132, 0x413: 0x133, 0x414: 0xb8, 0x415: 0xb8, 0x416: 0x134, 0x417: 0x135, - 0x418: 0x136, 0x419: 0x137, 0x41a: 0x138, 0x41b: 0x139, 0x41c: 0x13a, 0x41d: 0xb8, 0x41e: 0xb8, 0x41f: 0xb8, - 0x420: 0xb8, 0x421: 0xb8, 0x422: 0x13b, 0x423: 0x13c, 0x424: 0xb8, 0x425: 0xb8, 0x426: 0xb8, 0x427: 0xb8, - 0x428: 0xb8, 0x429: 0xb8, 0x42a: 0xb8, 0x42b: 0x13d, 0x42c: 0xb8, 0x42d: 0xb8, 0x42e: 0xb8, 0x42f: 0xb8, - 0x430: 0x13e, 0x431: 0x13f, 0x432: 0x140, 0x433: 0xb8, 0x434: 0xb8, 0x435: 0xb8, 0x436: 0xb8, 0x437: 0xb8, - 0x438: 0xb8, 0x439: 0xb8, 0x43a: 0xb8, 0x43b: 0xb8, 0x43c: 0xb8, 0x43d: 0xb8, 0x43e: 0xb8, 0x43f: 0xb8, + 0x400: 0x127, 0x401: 0x128, 0x402: 0x129, 0x403: 0x12a, 0x404: 0x12b, 0x405: 0x12c, 0x406: 0x12d, 0x407: 0x12e, + 0x408: 0x12f, 0x409: 0xba, 0x40a: 0x130, 0x40b: 0x131, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xba, 0x40f: 0xba, + 0x410: 0x132, 0x411: 0x133, 0x412: 0x134, 0x413: 0x135, 0x414: 0xba, 0x415: 0xba, 0x416: 0x136, 0x417: 0x137, + 0x418: 0x138, 0x419: 0x139, 0x41a: 0x13a, 0x41b: 0x13b, 0x41c: 0x13c, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba, + 0x420: 0xba, 0x421: 0xba, 0x422: 0x13d, 0x423: 0x13e, 0x424: 0xba, 0x425: 0xba, 0x426: 0xba, 0x427: 0xba, + 0x428: 0x13f, 0x429: 0x140, 0x42a: 0x141, 0x42b: 0x142, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba, + 0x430: 0x143, 0x431: 0x144, 0x432: 0x145, 0x433: 0xba, 0x434: 0x146, 0x435: 0x147, 0x436: 0xba, 0x437: 0xba, + 0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0xba, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0xba, // Block 0x11, offset 0x440 - 0x440: 0x9d, 0x441: 0x9d, 0x442: 0x9d, 0x443: 0x9d, 0x444: 0x9d, 0x445: 0x9d, 0x446: 0x9d, 0x447: 0x9d, - 0x448: 0x9d, 0x449: 0x9d, 0x44a: 0x9d, 0x44b: 0x9d, 0x44c: 0x9d, 0x44d: 0x9d, 0x44e: 0x141, 0x44f: 0xb8, - 0x450: 0x9b, 0x451: 0x142, 0x452: 0x9d, 0x453: 0x9d, 0x454: 0x9d, 0x455: 0x143, 0x456: 0xb8, 0x457: 0xb8, - 0x458: 0xb8, 0x459: 0xb8, 0x45a: 0xb8, 0x45b: 0xb8, 0x45c: 0xb8, 0x45d: 0xb8, 0x45e: 0xb8, 0x45f: 0xb8, - 0x460: 0xb8, 0x461: 0xb8, 0x462: 0xb8, 0x463: 0xb8, 0x464: 0xb8, 0x465: 0xb8, 0x466: 0xb8, 0x467: 0xb8, - 0x468: 0xb8, 0x469: 0xb8, 0x46a: 0xb8, 0x46b: 0xb8, 0x46c: 0xb8, 0x46d: 0xb8, 0x46e: 0xb8, 0x46f: 0xb8, - 0x470: 0xb8, 0x471: 0xb8, 0x472: 0xb8, 0x473: 0xb8, 0x474: 0xb8, 0x475: 0xb8, 0x476: 0xb8, 0x477: 0xb8, - 0x478: 0xb8, 0x479: 0xb8, 0x47a: 0xb8, 0x47b: 0xb8, 0x47c: 0xb8, 0x47d: 0xb8, 0x47e: 0xb8, 0x47f: 0xb8, + 0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f, + 0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x148, 0x44f: 0xba, + 0x450: 0x9b, 0x451: 0x149, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x14a, 0x456: 0xba, 0x457: 0xba, + 0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba, + 0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba, + 0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba, + 0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba, + 0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba, // Block 0x12, offset 0x480 - 0x480: 0x9d, 0x481: 0x9d, 0x482: 0x9d, 0x483: 0x9d, 0x484: 0x9d, 0x485: 0x9d, 0x486: 0x9d, 0x487: 0x9d, - 0x488: 0x9d, 0x489: 0x9d, 0x48a: 0x9d, 0x48b: 0x9d, 0x48c: 0x9d, 0x48d: 0x9d, 0x48e: 0x9d, 0x48f: 0x9d, - 0x490: 0x144, 0x491: 0xb8, 0x492: 0xb8, 0x493: 0xb8, 0x494: 0xb8, 0x495: 0xb8, 0x496: 0xb8, 0x497: 0xb8, - 0x498: 0xb8, 0x499: 0xb8, 0x49a: 0xb8, 0x49b: 0xb8, 0x49c: 0xb8, 0x49d: 0xb8, 0x49e: 0xb8, 0x49f: 0xb8, - 0x4a0: 0xb8, 0x4a1: 0xb8, 0x4a2: 0xb8, 0x4a3: 0xb8, 0x4a4: 0xb8, 0x4a5: 0xb8, 0x4a6: 0xb8, 0x4a7: 0xb8, - 0x4a8: 0xb8, 0x4a9: 0xb8, 0x4aa: 0xb8, 0x4ab: 0xb8, 0x4ac: 0xb8, 0x4ad: 0xb8, 0x4ae: 0xb8, 0x4af: 0xb8, - 0x4b0: 0xb8, 0x4b1: 0xb8, 0x4b2: 0xb8, 0x4b3: 0xb8, 0x4b4: 0xb8, 0x4b5: 0xb8, 0x4b6: 0xb8, 0x4b7: 0xb8, - 0x4b8: 0xb8, 0x4b9: 0xb8, 0x4ba: 0xb8, 0x4bb: 0xb8, 0x4bc: 0xb8, 0x4bd: 0xb8, 0x4be: 0xb8, 0x4bf: 0xb8, + 0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f, + 0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f, + 0x490: 0x14b, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba, + 0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba, + 0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba, + 0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba, + 0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba, + 0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba, // Block 0x13, offset 0x4c0 - 0x4c0: 0xb8, 0x4c1: 0xb8, 0x4c2: 0xb8, 0x4c3: 0xb8, 0x4c4: 0xb8, 0x4c5: 0xb8, 0x4c6: 0xb8, 0x4c7: 0xb8, - 0x4c8: 0xb8, 0x4c9: 0xb8, 0x4ca: 0xb8, 0x4cb: 0xb8, 0x4cc: 0xb8, 0x4cd: 0xb8, 0x4ce: 0xb8, 0x4cf: 0xb8, - 0x4d0: 0x9d, 0x4d1: 0x9d, 0x4d2: 0x9d, 0x4d3: 0x9d, 0x4d4: 0x9d, 0x4d5: 0x9d, 0x4d6: 0x9d, 0x4d7: 0x9d, - 0x4d8: 0x9d, 0x4d9: 0x145, 0x4da: 0xb8, 0x4db: 0xb8, 0x4dc: 0xb8, 0x4dd: 0xb8, 0x4de: 0xb8, 0x4df: 0xb8, - 0x4e0: 0xb8, 0x4e1: 0xb8, 0x4e2: 0xb8, 0x4e3: 0xb8, 0x4e4: 0xb8, 0x4e5: 0xb8, 0x4e6: 0xb8, 0x4e7: 0xb8, - 0x4e8: 0xb8, 0x4e9: 0xb8, 0x4ea: 0xb8, 0x4eb: 0xb8, 0x4ec: 0xb8, 0x4ed: 0xb8, 0x4ee: 0xb8, 0x4ef: 0xb8, - 0x4f0: 0xb8, 0x4f1: 0xb8, 0x4f2: 0xb8, 0x4f3: 0xb8, 0x4f4: 0xb8, 0x4f5: 0xb8, 0x4f6: 0xb8, 0x4f7: 0xb8, - 0x4f8: 0xb8, 0x4f9: 0xb8, 0x4fa: 0xb8, 0x4fb: 0xb8, 0x4fc: 0xb8, 0x4fd: 0xb8, 0x4fe: 0xb8, 0x4ff: 0xb8, + 0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba, + 0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba, + 0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f, + 0x4d8: 0x9f, 0x4d9: 0x14c, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba, + 0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba, + 0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba, + 0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba, + 0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba, // Block 0x14, offset 0x500 - 0x500: 0xb8, 0x501: 0xb8, 0x502: 0xb8, 0x503: 0xb8, 0x504: 0xb8, 0x505: 0xb8, 0x506: 0xb8, 0x507: 0xb8, - 0x508: 0xb8, 0x509: 0xb8, 0x50a: 0xb8, 0x50b: 0xb8, 0x50c: 0xb8, 0x50d: 0xb8, 0x50e: 0xb8, 0x50f: 0xb8, - 0x510: 0xb8, 0x511: 0xb8, 0x512: 0xb8, 0x513: 0xb8, 0x514: 0xb8, 0x515: 0xb8, 0x516: 0xb8, 0x517: 0xb8, - 0x518: 0xb8, 0x519: 0xb8, 0x51a: 0xb8, 0x51b: 0xb8, 0x51c: 0xb8, 0x51d: 0xb8, 0x51e: 0xb8, 0x51f: 0xb8, - 0x520: 0x9d, 0x521: 0x9d, 0x522: 0x9d, 0x523: 0x9d, 0x524: 0x9d, 0x525: 0x9d, 0x526: 0x9d, 0x527: 0x9d, - 0x528: 0x13d, 0x529: 0x146, 0x52a: 0xb8, 0x52b: 0x147, 0x52c: 0x148, 0x52d: 0x149, 0x52e: 0x14a, 0x52f: 0xb8, - 0x530: 0xb8, 0x531: 0xb8, 0x532: 0xb8, 0x533: 0xb8, 0x534: 0xb8, 0x535: 0xb8, 0x536: 0xb8, 0x537: 0xb8, - 0x538: 0xb8, 0x539: 0xb8, 0x53a: 0xb8, 0x53b: 0xb8, 0x53c: 0x9d, 0x53d: 0x14b, 0x53e: 0x14c, 0x53f: 0x14d, + 0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba, + 0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba, + 0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba, + 0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba, + 0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f, + 0x528: 0x142, 0x529: 0x14d, 0x52a: 0xba, 0x52b: 0x14e, 0x52c: 0x14f, 0x52d: 0x150, 0x52e: 0x151, 0x52f: 0xba, + 0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba, + 0x538: 0xba, 0x539: 0xba, 0x53a: 0xba, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x152, 0x53e: 0x153, 0x53f: 0x154, // Block 0x15, offset 0x540 - 0x540: 0x9d, 0x541: 0x9d, 0x542: 0x9d, 0x543: 0x9d, 0x544: 0x9d, 0x545: 0x9d, 0x546: 0x9d, 0x547: 0x9d, - 0x548: 0x9d, 0x549: 0x9d, 0x54a: 0x9d, 0x54b: 0x9d, 0x54c: 0x9d, 0x54d: 0x9d, 0x54e: 0x9d, 0x54f: 0x9d, - 0x550: 0x9d, 0x551: 0x9d, 0x552: 0x9d, 0x553: 0x9d, 0x554: 0x9d, 0x555: 0x9d, 0x556: 0x9d, 0x557: 0x9d, - 0x558: 0x9d, 0x559: 0x9d, 0x55a: 0x9d, 0x55b: 0x9d, 0x55c: 0x9d, 0x55d: 0x9d, 0x55e: 0x9d, 0x55f: 0x14e, - 0x560: 0x9d, 0x561: 0x9d, 0x562: 0x9d, 0x563: 0x9d, 0x564: 0x9d, 0x565: 0x9d, 0x566: 0x9d, 0x567: 0x9d, - 0x568: 0x9d, 0x569: 0x9d, 0x56a: 0x9d, 0x56b: 0x14f, 0x56c: 0xb8, 0x56d: 0xb8, 0x56e: 0xb8, 0x56f: 0xb8, - 0x570: 0xb8, 0x571: 0xb8, 0x572: 0xb8, 0x573: 0xb8, 0x574: 0xb8, 0x575: 0xb8, 0x576: 0xb8, 0x577: 0xb8, - 0x578: 0xb8, 0x579: 0xb8, 0x57a: 0xb8, 0x57b: 0xb8, 0x57c: 0xb8, 0x57d: 0xb8, 0x57e: 0xb8, 0x57f: 0xb8, + 0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f, + 0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f, + 0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f, + 0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x155, + 0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f, + 0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x156, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba, + 0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba, + 0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba, // Block 0x16, offset 0x580 - 0x580: 0x150, 0x581: 0xb8, 0x582: 0xb8, 0x583: 0xb8, 0x584: 0xb8, 0x585: 0xb8, 0x586: 0xb8, 0x587: 0xb8, - 0x588: 0xb8, 0x589: 0xb8, 0x58a: 0xb8, 0x58b: 0xb8, 0x58c: 0xb8, 0x58d: 0xb8, 0x58e: 0xb8, 0x58f: 0xb8, - 0x590: 0xb8, 0x591: 0xb8, 0x592: 0xb8, 0x593: 0xb8, 0x594: 0xb8, 0x595: 0xb8, 0x596: 0xb8, 0x597: 0xb8, - 0x598: 0xb8, 0x599: 0xb8, 0x59a: 0xb8, 0x59b: 0xb8, 0x59c: 0xb8, 0x59d: 0xb8, 0x59e: 0xb8, 0x59f: 0xb8, - 0x5a0: 0xb8, 0x5a1: 0xb8, 0x5a2: 0xb8, 0x5a3: 0xb8, 0x5a4: 0xb8, 0x5a5: 0xb8, 0x5a6: 0xb8, 0x5a7: 0xb8, - 0x5a8: 0xb8, 0x5a9: 0xb8, 0x5aa: 0xb8, 0x5ab: 0xb8, 0x5ac: 0xb8, 0x5ad: 0xb8, 0x5ae: 0xb8, 0x5af: 0xb8, - 0x5b0: 0x9d, 0x5b1: 0x151, 0x5b2: 0x152, 0x5b3: 0xb8, 0x5b4: 0xb8, 0x5b5: 0xb8, 0x5b6: 0xb8, 0x5b7: 0xb8, - 0x5b8: 0xb8, 0x5b9: 0xb8, 0x5ba: 0xb8, 0x5bb: 0xb8, 0x5bc: 0xb8, 0x5bd: 0xb8, 0x5be: 0xb8, 0x5bf: 0xb8, + 0x580: 0x9f, 0x581: 0x9f, 0x582: 0x9f, 0x583: 0x9f, 0x584: 0x157, 0x585: 0x158, 0x586: 0x9f, 0x587: 0x9f, + 0x588: 0x9f, 0x589: 0x9f, 0x58a: 0x9f, 0x58b: 0x159, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba, + 0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba, + 0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba, + 0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba, + 0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba, + 0x5b0: 0x9f, 0x5b1: 0x15a, 0x5b2: 0x15b, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba, + 0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba, // Block 0x17, offset 0x5c0 - 0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x153, 0x5c4: 0x154, 0x5c5: 0x155, 0x5c6: 0x156, 0x5c7: 0x157, - 0x5c8: 0x9b, 0x5c9: 0x158, 0x5ca: 0xb8, 0x5cb: 0xb8, 0x5cc: 0x9b, 0x5cd: 0x159, 0x5ce: 0xb8, 0x5cf: 0xb8, - 0x5d0: 0x5d, 0x5d1: 0x5e, 0x5d2: 0x5f, 0x5d3: 0x60, 0x5d4: 0x61, 0x5d5: 0x62, 0x5d6: 0x63, 0x5d7: 0x64, - 0x5d8: 0x65, 0x5d9: 0x66, 0x5da: 0x67, 0x5db: 0x68, 0x5dc: 0x69, 0x5dd: 0x6a, 0x5de: 0x6b, 0x5df: 0x6c, + 0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x15c, 0x5c4: 0x15d, 0x5c5: 0x15e, 0x5c6: 0x15f, 0x5c7: 0x160, + 0x5c8: 0x9b, 0x5c9: 0x161, 0x5ca: 0xba, 0x5cb: 0xba, 0x5cc: 0x9b, 0x5cd: 0x162, 0x5ce: 0xba, 0x5cf: 0xba, + 0x5d0: 0x5f, 0x5d1: 0x60, 0x5d2: 0x61, 0x5d3: 0x62, 0x5d4: 0x63, 0x5d5: 0x64, 0x5d6: 0x65, 0x5d7: 0x66, + 0x5d8: 0x67, 0x5d9: 0x68, 0x5da: 0x69, 0x5db: 0x6a, 0x5dc: 0x6b, 0x5dd: 0x6c, 0x5de: 0x6d, 0x5df: 0x6e, 0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b, - 0x5e8: 0x15a, 0x5e9: 0x15b, 0x5ea: 0x15c, 0x5eb: 0xb8, 0x5ec: 0xb8, 0x5ed: 0xb8, 0x5ee: 0xb8, 0x5ef: 0xb8, - 0x5f0: 0xb8, 0x5f1: 0xb8, 0x5f2: 0xb8, 0x5f3: 0xb8, 0x5f4: 0xb8, 0x5f5: 0xb8, 0x5f6: 0xb8, 0x5f7: 0xb8, - 0x5f8: 0xb8, 0x5f9: 0xb8, 0x5fa: 0xb8, 0x5fb: 0xb8, 0x5fc: 0xb8, 0x5fd: 0xb8, 0x5fe: 0xb8, 0x5ff: 0xb8, + 0x5e8: 0x163, 0x5e9: 0x164, 0x5ea: 0x165, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba, + 0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba, + 0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba, // Block 0x18, offset 0x600 - 0x600: 0x15d, 0x601: 0xb8, 0x602: 0xb8, 0x603: 0xb8, 0x604: 0xb8, 0x605: 0xb8, 0x606: 0xb8, 0x607: 0xb8, - 0x608: 0xb8, 0x609: 0xb8, 0x60a: 0xb8, 0x60b: 0xb8, 0x60c: 0xb8, 0x60d: 0xb8, 0x60e: 0xb8, 0x60f: 0xb8, - 0x610: 0xb8, 0x611: 0xb8, 0x612: 0xb8, 0x613: 0xb8, 0x614: 0xb8, 0x615: 0xb8, 0x616: 0xb8, 0x617: 0xb8, - 0x618: 0xb8, 0x619: 0xb8, 0x61a: 0xb8, 0x61b: 0xb8, 0x61c: 0xb8, 0x61d: 0xb8, 0x61e: 0xb8, 0x61f: 0xb8, - 0x620: 0x9d, 0x621: 0x9d, 0x622: 0x9d, 0x623: 0x15e, 0x624: 0x6d, 0x625: 0x15f, 0x626: 0xb8, 0x627: 0xb8, - 0x628: 0xb8, 0x629: 0xb8, 0x62a: 0xb8, 0x62b: 0xb8, 0x62c: 0xb8, 0x62d: 0xb8, 0x62e: 0xb8, 0x62f: 0xb8, - 0x630: 0xb8, 0x631: 0xb8, 0x632: 0xb8, 0x633: 0xb8, 0x634: 0xb8, 0x635: 0xb8, 0x636: 0xb8, 0x637: 0xb8, - 0x638: 0x6e, 0x639: 0x6f, 0x63a: 0x70, 0x63b: 0x160, 0x63c: 0xb8, 0x63d: 0xb8, 0x63e: 0xb8, 0x63f: 0xb8, + 0x600: 0x166, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0xba, 0x605: 0xba, 0x606: 0xba, 0x607: 0xba, + 0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0xba, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba, + 0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba, + 0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba, + 0x620: 0x122, 0x621: 0x122, 0x622: 0x122, 0x623: 0x167, 0x624: 0x6f, 0x625: 0x168, 0x626: 0xba, 0x627: 0xba, + 0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba, + 0x630: 0xba, 0x631: 0xba, 0x632: 0xba, 0x633: 0xba, 0x634: 0xba, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba, + 0x638: 0x70, 0x639: 0x71, 0x63a: 0x72, 0x63b: 0x169, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba, // Block 0x19, offset 0x640 - 0x640: 0x161, 0x641: 0x9b, 0x642: 0x162, 0x643: 0x163, 0x644: 0x71, 0x645: 0x72, 0x646: 0x164, 0x647: 0x165, - 0x648: 0x73, 0x649: 0x166, 0x64a: 0xb8, 0x64b: 0xb8, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b, + 0x640: 0x16a, 0x641: 0x9b, 0x642: 0x16b, 0x643: 0x16c, 0x644: 0x73, 0x645: 0x74, 0x646: 0x16d, 0x647: 0x16e, + 0x648: 0x75, 0x649: 0x16f, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b, 0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b, - 0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x167, 0x65c: 0x9b, 0x65d: 0x168, 0x65e: 0x9b, 0x65f: 0x169, - 0x660: 0x16a, 0x661: 0x16b, 0x662: 0x16c, 0x663: 0xb8, 0x664: 0x16d, 0x665: 0x16e, 0x666: 0x16f, 0x667: 0x170, - 0x668: 0xb8, 0x669: 0xb8, 0x66a: 0xb8, 0x66b: 0xb8, 0x66c: 0xb8, 0x66d: 0xb8, 0x66e: 0xb8, 0x66f: 0xb8, - 0x670: 0xb8, 0x671: 0xb8, 0x672: 0xb8, 0x673: 0xb8, 0x674: 0xb8, 0x675: 0xb8, 0x676: 0xb8, 0x677: 0xb8, - 0x678: 0xb8, 0x679: 0xb8, 0x67a: 0xb8, 0x67b: 0xb8, 0x67c: 0xb8, 0x67d: 0xb8, 0x67e: 0xb8, 0x67f: 0xb8, + 0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x170, 0x65c: 0x9b, 0x65d: 0x171, 0x65e: 0x9b, 0x65f: 0x172, + 0x660: 0x173, 0x661: 0x174, 0x662: 0x175, 0x663: 0xba, 0x664: 0x176, 0x665: 0x177, 0x666: 0x178, 0x667: 0x179, + 0x668: 0xba, 0x669: 0xba, 0x66a: 0xba, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba, + 0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba, + 0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba, // Block 0x1a, offset 0x680 - 0x680: 0x9d, 0x681: 0x9d, 0x682: 0x9d, 0x683: 0x9d, 0x684: 0x9d, 0x685: 0x9d, 0x686: 0x9d, 0x687: 0x9d, - 0x688: 0x9d, 0x689: 0x9d, 0x68a: 0x9d, 0x68b: 0x9d, 0x68c: 0x9d, 0x68d: 0x9d, 0x68e: 0x9d, 0x68f: 0x9d, - 0x690: 0x9d, 0x691: 0x9d, 0x692: 0x9d, 0x693: 0x9d, 0x694: 0x9d, 0x695: 0x9d, 0x696: 0x9d, 0x697: 0x9d, - 0x698: 0x9d, 0x699: 0x9d, 0x69a: 0x9d, 0x69b: 0x171, 0x69c: 0x9d, 0x69d: 0x9d, 0x69e: 0x9d, 0x69f: 0x9d, - 0x6a0: 0x9d, 0x6a1: 0x9d, 0x6a2: 0x9d, 0x6a3: 0x9d, 0x6a4: 0x9d, 0x6a5: 0x9d, 0x6a6: 0x9d, 0x6a7: 0x9d, - 0x6a8: 0x9d, 0x6a9: 0x9d, 0x6aa: 0x9d, 0x6ab: 0x9d, 0x6ac: 0x9d, 0x6ad: 0x9d, 0x6ae: 0x9d, 0x6af: 0x9d, - 0x6b0: 0x9d, 0x6b1: 0x9d, 0x6b2: 0x9d, 0x6b3: 0x9d, 0x6b4: 0x9d, 0x6b5: 0x9d, 0x6b6: 0x9d, 0x6b7: 0x9d, - 0x6b8: 0x9d, 0x6b9: 0x9d, 0x6ba: 0x9d, 0x6bb: 0x9d, 0x6bc: 0x9d, 0x6bd: 0x9d, 0x6be: 0x9d, 0x6bf: 0x9d, + 0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f, + 0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f, + 0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f, + 0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x17a, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f, + 0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f, + 0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f, + 0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f, + 0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f, // Block 0x1b, offset 0x6c0 - 0x6c0: 0x9d, 0x6c1: 0x9d, 0x6c2: 0x9d, 0x6c3: 0x9d, 0x6c4: 0x9d, 0x6c5: 0x9d, 0x6c6: 0x9d, 0x6c7: 0x9d, - 0x6c8: 0x9d, 0x6c9: 0x9d, 0x6ca: 0x9d, 0x6cb: 0x9d, 0x6cc: 0x9d, 0x6cd: 0x9d, 0x6ce: 0x9d, 0x6cf: 0x9d, - 0x6d0: 0x9d, 0x6d1: 0x9d, 0x6d2: 0x9d, 0x6d3: 0x9d, 0x6d4: 0x9d, 0x6d5: 0x9d, 0x6d6: 0x9d, 0x6d7: 0x9d, - 0x6d8: 0x9d, 0x6d9: 0x9d, 0x6da: 0x9d, 0x6db: 0x9d, 0x6dc: 0x172, 0x6dd: 0x9d, 0x6de: 0x9d, 0x6df: 0x9d, - 0x6e0: 0x173, 0x6e1: 0x9d, 0x6e2: 0x9d, 0x6e3: 0x9d, 0x6e4: 0x9d, 0x6e5: 0x9d, 0x6e6: 0x9d, 0x6e7: 0x9d, - 0x6e8: 0x9d, 0x6e9: 0x9d, 0x6ea: 0x9d, 0x6eb: 0x9d, 0x6ec: 0x9d, 0x6ed: 0x9d, 0x6ee: 0x9d, 0x6ef: 0x9d, - 0x6f0: 0x9d, 0x6f1: 0x9d, 0x6f2: 0x9d, 0x6f3: 0x9d, 0x6f4: 0x9d, 0x6f5: 0x9d, 0x6f6: 0x9d, 0x6f7: 0x9d, - 0x6f8: 0x9d, 0x6f9: 0x9d, 0x6fa: 0x9d, 0x6fb: 0x9d, 0x6fc: 0x9d, 0x6fd: 0x9d, 0x6fe: 0x9d, 0x6ff: 0x9d, + 0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f, + 0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f, + 0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f, + 0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x17b, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f, + 0x6e0: 0x17c, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f, + 0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f, + 0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f, + 0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f, // Block 0x1c, offset 0x700 - 0x700: 0x9d, 0x701: 0x9d, 0x702: 0x9d, 0x703: 0x9d, 0x704: 0x9d, 0x705: 0x9d, 0x706: 0x9d, 0x707: 0x9d, - 0x708: 0x9d, 0x709: 0x9d, 0x70a: 0x9d, 0x70b: 0x9d, 0x70c: 0x9d, 0x70d: 0x9d, 0x70e: 0x9d, 0x70f: 0x9d, - 0x710: 0x9d, 0x711: 0x9d, 0x712: 0x9d, 0x713: 0x9d, 0x714: 0x9d, 0x715: 0x9d, 0x716: 0x9d, 0x717: 0x9d, - 0x718: 0x9d, 0x719: 0x9d, 0x71a: 0x9d, 0x71b: 0x9d, 0x71c: 0x9d, 0x71d: 0x9d, 0x71e: 0x9d, 0x71f: 0x9d, - 0x720: 0x9d, 0x721: 0x9d, 0x722: 0x9d, 0x723: 0x9d, 0x724: 0x9d, 0x725: 0x9d, 0x726: 0x9d, 0x727: 0x9d, - 0x728: 0x9d, 0x729: 0x9d, 0x72a: 0x9d, 0x72b: 0x9d, 0x72c: 0x9d, 0x72d: 0x9d, 0x72e: 0x9d, 0x72f: 0x9d, - 0x730: 0x9d, 0x731: 0x9d, 0x732: 0x9d, 0x733: 0x9d, 0x734: 0x9d, 0x735: 0x9d, 0x736: 0x9d, 0x737: 0x9d, - 0x738: 0x9d, 0x739: 0x9d, 0x73a: 0x174, 0x73b: 0xb8, 0x73c: 0xb8, 0x73d: 0xb8, 0x73e: 0xb8, 0x73f: 0xb8, + 0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f, + 0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f, + 0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f, + 0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f, + 0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f, + 0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f, + 0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f, + 0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x17d, 0x73b: 0x9f, 0x73c: 0x9f, 0x73d: 0x9f, 0x73e: 0x9f, 0x73f: 0x9f, // Block 0x1d, offset 0x740 - 0x740: 0xb8, 0x741: 0xb8, 0x742: 0xb8, 0x743: 0xb8, 0x744: 0xb8, 0x745: 0xb8, 0x746: 0xb8, 0x747: 0xb8, - 0x748: 0xb8, 0x749: 0xb8, 0x74a: 0xb8, 0x74b: 0xb8, 0x74c: 0xb8, 0x74d: 0xb8, 0x74e: 0xb8, 0x74f: 0xb8, - 0x750: 0xb8, 0x751: 0xb8, 0x752: 0xb8, 0x753: 0xb8, 0x754: 0xb8, 0x755: 0xb8, 0x756: 0xb8, 0x757: 0xb8, - 0x758: 0xb8, 0x759: 0xb8, 0x75a: 0xb8, 0x75b: 0xb8, 0x75c: 0xb8, 0x75d: 0xb8, 0x75e: 0xb8, 0x75f: 0xb8, - 0x760: 0x74, 0x761: 0x75, 0x762: 0x76, 0x763: 0x175, 0x764: 0x77, 0x765: 0x78, 0x766: 0x176, 0x767: 0x79, - 0x768: 0x7a, 0x769: 0xb8, 0x76a: 0xb8, 0x76b: 0xb8, 0x76c: 0xb8, 0x76d: 0xb8, 0x76e: 0xb8, 0x76f: 0xb8, - 0x770: 0xb8, 0x771: 0xb8, 0x772: 0xb8, 0x773: 0xb8, 0x774: 0xb8, 0x775: 0xb8, 0x776: 0xb8, 0x777: 0xb8, - 0x778: 0xb8, 0x779: 0xb8, 0x77a: 0xb8, 0x77b: 0xb8, 0x77c: 0xb8, 0x77d: 0xb8, 0x77e: 0xb8, 0x77f: 0xb8, + 0x740: 0x9f, 0x741: 0x9f, 0x742: 0x9f, 0x743: 0x9f, 0x744: 0x9f, 0x745: 0x9f, 0x746: 0x9f, 0x747: 0x9f, + 0x748: 0x9f, 0x749: 0x9f, 0x74a: 0x9f, 0x74b: 0x9f, 0x74c: 0x9f, 0x74d: 0x9f, 0x74e: 0x9f, 0x74f: 0x9f, + 0x750: 0x9f, 0x751: 0x9f, 0x752: 0x9f, 0x753: 0x9f, 0x754: 0x9f, 0x755: 0x9f, 0x756: 0x9f, 0x757: 0x9f, + 0x758: 0x9f, 0x759: 0x9f, 0x75a: 0x9f, 0x75b: 0x9f, 0x75c: 0x9f, 0x75d: 0x9f, 0x75e: 0x9f, 0x75f: 0x9f, + 0x760: 0x9f, 0x761: 0x9f, 0x762: 0x9f, 0x763: 0x9f, 0x764: 0x9f, 0x765: 0x9f, 0x766: 0x9f, 0x767: 0x9f, + 0x768: 0x9f, 0x769: 0x9f, 0x76a: 0x9f, 0x76b: 0x9f, 0x76c: 0x9f, 0x76d: 0x9f, 0x76e: 0x9f, 0x76f: 0x17e, + 0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba, + 0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba, // Block 0x1e, offset 0x780 - 0x790: 0x0d, 0x791: 0x0e, 0x792: 0x0f, 0x793: 0x10, 0x794: 0x11, 0x795: 0x0b, 0x796: 0x12, 0x797: 0x07, - 0x798: 0x13, 0x799: 0x0b, 0x79a: 0x0b, 0x79b: 0x14, 0x79c: 0x0b, 0x79d: 0x15, 0x79e: 0x16, 0x79f: 0x17, - 0x7a0: 0x07, 0x7a1: 0x07, 0x7a2: 0x07, 0x7a3: 0x07, 0x7a4: 0x07, 0x7a5: 0x07, 0x7a6: 0x07, 0x7a7: 0x07, - 0x7a8: 0x07, 0x7a9: 0x07, 0x7aa: 0x18, 0x7ab: 0x19, 0x7ac: 0x1a, 0x7ad: 0x0b, 0x7ae: 0x0b, 0x7af: 0x1b, - 0x7b0: 0x0b, 0x7b1: 0x0b, 0x7b2: 0x0b, 0x7b3: 0x0b, 0x7b4: 0x0b, 0x7b5: 0x0b, 0x7b6: 0x0b, 0x7b7: 0x0b, - 0x7b8: 0x0b, 0x7b9: 0x0b, 0x7ba: 0x0b, 0x7bb: 0x0b, 0x7bc: 0x0b, 0x7bd: 0x0b, 0x7be: 0x0b, 0x7bf: 0x0b, + 0x780: 0xba, 0x781: 0xba, 0x782: 0xba, 0x783: 0xba, 0x784: 0xba, 0x785: 0xba, 0x786: 0xba, 0x787: 0xba, + 0x788: 0xba, 0x789: 0xba, 0x78a: 0xba, 0x78b: 0xba, 0x78c: 0xba, 0x78d: 0xba, 0x78e: 0xba, 0x78f: 0xba, + 0x790: 0xba, 0x791: 0xba, 0x792: 0xba, 0x793: 0xba, 0x794: 0xba, 0x795: 0xba, 0x796: 0xba, 0x797: 0xba, + 0x798: 0xba, 0x799: 0xba, 0x79a: 0xba, 0x79b: 0xba, 0x79c: 0xba, 0x79d: 0xba, 0x79e: 0xba, 0x79f: 0xba, + 0x7a0: 0x76, 0x7a1: 0x77, 0x7a2: 0x78, 0x7a3: 0x17f, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x180, 0x7a7: 0x7b, + 0x7a8: 0x7c, 0x7a9: 0xba, 0x7aa: 0xba, 0x7ab: 0xba, 0x7ac: 0xba, 0x7ad: 0xba, 0x7ae: 0xba, 0x7af: 0xba, + 0x7b0: 0xba, 0x7b1: 0xba, 0x7b2: 0xba, 0x7b3: 0xba, 0x7b4: 0xba, 0x7b5: 0xba, 0x7b6: 0xba, 0x7b7: 0xba, + 0x7b8: 0xba, 0x7b9: 0xba, 0x7ba: 0xba, 0x7bb: 0xba, 0x7bc: 0xba, 0x7bd: 0xba, 0x7be: 0xba, 0x7bf: 0xba, // Block 0x1f, offset 0x7c0 - 0x7c0: 0x0b, 0x7c1: 0x0b, 0x7c2: 0x0b, 0x7c3: 0x0b, 0x7c4: 0x0b, 0x7c5: 0x0b, 0x7c6: 0x0b, 0x7c7: 0x0b, - 0x7c8: 0x0b, 0x7c9: 0x0b, 0x7ca: 0x0b, 0x7cb: 0x0b, 0x7cc: 0x0b, 0x7cd: 0x0b, 0x7ce: 0x0b, 0x7cf: 0x0b, - 0x7d0: 0x0b, 0x7d1: 0x0b, 0x7d2: 0x0b, 0x7d3: 0x0b, 0x7d4: 0x0b, 0x7d5: 0x0b, 0x7d6: 0x0b, 0x7d7: 0x0b, - 0x7d8: 0x0b, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x0b, 0x7dc: 0x0b, 0x7dd: 0x0b, 0x7de: 0x0b, 0x7df: 0x0b, - 0x7e0: 0x0b, 0x7e1: 0x0b, 0x7e2: 0x0b, 0x7e3: 0x0b, 0x7e4: 0x0b, 0x7e5: 0x0b, 0x7e6: 0x0b, 0x7e7: 0x0b, - 0x7e8: 0x0b, 0x7e9: 0x0b, 0x7ea: 0x0b, 0x7eb: 0x0b, 0x7ec: 0x0b, 0x7ed: 0x0b, 0x7ee: 0x0b, 0x7ef: 0x0b, + 0x7d0: 0x0d, 0x7d1: 0x0e, 0x7d2: 0x0f, 0x7d3: 0x10, 0x7d4: 0x11, 0x7d5: 0x0b, 0x7d6: 0x12, 0x7d7: 0x07, + 0x7d8: 0x13, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x14, 0x7dc: 0x0b, 0x7dd: 0x15, 0x7de: 0x16, 0x7df: 0x17, + 0x7e0: 0x07, 0x7e1: 0x07, 0x7e2: 0x07, 0x7e3: 0x07, 0x7e4: 0x07, 0x7e5: 0x07, 0x7e6: 0x07, 0x7e7: 0x07, + 0x7e8: 0x07, 0x7e9: 0x07, 0x7ea: 0x18, 0x7eb: 0x19, 0x7ec: 0x1a, 0x7ed: 0x07, 0x7ee: 0x1b, 0x7ef: 0x1c, 0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b, 0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b, // Block 0x20, offset 0x800 - 0x800: 0x177, 0x801: 0x178, 0x802: 0xb8, 0x803: 0xb8, 0x804: 0x179, 0x805: 0x179, 0x806: 0x179, 0x807: 0x17a, - 0x808: 0xb8, 0x809: 0xb8, 0x80a: 0xb8, 0x80b: 0xb8, 0x80c: 0xb8, 0x80d: 0xb8, 0x80e: 0xb8, 0x80f: 0xb8, - 0x810: 0xb8, 0x811: 0xb8, 0x812: 0xb8, 0x813: 0xb8, 0x814: 0xb8, 0x815: 0xb8, 0x816: 0xb8, 0x817: 0xb8, - 0x818: 0xb8, 0x819: 0xb8, 0x81a: 0xb8, 0x81b: 0xb8, 0x81c: 0xb8, 0x81d: 0xb8, 0x81e: 0xb8, 0x81f: 0xb8, - 0x820: 0xb8, 0x821: 0xb8, 0x822: 0xb8, 0x823: 0xb8, 0x824: 0xb8, 0x825: 0xb8, 0x826: 0xb8, 0x827: 0xb8, - 0x828: 0xb8, 0x829: 0xb8, 0x82a: 0xb8, 0x82b: 0xb8, 0x82c: 0xb8, 0x82d: 0xb8, 0x82e: 0xb8, 0x82f: 0xb8, - 0x830: 0xb8, 0x831: 0xb8, 0x832: 0xb8, 0x833: 0xb8, 0x834: 0xb8, 0x835: 0xb8, 0x836: 0xb8, 0x837: 0xb8, - 0x838: 0xb8, 0x839: 0xb8, 0x83a: 0xb8, 0x83b: 0xb8, 0x83c: 0xb8, 0x83d: 0xb8, 0x83e: 0xb8, 0x83f: 0xb8, + 0x800: 0x0b, 0x801: 0x0b, 0x802: 0x0b, 0x803: 0x0b, 0x804: 0x0b, 0x805: 0x0b, 0x806: 0x0b, 0x807: 0x0b, + 0x808: 0x0b, 0x809: 0x0b, 0x80a: 0x0b, 0x80b: 0x0b, 0x80c: 0x0b, 0x80d: 0x0b, 0x80e: 0x0b, 0x80f: 0x0b, + 0x810: 0x0b, 0x811: 0x0b, 0x812: 0x0b, 0x813: 0x0b, 0x814: 0x0b, 0x815: 0x0b, 0x816: 0x0b, 0x817: 0x0b, + 0x818: 0x0b, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x0b, 0x81c: 0x0b, 0x81d: 0x0b, 0x81e: 0x0b, 0x81f: 0x0b, + 0x820: 0x0b, 0x821: 0x0b, 0x822: 0x0b, 0x823: 0x0b, 0x824: 0x0b, 0x825: 0x0b, 0x826: 0x0b, 0x827: 0x0b, + 0x828: 0x0b, 0x829: 0x0b, 0x82a: 0x0b, 0x82b: 0x0b, 0x82c: 0x0b, 0x82d: 0x0b, 0x82e: 0x0b, 0x82f: 0x0b, + 0x830: 0x0b, 0x831: 0x0b, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b, + 0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b, // Block 0x21, offset 0x840 - 0x840: 0x0b, 0x841: 0x0b, 0x842: 0x0b, 0x843: 0x0b, 0x844: 0x0b, 0x845: 0x0b, 0x846: 0x0b, 0x847: 0x0b, - 0x848: 0x0b, 0x849: 0x0b, 0x84a: 0x0b, 0x84b: 0x0b, 0x84c: 0x0b, 0x84d: 0x0b, 0x84e: 0x0b, 0x84f: 0x0b, - 0x850: 0x0b, 0x851: 0x0b, 0x852: 0x0b, 0x853: 0x0b, 0x854: 0x0b, 0x855: 0x0b, 0x856: 0x0b, 0x857: 0x0b, - 0x858: 0x0b, 0x859: 0x0b, 0x85a: 0x0b, 0x85b: 0x0b, 0x85c: 0x0b, 0x85d: 0x0b, 0x85e: 0x0b, 0x85f: 0x0b, - 0x860: 0x1e, 0x861: 0x0b, 0x862: 0x0b, 0x863: 0x0b, 0x864: 0x0b, 0x865: 0x0b, 0x866: 0x0b, 0x867: 0x0b, - 0x868: 0x0b, 0x869: 0x0b, 0x86a: 0x0b, 0x86b: 0x0b, 0x86c: 0x0b, 0x86d: 0x0b, 0x86e: 0x0b, 0x86f: 0x0b, - 0x870: 0x0b, 0x871: 0x0b, 0x872: 0x0b, 0x873: 0x0b, 0x874: 0x0b, 0x875: 0x0b, 0x876: 0x0b, 0x877: 0x0b, - 0x878: 0x0b, 0x879: 0x0b, 0x87a: 0x0b, 0x87b: 0x0b, 0x87c: 0x0b, 0x87d: 0x0b, 0x87e: 0x0b, 0x87f: 0x0b, + 0x840: 0x181, 0x841: 0x182, 0x842: 0xba, 0x843: 0xba, 0x844: 0x183, 0x845: 0x183, 0x846: 0x183, 0x847: 0x184, + 0x848: 0xba, 0x849: 0xba, 0x84a: 0xba, 0x84b: 0xba, 0x84c: 0xba, 0x84d: 0xba, 0x84e: 0xba, 0x84f: 0xba, + 0x850: 0xba, 0x851: 0xba, 0x852: 0xba, 0x853: 0xba, 0x854: 0xba, 0x855: 0xba, 0x856: 0xba, 0x857: 0xba, + 0x858: 0xba, 0x859: 0xba, 0x85a: 0xba, 0x85b: 0xba, 0x85c: 0xba, 0x85d: 0xba, 0x85e: 0xba, 0x85f: 0xba, + 0x860: 0xba, 0x861: 0xba, 0x862: 0xba, 0x863: 0xba, 0x864: 0xba, 0x865: 0xba, 0x866: 0xba, 0x867: 0xba, + 0x868: 0xba, 0x869: 0xba, 0x86a: 0xba, 0x86b: 0xba, 0x86c: 0xba, 0x86d: 0xba, 0x86e: 0xba, 0x86f: 0xba, + 0x870: 0xba, 0x871: 0xba, 0x872: 0xba, 0x873: 0xba, 0x874: 0xba, 0x875: 0xba, 0x876: 0xba, 0x877: 0xba, + 0x878: 0xba, 0x879: 0xba, 0x87a: 0xba, 0x87b: 0xba, 0x87c: 0xba, 0x87d: 0xba, 0x87e: 0xba, 0x87f: 0xba, // Block 0x22, offset 0x880 0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b, 0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b, + 0x890: 0x0b, 0x891: 0x0b, 0x892: 0x0b, 0x893: 0x0b, 0x894: 0x0b, 0x895: 0x0b, 0x896: 0x0b, 0x897: 0x0b, + 0x898: 0x0b, 0x899: 0x0b, 0x89a: 0x0b, 0x89b: 0x0b, 0x89c: 0x0b, 0x89d: 0x0b, 0x89e: 0x0b, 0x89f: 0x0b, + 0x8a0: 0x1f, 0x8a1: 0x0b, 0x8a2: 0x0b, 0x8a3: 0x0b, 0x8a4: 0x0b, 0x8a5: 0x0b, 0x8a6: 0x0b, 0x8a7: 0x0b, + 0x8a8: 0x0b, 0x8a9: 0x0b, 0x8aa: 0x0b, 0x8ab: 0x0b, 0x8ac: 0x0b, 0x8ad: 0x0b, 0x8ae: 0x0b, 0x8af: 0x0b, + 0x8b0: 0x0b, 0x8b1: 0x0b, 0x8b2: 0x0b, 0x8b3: 0x0b, 0x8b4: 0x0b, 0x8b5: 0x0b, 0x8b6: 0x0b, 0x8b7: 0x0b, + 0x8b8: 0x0b, 0x8b9: 0x0b, 0x8ba: 0x0b, 0x8bb: 0x0b, 0x8bc: 0x0b, 0x8bd: 0x0b, 0x8be: 0x0b, 0x8bf: 0x0b, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b, + 0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b, } -// idnaSparseOffset: 256 entries, 512 bytes -var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x34, 0x3f, 0x4b, 0x5c, 0x60, 0x6f, 0x74, 0x7b, 0x87, 0x95, 0xa3, 0xa8, 0xb1, 0xc1, 0xcf, 0xdc, 0xe8, 0xf9, 0x103, 0x10a, 0x117, 0x128, 0x12f, 0x13a, 0x149, 0x157, 0x161, 0x163, 0x167, 0x169, 0x175, 0x180, 0x188, 0x18e, 0x194, 0x199, 0x19e, 0x1a1, 0x1a5, 0x1ab, 0x1b0, 0x1bc, 0x1c6, 0x1cc, 0x1dd, 0x1e7, 0x1ea, 0x1f2, 0x1f5, 0x202, 0x20a, 0x20e, 0x215, 0x21d, 0x22d, 0x239, 0x23b, 0x245, 0x251, 0x25d, 0x269, 0x271, 0x276, 0x280, 0x291, 0x295, 0x2a0, 0x2a4, 0x2ad, 0x2b5, 0x2bb, 0x2c0, 0x2c3, 0x2c6, 0x2ca, 0x2d0, 0x2d4, 0x2d8, 0x2de, 0x2e5, 0x2eb, 0x2f3, 0x2fa, 0x305, 0x30f, 0x313, 0x316, 0x31c, 0x320, 0x322, 0x325, 0x327, 0x32a, 0x334, 0x337, 0x346, 0x34a, 0x34f, 0x352, 0x356, 0x35b, 0x360, 0x366, 0x36c, 0x37b, 0x381, 0x385, 0x394, 0x399, 0x3a1, 0x3ab, 0x3b6, 0x3be, 0x3cf, 0x3d8, 0x3e8, 0x3f5, 0x3ff, 0x404, 0x411, 0x415, 0x41a, 0x41c, 0x420, 0x422, 0x426, 0x42f, 0x435, 0x439, 0x449, 0x453, 0x458, 0x45b, 0x461, 0x468, 0x46d, 0x471, 0x477, 0x47c, 0x485, 0x48a, 0x490, 0x497, 0x49e, 0x4a5, 0x4a9, 0x4ae, 0x4b1, 0x4b6, 0x4c2, 0x4c8, 0x4cd, 0x4d4, 0x4dc, 0x4e1, 0x4e5, 0x4f5, 0x4fc, 0x500, 0x504, 0x50b, 0x50e, 0x511, 0x515, 0x519, 0x51f, 0x528, 0x534, 0x53b, 0x544, 0x54c, 0x553, 0x561, 0x56e, 0x57b, 0x584, 0x588, 0x596, 0x59e, 0x5a9, 0x5b2, 0x5b8, 0x5c0, 0x5c9, 0x5d3, 0x5d6, 0x5e2, 0x5e5, 0x5ea, 0x5ed, 0x5f7, 0x600, 0x60c, 0x60f, 0x614, 0x617, 0x61a, 0x61d, 0x624, 0x62b, 0x62f, 0x63a, 0x63d, 0x643, 0x648, 0x64c, 0x64f, 0x652, 0x655, 0x65a, 0x664, 0x667, 0x66b, 0x67a, 0x686, 0x68a, 0x68f, 0x694, 0x698, 0x69d, 0x6a6, 0x6b1, 0x6b7, 0x6bf, 0x6c3, 0x6c7, 0x6cd, 0x6d3, 0x6d8, 0x6db, 0x6e9, 0x6f0, 0x6f3, 0x6f6, 0x6fa, 0x700, 0x705, 0x70f, 0x714, 0x717, 0x71a, 0x71d, 0x720, 0x724, 0x727, 0x737, 0x748, 0x74d, 0x74f, 0x751} +// idnaSparseOffset: 264 entries, 528 bytes +var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x34, 0x3f, 0x4b, 0x4f, 0x5e, 0x63, 0x6b, 0x77, 0x85, 0x8a, 0x93, 0xa3, 0xb1, 0xbd, 0xc9, 0xda, 0xe4, 0xeb, 0xf8, 0x109, 0x110, 0x11b, 0x12a, 0x138, 0x142, 0x144, 0x149, 0x14c, 0x14f, 0x151, 0x15d, 0x168, 0x170, 0x176, 0x17c, 0x181, 0x186, 0x189, 0x18d, 0x193, 0x198, 0x1a4, 0x1ae, 0x1b4, 0x1c5, 0x1cf, 0x1d2, 0x1da, 0x1dd, 0x1ea, 0x1f2, 0x1f6, 0x1fd, 0x205, 0x215, 0x221, 0x223, 0x22d, 0x239, 0x245, 0x251, 0x259, 0x25e, 0x268, 0x279, 0x27d, 0x288, 0x28c, 0x295, 0x29d, 0x2a3, 0x2a8, 0x2ab, 0x2af, 0x2b5, 0x2b9, 0x2bd, 0x2c3, 0x2ca, 0x2d0, 0x2d8, 0x2df, 0x2ea, 0x2f4, 0x2f8, 0x2fb, 0x301, 0x305, 0x307, 0x30a, 0x30c, 0x30f, 0x319, 0x31c, 0x32b, 0x32f, 0x334, 0x337, 0x33b, 0x340, 0x345, 0x34b, 0x351, 0x360, 0x366, 0x36a, 0x379, 0x37e, 0x386, 0x390, 0x39b, 0x3a3, 0x3b4, 0x3bd, 0x3cd, 0x3da, 0x3e4, 0x3e9, 0x3f6, 0x3fa, 0x3ff, 0x401, 0x405, 0x407, 0x40b, 0x414, 0x41a, 0x41e, 0x42e, 0x438, 0x43d, 0x440, 0x446, 0x44d, 0x452, 0x456, 0x45c, 0x461, 0x46a, 0x46f, 0x475, 0x47c, 0x483, 0x48a, 0x48e, 0x493, 0x496, 0x49b, 0x4a7, 0x4ad, 0x4b2, 0x4b9, 0x4c1, 0x4c6, 0x4ca, 0x4da, 0x4e1, 0x4e5, 0x4e9, 0x4f0, 0x4f2, 0x4f5, 0x4f8, 0x4fc, 0x500, 0x506, 0x50f, 0x51b, 0x522, 0x52b, 0x533, 0x53a, 0x548, 0x555, 0x562, 0x56b, 0x56f, 0x57d, 0x585, 0x590, 0x599, 0x59f, 0x5a7, 0x5b0, 0x5ba, 0x5bd, 0x5c9, 0x5cc, 0x5d1, 0x5de, 0x5e7, 0x5f3, 0x5f6, 0x600, 0x609, 0x615, 0x622, 0x62a, 0x62d, 0x632, 0x635, 0x638, 0x63b, 0x642, 0x649, 0x64d, 0x658, 0x65b, 0x661, 0x666, 0x66a, 0x66d, 0x670, 0x673, 0x676, 0x679, 0x67e, 0x688, 0x68b, 0x68f, 0x69e, 0x6aa, 0x6ae, 0x6b3, 0x6b8, 0x6bc, 0x6c1, 0x6ca, 0x6d5, 0x6db, 0x6e3, 0x6e7, 0x6eb, 0x6f1, 0x6f7, 0x6fc, 0x6ff, 0x70f, 0x716, 0x719, 0x71c, 0x720, 0x726, 0x72b, 0x730, 0x735, 0x738, 0x73d, 0x740, 0x743, 0x747, 0x74b, 0x74e, 0x75e, 0x76f, 0x774, 0x776, 0x778} -// idnaSparseValues: 1876 entries, 7504 bytes -var idnaSparseValues = [1876]valueRange{ +// idnaSparseValues: 1915 entries, 7660 bytes +var idnaSparseValues = [1915]valueRange{ // Block 0x0, offset 0x0 {value: 0x0000, lo: 0x07}, {value: 0xe105, lo: 0x80, hi: 0x96}, @@ -2382,7 +2415,7 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0008, lo: 0xb9, hi: 0xbf}, // Block 0x3, offset 0x25 {value: 0x0000, lo: 0x01}, - {value: 0x1308, lo: 0x80, hi: 0xbf}, + {value: 0x3308, lo: 0x80, hi: 0xbf}, // Block 0x4, offset 0x27 {value: 0x0000, lo: 0x04}, {value: 0x03f5, lo: 0x80, hi: 0x8f}, @@ -2407,155 +2440,123 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0x8b, hi: 0x8c}, {value: 0x0018, lo: 0x8d, hi: 0x8f}, {value: 0x0040, lo: 0x90, hi: 0x90}, - {value: 0x1308, lo: 0x91, hi: 0xbd}, - {value: 0x0018, lo: 0xbe, hi: 0xbe}, - {value: 0x1308, lo: 0xbf, hi: 0xbf}, + {value: 0x3308, lo: 0x91, hi: 0xbd}, + {value: 0x0818, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, // Block 0x7, offset 0x3f {value: 0x0000, lo: 0x0b}, - {value: 0x0018, lo: 0x80, hi: 0x80}, - {value: 0x1308, lo: 0x81, hi: 0x82}, - {value: 0x0018, lo: 0x83, hi: 0x83}, - {value: 0x1308, lo: 0x84, hi: 0x85}, - {value: 0x0018, lo: 0x86, hi: 0x86}, - {value: 0x1308, lo: 0x87, hi: 0x87}, + {value: 0x0818, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x82}, + {value: 0x0818, lo: 0x83, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x85}, + {value: 0x0818, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x87}, {value: 0x0040, lo: 0x88, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0xaa}, + {value: 0x0808, lo: 0x90, hi: 0xaa}, {value: 0x0040, lo: 0xab, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xb4}, + {value: 0x0808, lo: 0xb0, hi: 0xb4}, {value: 0x0040, lo: 0xb5, hi: 0xbf}, // Block 0x8, offset 0x4b - {value: 0x0000, lo: 0x10}, - {value: 0x0018, lo: 0x80, hi: 0x80}, - {value: 0x0208, lo: 0x81, hi: 0x87}, - {value: 0x0408, lo: 0x88, hi: 0x88}, - {value: 0x0208, lo: 0x89, hi: 0x8a}, - {value: 0x1308, lo: 0x8b, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xa9}, - {value: 0x0018, lo: 0xaa, hi: 0xad}, - {value: 0x0208, lo: 0xae, hi: 0xaf}, - {value: 0x1308, lo: 0xb0, hi: 0xb0}, - {value: 0x0408, lo: 0xb1, hi: 0xb3}, - {value: 0x0008, lo: 0xb4, hi: 0xb4}, - {value: 0x0429, lo: 0xb5, hi: 0xb5}, - {value: 0x0451, lo: 0xb6, hi: 0xb6}, - {value: 0x0479, lo: 0xb7, hi: 0xb7}, - {value: 0x04a1, lo: 0xb8, hi: 0xb8}, - {value: 0x0208, lo: 0xb9, hi: 0xbf}, - // Block 0x9, offset 0x5c {value: 0x0000, lo: 0x03}, - {value: 0x0208, lo: 0x80, hi: 0x87}, - {value: 0x0408, lo: 0x88, hi: 0x99}, - {value: 0x0208, lo: 0x9a, hi: 0xbf}, - // Block 0xa, offset 0x60 + {value: 0x0a08, lo: 0x80, hi: 0x87}, + {value: 0x0c08, lo: 0x88, hi: 0x99}, + {value: 0x0a08, lo: 0x9a, hi: 0xbf}, + // Block 0x9, offset 0x4f {value: 0x0000, lo: 0x0e}, - {value: 0x1308, lo: 0x80, hi: 0x8a}, + {value: 0x3308, lo: 0x80, hi: 0x8a}, {value: 0x0040, lo: 0x8b, hi: 0x8c}, - {value: 0x0408, lo: 0x8d, hi: 0x8d}, - {value: 0x0208, lo: 0x8e, hi: 0x98}, - {value: 0x0408, lo: 0x99, hi: 0x9b}, - {value: 0x0208, lo: 0x9c, hi: 0xaa}, - {value: 0x0408, lo: 0xab, hi: 0xac}, - {value: 0x0208, lo: 0xad, hi: 0xb0}, - {value: 0x0408, lo: 0xb1, hi: 0xb1}, - {value: 0x0208, lo: 0xb2, hi: 0xb2}, - {value: 0x0408, lo: 0xb3, hi: 0xb4}, - {value: 0x0208, lo: 0xb5, hi: 0xb7}, - {value: 0x0408, lo: 0xb8, hi: 0xb9}, - {value: 0x0208, lo: 0xba, hi: 0xbf}, - // Block 0xb, offset 0x6f + {value: 0x0c08, lo: 0x8d, hi: 0x8d}, + {value: 0x0a08, lo: 0x8e, hi: 0x98}, + {value: 0x0c08, lo: 0x99, hi: 0x9b}, + {value: 0x0a08, lo: 0x9c, hi: 0xaa}, + {value: 0x0c08, lo: 0xab, hi: 0xac}, + {value: 0x0a08, lo: 0xad, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb1}, + {value: 0x0a08, lo: 0xb2, hi: 0xb2}, + {value: 0x0c08, lo: 0xb3, hi: 0xb4}, + {value: 0x0a08, lo: 0xb5, hi: 0xb7}, + {value: 0x0c08, lo: 0xb8, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbf}, + // Block 0xa, offset 0x5e {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0xa5}, - {value: 0x1308, lo: 0xa6, hi: 0xb0}, - {value: 0x0008, lo: 0xb1, hi: 0xb1}, + {value: 0x0808, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xb0}, + {value: 0x0808, lo: 0xb1, hi: 0xb1}, {value: 0x0040, lo: 0xb2, hi: 0xbf}, - // Block 0xc, offset 0x74 - {value: 0x0000, lo: 0x06}, - {value: 0x0008, lo: 0x80, hi: 0x89}, - {value: 0x0208, lo: 0x8a, hi: 0xaa}, - {value: 0x1308, lo: 0xab, hi: 0xb3}, - {value: 0x0008, lo: 0xb4, hi: 0xb5}, - {value: 0x0018, lo: 0xb6, hi: 0xba}, + // Block 0xb, offset 0x63 + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x89}, + {value: 0x0a08, lo: 0x8a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xba}, {value: 0x0040, lo: 0xbb, hi: 0xbf}, - // Block 0xd, offset 0x7b + // Block 0xc, offset 0x6b {value: 0x0000, lo: 0x0b}, - {value: 0x0008, lo: 0x80, hi: 0x95}, - {value: 0x1308, lo: 0x96, hi: 0x99}, - {value: 0x0008, lo: 0x9a, hi: 0x9a}, - {value: 0x1308, lo: 0x9b, hi: 0xa3}, - {value: 0x0008, lo: 0xa4, hi: 0xa4}, - {value: 0x1308, lo: 0xa5, hi: 0xa7}, - {value: 0x0008, lo: 0xa8, hi: 0xa8}, - {value: 0x1308, lo: 0xa9, hi: 0xad}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x99}, + {value: 0x0808, lo: 0x9a, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa3}, + {value: 0x0808, lo: 0xa4, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa7}, + {value: 0x0808, lo: 0xa8, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xad}, {value: 0x0040, lo: 0xae, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xbe}, + {value: 0x0818, lo: 0xb0, hi: 0xbe}, {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0xe, offset 0x87 - {value: 0x0000, lo: 0x0d}, - {value: 0x0408, lo: 0x80, hi: 0x80}, - {value: 0x0208, lo: 0x81, hi: 0x85}, - {value: 0x0408, lo: 0x86, hi: 0x87}, - {value: 0x0208, lo: 0x88, hi: 0x88}, - {value: 0x0408, lo: 0x89, hi: 0x89}, - {value: 0x0208, lo: 0x8a, hi: 0x93}, - {value: 0x0408, lo: 0x94, hi: 0x94}, - {value: 0x0208, lo: 0x95, hi: 0x95}, - {value: 0x0008, lo: 0x96, hi: 0x98}, - {value: 0x1308, lo: 0x99, hi: 0x9b}, - {value: 0x0040, lo: 0x9c, hi: 0x9d}, - {value: 0x0018, lo: 0x9e, hi: 0x9e}, - {value: 0x0040, lo: 0x9f, hi: 0xbf}, - // Block 0xf, offset 0x95 + // Block 0xd, offset 0x77 {value: 0x0000, lo: 0x0d}, {value: 0x0040, lo: 0x80, hi: 0x9f}, - {value: 0x0208, lo: 0xa0, hi: 0xa9}, - {value: 0x0408, lo: 0xaa, hi: 0xac}, - {value: 0x0008, lo: 0xad, hi: 0xad}, - {value: 0x0408, lo: 0xae, hi: 0xae}, - {value: 0x0208, lo: 0xaf, hi: 0xb0}, - {value: 0x0408, lo: 0xb1, hi: 0xb2}, - {value: 0x0208, lo: 0xb3, hi: 0xb4}, + {value: 0x0a08, lo: 0xa0, hi: 0xa9}, + {value: 0x0c08, lo: 0xaa, hi: 0xac}, + {value: 0x0808, lo: 0xad, hi: 0xad}, + {value: 0x0c08, lo: 0xae, hi: 0xae}, + {value: 0x0a08, lo: 0xaf, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb2}, + {value: 0x0a08, lo: 0xb3, hi: 0xb4}, {value: 0x0040, lo: 0xb5, hi: 0xb5}, - {value: 0x0208, lo: 0xb6, hi: 0xb8}, - {value: 0x0408, lo: 0xb9, hi: 0xb9}, - {value: 0x0208, lo: 0xba, hi: 0xbd}, + {value: 0x0a08, lo: 0xb6, hi: 0xb8}, + {value: 0x0c08, lo: 0xb9, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbd}, {value: 0x0040, lo: 0xbe, hi: 0xbf}, - // Block 0x10, offset 0xa3 + // Block 0xe, offset 0x85 {value: 0x0000, lo: 0x04}, {value: 0x0040, lo: 0x80, hi: 0x93}, - {value: 0x1308, lo: 0x94, hi: 0xa1}, - {value: 0x0040, lo: 0xa2, hi: 0xa2}, - {value: 0x1308, lo: 0xa3, hi: 0xbf}, - // Block 0x11, offset 0xa8 + {value: 0x3308, lo: 0x94, hi: 0xa1}, + {value: 0x0840, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xbf}, + // Block 0xf, offset 0x8a {value: 0x0000, lo: 0x08}, - {value: 0x1308, lo: 0x80, hi: 0x82}, - {value: 0x1008, lo: 0x83, hi: 0x83}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, {value: 0x0008, lo: 0x84, hi: 0xb9}, - {value: 0x1308, lo: 0xba, hi: 0xba}, - {value: 0x1008, lo: 0xbb, hi: 0xbb}, - {value: 0x1308, lo: 0xbc, hi: 0xbc}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, {value: 0x0008, lo: 0xbd, hi: 0xbd}, - {value: 0x1008, lo: 0xbe, hi: 0xbf}, - // Block 0x12, offset 0xb1 + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x10, offset 0x93 {value: 0x0000, lo: 0x0f}, - {value: 0x1308, lo: 0x80, hi: 0x80}, - {value: 0x1008, lo: 0x81, hi: 0x82}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x82}, {value: 0x0040, lo: 0x83, hi: 0x85}, - {value: 0x1008, lo: 0x86, hi: 0x88}, + {value: 0x3008, lo: 0x86, hi: 0x88}, {value: 0x0040, lo: 0x89, hi: 0x89}, - {value: 0x1008, lo: 0x8a, hi: 0x8c}, - {value: 0x1b08, lo: 0x8d, hi: 0x8d}, + {value: 0x3008, lo: 0x8a, hi: 0x8c}, + {value: 0x3b08, lo: 0x8d, hi: 0x8d}, {value: 0x0040, lo: 0x8e, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x90}, {value: 0x0040, lo: 0x91, hi: 0x96}, - {value: 0x1008, lo: 0x97, hi: 0x97}, + {value: 0x3008, lo: 0x97, hi: 0x97}, {value: 0x0040, lo: 0x98, hi: 0xa5}, {value: 0x0008, lo: 0xa6, hi: 0xaf}, {value: 0x0018, lo: 0xb0, hi: 0xba}, {value: 0x0040, lo: 0xbb, hi: 0xbf}, - // Block 0x13, offset 0xc1 + // Block 0x11, offset 0xa3 {value: 0x0000, lo: 0x0d}, - {value: 0x1308, lo: 0x80, hi: 0x80}, - {value: 0x1008, lo: 0x81, hi: 0x83}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x83}, {value: 0x0040, lo: 0x84, hi: 0x84}, {value: 0x0008, lo: 0x85, hi: 0x8c}, {value: 0x0040, lo: 0x8d, hi: 0x8d}, @@ -2566,25 +2567,24 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0008, lo: 0xaa, hi: 0xb9}, {value: 0x0040, lo: 0xba, hi: 0xbc}, {value: 0x0008, lo: 0xbd, hi: 0xbd}, - {value: 0x1308, lo: 0xbe, hi: 0xbf}, - // Block 0x14, offset 0xcf - {value: 0x0000, lo: 0x0c}, - {value: 0x0040, lo: 0x80, hi: 0x80}, - {value: 0x1308, lo: 0x81, hi: 0x81}, - {value: 0x1008, lo: 0x82, hi: 0x83}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x12, offset 0xb1 + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, {value: 0x0040, lo: 0x84, hi: 0x84}, {value: 0x0008, lo: 0x85, hi: 0x8c}, {value: 0x0040, lo: 0x8d, hi: 0x8d}, {value: 0x0008, lo: 0x8e, hi: 0x90}, {value: 0x0040, lo: 0x91, hi: 0x91}, {value: 0x0008, lo: 0x92, hi: 0xba}, - {value: 0x0040, lo: 0xbb, hi: 0xbc}, + {value: 0x3b08, lo: 0xbb, hi: 0xbc}, {value: 0x0008, lo: 0xbd, hi: 0xbd}, - {value: 0x1008, lo: 0xbe, hi: 0xbf}, - // Block 0x15, offset 0xdc + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x13, offset 0xbd {value: 0x0000, lo: 0x0b}, {value: 0x0040, lo: 0x80, hi: 0x81}, - {value: 0x1008, lo: 0x82, hi: 0x83}, + {value: 0x3008, lo: 0x82, hi: 0x83}, {value: 0x0040, lo: 0x84, hi: 0x84}, {value: 0x0008, lo: 0x85, hi: 0x96}, {value: 0x0040, lo: 0x97, hi: 0x99}, @@ -2594,50 +2594,50 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0xbc, hi: 0xbc}, {value: 0x0008, lo: 0xbd, hi: 0xbd}, {value: 0x0040, lo: 0xbe, hi: 0xbf}, - // Block 0x16, offset 0xe8 + // Block 0x14, offset 0xc9 {value: 0x0000, lo: 0x10}, {value: 0x0008, lo: 0x80, hi: 0x86}, {value: 0x0040, lo: 0x87, hi: 0x89}, - {value: 0x1b08, lo: 0x8a, hi: 0x8a}, + {value: 0x3b08, lo: 0x8a, hi: 0x8a}, {value: 0x0040, lo: 0x8b, hi: 0x8e}, - {value: 0x1008, lo: 0x8f, hi: 0x91}, - {value: 0x1308, lo: 0x92, hi: 0x94}, + {value: 0x3008, lo: 0x8f, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x94}, {value: 0x0040, lo: 0x95, hi: 0x95}, - {value: 0x1308, lo: 0x96, hi: 0x96}, + {value: 0x3308, lo: 0x96, hi: 0x96}, {value: 0x0040, lo: 0x97, hi: 0x97}, - {value: 0x1008, lo: 0x98, hi: 0x9f}, + {value: 0x3008, lo: 0x98, hi: 0x9f}, {value: 0x0040, lo: 0xa0, hi: 0xa5}, {value: 0x0008, lo: 0xa6, hi: 0xaf}, {value: 0x0040, lo: 0xb0, hi: 0xb1}, - {value: 0x1008, lo: 0xb2, hi: 0xb3}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, {value: 0x0018, lo: 0xb4, hi: 0xb4}, {value: 0x0040, lo: 0xb5, hi: 0xbf}, - // Block 0x17, offset 0xf9 + // Block 0x15, offset 0xda {value: 0x0000, lo: 0x09}, {value: 0x0040, lo: 0x80, hi: 0x80}, {value: 0x0008, lo: 0x81, hi: 0xb0}, - {value: 0x1308, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb1, hi: 0xb1}, {value: 0x0008, lo: 0xb2, hi: 0xb2}, {value: 0x08f1, lo: 0xb3, hi: 0xb3}, - {value: 0x1308, lo: 0xb4, hi: 0xb9}, - {value: 0x1b08, lo: 0xba, hi: 0xba}, + {value: 0x3308, lo: 0xb4, hi: 0xb9}, + {value: 0x3b08, lo: 0xba, hi: 0xba}, {value: 0x0040, lo: 0xbb, hi: 0xbe}, {value: 0x0018, lo: 0xbf, hi: 0xbf}, - // Block 0x18, offset 0x103 + // Block 0x16, offset 0xe4 {value: 0x0000, lo: 0x06}, {value: 0x0008, lo: 0x80, hi: 0x86}, - {value: 0x1308, lo: 0x87, hi: 0x8e}, + {value: 0x3308, lo: 0x87, hi: 0x8e}, {value: 0x0018, lo: 0x8f, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x99}, {value: 0x0018, lo: 0x9a, hi: 0x9b}, {value: 0x0040, lo: 0x9c, hi: 0xbf}, - // Block 0x19, offset 0x10a + // Block 0x17, offset 0xeb {value: 0x0000, lo: 0x0c}, {value: 0x0008, lo: 0x80, hi: 0x84}, {value: 0x0040, lo: 0x85, hi: 0x85}, {value: 0x0008, lo: 0x86, hi: 0x86}, {value: 0x0040, lo: 0x87, hi: 0x87}, - {value: 0x1308, lo: 0x88, hi: 0x8d}, + {value: 0x3308, lo: 0x88, hi: 0x8d}, {value: 0x0040, lo: 0x8e, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x99}, {value: 0x0040, lo: 0x9a, hi: 0x9b}, @@ -2645,76 +2645,76 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0999, lo: 0x9d, hi: 0x9d}, {value: 0x0008, lo: 0x9e, hi: 0x9f}, {value: 0x0040, lo: 0xa0, hi: 0xbf}, - // Block 0x1a, offset 0x117 + // Block 0x18, offset 0xf8 {value: 0x0000, lo: 0x10}, {value: 0x0008, lo: 0x80, hi: 0x80}, {value: 0x0018, lo: 0x81, hi: 0x8a}, {value: 0x0008, lo: 0x8b, hi: 0x8b}, {value: 0xe03d, lo: 0x8c, hi: 0x8c}, {value: 0x0018, lo: 0x8d, hi: 0x97}, - {value: 0x1308, lo: 0x98, hi: 0x99}, + {value: 0x3308, lo: 0x98, hi: 0x99}, {value: 0x0018, lo: 0x9a, hi: 0x9f}, {value: 0x0008, lo: 0xa0, hi: 0xa9}, {value: 0x0018, lo: 0xaa, hi: 0xb4}, - {value: 0x1308, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, {value: 0x0018, lo: 0xb6, hi: 0xb6}, - {value: 0x1308, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, {value: 0x0018, lo: 0xb8, hi: 0xb8}, - {value: 0x1308, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xb9, hi: 0xb9}, {value: 0x0018, lo: 0xba, hi: 0xbd}, - {value: 0x1008, lo: 0xbe, hi: 0xbf}, - // Block 0x1b, offset 0x128 + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x19, offset 0x109 {value: 0x0000, lo: 0x06}, {value: 0x0018, lo: 0x80, hi: 0x85}, - {value: 0x1308, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x86, hi: 0x86}, {value: 0x0018, lo: 0x87, hi: 0x8c}, {value: 0x0040, lo: 0x8d, hi: 0x8d}, {value: 0x0018, lo: 0x8e, hi: 0x9a}, {value: 0x0040, lo: 0x9b, hi: 0xbf}, - // Block 0x1c, offset 0x12f + // Block 0x1a, offset 0x110 {value: 0x0000, lo: 0x0a}, {value: 0x0008, lo: 0x80, hi: 0xaa}, - {value: 0x1008, lo: 0xab, hi: 0xac}, - {value: 0x1308, lo: 0xad, hi: 0xb0}, - {value: 0x1008, lo: 0xb1, hi: 0xb1}, - {value: 0x1308, lo: 0xb2, hi: 0xb7}, - {value: 0x1008, lo: 0xb8, hi: 0xb8}, - {value: 0x1b08, lo: 0xb9, hi: 0xba}, - {value: 0x1008, lo: 0xbb, hi: 0xbc}, - {value: 0x1308, lo: 0xbd, hi: 0xbe}, + {value: 0x3008, lo: 0xab, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbe}, {value: 0x0008, lo: 0xbf, hi: 0xbf}, - // Block 0x1d, offset 0x13a + // Block 0x1b, offset 0x11b {value: 0x0000, lo: 0x0e}, {value: 0x0008, lo: 0x80, hi: 0x89}, {value: 0x0018, lo: 0x8a, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x95}, - {value: 0x1008, lo: 0x96, hi: 0x97}, - {value: 0x1308, lo: 0x98, hi: 0x99}, + {value: 0x3008, lo: 0x96, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, {value: 0x0008, lo: 0x9a, hi: 0x9d}, - {value: 0x1308, lo: 0x9e, hi: 0xa0}, + {value: 0x3308, lo: 0x9e, hi: 0xa0}, {value: 0x0008, lo: 0xa1, hi: 0xa1}, - {value: 0x1008, lo: 0xa2, hi: 0xa4}, + {value: 0x3008, lo: 0xa2, hi: 0xa4}, {value: 0x0008, lo: 0xa5, hi: 0xa6}, - {value: 0x1008, lo: 0xa7, hi: 0xad}, + {value: 0x3008, lo: 0xa7, hi: 0xad}, {value: 0x0008, lo: 0xae, hi: 0xb0}, - {value: 0x1308, lo: 0xb1, hi: 0xb4}, + {value: 0x3308, lo: 0xb1, hi: 0xb4}, {value: 0x0008, lo: 0xb5, hi: 0xbf}, - // Block 0x1e, offset 0x149 + // Block 0x1c, offset 0x12a {value: 0x0000, lo: 0x0d}, {value: 0x0008, lo: 0x80, hi: 0x81}, - {value: 0x1308, lo: 0x82, hi: 0x82}, - {value: 0x1008, lo: 0x83, hi: 0x84}, - {value: 0x1308, lo: 0x85, hi: 0x86}, - {value: 0x1008, lo: 0x87, hi: 0x8c}, - {value: 0x1308, lo: 0x8d, hi: 0x8d}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x8c}, + {value: 0x3308, lo: 0x8d, hi: 0x8d}, {value: 0x0008, lo: 0x8e, hi: 0x8e}, - {value: 0x1008, lo: 0x8f, hi: 0x8f}, + {value: 0x3008, lo: 0x8f, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x99}, - {value: 0x1008, lo: 0x9a, hi: 0x9c}, - {value: 0x1308, lo: 0x9d, hi: 0x9d}, + {value: 0x3008, lo: 0x9a, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, {value: 0x0018, lo: 0x9e, hi: 0x9f}, {value: 0x0040, lo: 0xa0, hi: 0xbf}, - // Block 0x1f, offset 0x157 + // Block 0x1d, offset 0x138 {value: 0x0000, lo: 0x09}, {value: 0x0040, lo: 0x80, hi: 0x86}, {value: 0x055d, lo: 0x87, hi: 0x87}, @@ -2725,18 +2725,27 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0018, lo: 0xbb, hi: 0xbb}, {value: 0xe105, lo: 0xbc, hi: 0xbc}, {value: 0x0008, lo: 0xbd, hi: 0xbf}, - // Block 0x20, offset 0x161 + // Block 0x1e, offset 0x142 {value: 0x0000, lo: 0x01}, {value: 0x0018, lo: 0x80, hi: 0xbf}, - // Block 0x21, offset 0x163 - {value: 0x0000, lo: 0x03}, + // Block 0x1f, offset 0x144 + {value: 0x0000, lo: 0x04}, {value: 0x0018, lo: 0x80, hi: 0x9e}, {value: 0x0040, lo: 0x9f, hi: 0xa0}, - {value: 0x0018, lo: 0xa1, hi: 0xbf}, - // Block 0x22, offset 0x167 + {value: 0x2018, lo: 0xa1, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x20, offset 0x149 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa7}, + {value: 0x2018, lo: 0xa8, hi: 0xbf}, + // Block 0x21, offset 0x14c + {value: 0x0000, lo: 0x02}, + {value: 0x2018, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0xbf}, + // Block 0x22, offset 0x14f {value: 0x0000, lo: 0x01}, {value: 0x0008, lo: 0x80, hi: 0xbf}, - // Block 0x23, offset 0x169 + // Block 0x23, offset 0x151 {value: 0x0000, lo: 0x0b}, {value: 0x0008, lo: 0x80, hi: 0x88}, {value: 0x0040, lo: 0x89, hi: 0x89}, @@ -2749,7 +2758,7 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0008, lo: 0x9a, hi: 0x9d}, {value: 0x0040, lo: 0x9e, hi: 0x9f}, {value: 0x0008, lo: 0xa0, hi: 0xbf}, - // Block 0x24, offset 0x175 + // Block 0x24, offset 0x15d {value: 0x0000, lo: 0x0a}, {value: 0x0008, lo: 0x80, hi: 0x88}, {value: 0x0040, lo: 0x89, hi: 0x89}, @@ -2761,7 +2770,7 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0xb6, hi: 0xb7}, {value: 0x0008, lo: 0xb8, hi: 0xbe}, {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0x25, offset 0x180 + // Block 0x25, offset 0x168 {value: 0x0000, lo: 0x07}, {value: 0x0008, lo: 0x80, hi: 0x80}, {value: 0x0040, lo: 0x81, hi: 0x81}, @@ -2770,146 +2779,146 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0008, lo: 0x88, hi: 0x96}, {value: 0x0040, lo: 0x97, hi: 0x97}, {value: 0x0008, lo: 0x98, hi: 0xbf}, - // Block 0x26, offset 0x188 + // Block 0x26, offset 0x170 {value: 0x0000, lo: 0x05}, {value: 0x0008, lo: 0x80, hi: 0x90}, {value: 0x0040, lo: 0x91, hi: 0x91}, {value: 0x0008, lo: 0x92, hi: 0x95}, {value: 0x0040, lo: 0x96, hi: 0x97}, {value: 0x0008, lo: 0x98, hi: 0xbf}, - // Block 0x27, offset 0x18e + // Block 0x27, offset 0x176 {value: 0x0000, lo: 0x05}, {value: 0x0008, lo: 0x80, hi: 0x9a}, {value: 0x0040, lo: 0x9b, hi: 0x9c}, - {value: 0x1308, lo: 0x9d, hi: 0x9f}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, {value: 0x0018, lo: 0xa0, hi: 0xbc}, {value: 0x0040, lo: 0xbd, hi: 0xbf}, - // Block 0x28, offset 0x194 + // Block 0x28, offset 0x17c {value: 0x0000, lo: 0x04}, {value: 0x0008, lo: 0x80, hi: 0x8f}, {value: 0x0018, lo: 0x90, hi: 0x99}, {value: 0x0040, lo: 0x9a, hi: 0x9f}, {value: 0x0008, lo: 0xa0, hi: 0xbf}, - // Block 0x29, offset 0x199 + // Block 0x29, offset 0x181 {value: 0x0000, lo: 0x04}, {value: 0x0008, lo: 0x80, hi: 0xb5}, {value: 0x0040, lo: 0xb6, hi: 0xb7}, {value: 0xe045, lo: 0xb8, hi: 0xbd}, {value: 0x0040, lo: 0xbe, hi: 0xbf}, - // Block 0x2a, offset 0x19e + // Block 0x2a, offset 0x186 {value: 0x0000, lo: 0x02}, {value: 0x0018, lo: 0x80, hi: 0x80}, {value: 0x0008, lo: 0x81, hi: 0xbf}, - // Block 0x2b, offset 0x1a1 + // Block 0x2b, offset 0x189 {value: 0x0000, lo: 0x03}, {value: 0x0008, lo: 0x80, hi: 0xac}, {value: 0x0018, lo: 0xad, hi: 0xae}, {value: 0x0008, lo: 0xaf, hi: 0xbf}, - // Block 0x2c, offset 0x1a5 + // Block 0x2c, offset 0x18d {value: 0x0000, lo: 0x05}, {value: 0x0040, lo: 0x80, hi: 0x80}, {value: 0x0008, lo: 0x81, hi: 0x9a}, {value: 0x0018, lo: 0x9b, hi: 0x9c}, {value: 0x0040, lo: 0x9d, hi: 0x9f}, {value: 0x0008, lo: 0xa0, hi: 0xbf}, - // Block 0x2d, offset 0x1ab + // Block 0x2d, offset 0x193 {value: 0x0000, lo: 0x04}, {value: 0x0008, lo: 0x80, hi: 0xaa}, {value: 0x0018, lo: 0xab, hi: 0xb0}, {value: 0x0008, lo: 0xb1, hi: 0xb8}, {value: 0x0040, lo: 0xb9, hi: 0xbf}, - // Block 0x2e, offset 0x1b0 + // Block 0x2e, offset 0x198 {value: 0x0000, lo: 0x0b}, {value: 0x0008, lo: 0x80, hi: 0x8c}, {value: 0x0040, lo: 0x8d, hi: 0x8d}, {value: 0x0008, lo: 0x8e, hi: 0x91}, - {value: 0x1308, lo: 0x92, hi: 0x93}, - {value: 0x1b08, lo: 0x94, hi: 0x94}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x3b08, lo: 0x94, hi: 0x94}, {value: 0x0040, lo: 0x95, hi: 0x9f}, {value: 0x0008, lo: 0xa0, hi: 0xb1}, - {value: 0x1308, lo: 0xb2, hi: 0xb3}, - {value: 0x1b08, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3b08, lo: 0xb4, hi: 0xb4}, {value: 0x0018, lo: 0xb5, hi: 0xb6}, {value: 0x0040, lo: 0xb7, hi: 0xbf}, - // Block 0x2f, offset 0x1bc + // Block 0x2f, offset 0x1a4 {value: 0x0000, lo: 0x09}, {value: 0x0008, lo: 0x80, hi: 0x91}, - {value: 0x1308, lo: 0x92, hi: 0x93}, + {value: 0x3308, lo: 0x92, hi: 0x93}, {value: 0x0040, lo: 0x94, hi: 0x9f}, {value: 0x0008, lo: 0xa0, hi: 0xac}, {value: 0x0040, lo: 0xad, hi: 0xad}, {value: 0x0008, lo: 0xae, hi: 0xb0}, {value: 0x0040, lo: 0xb1, hi: 0xb1}, - {value: 0x1308, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, {value: 0x0040, lo: 0xb4, hi: 0xbf}, - // Block 0x30, offset 0x1c6 + // Block 0x30, offset 0x1ae {value: 0x0000, lo: 0x05}, {value: 0x0008, lo: 0x80, hi: 0xb3}, - {value: 0x1340, lo: 0xb4, hi: 0xb5}, - {value: 0x1008, lo: 0xb6, hi: 0xb6}, - {value: 0x1308, lo: 0xb7, hi: 0xbd}, - {value: 0x1008, lo: 0xbe, hi: 0xbf}, - // Block 0x31, offset 0x1cc + {value: 0x3340, lo: 0xb4, hi: 0xb5}, + {value: 0x3008, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x31, offset 0x1b4 {value: 0x0000, lo: 0x10}, - {value: 0x1008, lo: 0x80, hi: 0x85}, - {value: 0x1308, lo: 0x86, hi: 0x86}, - {value: 0x1008, lo: 0x87, hi: 0x88}, - {value: 0x1308, lo: 0x89, hi: 0x91}, - {value: 0x1b08, lo: 0x92, hi: 0x92}, - {value: 0x1308, lo: 0x93, hi: 0x93}, + {value: 0x3008, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x88}, + {value: 0x3308, lo: 0x89, hi: 0x91}, + {value: 0x3b08, lo: 0x92, hi: 0x92}, + {value: 0x3308, lo: 0x93, hi: 0x93}, {value: 0x0018, lo: 0x94, hi: 0x96}, {value: 0x0008, lo: 0x97, hi: 0x97}, {value: 0x0018, lo: 0x98, hi: 0x9b}, {value: 0x0008, lo: 0x9c, hi: 0x9c}, - {value: 0x1308, lo: 0x9d, hi: 0x9d}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, {value: 0x0040, lo: 0x9e, hi: 0x9f}, {value: 0x0008, lo: 0xa0, hi: 0xa9}, {value: 0x0040, lo: 0xaa, hi: 0xaf}, {value: 0x0018, lo: 0xb0, hi: 0xb9}, {value: 0x0040, lo: 0xba, hi: 0xbf}, - // Block 0x32, offset 0x1dd + // Block 0x32, offset 0x1c5 {value: 0x0000, lo: 0x09}, {value: 0x0018, lo: 0x80, hi: 0x85}, {value: 0x0040, lo: 0x86, hi: 0x86}, {value: 0x0218, lo: 0x87, hi: 0x87}, {value: 0x0018, lo: 0x88, hi: 0x8a}, - {value: 0x13c0, lo: 0x8b, hi: 0x8d}, + {value: 0x33c0, lo: 0x8b, hi: 0x8d}, {value: 0x0040, lo: 0x8e, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x99}, {value: 0x0040, lo: 0x9a, hi: 0x9f}, {value: 0x0208, lo: 0xa0, hi: 0xbf}, - // Block 0x33, offset 0x1e7 + // Block 0x33, offset 0x1cf {value: 0x0000, lo: 0x02}, {value: 0x0208, lo: 0x80, hi: 0xb7}, {value: 0x0040, lo: 0xb8, hi: 0xbf}, - // Block 0x34, offset 0x1ea + // Block 0x34, offset 0x1d2 {value: 0x0000, lo: 0x07}, {value: 0x0008, lo: 0x80, hi: 0x84}, - {value: 0x1308, lo: 0x85, hi: 0x86}, + {value: 0x3308, lo: 0x85, hi: 0x86}, {value: 0x0208, lo: 0x87, hi: 0xa8}, - {value: 0x1308, lo: 0xa9, hi: 0xa9}, + {value: 0x3308, lo: 0xa9, hi: 0xa9}, {value: 0x0208, lo: 0xaa, hi: 0xaa}, {value: 0x0040, lo: 0xab, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x35, offset 0x1f2 + // Block 0x35, offset 0x1da {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0xb5}, {value: 0x0040, lo: 0xb6, hi: 0xbf}, - // Block 0x36, offset 0x1f5 + // Block 0x36, offset 0x1dd {value: 0x0000, lo: 0x0c}, {value: 0x0008, lo: 0x80, hi: 0x9e}, {value: 0x0040, lo: 0x9f, hi: 0x9f}, - {value: 0x1308, lo: 0xa0, hi: 0xa2}, - {value: 0x1008, lo: 0xa3, hi: 0xa6}, - {value: 0x1308, lo: 0xa7, hi: 0xa8}, - {value: 0x1008, lo: 0xa9, hi: 0xab}, + {value: 0x3308, lo: 0xa0, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xab}, {value: 0x0040, lo: 0xac, hi: 0xaf}, - {value: 0x1008, lo: 0xb0, hi: 0xb1}, - {value: 0x1308, lo: 0xb2, hi: 0xb2}, - {value: 0x1008, lo: 0xb3, hi: 0xb8}, - {value: 0x1308, lo: 0xb9, hi: 0xbb}, + {value: 0x3008, lo: 0xb0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xbb}, {value: 0x0040, lo: 0xbc, hi: 0xbf}, - // Block 0x37, offset 0x202 + // Block 0x37, offset 0x1ea {value: 0x0000, lo: 0x07}, {value: 0x0018, lo: 0x80, hi: 0x80}, {value: 0x0040, lo: 0x81, hi: 0x83}, @@ -2918,12 +2927,12 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0xae, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xb4}, {value: 0x0040, lo: 0xb5, hi: 0xbf}, - // Block 0x38, offset 0x20a + // Block 0x38, offset 0x1f2 {value: 0x0000, lo: 0x03}, {value: 0x0008, lo: 0x80, hi: 0xab}, {value: 0x0040, lo: 0xac, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x39, offset 0x20e + // Block 0x39, offset 0x1f6 {value: 0x0000, lo: 0x06}, {value: 0x0008, lo: 0x80, hi: 0x89}, {value: 0x0040, lo: 0x8a, hi: 0x8f}, @@ -2931,33 +2940,33 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0028, lo: 0x9a, hi: 0x9a}, {value: 0x0040, lo: 0x9b, hi: 0x9d}, {value: 0x0018, lo: 0x9e, hi: 0xbf}, - // Block 0x3a, offset 0x215 + // Block 0x3a, offset 0x1fd {value: 0x0000, lo: 0x07}, {value: 0x0008, lo: 0x80, hi: 0x96}, - {value: 0x1308, lo: 0x97, hi: 0x98}, - {value: 0x1008, lo: 0x99, hi: 0x9a}, - {value: 0x1308, lo: 0x9b, hi: 0x9b}, + {value: 0x3308, lo: 0x97, hi: 0x98}, + {value: 0x3008, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9b}, {value: 0x0040, lo: 0x9c, hi: 0x9d}, {value: 0x0018, lo: 0x9e, hi: 0x9f}, {value: 0x0008, lo: 0xa0, hi: 0xbf}, - // Block 0x3b, offset 0x21d + // Block 0x3b, offset 0x205 {value: 0x0000, lo: 0x0f}, {value: 0x0008, lo: 0x80, hi: 0x94}, - {value: 0x1008, lo: 0x95, hi: 0x95}, - {value: 0x1308, lo: 0x96, hi: 0x96}, - {value: 0x1008, lo: 0x97, hi: 0x97}, - {value: 0x1308, lo: 0x98, hi: 0x9e}, + {value: 0x3008, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x9e}, {value: 0x0040, lo: 0x9f, hi: 0x9f}, - {value: 0x1b08, lo: 0xa0, hi: 0xa0}, - {value: 0x1008, lo: 0xa1, hi: 0xa1}, - {value: 0x1308, lo: 0xa2, hi: 0xa2}, - {value: 0x1008, lo: 0xa3, hi: 0xa4}, - {value: 0x1308, lo: 0xa5, hi: 0xac}, - {value: 0x1008, lo: 0xad, hi: 0xb2}, - {value: 0x1308, lo: 0xb3, hi: 0xbc}, + {value: 0x3b08, lo: 0xa0, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xac}, + {value: 0x3008, lo: 0xad, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xbc}, {value: 0x0040, lo: 0xbd, hi: 0xbe}, - {value: 0x1308, lo: 0xbf, hi: 0xbf}, - // Block 0x3c, offset 0x22d + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x3c, offset 0x215 {value: 0x0000, lo: 0x0b}, {value: 0x0008, lo: 0x80, hi: 0x89}, {value: 0x0040, lo: 0x8a, hi: 0x8f}, @@ -2967,78 +2976,78 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0008, lo: 0xa7, hi: 0xa7}, {value: 0x0018, lo: 0xa8, hi: 0xad}, {value: 0x0040, lo: 0xae, hi: 0xaf}, - {value: 0x1308, lo: 0xb0, hi: 0xbd}, - {value: 0x1318, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xb0, hi: 0xbd}, + {value: 0x3318, lo: 0xbe, hi: 0xbe}, {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0x3d, offset 0x239 + // Block 0x3d, offset 0x221 {value: 0x0000, lo: 0x01}, {value: 0x0040, lo: 0x80, hi: 0xbf}, - // Block 0x3e, offset 0x23b + // Block 0x3e, offset 0x223 {value: 0x0000, lo: 0x09}, - {value: 0x1308, lo: 0x80, hi: 0x83}, - {value: 0x1008, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x80, hi: 0x83}, + {value: 0x3008, lo: 0x84, hi: 0x84}, {value: 0x0008, lo: 0x85, hi: 0xb3}, - {value: 0x1308, lo: 0xb4, hi: 0xb4}, - {value: 0x1008, lo: 0xb5, hi: 0xb5}, - {value: 0x1308, lo: 0xb6, hi: 0xba}, - {value: 0x1008, lo: 0xbb, hi: 0xbb}, - {value: 0x1308, lo: 0xbc, hi: 0xbc}, - {value: 0x1008, lo: 0xbd, hi: 0xbf}, - // Block 0x3f, offset 0x245 + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x3f, offset 0x22d {value: 0x0000, lo: 0x0b}, - {value: 0x1008, lo: 0x80, hi: 0x81}, - {value: 0x1308, lo: 0x82, hi: 0x82}, - {value: 0x1008, lo: 0x83, hi: 0x83}, - {value: 0x1808, lo: 0x84, hi: 0x84}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x3808, lo: 0x84, hi: 0x84}, {value: 0x0008, lo: 0x85, hi: 0x8b}, {value: 0x0040, lo: 0x8c, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x99}, {value: 0x0018, lo: 0x9a, hi: 0xaa}, - {value: 0x1308, lo: 0xab, hi: 0xb3}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, {value: 0x0018, lo: 0xb4, hi: 0xbc}, {value: 0x0040, lo: 0xbd, hi: 0xbf}, - // Block 0x40, offset 0x251 + // Block 0x40, offset 0x239 {value: 0x0000, lo: 0x0b}, - {value: 0x1308, lo: 0x80, hi: 0x81}, - {value: 0x1008, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, {value: 0x0008, lo: 0x83, hi: 0xa0}, - {value: 0x1008, lo: 0xa1, hi: 0xa1}, - {value: 0x1308, lo: 0xa2, hi: 0xa5}, - {value: 0x1008, lo: 0xa6, hi: 0xa7}, - {value: 0x1308, lo: 0xa8, hi: 0xa9}, - {value: 0x1808, lo: 0xaa, hi: 0xaa}, - {value: 0x1b08, lo: 0xab, hi: 0xab}, - {value: 0x1308, lo: 0xac, hi: 0xad}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3808, lo: 0xaa, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, {value: 0x0008, lo: 0xae, hi: 0xbf}, - // Block 0x41, offset 0x25d + // Block 0x41, offset 0x245 {value: 0x0000, lo: 0x0b}, {value: 0x0008, lo: 0x80, hi: 0xa5}, - {value: 0x1308, lo: 0xa6, hi: 0xa6}, - {value: 0x1008, lo: 0xa7, hi: 0xa7}, - {value: 0x1308, lo: 0xa8, hi: 0xa9}, - {value: 0x1008, lo: 0xaa, hi: 0xac}, - {value: 0x1308, lo: 0xad, hi: 0xad}, - {value: 0x1008, lo: 0xae, hi: 0xae}, - {value: 0x1308, lo: 0xaf, hi: 0xb1}, - {value: 0x1808, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xa6, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3008, lo: 0xaa, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3808, lo: 0xb2, hi: 0xb3}, {value: 0x0040, lo: 0xb4, hi: 0xbb}, {value: 0x0018, lo: 0xbc, hi: 0xbf}, - // Block 0x42, offset 0x269 + // Block 0x42, offset 0x251 {value: 0x0000, lo: 0x07}, {value: 0x0008, lo: 0x80, hi: 0xa3}, - {value: 0x1008, lo: 0xa4, hi: 0xab}, - {value: 0x1308, lo: 0xac, hi: 0xb3}, - {value: 0x1008, lo: 0xb4, hi: 0xb5}, - {value: 0x1308, lo: 0xb6, hi: 0xb7}, + {value: 0x3008, lo: 0xa4, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, {value: 0x0040, lo: 0xb8, hi: 0xba}, {value: 0x0018, lo: 0xbb, hi: 0xbf}, - // Block 0x43, offset 0x271 + // Block 0x43, offset 0x259 {value: 0x0000, lo: 0x04}, {value: 0x0008, lo: 0x80, hi: 0x89}, {value: 0x0040, lo: 0x8a, hi: 0x8c}, {value: 0x0008, lo: 0x8d, hi: 0xbd}, {value: 0x0018, lo: 0xbe, hi: 0xbf}, - // Block 0x44, offset 0x276 + // Block 0x44, offset 0x25e {value: 0x0000, lo: 0x09}, {value: 0x0e29, lo: 0x80, hi: 0x80}, {value: 0x0e41, lo: 0x81, hi: 0x81}, @@ -3049,30 +3058,30 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0eb9, lo: 0x87, hi: 0x87}, {value: 0x057d, lo: 0x88, hi: 0x88}, {value: 0x0040, lo: 0x89, hi: 0xbf}, - // Block 0x45, offset 0x280 + // Block 0x45, offset 0x268 {value: 0x0000, lo: 0x10}, {value: 0x0018, lo: 0x80, hi: 0x87}, {value: 0x0040, lo: 0x88, hi: 0x8f}, - {value: 0x1308, lo: 0x90, hi: 0x92}, + {value: 0x3308, lo: 0x90, hi: 0x92}, {value: 0x0018, lo: 0x93, hi: 0x93}, - {value: 0x1308, lo: 0x94, hi: 0xa0}, - {value: 0x1008, lo: 0xa1, hi: 0xa1}, - {value: 0x1308, lo: 0xa2, hi: 0xa8}, + {value: 0x3308, lo: 0x94, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa8}, {value: 0x0008, lo: 0xa9, hi: 0xac}, - {value: 0x1308, lo: 0xad, hi: 0xad}, + {value: 0x3308, lo: 0xad, hi: 0xad}, {value: 0x0008, lo: 0xae, hi: 0xb1}, - {value: 0x1008, lo: 0xb2, hi: 0xb3}, - {value: 0x1308, lo: 0xb4, hi: 0xb4}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, {value: 0x0008, lo: 0xb5, hi: 0xb6}, - {value: 0x0040, lo: 0xb7, hi: 0xb7}, - {value: 0x1308, lo: 0xb8, hi: 0xb9}, + {value: 0x3008, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xb9}, {value: 0x0040, lo: 0xba, hi: 0xbf}, - // Block 0x46, offset 0x291 + // Block 0x46, offset 0x279 {value: 0x0000, lo: 0x03}, - {value: 0x1308, lo: 0x80, hi: 0xb5}, - {value: 0x0040, lo: 0xb6, hi: 0xba}, - {value: 0x1308, lo: 0xbb, hi: 0xbf}, - // Block 0x47, offset 0x295 + {value: 0x3308, lo: 0x80, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0x47, offset 0x27d {value: 0x0000, lo: 0x0a}, {value: 0x0008, lo: 0x80, hi: 0x87}, {value: 0xe045, lo: 0x88, hi: 0x8f}, @@ -3084,12 +3093,12 @@ var idnaSparseValues = [1876]valueRange{ {value: 0xe045, lo: 0xa8, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xb7}, {value: 0xe045, lo: 0xb8, hi: 0xbf}, - // Block 0x48, offset 0x2a0 + // Block 0x48, offset 0x288 {value: 0x0000, lo: 0x03}, {value: 0x0040, lo: 0x80, hi: 0x8f}, - {value: 0x1318, lo: 0x90, hi: 0xb0}, + {value: 0x3318, lo: 0x90, hi: 0xb0}, {value: 0x0040, lo: 0xb1, hi: 0xbf}, - // Block 0x49, offset 0x2a4 + // Block 0x49, offset 0x28c {value: 0x0000, lo: 0x08}, {value: 0x0018, lo: 0x80, hi: 0x82}, {value: 0x0040, lo: 0x83, hi: 0x83}, @@ -3099,7 +3108,7 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0018, lo: 0x8a, hi: 0x8b}, {value: 0x0040, lo: 0x8c, hi: 0x8f}, {value: 0x0018, lo: 0x90, hi: 0xbf}, - // Block 0x4a, offset 0x2ad + // Block 0x4a, offset 0x295 {value: 0x0000, lo: 0x07}, {value: 0x0018, lo: 0x80, hi: 0xab}, {value: 0x24f1, lo: 0xac, hi: 0xac}, @@ -3108,72 +3117,68 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x2579, lo: 0xaf, hi: 0xaf}, {value: 0x25b1, lo: 0xb0, hi: 0xb0}, {value: 0x0018, lo: 0xb1, hi: 0xbf}, - // Block 0x4b, offset 0x2b5 + // Block 0x4b, offset 0x29d {value: 0x0000, lo: 0x05}, {value: 0x0018, lo: 0x80, hi: 0x9f}, {value: 0x0080, lo: 0xa0, hi: 0xa0}, {value: 0x0018, lo: 0xa1, hi: 0xad}, {value: 0x0080, lo: 0xae, hi: 0xaf}, {value: 0x0018, lo: 0xb0, hi: 0xbf}, - // Block 0x4c, offset 0x2bb + // Block 0x4c, offset 0x2a3 {value: 0x0000, lo: 0x04}, {value: 0x0018, lo: 0x80, hi: 0xa8}, {value: 0x09c5, lo: 0xa9, hi: 0xa9}, {value: 0x09e5, lo: 0xaa, hi: 0xaa}, {value: 0x0018, lo: 0xab, hi: 0xbf}, - // Block 0x4d, offset 0x2c0 - {value: 0x0000, lo: 0x02}, - {value: 0x0018, lo: 0x80, hi: 0xbe}, - {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0x4e, offset 0x2c3 + // Block 0x4d, offset 0x2a8 {value: 0x0000, lo: 0x02}, {value: 0x0018, lo: 0x80, hi: 0xa6}, {value: 0x0040, lo: 0xa7, hi: 0xbf}, - // Block 0x4f, offset 0x2c6 + // Block 0x4e, offset 0x2ab {value: 0x0000, lo: 0x03}, {value: 0x0018, lo: 0x80, hi: 0x8b}, {value: 0x28c1, lo: 0x8c, hi: 0x8c}, {value: 0x0018, lo: 0x8d, hi: 0xbf}, - // Block 0x50, offset 0x2ca + // Block 0x4f, offset 0x2af {value: 0x0000, lo: 0x05}, {value: 0x0018, lo: 0x80, hi: 0xb3}, {value: 0x0e66, lo: 0xb4, hi: 0xb4}, {value: 0x292a, lo: 0xb5, hi: 0xb5}, {value: 0x0e86, lo: 0xb6, hi: 0xb6}, {value: 0x0018, lo: 0xb7, hi: 0xbf}, - // Block 0x51, offset 0x2d0 + // Block 0x50, offset 0x2b5 {value: 0x0000, lo: 0x03}, {value: 0x0018, lo: 0x80, hi: 0x9b}, {value: 0x2941, lo: 0x9c, hi: 0x9c}, {value: 0x0018, lo: 0x9d, hi: 0xbf}, - // Block 0x52, offset 0x2d4 + // Block 0x51, offset 0x2b9 {value: 0x0000, lo: 0x03}, {value: 0x0018, lo: 0x80, hi: 0xb3}, {value: 0x0040, lo: 0xb4, hi: 0xb5}, {value: 0x0018, lo: 0xb6, hi: 0xbf}, - // Block 0x53, offset 0x2d8 + // Block 0x52, offset 0x2bd {value: 0x0000, lo: 0x05}, {value: 0x0018, lo: 0x80, hi: 0x95}, {value: 0x0040, lo: 0x96, hi: 0x97}, {value: 0x0018, lo: 0x98, hi: 0xb9}, {value: 0x0040, lo: 0xba, hi: 0xbc}, {value: 0x0018, lo: 0xbd, hi: 0xbf}, - // Block 0x54, offset 0x2de + // Block 0x53, offset 0x2c3 {value: 0x0000, lo: 0x06}, {value: 0x0018, lo: 0x80, hi: 0x88}, {value: 0x0040, lo: 0x89, hi: 0x89}, - {value: 0x0018, lo: 0x8a, hi: 0x91}, - {value: 0x0040, lo: 0x92, hi: 0xab}, + {value: 0x0018, lo: 0x8a, hi: 0x92}, + {value: 0x0040, lo: 0x93, hi: 0xab}, {value: 0x0018, lo: 0xac, hi: 0xaf}, {value: 0x0040, lo: 0xb0, hi: 0xbf}, - // Block 0x55, offset 0x2e5 + // Block 0x54, offset 0x2ca {value: 0x0000, lo: 0x05}, {value: 0xe185, lo: 0x80, hi: 0x8f}, {value: 0x03f5, lo: 0x90, hi: 0x9f}, {value: 0x0ea5, lo: 0xa0, hi: 0xae}, {value: 0x0040, lo: 0xaf, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x56, offset 0x2eb + // Block 0x55, offset 0x2d0 {value: 0x0000, lo: 0x07}, {value: 0x0008, lo: 0x80, hi: 0xa5}, {value: 0x0040, lo: 0xa6, hi: 0xa6}, @@ -3182,15 +3187,15 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0008, lo: 0xad, hi: 0xad}, {value: 0x0040, lo: 0xae, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x57, offset 0x2f3 + // Block 0x56, offset 0x2d8 {value: 0x0000, lo: 0x06}, {value: 0x0008, lo: 0x80, hi: 0xa7}, {value: 0x0040, lo: 0xa8, hi: 0xae}, {value: 0xe075, lo: 0xaf, hi: 0xaf}, {value: 0x0018, lo: 0xb0, hi: 0xb0}, {value: 0x0040, lo: 0xb1, hi: 0xbe}, - {value: 0x1b08, lo: 0xbf, hi: 0xbf}, - // Block 0x58, offset 0x2fa + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0x57, offset 0x2df {value: 0x0000, lo: 0x0a}, {value: 0x0008, lo: 0x80, hi: 0x96}, {value: 0x0040, lo: 0x97, hi: 0x9f}, @@ -3202,7 +3207,7 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0xb7, hi: 0xb7}, {value: 0x0008, lo: 0xb8, hi: 0xbe}, {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0x59, offset 0x305 + // Block 0x58, offset 0x2ea {value: 0x0000, lo: 0x09}, {value: 0x0008, lo: 0x80, hi: 0x86}, {value: 0x0040, lo: 0x87, hi: 0x87}, @@ -3212,62 +3217,62 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0x97, hi: 0x97}, {value: 0x0008, lo: 0x98, hi: 0x9e}, {value: 0x0040, lo: 0x9f, hi: 0x9f}, - {value: 0x1308, lo: 0xa0, hi: 0xbf}, - // Block 0x5a, offset 0x30f + {value: 0x3308, lo: 0xa0, hi: 0xbf}, + // Block 0x59, offset 0x2f4 {value: 0x0000, lo: 0x03}, {value: 0x0018, lo: 0x80, hi: 0xae}, {value: 0x0008, lo: 0xaf, hi: 0xaf}, {value: 0x0018, lo: 0xb0, hi: 0xbf}, - // Block 0x5b, offset 0x313 + // Block 0x5a, offset 0x2f8 {value: 0x0000, lo: 0x02}, - {value: 0x0018, lo: 0x80, hi: 0x84}, - {value: 0x0040, lo: 0x85, hi: 0xbf}, - // Block 0x5c, offset 0x316 + {value: 0x0018, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0xbf}, + // Block 0x5b, offset 0x2fb {value: 0x0000, lo: 0x05}, {value: 0x0018, lo: 0x80, hi: 0x99}, {value: 0x0040, lo: 0x9a, hi: 0x9a}, {value: 0x0018, lo: 0x9b, hi: 0x9e}, {value: 0x0edd, lo: 0x9f, hi: 0x9f}, {value: 0x0018, lo: 0xa0, hi: 0xbf}, - // Block 0x5d, offset 0x31c + // Block 0x5c, offset 0x301 {value: 0x0000, lo: 0x03}, {value: 0x0018, lo: 0x80, hi: 0xb2}, {value: 0x0efd, lo: 0xb3, hi: 0xb3}, {value: 0x0040, lo: 0xb4, hi: 0xbf}, - // Block 0x5e, offset 0x320 + // Block 0x5d, offset 0x305 {value: 0x0020, lo: 0x01}, {value: 0x0f1d, lo: 0x80, hi: 0xbf}, - // Block 0x5f, offset 0x322 + // Block 0x5e, offset 0x307 {value: 0x0020, lo: 0x02}, {value: 0x171d, lo: 0x80, hi: 0x8f}, {value: 0x18fd, lo: 0x90, hi: 0xbf}, - // Block 0x60, offset 0x325 + // Block 0x5f, offset 0x30a {value: 0x0020, lo: 0x01}, {value: 0x1efd, lo: 0x80, hi: 0xbf}, - // Block 0x61, offset 0x327 + // Block 0x60, offset 0x30c {value: 0x0000, lo: 0x02}, {value: 0x0040, lo: 0x80, hi: 0x80}, {value: 0x0008, lo: 0x81, hi: 0xbf}, - // Block 0x62, offset 0x32a + // Block 0x61, offset 0x30f {value: 0x0000, lo: 0x09}, {value: 0x0008, lo: 0x80, hi: 0x96}, {value: 0x0040, lo: 0x97, hi: 0x98}, - {value: 0x1308, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x99, hi: 0x9a}, {value: 0x29e2, lo: 0x9b, hi: 0x9b}, {value: 0x2a0a, lo: 0x9c, hi: 0x9c}, {value: 0x0008, lo: 0x9d, hi: 0x9e}, {value: 0x2a31, lo: 0x9f, hi: 0x9f}, {value: 0x0018, lo: 0xa0, hi: 0xa0}, {value: 0x0008, lo: 0xa1, hi: 0xbf}, - // Block 0x63, offset 0x334 + // Block 0x62, offset 0x319 {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0xbe}, {value: 0x2a69, lo: 0xbf, hi: 0xbf}, - // Block 0x64, offset 0x337 + // Block 0x63, offset 0x31c {value: 0x0000, lo: 0x0e}, {value: 0x0040, lo: 0x80, hi: 0x84}, - {value: 0x0008, lo: 0x85, hi: 0xad}, - {value: 0x0040, lo: 0xae, hi: 0xb0}, + {value: 0x0008, lo: 0x85, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xb0}, {value: 0x2a1d, lo: 0xb1, hi: 0xb1}, {value: 0x2a3d, lo: 0xb2, hi: 0xb2}, {value: 0x2a5d, lo: 0xb3, hi: 0xb3}, @@ -3279,150 +3284,150 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x2afd, lo: 0xba, hi: 0xbb}, {value: 0x2b1d, lo: 0xbc, hi: 0xbd}, {value: 0x2afd, lo: 0xbe, hi: 0xbf}, - // Block 0x65, offset 0x346 + // Block 0x64, offset 0x32b {value: 0x0000, lo: 0x03}, {value: 0x0018, lo: 0x80, hi: 0xa3}, {value: 0x0040, lo: 0xa4, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x66, offset 0x34a + // Block 0x65, offset 0x32f {value: 0x0030, lo: 0x04}, {value: 0x2aa2, lo: 0x80, hi: 0x9d}, {value: 0x305a, lo: 0x9e, hi: 0x9e}, {value: 0x0040, lo: 0x9f, hi: 0x9f}, {value: 0x30a2, lo: 0xa0, hi: 0xbf}, - // Block 0x67, offset 0x34f + // Block 0x66, offset 0x334 {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0x95}, - {value: 0x0040, lo: 0x96, hi: 0xbf}, - // Block 0x68, offset 0x352 + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xbf}, + // Block 0x67, offset 0x337 {value: 0x0000, lo: 0x03}, {value: 0x0008, lo: 0x80, hi: 0x8c}, {value: 0x0040, lo: 0x8d, hi: 0x8f}, {value: 0x0018, lo: 0x90, hi: 0xbf}, - // Block 0x69, offset 0x356 + // Block 0x68, offset 0x33b {value: 0x0000, lo: 0x04}, {value: 0x0018, lo: 0x80, hi: 0x86}, {value: 0x0040, lo: 0x87, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0xbd}, {value: 0x0018, lo: 0xbe, hi: 0xbf}, - // Block 0x6a, offset 0x35b + // Block 0x69, offset 0x340 {value: 0x0000, lo: 0x04}, {value: 0x0008, lo: 0x80, hi: 0x8c}, {value: 0x0018, lo: 0x8d, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0xab}, {value: 0x0040, lo: 0xac, hi: 0xbf}, - // Block 0x6b, offset 0x360 + // Block 0x6a, offset 0x345 {value: 0x0000, lo: 0x05}, {value: 0x0008, lo: 0x80, hi: 0xa5}, {value: 0x0018, lo: 0xa6, hi: 0xaf}, - {value: 0x1308, lo: 0xb0, hi: 0xb1}, + {value: 0x3308, lo: 0xb0, hi: 0xb1}, {value: 0x0018, lo: 0xb2, hi: 0xb7}, {value: 0x0040, lo: 0xb8, hi: 0xbf}, - // Block 0x6c, offset 0x366 + // Block 0x6b, offset 0x34b {value: 0x0000, lo: 0x05}, {value: 0x0040, lo: 0x80, hi: 0xb6}, {value: 0x0008, lo: 0xb7, hi: 0xb7}, {value: 0x2009, lo: 0xb8, hi: 0xb8}, {value: 0x6e89, lo: 0xb9, hi: 0xb9}, {value: 0x0008, lo: 0xba, hi: 0xbf}, - // Block 0x6d, offset 0x36c + // Block 0x6c, offset 0x351 {value: 0x0000, lo: 0x0e}, {value: 0x0008, lo: 0x80, hi: 0x81}, - {value: 0x1308, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x82, hi: 0x82}, {value: 0x0008, lo: 0x83, hi: 0x85}, - {value: 0x1b08, lo: 0x86, hi: 0x86}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, {value: 0x0008, lo: 0x87, hi: 0x8a}, - {value: 0x1308, lo: 0x8b, hi: 0x8b}, + {value: 0x3308, lo: 0x8b, hi: 0x8b}, {value: 0x0008, lo: 0x8c, hi: 0xa2}, - {value: 0x1008, lo: 0xa3, hi: 0xa4}, - {value: 0x1308, lo: 0xa5, hi: 0xa6}, - {value: 0x1008, lo: 0xa7, hi: 0xa7}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, {value: 0x0018, lo: 0xa8, hi: 0xab}, {value: 0x0040, lo: 0xac, hi: 0xaf}, {value: 0x0018, lo: 0xb0, hi: 0xb9}, {value: 0x0040, lo: 0xba, hi: 0xbf}, - // Block 0x6e, offset 0x37b + // Block 0x6d, offset 0x360 {value: 0x0000, lo: 0x05}, {value: 0x0208, lo: 0x80, hi: 0xb1}, {value: 0x0108, lo: 0xb2, hi: 0xb2}, {value: 0x0008, lo: 0xb3, hi: 0xb3}, {value: 0x0018, lo: 0xb4, hi: 0xb7}, {value: 0x0040, lo: 0xb8, hi: 0xbf}, - // Block 0x6f, offset 0x381 + // Block 0x6e, offset 0x366 {value: 0x0000, lo: 0x03}, - {value: 0x1008, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x80, hi: 0x81}, {value: 0x0008, lo: 0x82, hi: 0xb3}, - {value: 0x1008, lo: 0xb4, hi: 0xbf}, - // Block 0x70, offset 0x385 + {value: 0x3008, lo: 0xb4, hi: 0xbf}, + // Block 0x6f, offset 0x36a {value: 0x0000, lo: 0x0e}, - {value: 0x1008, lo: 0x80, hi: 0x83}, - {value: 0x1b08, lo: 0x84, hi: 0x84}, - {value: 0x1308, lo: 0x85, hi: 0x85}, + {value: 0x3008, lo: 0x80, hi: 0x83}, + {value: 0x3b08, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x85}, {value: 0x0040, lo: 0x86, hi: 0x8d}, {value: 0x0018, lo: 0x8e, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x99}, {value: 0x0040, lo: 0x9a, hi: 0x9f}, - {value: 0x1308, lo: 0xa0, hi: 0xb1}, + {value: 0x3308, lo: 0xa0, hi: 0xb1}, {value: 0x0008, lo: 0xb2, hi: 0xb7}, {value: 0x0018, lo: 0xb8, hi: 0xba}, {value: 0x0008, lo: 0xbb, hi: 0xbb}, {value: 0x0018, lo: 0xbc, hi: 0xbc}, {value: 0x0008, lo: 0xbd, hi: 0xbd}, {value: 0x0040, lo: 0xbe, hi: 0xbf}, - // Block 0x71, offset 0x394 + // Block 0x70, offset 0x379 {value: 0x0000, lo: 0x04}, {value: 0x0008, lo: 0x80, hi: 0xa5}, - {value: 0x1308, lo: 0xa6, hi: 0xad}, + {value: 0x3308, lo: 0xa6, hi: 0xad}, {value: 0x0018, lo: 0xae, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x72, offset 0x399 + // Block 0x71, offset 0x37e {value: 0x0000, lo: 0x07}, {value: 0x0008, lo: 0x80, hi: 0x86}, - {value: 0x1308, lo: 0x87, hi: 0x91}, - {value: 0x1008, lo: 0x92, hi: 0x92}, - {value: 0x1808, lo: 0x93, hi: 0x93}, + {value: 0x3308, lo: 0x87, hi: 0x91}, + {value: 0x3008, lo: 0x92, hi: 0x92}, + {value: 0x3808, lo: 0x93, hi: 0x93}, {value: 0x0040, lo: 0x94, hi: 0x9e}, {value: 0x0018, lo: 0x9f, hi: 0xbc}, {value: 0x0040, lo: 0xbd, hi: 0xbf}, - // Block 0x73, offset 0x3a1 + // Block 0x72, offset 0x386 {value: 0x0000, lo: 0x09}, - {value: 0x1308, lo: 0x80, hi: 0x82}, - {value: 0x1008, lo: 0x83, hi: 0x83}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, {value: 0x0008, lo: 0x84, hi: 0xb2}, - {value: 0x1308, lo: 0xb3, hi: 0xb3}, - {value: 0x1008, lo: 0xb4, hi: 0xb5}, - {value: 0x1308, lo: 0xb6, hi: 0xb9}, - {value: 0x1008, lo: 0xba, hi: 0xbb}, - {value: 0x1308, lo: 0xbc, hi: 0xbc}, - {value: 0x1008, lo: 0xbd, hi: 0xbf}, - // Block 0x74, offset 0x3ab + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb9}, + {value: 0x3008, lo: 0xba, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x73, offset 0x390 {value: 0x0000, lo: 0x0a}, - {value: 0x1808, lo: 0x80, hi: 0x80}, + {value: 0x3808, lo: 0x80, hi: 0x80}, {value: 0x0018, lo: 0x81, hi: 0x8d}, {value: 0x0040, lo: 0x8e, hi: 0x8e}, {value: 0x0008, lo: 0x8f, hi: 0x99}, {value: 0x0040, lo: 0x9a, hi: 0x9d}, {value: 0x0018, lo: 0x9e, hi: 0x9f}, {value: 0x0008, lo: 0xa0, hi: 0xa4}, - {value: 0x1308, lo: 0xa5, hi: 0xa5}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, {value: 0x0008, lo: 0xa6, hi: 0xbe}, {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0x75, offset 0x3b6 + // Block 0x74, offset 0x39b {value: 0x0000, lo: 0x07}, {value: 0x0008, lo: 0x80, hi: 0xa8}, - {value: 0x1308, lo: 0xa9, hi: 0xae}, - {value: 0x1008, lo: 0xaf, hi: 0xb0}, - {value: 0x1308, lo: 0xb1, hi: 0xb2}, - {value: 0x1008, lo: 0xb3, hi: 0xb4}, - {value: 0x1308, lo: 0xb5, hi: 0xb6}, + {value: 0x3308, lo: 0xa9, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, {value: 0x0040, lo: 0xb7, hi: 0xbf}, - // Block 0x76, offset 0x3be + // Block 0x75, offset 0x3a3 {value: 0x0000, lo: 0x10}, {value: 0x0008, lo: 0x80, hi: 0x82}, - {value: 0x1308, lo: 0x83, hi: 0x83}, + {value: 0x3308, lo: 0x83, hi: 0x83}, {value: 0x0008, lo: 0x84, hi: 0x8b}, - {value: 0x1308, lo: 0x8c, hi: 0x8c}, - {value: 0x1008, lo: 0x8d, hi: 0x8d}, + {value: 0x3308, lo: 0x8c, hi: 0x8c}, + {value: 0x3008, lo: 0x8d, hi: 0x8d}, {value: 0x0040, lo: 0x8e, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x99}, {value: 0x0040, lo: 0x9a, hi: 0x9b}, @@ -3430,38 +3435,38 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0008, lo: 0xa0, hi: 0xb6}, {value: 0x0018, lo: 0xb7, hi: 0xb9}, {value: 0x0008, lo: 0xba, hi: 0xba}, - {value: 0x1008, lo: 0xbb, hi: 0xbb}, - {value: 0x1308, lo: 0xbc, hi: 0xbc}, - {value: 0x1008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbd}, {value: 0x0008, lo: 0xbe, hi: 0xbf}, - // Block 0x77, offset 0x3cf + // Block 0x76, offset 0x3b4 {value: 0x0000, lo: 0x08}, {value: 0x0008, lo: 0x80, hi: 0xaf}, - {value: 0x1308, lo: 0xb0, hi: 0xb0}, + {value: 0x3308, lo: 0xb0, hi: 0xb0}, {value: 0x0008, lo: 0xb1, hi: 0xb1}, - {value: 0x1308, lo: 0xb2, hi: 0xb4}, + {value: 0x3308, lo: 0xb2, hi: 0xb4}, {value: 0x0008, lo: 0xb5, hi: 0xb6}, - {value: 0x1308, lo: 0xb7, hi: 0xb8}, + {value: 0x3308, lo: 0xb7, hi: 0xb8}, {value: 0x0008, lo: 0xb9, hi: 0xbd}, - {value: 0x1308, lo: 0xbe, hi: 0xbf}, - // Block 0x78, offset 0x3d8 + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x77, offset 0x3bd {value: 0x0000, lo: 0x0f}, {value: 0x0008, lo: 0x80, hi: 0x80}, - {value: 0x1308, lo: 0x81, hi: 0x81}, + {value: 0x3308, lo: 0x81, hi: 0x81}, {value: 0x0008, lo: 0x82, hi: 0x82}, {value: 0x0040, lo: 0x83, hi: 0x9a}, {value: 0x0008, lo: 0x9b, hi: 0x9d}, {value: 0x0018, lo: 0x9e, hi: 0x9f}, {value: 0x0008, lo: 0xa0, hi: 0xaa}, - {value: 0x1008, lo: 0xab, hi: 0xab}, - {value: 0x1308, lo: 0xac, hi: 0xad}, - {value: 0x1008, lo: 0xae, hi: 0xaf}, + {value: 0x3008, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, {value: 0x0018, lo: 0xb0, hi: 0xb1}, {value: 0x0008, lo: 0xb2, hi: 0xb4}, - {value: 0x1008, lo: 0xb5, hi: 0xb5}, - {value: 0x1b08, lo: 0xb6, hi: 0xb6}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3b08, lo: 0xb6, hi: 0xb6}, {value: 0x0040, lo: 0xb7, hi: 0xbf}, - // Block 0x79, offset 0x3e8 + // Block 0x78, offset 0x3cd {value: 0x0000, lo: 0x0c}, {value: 0x0040, lo: 0x80, hi: 0x80}, {value: 0x0008, lo: 0x81, hi: 0x86}, @@ -3475,7 +3480,7 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0008, lo: 0xa8, hi: 0xae}, {value: 0x0040, lo: 0xaf, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x7a, offset 0x3f5 + // Block 0x79, offset 0x3da {value: 0x0000, lo: 0x09}, {value: 0x0008, lo: 0x80, hi: 0x9a}, {value: 0x0018, lo: 0x9b, hi: 0x9b}, @@ -3486,54 +3491,54 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0008, lo: 0xa0, hi: 0xa5}, {value: 0x0040, lo: 0xa6, hi: 0xaf}, {value: 0x4495, lo: 0xb0, hi: 0xbf}, - // Block 0x7b, offset 0x3ff + // Block 0x7a, offset 0x3e4 {value: 0x0000, lo: 0x04}, {value: 0x44b5, lo: 0x80, hi: 0x8f}, {value: 0x44d5, lo: 0x90, hi: 0x9f}, {value: 0x44f5, lo: 0xa0, hi: 0xaf}, {value: 0x44d5, lo: 0xb0, hi: 0xbf}, - // Block 0x7c, offset 0x404 + // Block 0x7b, offset 0x3e9 {value: 0x0000, lo: 0x0c}, {value: 0x0008, lo: 0x80, hi: 0xa2}, - {value: 0x1008, lo: 0xa3, hi: 0xa4}, - {value: 0x1308, lo: 0xa5, hi: 0xa5}, - {value: 0x1008, lo: 0xa6, hi: 0xa7}, - {value: 0x1308, lo: 0xa8, hi: 0xa8}, - {value: 0x1008, lo: 0xa9, hi: 0xaa}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xaa}, {value: 0x0018, lo: 0xab, hi: 0xab}, - {value: 0x1008, lo: 0xac, hi: 0xac}, - {value: 0x1b08, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3b08, lo: 0xad, hi: 0xad}, {value: 0x0040, lo: 0xae, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xb9}, {value: 0x0040, lo: 0xba, hi: 0xbf}, - // Block 0x7d, offset 0x411 + // Block 0x7c, offset 0x3f6 {value: 0x0000, lo: 0x03}, {value: 0x0008, lo: 0x80, hi: 0xa3}, {value: 0x0040, lo: 0xa4, hi: 0xaf}, {value: 0x0018, lo: 0xb0, hi: 0xbf}, - // Block 0x7e, offset 0x415 + // Block 0x7d, offset 0x3fa {value: 0x0000, lo: 0x04}, {value: 0x0018, lo: 0x80, hi: 0x86}, {value: 0x0040, lo: 0x87, hi: 0x8a}, {value: 0x0018, lo: 0x8b, hi: 0xbb}, {value: 0x0040, lo: 0xbc, hi: 0xbf}, - // Block 0x7f, offset 0x41a + // Block 0x7e, offset 0x3ff {value: 0x0020, lo: 0x01}, {value: 0x4515, lo: 0x80, hi: 0xbf}, - // Block 0x80, offset 0x41c + // Block 0x7f, offset 0x401 {value: 0x0020, lo: 0x03}, {value: 0x4d15, lo: 0x80, hi: 0x94}, {value: 0x4ad5, lo: 0x95, hi: 0x95}, {value: 0x4fb5, lo: 0x96, hi: 0xbf}, - // Block 0x81, offset 0x420 + // Block 0x80, offset 0x405 {value: 0x0020, lo: 0x01}, {value: 0x54f5, lo: 0x80, hi: 0xbf}, - // Block 0x82, offset 0x422 + // Block 0x81, offset 0x407 {value: 0x0020, lo: 0x03}, {value: 0x5cf5, lo: 0x80, hi: 0x84}, {value: 0x5655, lo: 0x85, hi: 0x85}, {value: 0x5d95, lo: 0x86, hi: 0xbf}, - // Block 0x83, offset 0x426 + // Block 0x82, offset 0x40b {value: 0x0020, lo: 0x08}, {value: 0x6b55, lo: 0x80, hi: 0x8f}, {value: 0x6d15, lo: 0x90, hi: 0x90}, @@ -3543,19 +3548,19 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0xae, hi: 0xae}, {value: 0x0040, lo: 0xaf, hi: 0xaf}, {value: 0x70d5, lo: 0xb0, hi: 0xbf}, - // Block 0x84, offset 0x42f + // Block 0x83, offset 0x414 {value: 0x0020, lo: 0x05}, {value: 0x72d5, lo: 0x80, hi: 0xad}, {value: 0x6535, lo: 0xae, hi: 0xae}, {value: 0x7895, lo: 0xaf, hi: 0xb5}, {value: 0x6f55, lo: 0xb6, hi: 0xb6}, {value: 0x7975, lo: 0xb7, hi: 0xbf}, - // Block 0x85, offset 0x435 + // Block 0x84, offset 0x41a {value: 0x0028, lo: 0x03}, {value: 0x7c21, lo: 0x80, hi: 0x82}, {value: 0x7be1, lo: 0x83, hi: 0x83}, {value: 0x7c99, lo: 0x84, hi: 0xbf}, - // Block 0x86, offset 0x439 + // Block 0x85, offset 0x41e {value: 0x0038, lo: 0x0f}, {value: 0x9db1, lo: 0x80, hi: 0x83}, {value: 0x9e59, lo: 0x84, hi: 0x85}, @@ -3572,7 +3577,7 @@ var idnaSparseValues = [1876]valueRange{ {value: 0xa869, lo: 0xbc, hi: 0xbc}, {value: 0xa7f9, lo: 0xbd, hi: 0xbd}, {value: 0xa8d9, lo: 0xbe, hi: 0xbf}, - // Block 0x87, offset 0x449 + // Block 0x86, offset 0x42e {value: 0x0000, lo: 0x09}, {value: 0x0008, lo: 0x80, hi: 0x8b}, {value: 0x0040, lo: 0x8c, hi: 0x8c}, @@ -3583,24 +3588,24 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0008, lo: 0xbc, hi: 0xbd}, {value: 0x0040, lo: 0xbe, hi: 0xbe}, {value: 0x0008, lo: 0xbf, hi: 0xbf}, - // Block 0x88, offset 0x453 + // Block 0x87, offset 0x438 {value: 0x0000, lo: 0x04}, {value: 0x0008, lo: 0x80, hi: 0x8d}, {value: 0x0040, lo: 0x8e, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x9d}, {value: 0x0040, lo: 0x9e, hi: 0xbf}, - // Block 0x89, offset 0x458 + // Block 0x88, offset 0x43d {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0xba}, {value: 0x0040, lo: 0xbb, hi: 0xbf}, - // Block 0x8a, offset 0x45b + // Block 0x89, offset 0x440 {value: 0x0000, lo: 0x05}, {value: 0x0018, lo: 0x80, hi: 0x82}, {value: 0x0040, lo: 0x83, hi: 0x86}, {value: 0x0018, lo: 0x87, hi: 0xb3}, {value: 0x0040, lo: 0xb4, hi: 0xb6}, {value: 0x0018, lo: 0xb7, hi: 0xbf}, - // Block 0x8b, offset 0x461 + // Block 0x8a, offset 0x446 {value: 0x0000, lo: 0x06}, {value: 0x0018, lo: 0x80, hi: 0x8e}, {value: 0x0040, lo: 0x8f, hi: 0x8f}, @@ -3608,31 +3613,31 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0x9c, hi: 0x9f}, {value: 0x0018, lo: 0xa0, hi: 0xa0}, {value: 0x0040, lo: 0xa1, hi: 0xbf}, - // Block 0x8c, offset 0x468 + // Block 0x8b, offset 0x44d {value: 0x0000, lo: 0x04}, {value: 0x0040, lo: 0x80, hi: 0x8f}, {value: 0x0018, lo: 0x90, hi: 0xbc}, - {value: 0x1308, lo: 0xbd, hi: 0xbd}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, {value: 0x0040, lo: 0xbe, hi: 0xbf}, - // Block 0x8d, offset 0x46d + // Block 0x8c, offset 0x452 {value: 0x0000, lo: 0x03}, {value: 0x0008, lo: 0x80, hi: 0x9c}, {value: 0x0040, lo: 0x9d, hi: 0x9f}, {value: 0x0008, lo: 0xa0, hi: 0xbf}, - // Block 0x8e, offset 0x471 + // Block 0x8d, offset 0x456 {value: 0x0000, lo: 0x05}, {value: 0x0008, lo: 0x80, hi: 0x90}, {value: 0x0040, lo: 0x91, hi: 0x9f}, - {value: 0x1308, lo: 0xa0, hi: 0xa0}, + {value: 0x3308, lo: 0xa0, hi: 0xa0}, {value: 0x0018, lo: 0xa1, hi: 0xbb}, {value: 0x0040, lo: 0xbc, hi: 0xbf}, - // Block 0x8f, offset 0x477 + // Block 0x8e, offset 0x45c {value: 0x0000, lo: 0x04}, {value: 0x0008, lo: 0x80, hi: 0x9f}, {value: 0x0018, lo: 0xa0, hi: 0xa3}, - {value: 0x0040, lo: 0xa4, hi: 0xaf}, - {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x90, offset 0x47c + {value: 0x0040, lo: 0xa4, hi: 0xac}, + {value: 0x0008, lo: 0xad, hi: 0xbf}, + // Block 0x8f, offset 0x461 {value: 0x0000, lo: 0x08}, {value: 0x0008, lo: 0x80, hi: 0x80}, {value: 0x0018, lo: 0x81, hi: 0x81}, @@ -3640,22 +3645,22 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0018, lo: 0x8a, hi: 0x8a}, {value: 0x0040, lo: 0x8b, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0xb5}, - {value: 0x1308, lo: 0xb6, hi: 0xba}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, {value: 0x0040, lo: 0xbb, hi: 0xbf}, - // Block 0x91, offset 0x485 + // Block 0x90, offset 0x46a {value: 0x0000, lo: 0x04}, {value: 0x0008, lo: 0x80, hi: 0x9d}, {value: 0x0040, lo: 0x9e, hi: 0x9e}, {value: 0x0018, lo: 0x9f, hi: 0x9f}, {value: 0x0008, lo: 0xa0, hi: 0xbf}, - // Block 0x92, offset 0x48a + // Block 0x91, offset 0x46f {value: 0x0000, lo: 0x05}, {value: 0x0008, lo: 0x80, hi: 0x83}, {value: 0x0040, lo: 0x84, hi: 0x87}, {value: 0x0008, lo: 0x88, hi: 0x8f}, {value: 0x0018, lo: 0x90, hi: 0x95}, {value: 0x0040, lo: 0x96, hi: 0xbf}, - // Block 0x93, offset 0x490 + // Block 0x92, offset 0x475 {value: 0x0000, lo: 0x06}, {value: 0xe145, lo: 0x80, hi: 0x87}, {value: 0xe1c5, lo: 0x88, hi: 0x8f}, @@ -3663,7 +3668,7 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x8ad5, lo: 0x98, hi: 0x9f}, {value: 0x8aed, lo: 0xa0, hi: 0xa7}, {value: 0x0008, lo: 0xa8, hi: 0xbf}, - // Block 0x94, offset 0x497 + // Block 0x93, offset 0x47c {value: 0x0000, lo: 0x06}, {value: 0x0008, lo: 0x80, hi: 0x9d}, {value: 0x0040, lo: 0x9e, hi: 0x9f}, @@ -3671,7 +3676,7 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0xaa, hi: 0xaf}, {value: 0x8aed, lo: 0xb0, hi: 0xb7}, {value: 0x8ad5, lo: 0xb8, hi: 0xbf}, - // Block 0x95, offset 0x49e + // Block 0x94, offset 0x483 {value: 0x0000, lo: 0x06}, {value: 0xe145, lo: 0x80, hi: 0x87}, {value: 0xe1c5, lo: 0x88, hi: 0x8f}, @@ -3679,173 +3684,176 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0x94, hi: 0x97}, {value: 0x0008, lo: 0x98, hi: 0xbb}, {value: 0x0040, lo: 0xbc, hi: 0xbf}, - // Block 0x96, offset 0x4a5 + // Block 0x95, offset 0x48a {value: 0x0000, lo: 0x03}, {value: 0x0008, lo: 0x80, hi: 0xa7}, {value: 0x0040, lo: 0xa8, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0x97, offset 0x4a9 + // Block 0x96, offset 0x48e {value: 0x0000, lo: 0x04}, {value: 0x0008, lo: 0x80, hi: 0xa3}, {value: 0x0040, lo: 0xa4, hi: 0xae}, {value: 0x0018, lo: 0xaf, hi: 0xaf}, {value: 0x0040, lo: 0xb0, hi: 0xbf}, - // Block 0x98, offset 0x4ae + // Block 0x97, offset 0x493 {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0xb6}, {value: 0x0040, lo: 0xb7, hi: 0xbf}, - // Block 0x99, offset 0x4b1 + // Block 0x98, offset 0x496 {value: 0x0000, lo: 0x04}, {value: 0x0008, lo: 0x80, hi: 0x95}, {value: 0x0040, lo: 0x96, hi: 0x9f}, {value: 0x0008, lo: 0xa0, hi: 0xa7}, {value: 0x0040, lo: 0xa8, hi: 0xbf}, - // Block 0x9a, offset 0x4b6 + // Block 0x99, offset 0x49b {value: 0x0000, lo: 0x0b}, - {value: 0x0008, lo: 0x80, hi: 0x85}, + {value: 0x0808, lo: 0x80, hi: 0x85}, {value: 0x0040, lo: 0x86, hi: 0x87}, - {value: 0x0008, lo: 0x88, hi: 0x88}, + {value: 0x0808, lo: 0x88, hi: 0x88}, {value: 0x0040, lo: 0x89, hi: 0x89}, - {value: 0x0008, lo: 0x8a, hi: 0xb5}, + {value: 0x0808, lo: 0x8a, hi: 0xb5}, {value: 0x0040, lo: 0xb6, hi: 0xb6}, - {value: 0x0008, lo: 0xb7, hi: 0xb8}, + {value: 0x0808, lo: 0xb7, hi: 0xb8}, {value: 0x0040, lo: 0xb9, hi: 0xbb}, - {value: 0x0008, lo: 0xbc, hi: 0xbc}, + {value: 0x0808, lo: 0xbc, hi: 0xbc}, {value: 0x0040, lo: 0xbd, hi: 0xbe}, - {value: 0x0008, lo: 0xbf, hi: 0xbf}, - // Block 0x9b, offset 0x4c2 + {value: 0x0808, lo: 0xbf, hi: 0xbf}, + // Block 0x9a, offset 0x4a7 {value: 0x0000, lo: 0x05}, - {value: 0x0008, lo: 0x80, hi: 0x95}, + {value: 0x0808, lo: 0x80, hi: 0x95}, {value: 0x0040, lo: 0x96, hi: 0x96}, - {value: 0x0018, lo: 0x97, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xb6}, - {value: 0x0018, lo: 0xb7, hi: 0xbf}, - // Block 0x9c, offset 0x4c8 + {value: 0x0818, lo: 0x97, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb6}, + {value: 0x0818, lo: 0xb7, hi: 0xbf}, + // Block 0x9b, offset 0x4ad {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0808, lo: 0x80, hi: 0x9e}, {value: 0x0040, lo: 0x9f, hi: 0xa6}, - {value: 0x0018, lo: 0xa7, hi: 0xaf}, + {value: 0x0818, lo: 0xa7, hi: 0xaf}, {value: 0x0040, lo: 0xb0, hi: 0xbf}, - // Block 0x9d, offset 0x4cd + // Block 0x9c, offset 0x4b2 {value: 0x0000, lo: 0x06}, {value: 0x0040, lo: 0x80, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xb2}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, {value: 0x0040, lo: 0xb3, hi: 0xb3}, - {value: 0x0008, lo: 0xb4, hi: 0xb5}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, {value: 0x0040, lo: 0xb6, hi: 0xba}, - {value: 0x0018, lo: 0xbb, hi: 0xbf}, - // Block 0x9e, offset 0x4d4 + {value: 0x0818, lo: 0xbb, hi: 0xbf}, + // Block 0x9d, offset 0x4b9 {value: 0x0000, lo: 0x07}, - {value: 0x0008, lo: 0x80, hi: 0x95}, - {value: 0x0018, lo: 0x96, hi: 0x9b}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0818, lo: 0x96, hi: 0x9b}, {value: 0x0040, lo: 0x9c, hi: 0x9e}, {value: 0x0018, lo: 0x9f, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xb9}, + {value: 0x0808, lo: 0xa0, hi: 0xb9}, {value: 0x0040, lo: 0xba, hi: 0xbe}, - {value: 0x0018, lo: 0xbf, hi: 0xbf}, - // Block 0x9f, offset 0x4dc + {value: 0x0818, lo: 0xbf, hi: 0xbf}, + // Block 0x9e, offset 0x4c1 {value: 0x0000, lo: 0x04}, - {value: 0x0008, lo: 0x80, hi: 0xb7}, + {value: 0x0808, lo: 0x80, hi: 0xb7}, {value: 0x0040, lo: 0xb8, hi: 0xbb}, - {value: 0x0018, lo: 0xbc, hi: 0xbd}, - {value: 0x0008, lo: 0xbe, hi: 0xbf}, - // Block 0xa0, offset 0x4e1 + {value: 0x0818, lo: 0xbc, hi: 0xbd}, + {value: 0x0808, lo: 0xbe, hi: 0xbf}, + // Block 0x9f, offset 0x4c6 {value: 0x0000, lo: 0x03}, - {value: 0x0018, lo: 0x80, hi: 0x8f}, + {value: 0x0818, lo: 0x80, hi: 0x8f}, {value: 0x0040, lo: 0x90, hi: 0x91}, - {value: 0x0018, lo: 0x92, hi: 0xbf}, - // Block 0xa1, offset 0x4e5 + {value: 0x0818, lo: 0x92, hi: 0xbf}, + // Block 0xa0, offset 0x4ca {value: 0x0000, lo: 0x0f}, - {value: 0x0008, lo: 0x80, hi: 0x80}, - {value: 0x1308, lo: 0x81, hi: 0x83}, + {value: 0x0808, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x83}, {value: 0x0040, lo: 0x84, hi: 0x84}, - {value: 0x1308, lo: 0x85, hi: 0x86}, + {value: 0x3308, lo: 0x85, hi: 0x86}, {value: 0x0040, lo: 0x87, hi: 0x8b}, - {value: 0x1308, lo: 0x8c, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x93}, + {value: 0x3308, lo: 0x8c, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x93}, {value: 0x0040, lo: 0x94, hi: 0x94}, - {value: 0x0008, lo: 0x95, hi: 0x97}, + {value: 0x0808, lo: 0x95, hi: 0x97}, {value: 0x0040, lo: 0x98, hi: 0x98}, - {value: 0x0008, lo: 0x99, hi: 0xb3}, + {value: 0x0808, lo: 0x99, hi: 0xb3}, {value: 0x0040, lo: 0xb4, hi: 0xb7}, - {value: 0x1308, lo: 0xb8, hi: 0xba}, + {value: 0x3308, lo: 0xb8, hi: 0xba}, {value: 0x0040, lo: 0xbb, hi: 0xbe}, - {value: 0x1b08, lo: 0xbf, hi: 0xbf}, - // Block 0xa2, offset 0x4f5 + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xa1, offset 0x4da {value: 0x0000, lo: 0x06}, - {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0818, lo: 0x80, hi: 0x87}, {value: 0x0040, lo: 0x88, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0x98}, + {value: 0x0818, lo: 0x90, hi: 0x98}, {value: 0x0040, lo: 0x99, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xbc}, - {value: 0x0018, lo: 0xbd, hi: 0xbf}, - // Block 0xa3, offset 0x4fc + {value: 0x0808, lo: 0xa0, hi: 0xbc}, + {value: 0x0818, lo: 0xbd, hi: 0xbf}, + // Block 0xa2, offset 0x4e1 {value: 0x0000, lo: 0x03}, - {value: 0x0008, lo: 0x80, hi: 0x9c}, - {value: 0x0018, lo: 0x9d, hi: 0x9f}, + {value: 0x0808, lo: 0x80, hi: 0x9c}, + {value: 0x0818, lo: 0x9d, hi: 0x9f}, {value: 0x0040, lo: 0xa0, hi: 0xbf}, - // Block 0xa4, offset 0x500 + // Block 0xa3, offset 0x4e5 {value: 0x0000, lo: 0x03}, - {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0808, lo: 0x80, hi: 0xb5}, {value: 0x0040, lo: 0xb6, hi: 0xb8}, {value: 0x0018, lo: 0xb9, hi: 0xbf}, - // Block 0xa5, offset 0x504 + // Block 0xa4, offset 0x4e9 {value: 0x0000, lo: 0x06}, - {value: 0x0008, lo: 0x80, hi: 0x95}, + {value: 0x0808, lo: 0x80, hi: 0x95}, {value: 0x0040, lo: 0x96, hi: 0x97}, - {value: 0x0018, lo: 0x98, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xb2}, + {value: 0x0818, lo: 0x98, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, {value: 0x0040, lo: 0xb3, hi: 0xb7}, - {value: 0x0018, lo: 0xb8, hi: 0xbf}, - // Block 0xa6, offset 0x50b + {value: 0x0818, lo: 0xb8, hi: 0xbf}, + // Block 0xa5, offset 0x4f0 + {value: 0x0000, lo: 0x01}, + {value: 0x0808, lo: 0x80, hi: 0xbf}, + // Block 0xa6, offset 0x4f2 {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0808, lo: 0x80, hi: 0x88}, {value: 0x0040, lo: 0x89, hi: 0xbf}, - // Block 0xa7, offset 0x50e + // Block 0xa7, offset 0x4f5 {value: 0x0000, lo: 0x02}, {value: 0x03dd, lo: 0x80, hi: 0xb2}, {value: 0x0040, lo: 0xb3, hi: 0xbf}, - // Block 0xa8, offset 0x511 + // Block 0xa8, offset 0x4f8 {value: 0x0000, lo: 0x03}, - {value: 0x0008, lo: 0x80, hi: 0xb2}, + {value: 0x0808, lo: 0x80, hi: 0xb2}, {value: 0x0040, lo: 0xb3, hi: 0xb9}, - {value: 0x0018, lo: 0xba, hi: 0xbf}, - // Block 0xa9, offset 0x515 + {value: 0x0818, lo: 0xba, hi: 0xbf}, + // Block 0xa9, offset 0x4fc {value: 0x0000, lo: 0x03}, {value: 0x0040, lo: 0x80, hi: 0x9f}, - {value: 0x0018, lo: 0xa0, hi: 0xbe}, + {value: 0x0818, lo: 0xa0, hi: 0xbe}, {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0xaa, offset 0x519 + // Block 0xaa, offset 0x500 {value: 0x0000, lo: 0x05}, - {value: 0x1008, lo: 0x80, hi: 0x80}, - {value: 0x1308, lo: 0x81, hi: 0x81}, - {value: 0x1008, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, {value: 0x0008, lo: 0x83, hi: 0xb7}, - {value: 0x1308, lo: 0xb8, hi: 0xbf}, - // Block 0xab, offset 0x51f + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xab, offset 0x506 {value: 0x0000, lo: 0x08}, - {value: 0x1308, lo: 0x80, hi: 0x85}, - {value: 0x1b08, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x80, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, {value: 0x0018, lo: 0x87, hi: 0x8d}, {value: 0x0040, lo: 0x8e, hi: 0x91}, {value: 0x0018, lo: 0x92, hi: 0xa5}, {value: 0x0008, lo: 0xa6, hi: 0xaf}, {value: 0x0040, lo: 0xb0, hi: 0xbe}, - {value: 0x1b08, lo: 0xbf, hi: 0xbf}, - // Block 0xac, offset 0x528 + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xac, offset 0x50f {value: 0x0000, lo: 0x0b}, - {value: 0x1308, lo: 0x80, hi: 0x81}, - {value: 0x1008, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, {value: 0x0008, lo: 0x83, hi: 0xaf}, - {value: 0x1008, lo: 0xb0, hi: 0xb2}, - {value: 0x1308, lo: 0xb3, hi: 0xb6}, - {value: 0x1008, lo: 0xb7, hi: 0xb8}, - {value: 0x1b08, lo: 0xb9, hi: 0xb9}, - {value: 0x1308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb6}, + {value: 0x3008, lo: 0xb7, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, {value: 0x0018, lo: 0xbb, hi: 0xbc}, {value: 0x0340, lo: 0xbd, hi: 0xbd}, {value: 0x0018, lo: 0xbe, hi: 0xbf}, - // Block 0xad, offset 0x534 + // Block 0xad, offset 0x51b {value: 0x0000, lo: 0x06}, {value: 0x0018, lo: 0x80, hi: 0x81}, {value: 0x0040, lo: 0x82, hi: 0x8f}, @@ -3853,39 +3861,39 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0xa9, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xb9}, {value: 0x0040, lo: 0xba, hi: 0xbf}, - // Block 0xae, offset 0x53b + // Block 0xae, offset 0x522 {value: 0x0000, lo: 0x08}, - {value: 0x1308, lo: 0x80, hi: 0x82}, + {value: 0x3308, lo: 0x80, hi: 0x82}, {value: 0x0008, lo: 0x83, hi: 0xa6}, - {value: 0x1308, lo: 0xa7, hi: 0xab}, - {value: 0x1008, lo: 0xac, hi: 0xac}, - {value: 0x1308, lo: 0xad, hi: 0xb2}, - {value: 0x1b08, lo: 0xb3, hi: 0xb4}, + {value: 0x3308, lo: 0xa7, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb2}, + {value: 0x3b08, lo: 0xb3, hi: 0xb4}, {value: 0x0040, lo: 0xb5, hi: 0xb5}, {value: 0x0008, lo: 0xb6, hi: 0xbf}, - // Block 0xaf, offset 0x544 + // Block 0xaf, offset 0x52b {value: 0x0000, lo: 0x07}, {value: 0x0018, lo: 0x80, hi: 0x83}, {value: 0x0040, lo: 0x84, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0xb2}, - {value: 0x1308, lo: 0xb3, hi: 0xb3}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, {value: 0x0018, lo: 0xb4, hi: 0xb5}, {value: 0x0008, lo: 0xb6, hi: 0xb6}, {value: 0x0040, lo: 0xb7, hi: 0xbf}, - // Block 0xb0, offset 0x54c + // Block 0xb0, offset 0x533 {value: 0x0000, lo: 0x06}, - {value: 0x1308, lo: 0x80, hi: 0x81}, - {value: 0x1008, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, {value: 0x0008, lo: 0x83, hi: 0xb2}, - {value: 0x1008, lo: 0xb3, hi: 0xb5}, - {value: 0x1308, lo: 0xb6, hi: 0xbe}, - {value: 0x1008, lo: 0xbf, hi: 0xbf}, - // Block 0xb1, offset 0x553 + {value: 0x3008, lo: 0xb3, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xbe}, + {value: 0x3008, lo: 0xbf, hi: 0xbf}, + // Block 0xb1, offset 0x53a {value: 0x0000, lo: 0x0d}, - {value: 0x1808, lo: 0x80, hi: 0x80}, + {value: 0x3808, lo: 0x80, hi: 0x80}, {value: 0x0008, lo: 0x81, hi: 0x84}, {value: 0x0018, lo: 0x85, hi: 0x89}, - {value: 0x1308, lo: 0x8a, hi: 0x8c}, + {value: 0x3308, lo: 0x8a, hi: 0x8c}, {value: 0x0018, lo: 0x8d, hi: 0x8d}, {value: 0x0040, lo: 0x8e, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x9a}, @@ -3895,21 +3903,21 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0xa0, hi: 0xa0}, {value: 0x0018, lo: 0xa1, hi: 0xb4}, {value: 0x0040, lo: 0xb5, hi: 0xbf}, - // Block 0xb2, offset 0x561 + // Block 0xb2, offset 0x548 {value: 0x0000, lo: 0x0c}, {value: 0x0008, lo: 0x80, hi: 0x91}, {value: 0x0040, lo: 0x92, hi: 0x92}, {value: 0x0008, lo: 0x93, hi: 0xab}, - {value: 0x1008, lo: 0xac, hi: 0xae}, - {value: 0x1308, lo: 0xaf, hi: 0xb1}, - {value: 0x1008, lo: 0xb2, hi: 0xb3}, - {value: 0x1308, lo: 0xb4, hi: 0xb4}, - {value: 0x1808, lo: 0xb5, hi: 0xb5}, - {value: 0x1308, lo: 0xb6, hi: 0xb7}, + {value: 0x3008, lo: 0xac, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3808, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, {value: 0x0018, lo: 0xb8, hi: 0xbd}, - {value: 0x1308, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbe, hi: 0xbe}, {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0xb3, offset 0x56e + // Block 0xb3, offset 0x555 {value: 0x0000, lo: 0x0c}, {value: 0x0008, lo: 0x80, hi: 0x86}, {value: 0x0040, lo: 0x87, hi: 0x87}, @@ -3923,28 +3931,28 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0018, lo: 0xa9, hi: 0xa9}, {value: 0x0040, lo: 0xaa, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xbf}, - // Block 0xb4, offset 0x57b + // Block 0xb4, offset 0x562 {value: 0x0000, lo: 0x08}, {value: 0x0008, lo: 0x80, hi: 0x9e}, - {value: 0x1308, lo: 0x9f, hi: 0x9f}, - {value: 0x1008, lo: 0xa0, hi: 0xa2}, - {value: 0x1308, lo: 0xa3, hi: 0xa9}, - {value: 0x1b08, lo: 0xaa, hi: 0xaa}, + {value: 0x3308, lo: 0x9f, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa9}, + {value: 0x3b08, lo: 0xaa, hi: 0xaa}, {value: 0x0040, lo: 0xab, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xb9}, {value: 0x0040, lo: 0xba, hi: 0xbf}, - // Block 0xb5, offset 0x584 + // Block 0xb5, offset 0x56b {value: 0x0000, lo: 0x03}, {value: 0x0008, lo: 0x80, hi: 0xb4}, - {value: 0x1008, lo: 0xb5, hi: 0xb7}, - {value: 0x1308, lo: 0xb8, hi: 0xbf}, - // Block 0xb6, offset 0x588 + {value: 0x3008, lo: 0xb5, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xb6, offset 0x56f {value: 0x0000, lo: 0x0d}, - {value: 0x1008, lo: 0x80, hi: 0x81}, - {value: 0x1b08, lo: 0x82, hi: 0x82}, - {value: 0x1308, lo: 0x83, hi: 0x84}, - {value: 0x1008, lo: 0x85, hi: 0x85}, - {value: 0x1308, lo: 0x86, hi: 0x86}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x84}, + {value: 0x3008, lo: 0x85, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, {value: 0x0008, lo: 0x87, hi: 0x8a}, {value: 0x0018, lo: 0x8b, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x99}, @@ -3953,56 +3961,56 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0x9c, hi: 0x9c}, {value: 0x0018, lo: 0x9d, hi: 0x9d}, {value: 0x0040, lo: 0x9e, hi: 0xbf}, - // Block 0xb7, offset 0x596 + // Block 0xb7, offset 0x57d {value: 0x0000, lo: 0x07}, {value: 0x0008, lo: 0x80, hi: 0xaf}, - {value: 0x1008, lo: 0xb0, hi: 0xb2}, - {value: 0x1308, lo: 0xb3, hi: 0xb8}, - {value: 0x1008, lo: 0xb9, hi: 0xb9}, - {value: 0x1308, lo: 0xba, hi: 0xba}, - {value: 0x1008, lo: 0xbb, hi: 0xbe}, - {value: 0x1308, lo: 0xbf, hi: 0xbf}, - // Block 0xb8, offset 0x59e + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb8}, + {value: 0x3008, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0xb8, offset 0x585 {value: 0x0000, lo: 0x0a}, - {value: 0x1308, lo: 0x80, hi: 0x80}, - {value: 0x1008, lo: 0x81, hi: 0x81}, - {value: 0x1b08, lo: 0x82, hi: 0x82}, - {value: 0x1308, lo: 0x83, hi: 0x83}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, {value: 0x0008, lo: 0x84, hi: 0x85}, {value: 0x0018, lo: 0x86, hi: 0x86}, {value: 0x0008, lo: 0x87, hi: 0x87}, {value: 0x0040, lo: 0x88, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x99}, {value: 0x0040, lo: 0x9a, hi: 0xbf}, - // Block 0xb9, offset 0x5a9 + // Block 0xb9, offset 0x590 {value: 0x0000, lo: 0x08}, {value: 0x0008, lo: 0x80, hi: 0xae}, - {value: 0x1008, lo: 0xaf, hi: 0xb1}, - {value: 0x1308, lo: 0xb2, hi: 0xb5}, + {value: 0x3008, lo: 0xaf, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb5}, {value: 0x0040, lo: 0xb6, hi: 0xb7}, - {value: 0x1008, lo: 0xb8, hi: 0xbb}, - {value: 0x1308, lo: 0xbc, hi: 0xbd}, - {value: 0x1008, lo: 0xbe, hi: 0xbe}, - {value: 0x1b08, lo: 0xbf, hi: 0xbf}, - // Block 0xba, offset 0x5b2 + {value: 0x3008, lo: 0xb8, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xba, offset 0x599 {value: 0x0000, lo: 0x05}, - {value: 0x1308, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x80, hi: 0x80}, {value: 0x0018, lo: 0x81, hi: 0x97}, {value: 0x0008, lo: 0x98, hi: 0x9b}, - {value: 0x1308, lo: 0x9c, hi: 0x9d}, + {value: 0x3308, lo: 0x9c, hi: 0x9d}, {value: 0x0040, lo: 0x9e, hi: 0xbf}, - // Block 0xbb, offset 0x5b8 + // Block 0xbb, offset 0x59f {value: 0x0000, lo: 0x07}, {value: 0x0008, lo: 0x80, hi: 0xaf}, - {value: 0x1008, lo: 0xb0, hi: 0xb2}, - {value: 0x1308, lo: 0xb3, hi: 0xba}, - {value: 0x1008, lo: 0xbb, hi: 0xbc}, - {value: 0x1308, lo: 0xbd, hi: 0xbd}, - {value: 0x1008, lo: 0xbe, hi: 0xbe}, - {value: 0x1b08, lo: 0xbf, hi: 0xbf}, - // Block 0xbc, offset 0x5c0 + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xbc, offset 0x5a7 {value: 0x0000, lo: 0x08}, - {value: 0x1308, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x80, hi: 0x80}, {value: 0x0018, lo: 0x81, hi: 0x83}, {value: 0x0008, lo: 0x84, hi: 0x84}, {value: 0x0040, lo: 0x85, hi: 0x8f}, @@ -4010,60 +4018,97 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0x9a, hi: 0x9f}, {value: 0x0018, lo: 0xa0, hi: 0xac}, {value: 0x0040, lo: 0xad, hi: 0xbf}, - // Block 0xbd, offset 0x5c9 + // Block 0xbd, offset 0x5b0 {value: 0x0000, lo: 0x09}, {value: 0x0008, lo: 0x80, hi: 0xaa}, - {value: 0x1308, lo: 0xab, hi: 0xab}, - {value: 0x1008, lo: 0xac, hi: 0xac}, - {value: 0x1308, lo: 0xad, hi: 0xad}, - {value: 0x1008, lo: 0xae, hi: 0xaf}, - {value: 0x1308, lo: 0xb0, hi: 0xb5}, - {value: 0x1808, lo: 0xb6, hi: 0xb6}, - {value: 0x1308, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb5}, + {value: 0x3808, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, {value: 0x0040, lo: 0xb8, hi: 0xbf}, - // Block 0xbe, offset 0x5d3 + // Block 0xbe, offset 0x5ba {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0x89}, {value: 0x0040, lo: 0x8a, hi: 0xbf}, - // Block 0xbf, offset 0x5d6 + // Block 0xbf, offset 0x5bd {value: 0x0000, lo: 0x0b}, {value: 0x0008, lo: 0x80, hi: 0x99}, {value: 0x0040, lo: 0x9a, hi: 0x9c}, - {value: 0x1308, lo: 0x9d, hi: 0x9f}, - {value: 0x1008, lo: 0xa0, hi: 0xa1}, - {value: 0x1308, lo: 0xa2, hi: 0xa5}, - {value: 0x1008, lo: 0xa6, hi: 0xa6}, - {value: 0x1308, lo: 0xa7, hi: 0xaa}, - {value: 0x1b08, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, {value: 0x0040, lo: 0xac, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xb9}, {value: 0x0018, lo: 0xba, hi: 0xbf}, - // Block 0xc0, offset 0x5e2 + // Block 0xc0, offset 0x5c9 {value: 0x0000, lo: 0x02}, {value: 0x0040, lo: 0x80, hi: 0x9f}, {value: 0x049d, lo: 0xa0, hi: 0xbf}, - // Block 0xc1, offset 0x5e5 + // Block 0xc1, offset 0x5cc {value: 0x0000, lo: 0x04}, {value: 0x0008, lo: 0x80, hi: 0xa9}, {value: 0x0018, lo: 0xaa, hi: 0xb2}, {value: 0x0040, lo: 0xb3, hi: 0xbe}, {value: 0x0008, lo: 0xbf, hi: 0xbf}, - // Block 0xc2, offset 0x5ea + // Block 0xc2, offset 0x5d1 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x88}, + {value: 0x3308, lo: 0x89, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x3b08, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb8}, + {value: 0x3008, lo: 0xb9, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0xc3, offset 0x5de + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x3b08, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x3308, lo: 0x91, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0xbf}, + // Block 0xc4, offset 0x5e7 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x89}, + {value: 0x3308, lo: 0x8a, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x98}, + {value: 0x3b08, lo: 0x99, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0xa2}, + {value: 0x0040, lo: 0xa3, hi: 0xbf}, + // Block 0xc5, offset 0x5f3 {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0xb8}, {value: 0x0040, lo: 0xb9, hi: 0xbf}, - // Block 0xc3, offset 0x5ed + // Block 0xc6, offset 0x5f6 {value: 0x0000, lo: 0x09}, {value: 0x0008, lo: 0x80, hi: 0x88}, {value: 0x0040, lo: 0x89, hi: 0x89}, {value: 0x0008, lo: 0x8a, hi: 0xae}, - {value: 0x1008, lo: 0xaf, hi: 0xaf}, - {value: 0x1308, lo: 0xb0, hi: 0xb6}, + {value: 0x3008, lo: 0xaf, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, {value: 0x0040, lo: 0xb7, hi: 0xb7}, - {value: 0x1308, lo: 0xb8, hi: 0xbd}, - {value: 0x1008, lo: 0xbe, hi: 0xbe}, - {value: 0x1b08, lo: 0xbf, hi: 0xbf}, - // Block 0xc4, offset 0x5f7 + {value: 0x3308, lo: 0xb8, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xc7, offset 0x600 {value: 0x0000, lo: 0x08}, {value: 0x0008, lo: 0x80, hi: 0x80}, {value: 0x0018, lo: 0x81, hi: 0x85}, @@ -4073,42 +4118,65 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0xad, hi: 0xaf}, {value: 0x0018, lo: 0xb0, hi: 0xb1}, {value: 0x0008, lo: 0xb2, hi: 0xbf}, - // Block 0xc5, offset 0x600 + // Block 0xc8, offset 0x609 {value: 0x0000, lo: 0x0b}, {value: 0x0008, lo: 0x80, hi: 0x8f}, {value: 0x0040, lo: 0x90, hi: 0x91}, - {value: 0x1308, lo: 0x92, hi: 0xa7}, + {value: 0x3308, lo: 0x92, hi: 0xa7}, {value: 0x0040, lo: 0xa8, hi: 0xa8}, - {value: 0x1008, lo: 0xa9, hi: 0xa9}, - {value: 0x1308, lo: 0xaa, hi: 0xb0}, - {value: 0x1008, lo: 0xb1, hi: 0xb1}, - {value: 0x1308, lo: 0xb2, hi: 0xb3}, - {value: 0x1008, lo: 0xb4, hi: 0xb4}, - {value: 0x1308, lo: 0xb5, hi: 0xb6}, + {value: 0x3008, lo: 0xa9, hi: 0xa9}, + {value: 0x3308, lo: 0xaa, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, {value: 0x0040, lo: 0xb7, hi: 0xbf}, - // Block 0xc6, offset 0x60c + // Block 0xc9, offset 0x615 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0xca, offset 0x622 + {value: 0x0000, lo: 0x07}, + {value: 0x3308, lo: 0x80, hi: 0x83}, + {value: 0x3b08, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xcb, offset 0x62a {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0x99}, {value: 0x0040, lo: 0x9a, hi: 0xbf}, - // Block 0xc7, offset 0x60f + // Block 0xcc, offset 0x62d {value: 0x0000, lo: 0x04}, {value: 0x0018, lo: 0x80, hi: 0xae}, {value: 0x0040, lo: 0xaf, hi: 0xaf}, {value: 0x0018, lo: 0xb0, hi: 0xb4}, {value: 0x0040, lo: 0xb5, hi: 0xbf}, - // Block 0xc8, offset 0x614 + // Block 0xcd, offset 0x632 {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0x83}, {value: 0x0040, lo: 0x84, hi: 0xbf}, - // Block 0xc9, offset 0x617 + // Block 0xce, offset 0x635 {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0xae}, {value: 0x0040, lo: 0xaf, hi: 0xbf}, - // Block 0xca, offset 0x61a + // Block 0xcf, offset 0x638 {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0x86}, {value: 0x0040, lo: 0x87, hi: 0xbf}, - // Block 0xcb, offset 0x61d + // Block 0xd0, offset 0x63b {value: 0x0000, lo: 0x06}, {value: 0x0008, lo: 0x80, hi: 0x9e}, {value: 0x0040, lo: 0x9f, hi: 0x9f}, @@ -4116,20 +4184,20 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0xaa, hi: 0xad}, {value: 0x0018, lo: 0xae, hi: 0xaf}, {value: 0x0040, lo: 0xb0, hi: 0xbf}, - // Block 0xcc, offset 0x624 + // Block 0xd1, offset 0x642 {value: 0x0000, lo: 0x06}, {value: 0x0040, lo: 0x80, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0xad}, {value: 0x0040, lo: 0xae, hi: 0xaf}, - {value: 0x1308, lo: 0xb0, hi: 0xb4}, + {value: 0x3308, lo: 0xb0, hi: 0xb4}, {value: 0x0018, lo: 0xb5, hi: 0xb5}, {value: 0x0040, lo: 0xb6, hi: 0xbf}, - // Block 0xcd, offset 0x62b + // Block 0xd2, offset 0x649 {value: 0x0000, lo: 0x03}, {value: 0x0008, lo: 0x80, hi: 0xaf}, - {value: 0x1308, lo: 0xb0, hi: 0xb6}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, {value: 0x0018, lo: 0xb7, hi: 0xbf}, - // Block 0xce, offset 0x62f + // Block 0xd3, offset 0x64d {value: 0x0000, lo: 0x0a}, {value: 0x0008, lo: 0x80, hi: 0x83}, {value: 0x0018, lo: 0x84, hi: 0x85}, @@ -4141,67 +4209,75 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0008, lo: 0xa3, hi: 0xb7}, {value: 0x0040, lo: 0xb8, hi: 0xbc}, {value: 0x0008, lo: 0xbd, hi: 0xbf}, - // Block 0xcf, offset 0x63a + // Block 0xd4, offset 0x658 {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0x8f}, {value: 0x0040, lo: 0x90, hi: 0xbf}, - // Block 0xd0, offset 0x63d + // Block 0xd5, offset 0x65b {value: 0x0000, lo: 0x05}, {value: 0x0008, lo: 0x80, hi: 0x84}, {value: 0x0040, lo: 0x85, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x90}, - {value: 0x1008, lo: 0x91, hi: 0xbe}, + {value: 0x3008, lo: 0x91, hi: 0xbe}, {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0xd1, offset 0x643 + // Block 0xd6, offset 0x661 {value: 0x0000, lo: 0x04}, {value: 0x0040, lo: 0x80, hi: 0x8e}, - {value: 0x1308, lo: 0x8f, hi: 0x92}, + {value: 0x3308, lo: 0x8f, hi: 0x92}, {value: 0x0008, lo: 0x93, hi: 0x9f}, {value: 0x0040, lo: 0xa0, hi: 0xbf}, - // Block 0xd2, offset 0x648 + // Block 0xd7, offset 0x666 {value: 0x0000, lo: 0x03}, {value: 0x0040, lo: 0x80, hi: 0x9f}, - {value: 0x0008, lo: 0xa0, hi: 0xa0}, - {value: 0x0040, lo: 0xa1, hi: 0xbf}, - // Block 0xd3, offset 0x64c + {value: 0x0008, lo: 0xa0, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xbf}, + // Block 0xd8, offset 0x66a {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0xac}, {value: 0x0040, lo: 0xad, hi: 0xbf}, - // Block 0xd4, offset 0x64f + // Block 0xd9, offset 0x66d {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0xb2}, {value: 0x0040, lo: 0xb3, hi: 0xbf}, - // Block 0xd5, offset 0x652 + // Block 0xda, offset 0x670 {value: 0x0000, lo: 0x02}, - {value: 0x0008, lo: 0x80, hi: 0x81}, - {value: 0x0040, lo: 0x82, hi: 0xbf}, - // Block 0xd6, offset 0x655 + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xbf}, + // Block 0xdb, offset 0x673 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0xdc, offset 0x676 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0xdd, offset 0x679 {value: 0x0000, lo: 0x04}, {value: 0x0008, lo: 0x80, hi: 0xaa}, {value: 0x0040, lo: 0xab, hi: 0xaf}, {value: 0x0008, lo: 0xb0, hi: 0xbc}, {value: 0x0040, lo: 0xbd, hi: 0xbf}, - // Block 0xd7, offset 0x65a + // Block 0xde, offset 0x67e {value: 0x0000, lo: 0x09}, {value: 0x0008, lo: 0x80, hi: 0x88}, {value: 0x0040, lo: 0x89, hi: 0x8f}, {value: 0x0008, lo: 0x90, hi: 0x99}, {value: 0x0040, lo: 0x9a, hi: 0x9b}, {value: 0x0018, lo: 0x9c, hi: 0x9c}, - {value: 0x1308, lo: 0x9d, hi: 0x9e}, + {value: 0x3308, lo: 0x9d, hi: 0x9e}, {value: 0x0018, lo: 0x9f, hi: 0x9f}, {value: 0x03c0, lo: 0xa0, hi: 0xa3}, {value: 0x0040, lo: 0xa4, hi: 0xbf}, - // Block 0xd8, offset 0x664 + // Block 0xdf, offset 0x688 {value: 0x0000, lo: 0x02}, {value: 0x0018, lo: 0x80, hi: 0xb5}, {value: 0x0040, lo: 0xb6, hi: 0xbf}, - // Block 0xd9, offset 0x667 + // Block 0xe0, offset 0x68b {value: 0x0000, lo: 0x03}, {value: 0x0018, lo: 0x80, hi: 0xa6}, {value: 0x0040, lo: 0xa7, hi: 0xa8}, {value: 0x0018, lo: 0xa9, hi: 0xbf}, - // Block 0xda, offset 0x66b + // Block 0xe1, offset 0x68f {value: 0x0000, lo: 0x0e}, {value: 0x0018, lo: 0x80, hi: 0x9d}, {value: 0xb5b9, lo: 0x9e, hi: 0x9e}, @@ -4211,127 +4287,127 @@ var idnaSparseValues = [1876]valueRange{ {value: 0xb719, lo: 0xa2, hi: 0xa2}, {value: 0xb781, lo: 0xa3, hi: 0xa3}, {value: 0xb7e9, lo: 0xa4, hi: 0xa4}, - {value: 0x1018, lo: 0xa5, hi: 0xa6}, - {value: 0x1318, lo: 0xa7, hi: 0xa9}, + {value: 0x3018, lo: 0xa5, hi: 0xa6}, + {value: 0x3318, lo: 0xa7, hi: 0xa9}, {value: 0x0018, lo: 0xaa, hi: 0xac}, - {value: 0x1018, lo: 0xad, hi: 0xb2}, + {value: 0x3018, lo: 0xad, hi: 0xb2}, {value: 0x0340, lo: 0xb3, hi: 0xba}, - {value: 0x1318, lo: 0xbb, hi: 0xbf}, - // Block 0xdb, offset 0x67a + {value: 0x3318, lo: 0xbb, hi: 0xbf}, + // Block 0xe2, offset 0x69e {value: 0x0000, lo: 0x0b}, - {value: 0x1318, lo: 0x80, hi: 0x82}, + {value: 0x3318, lo: 0x80, hi: 0x82}, {value: 0x0018, lo: 0x83, hi: 0x84}, - {value: 0x1318, lo: 0x85, hi: 0x8b}, + {value: 0x3318, lo: 0x85, hi: 0x8b}, {value: 0x0018, lo: 0x8c, hi: 0xa9}, - {value: 0x1318, lo: 0xaa, hi: 0xad}, + {value: 0x3318, lo: 0xaa, hi: 0xad}, {value: 0x0018, lo: 0xae, hi: 0xba}, {value: 0xb851, lo: 0xbb, hi: 0xbb}, {value: 0xb899, lo: 0xbc, hi: 0xbc}, {value: 0xb8e1, lo: 0xbd, hi: 0xbd}, {value: 0xb949, lo: 0xbe, hi: 0xbe}, {value: 0xb9b1, lo: 0xbf, hi: 0xbf}, - // Block 0xdc, offset 0x686 + // Block 0xe3, offset 0x6aa {value: 0x0000, lo: 0x03}, {value: 0xba19, lo: 0x80, hi: 0x80}, {value: 0x0018, lo: 0x81, hi: 0xa8}, {value: 0x0040, lo: 0xa9, hi: 0xbf}, - // Block 0xdd, offset 0x68a + // Block 0xe4, offset 0x6ae {value: 0x0000, lo: 0x04}, {value: 0x0018, lo: 0x80, hi: 0x81}, - {value: 0x1318, lo: 0x82, hi: 0x84}, + {value: 0x3318, lo: 0x82, hi: 0x84}, {value: 0x0018, lo: 0x85, hi: 0x85}, {value: 0x0040, lo: 0x86, hi: 0xbf}, - // Block 0xde, offset 0x68f + // Block 0xe5, offset 0x6b3 {value: 0x0000, lo: 0x04}, {value: 0x0018, lo: 0x80, hi: 0x96}, {value: 0x0040, lo: 0x97, hi: 0x9f}, {value: 0x0018, lo: 0xa0, hi: 0xb1}, {value: 0x0040, lo: 0xb2, hi: 0xbf}, - // Block 0xdf, offset 0x694 + // Block 0xe6, offset 0x6b8 {value: 0x0000, lo: 0x03}, - {value: 0x1308, lo: 0x80, hi: 0xb6}, + {value: 0x3308, lo: 0x80, hi: 0xb6}, {value: 0x0018, lo: 0xb7, hi: 0xba}, - {value: 0x1308, lo: 0xbb, hi: 0xbf}, - // Block 0xe0, offset 0x698 + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0xe7, offset 0x6bc {value: 0x0000, lo: 0x04}, - {value: 0x1308, lo: 0x80, hi: 0xac}, + {value: 0x3308, lo: 0x80, hi: 0xac}, {value: 0x0018, lo: 0xad, hi: 0xb4}, - {value: 0x1308, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, {value: 0x0018, lo: 0xb6, hi: 0xbf}, - // Block 0xe1, offset 0x69d + // Block 0xe8, offset 0x6c1 {value: 0x0000, lo: 0x08}, {value: 0x0018, lo: 0x80, hi: 0x83}, - {value: 0x1308, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x84, hi: 0x84}, {value: 0x0018, lo: 0x85, hi: 0x8b}, {value: 0x0040, lo: 0x8c, hi: 0x9a}, - {value: 0x1308, lo: 0x9b, hi: 0x9f}, + {value: 0x3308, lo: 0x9b, hi: 0x9f}, {value: 0x0040, lo: 0xa0, hi: 0xa0}, - {value: 0x1308, lo: 0xa1, hi: 0xaf}, + {value: 0x3308, lo: 0xa1, hi: 0xaf}, {value: 0x0040, lo: 0xb0, hi: 0xbf}, - // Block 0xe2, offset 0x6a6 + // Block 0xe9, offset 0x6ca {value: 0x0000, lo: 0x0a}, - {value: 0x1308, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x80, hi: 0x86}, {value: 0x0040, lo: 0x87, hi: 0x87}, - {value: 0x1308, lo: 0x88, hi: 0x98}, + {value: 0x3308, lo: 0x88, hi: 0x98}, {value: 0x0040, lo: 0x99, hi: 0x9a}, - {value: 0x1308, lo: 0x9b, hi: 0xa1}, + {value: 0x3308, lo: 0x9b, hi: 0xa1}, {value: 0x0040, lo: 0xa2, hi: 0xa2}, - {value: 0x1308, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa3, hi: 0xa4}, {value: 0x0040, lo: 0xa5, hi: 0xa5}, - {value: 0x1308, lo: 0xa6, hi: 0xaa}, + {value: 0x3308, lo: 0xa6, hi: 0xaa}, {value: 0x0040, lo: 0xab, hi: 0xbf}, - // Block 0xe3, offset 0x6b1 + // Block 0xea, offset 0x6d5 {value: 0x0000, lo: 0x05}, - {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x0808, lo: 0x80, hi: 0x84}, {value: 0x0040, lo: 0x85, hi: 0x86}, - {value: 0x0018, lo: 0x87, hi: 0x8f}, - {value: 0x1308, lo: 0x90, hi: 0x96}, + {value: 0x0818, lo: 0x87, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x96}, {value: 0x0040, lo: 0x97, hi: 0xbf}, - // Block 0xe4, offset 0x6b7 + // Block 0xeb, offset 0x6db {value: 0x0000, lo: 0x07}, - {value: 0x0208, lo: 0x80, hi: 0x83}, - {value: 0x1308, lo: 0x84, hi: 0x8a}, + {value: 0x0a08, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x8a}, {value: 0x0040, lo: 0x8b, hi: 0x8f}, - {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0808, lo: 0x90, hi: 0x99}, {value: 0x0040, lo: 0x9a, hi: 0x9d}, - {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0818, lo: 0x9e, hi: 0x9f}, {value: 0x0040, lo: 0xa0, hi: 0xbf}, - // Block 0xe5, offset 0x6bf + // Block 0xec, offset 0x6e3 {value: 0x0000, lo: 0x03}, {value: 0x0040, lo: 0x80, hi: 0xaf}, {value: 0x0018, lo: 0xb0, hi: 0xb1}, {value: 0x0040, lo: 0xb2, hi: 0xbf}, - // Block 0xe6, offset 0x6c3 + // Block 0xed, offset 0x6e7 {value: 0x0000, lo: 0x03}, {value: 0x0018, lo: 0x80, hi: 0xab}, {value: 0x0040, lo: 0xac, hi: 0xaf}, {value: 0x0018, lo: 0xb0, hi: 0xbf}, - // Block 0xe7, offset 0x6c7 + // Block 0xee, offset 0x6eb {value: 0x0000, lo: 0x05}, {value: 0x0018, lo: 0x80, hi: 0x93}, {value: 0x0040, lo: 0x94, hi: 0x9f}, {value: 0x0018, lo: 0xa0, hi: 0xae}, {value: 0x0040, lo: 0xaf, hi: 0xb0}, {value: 0x0018, lo: 0xb1, hi: 0xbf}, - // Block 0xe8, offset 0x6cd + // Block 0xef, offset 0x6f1 {value: 0x0000, lo: 0x05}, {value: 0x0040, lo: 0x80, hi: 0x80}, {value: 0x0018, lo: 0x81, hi: 0x8f}, {value: 0x0040, lo: 0x90, hi: 0x90}, {value: 0x0018, lo: 0x91, hi: 0xb5}, {value: 0x0040, lo: 0xb6, hi: 0xbf}, - // Block 0xe9, offset 0x6d3 + // Block 0xf0, offset 0x6f7 {value: 0x0000, lo: 0x04}, {value: 0x0018, lo: 0x80, hi: 0x8f}, {value: 0xc1c1, lo: 0x90, hi: 0x90}, {value: 0x0018, lo: 0x91, hi: 0xac}, {value: 0x0040, lo: 0xad, hi: 0xbf}, - // Block 0xea, offset 0x6d8 + // Block 0xf1, offset 0x6fc {value: 0x0000, lo: 0x02}, {value: 0x0040, lo: 0x80, hi: 0xa5}, {value: 0x0018, lo: 0xa6, hi: 0xbf}, - // Block 0xeb, offset 0x6db - {value: 0x0000, lo: 0x0d}, + // Block 0xf2, offset 0x6ff + {value: 0x0000, lo: 0x0f}, {value: 0xc7e9, lo: 0x80, hi: 0x80}, {value: 0xc839, lo: 0x81, hi: 0x81}, {value: 0xc889, lo: 0x82, hi: 0x82}, @@ -4344,84 +4420,88 @@ var idnaSparseValues = [1876]valueRange{ {value: 0x0040, lo: 0x89, hi: 0x8f}, {value: 0xcab9, lo: 0x90, hi: 0x90}, {value: 0xcad9, lo: 0x91, hi: 0x91}, - {value: 0x0040, lo: 0x92, hi: 0xbf}, - // Block 0xec, offset 0x6e9 + {value: 0x0040, lo: 0x92, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xbf}, + // Block 0xf3, offset 0x70f {value: 0x0000, lo: 0x06}, - {value: 0x0018, lo: 0x80, hi: 0x92}, - {value: 0x0040, lo: 0x93, hi: 0x9f}, + {value: 0x0018, lo: 0x80, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x9f}, {value: 0x0018, lo: 0xa0, hi: 0xac}, {value: 0x0040, lo: 0xad, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xb6}, - {value: 0x0040, lo: 0xb7, hi: 0xbf}, - // Block 0xed, offset 0x6f0 + {value: 0x0018, lo: 0xb0, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xf4, offset 0x716 {value: 0x0000, lo: 0x02}, {value: 0x0018, lo: 0x80, hi: 0xb3}, {value: 0x0040, lo: 0xb4, hi: 0xbf}, - // Block 0xee, offset 0x6f3 + // Block 0xf5, offset 0x719 {value: 0x0000, lo: 0x02}, {value: 0x0018, lo: 0x80, hi: 0x94}, {value: 0x0040, lo: 0x95, hi: 0xbf}, - // Block 0xef, offset 0x6f6 + // Block 0xf6, offset 0x71c {value: 0x0000, lo: 0x03}, {value: 0x0018, lo: 0x80, hi: 0x8b}, {value: 0x0040, lo: 0x8c, hi: 0x8f}, {value: 0x0018, lo: 0x90, hi: 0xbf}, - // Block 0xf0, offset 0x6fa + // Block 0xf7, offset 0x720 {value: 0x0000, lo: 0x05}, {value: 0x0018, lo: 0x80, hi: 0x87}, {value: 0x0040, lo: 0x88, hi: 0x8f}, {value: 0x0018, lo: 0x90, hi: 0x99}, {value: 0x0040, lo: 0x9a, hi: 0x9f}, {value: 0x0018, lo: 0xa0, hi: 0xbf}, - // Block 0xf1, offset 0x700 + // Block 0xf8, offset 0x726 {value: 0x0000, lo: 0x04}, {value: 0x0018, lo: 0x80, hi: 0x87}, {value: 0x0040, lo: 0x88, hi: 0x8f}, {value: 0x0018, lo: 0x90, hi: 0xad}, {value: 0x0040, lo: 0xae, hi: 0xbf}, - // Block 0xf2, offset 0x705 - {value: 0x0000, lo: 0x09}, - {value: 0x0040, lo: 0x80, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0x9e}, - {value: 0x0040, lo: 0x9f, hi: 0x9f}, - {value: 0x0018, lo: 0xa0, hi: 0xa7}, - {value: 0x0040, lo: 0xa8, hi: 0xaf}, - {value: 0x0018, lo: 0xb0, hi: 0xb0}, - {value: 0x0040, lo: 0xb1, hi: 0xb2}, - {value: 0x0018, lo: 0xb3, hi: 0xbe}, - {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0xf3, offset 0x70f + // Block 0xf9, offset 0x72b {value: 0x0000, lo: 0x04}, {value: 0x0018, lo: 0x80, hi: 0x8b}, {value: 0x0040, lo: 0x8c, hi: 0x8f}, - {value: 0x0018, lo: 0x90, hi: 0x9e}, - {value: 0x0040, lo: 0x9f, hi: 0xbf}, - // Block 0xf4, offset 0x714 - {value: 0x0000, lo: 0x02}, - {value: 0x0018, lo: 0x80, hi: 0x91}, - {value: 0x0040, lo: 0x92, hi: 0xbf}, - // Block 0xf5, offset 0x717 + {value: 0x0018, lo: 0x90, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xfa, offset 0x730 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xbf}, + // Block 0xfb, offset 0x735 {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0xbf}, + // Block 0xfc, offset 0x738 + {value: 0x0000, lo: 0x04}, {value: 0x0018, lo: 0x80, hi: 0x80}, - {value: 0x0040, lo: 0x81, hi: 0xbf}, - // Block 0xf6, offset 0x71a + {value: 0x0040, lo: 0x81, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xbf}, + // Block 0xfd, offset 0x73d {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0x96}, {value: 0x0040, lo: 0x97, hi: 0xbf}, - // Block 0xf7, offset 0x71d + // Block 0xfe, offset 0x740 {value: 0x0000, lo: 0x02}, {value: 0x0008, lo: 0x80, hi: 0xb4}, {value: 0x0040, lo: 0xb5, hi: 0xbf}, - // Block 0xf8, offset 0x720 + // Block 0xff, offset 0x743 {value: 0x0000, lo: 0x03}, {value: 0x0008, lo: 0x80, hi: 0x9d}, {value: 0x0040, lo: 0x9e, hi: 0x9f}, {value: 0x0008, lo: 0xa0, hi: 0xbf}, - // Block 0xf9, offset 0x724 - {value: 0x0000, lo: 0x02}, + // Block 0x100, offset 0x747 + {value: 0x0000, lo: 0x03}, {value: 0x0008, lo: 0x80, hi: 0xa1}, - {value: 0x0040, lo: 0xa2, hi: 0xbf}, - // Block 0xfa, offset 0x727 + {value: 0x0040, lo: 0xa2, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x101, offset 0x74b + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x102, offset 0x74e {value: 0x0020, lo: 0x0f}, {value: 0xdeb9, lo: 0x80, hi: 0x89}, {value: 0x8dfd, lo: 0x8a, hi: 0x8a}, @@ -4438,7 +4518,7 @@ var idnaSparseValues = [1876]valueRange{ {value: 0xe4f9, lo: 0xba, hi: 0xba}, {value: 0x8edd, lo: 0xbb, hi: 0xbb}, {value: 0xe519, lo: 0xbc, hi: 0xbf}, - // Block 0xfb, offset 0x737 + // Block 0x103, offset 0x75e {value: 0x0020, lo: 0x10}, {value: 0x937d, lo: 0x80, hi: 0x80}, {value: 0xf099, lo: 0x81, hi: 0x86}, @@ -4455,23 +4535,23 @@ var idnaSparseValues = [1876]valueRange{ {value: 0xf4d9, lo: 0xae, hi: 0xaf}, {value: 0x94dd, lo: 0xb0, hi: 0xb1}, {value: 0xf519, lo: 0xb2, hi: 0xbe}, - {value: 0x0040, lo: 0xbf, hi: 0xbf}, - // Block 0xfc, offset 0x748 + {value: 0x2040, lo: 0xbf, hi: 0xbf}, + // Block 0x104, offset 0x76f {value: 0x0000, lo: 0x04}, {value: 0x0040, lo: 0x80, hi: 0x80}, {value: 0x0340, lo: 0x81, hi: 0x81}, {value: 0x0040, lo: 0x82, hi: 0x9f}, {value: 0x0340, lo: 0xa0, hi: 0xbf}, - // Block 0xfd, offset 0x74d + // Block 0x105, offset 0x774 {value: 0x0000, lo: 0x01}, {value: 0x0340, lo: 0x80, hi: 0xbf}, - // Block 0xfe, offset 0x74f + // Block 0x106, offset 0x776 {value: 0x0000, lo: 0x01}, - {value: 0x13c0, lo: 0x80, hi: 0xbf}, - // Block 0xff, offset 0x751 + {value: 0x33c0, lo: 0x80, hi: 0xbf}, + // Block 0x107, offset 0x778 {value: 0x0000, lo: 0x02}, - {value: 0x13c0, lo: 0x80, hi: 0xaf}, + {value: 0x33c0, lo: 0x80, hi: 0xaf}, {value: 0x0040, lo: 0xb0, hi: 0xbf}, } -// Total table size 41559 bytes (40KiB); checksum: F4A1FA4E +// Total table size 42115 bytes (41KiB); checksum: F4A1FA4E diff --git a/vendor/golang.org/x/net/idna/trieval.go b/vendor/golang.org/x/net/idna/trieval.go index 63cb03b59..7a8cf889b 100644 --- a/vendor/golang.org/x/net/idna/trieval.go +++ b/vendor/golang.org/x/net/idna/trieval.go @@ -26,9 +26,9 @@ package idna // 15..3 index into xor or mapping table // } // } else { -// 15..13 unused -// 12 modifier (including virama) -// 11 virama modifier +// 15..14 unused +// 13 mayNeedNorm +// 12..11 attributes // 10..8 joining type // 7..3 category type // } @@ -49,15 +49,20 @@ const ( joinShift = 8 joinMask = 0x07 - viramaModifier = 0x0800 + // Attributes + attributesMask = 0x1800 + viramaModifier = 0x1800 modifier = 0x1000 + rtl = 0x0800 + + mayNeedNorm = 0x2000 ) // A category corresponds to a category defined in the IDNA mapping table. type category uint16 const ( - unknown category = 0 // not defined currently in unicode. + unknown category = 0 // not currently defined in unicode. mapped category = 1 disallowedSTD3Mapped category = 2 deviation category = 3 @@ -110,5 +115,5 @@ func (c info) isModifier() bool { } func (c info) isViramaModifier() bool { - return c&(viramaModifier|catSmallMask) == viramaModifier + return c&(attributesMask|catSmallMask) == viramaModifier } From 6bfd7cff72b2a8da3e51029606e1497391a4300b Mon Sep 17 00:00:00 2001 From: jregan Date: Sun, 24 Feb 2019 10:17:11 -0800 Subject: [PATCH 137/317] Improve error handling during var resolution. --- pkg/commands/build/build_test.go | 6 ++ pkg/commands/edit/add/flagsandargs.go | 2 +- pkg/expansion/expand.go | 1 - pkg/expansion/expand_test.go | 4 +- pkg/resmap/resmap.go | 9 -- pkg/resmap/resmap_test.go | 29 +++---- pkg/target/resaccumulator.go | 25 ++++-- pkg/target/resaccumulator_test.go | 118 ++++++++++++++++++++++++-- 8 files changed, 150 insertions(+), 44 deletions(-) diff --git a/pkg/commands/build/build_test.go b/pkg/commands/build/build_test.go index 169de1ad4..b06ccdea2 100644 --- a/pkg/commands/build/build_test.go +++ b/pkg/commands/build/build_test.go @@ -22,6 +22,12 @@ import ( "sigs.k8s.io/kustomize/pkg/constants" ) +func TestNewOptionsToSilenceCodeInspectionError(t *testing.T) { + if NewOptions("foo", "bar") == nil { + t.Fatal("could not make new options") + } +} + func TestBuildValidate(t *testing.T) { var cases = []struct { name string diff --git a/pkg/commands/edit/add/flagsandargs.go b/pkg/commands/edit/add/flagsandargs.go index a842ed817..1cfc7d8dc 100644 --- a/pkg/commands/edit/add/flagsandargs.go +++ b/pkg/commands/edit/add/flagsandargs.go @@ -94,7 +94,7 @@ func (a *flagsAndArgs) ExpandFileSource(fSys fs.FileSystem) error { if key != "" { if len(result) != 1 { return fmt.Errorf( - "'pattern '%s' catches files %v, should catch only one.", pattern, result) + "'pattern '%s' catches files %v, should catch only one", pattern, result) } fileSource := fmt.Sprintf("%s=%s", key, result[0]) results = append(results, fileSource) diff --git a/pkg/expansion/expand.go b/pkg/expansion/expand.go index c2a81ed6f..c4f0e0ba3 100644 --- a/pkg/expansion/expand.go +++ b/pkg/expansion/expand.go @@ -44,7 +44,6 @@ func MappingFuncFor(context ...map[string]string) func(string) string { return val } } - return syntaxWrap(input) } } diff --git a/pkg/expansion/expand_test.go b/pkg/expansion/expand_test.go index e418e33a1..4b6a98211 100644 --- a/pkg/expansion/expand_test.go +++ b/pkg/expansion/expand_test.go @@ -46,9 +46,7 @@ func TestMapReference(t *testing.T) { "BLU": "$(ZOO)-2", } - serviceEnv := map[string]string{} - - mapping := MappingFuncFor(declaredEnv, serviceEnv) + mapping := MappingFuncFor(declaredEnv) for _, env := range envs { declaredEnv[env.Name] = Expand(env.Value, mapping) diff --git a/pkg/resmap/resmap.go b/pkg/resmap/resmap.go index bb6dec478..ca1e72398 100644 --- a/pkg/resmap/resmap.go +++ b/pkg/resmap/resmap.go @@ -46,15 +46,6 @@ func (m ResMap) GetMatchingIds(matches IdMatcher) []resid.ResId { return result } -// DemandOneGvknMatchForId find the matched resource by Group/Version/Kind and Name -func (m ResMap) DemandOneGvknMatchForId(inputId resid.ResId) (*resource.Resource, bool) { - result := m.GetMatchingIds(inputId.GvknEquals) - if len(result) == 1 { - return m[result[0]], true - } - return nil, false -} - // EncodeAsYaml encodes a ResMap to YAML; encoded objects separated by `---`. func (m ResMap) EncodeAsYaml() ([]byte, error) { var ids []resid.ResId diff --git a/pkg/resmap/resmap_test.go b/pkg/resmap/resmap_test.go index 74a43cdd6..05341cb03 100644 --- a/pkg/resmap/resmap_test.go +++ b/pkg/resmap/resmap_test.go @@ -92,35 +92,34 @@ func TestDemandOneGvknMatchForId(t *testing.T) { }), } - _, ok := rm1.DemandOneGvknMatchForId( - resid.NewResIdWithPrefixNamespace(cmap, "cm2", "prefix1", "ns1")) - if !ok { - t.Fatal("Expected single map entry but got none") + result := rm1.GetMatchingIds( + resid.NewResIdWithPrefixNamespace(cmap, "cm2", "prefix1", "ns1").GvknEquals) + if len(result) != 1 { + t.Fatalf("Expected single map entry but got %v", result) } // confirm that ns and prefix are not included in match - _, ok = rm1.DemandOneGvknMatchForId( - resid.NewResIdWithPrefixNamespace(cmap, "cm2", "prefix", "ns")) - if !ok { - t.Fatal("Expected single map entry but got none") + result = rm1.GetMatchingIds( + resid.NewResIdWithPrefixNamespace(cmap, "cm2", "prefix", "ns").GvknEquals) + if len(result) != 1 { + t.Fatalf("Expected single map entry but got %v", result) } // confirm that name is matched correctly - result, ok := rm1.DemandOneGvknMatchForId( - resid.NewResIdWithPrefixNamespace(cmap, "cm3", "prefix1", "ns1")) - if ok { + result = rm1.GetMatchingIds( + resid.NewResIdWithPrefixNamespace(cmap, "cm3", "prefix1", "ns1").GvknEquals) + if len(result) > 0 { t.Fatalf("Expected no map entries but got %v", result) } cmap2 := gvk.Gvk{Version: "v2", Kind: "ConfigMap"} // confirm that gvk is matched correctly - result, ok = rm1.DemandOneGvknMatchForId( - resid.NewResIdWithPrefixNamespace(cmap2, "cm2", "prefix1", "ns1")) - if ok { + result = rm1.GetMatchingIds( + resid.NewResIdWithPrefixNamespace(cmap2, "cm2", "prefix1", "ns1").GvknEquals) + if len(result) > 0 { t.Fatalf("Expected no map entries but got %v", result) } - } func TestFilterBy(t *testing.T) { diff --git a/pkg/target/resaccumulator.go b/pkg/target/resaccumulator.go index c6ba0cd84..7894a8fb2 100644 --- a/pkg/target/resaccumulator.go +++ b/pkg/target/resaccumulator.go @@ -18,7 +18,6 @@ package target import ( "fmt" - "log" "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/transformers" @@ -101,17 +100,27 @@ func (ra *ResAccumulator) MergeAccumulator(other *ResAccumulator) (err error) { // for substitution wherever the $(var.Name) occurs. func (ra *ResAccumulator) makeVarReplacementMap() (map[string]string, error) { result := map[string]string{} - for _, v := range ra.varSet.Set() { - id := resid.NewResId(v.ObjRef.GVK(), v.ObjRef.Name) - if r, found := ra.resMap.DemandOneGvknMatchForId(id); found { - s, err := r.GetFieldValue(v.FieldRef.FieldPath) + for _, v := range ra.Vars() { + matched := ra.resMap.GetMatchingIds( + resid.NewResId(v.ObjRef.GVK(), v.ObjRef.Name).GvknEquals) + if len(matched) > 1 { + return nil, fmt.Errorf( + "found %d resId matches for var %s "+ + "(unable to disambiguate)", + len(matched), v) + } + if len(matched) == 1 { + s, err := ra.resMap[matched[0]].GetFieldValue(v.FieldRef.FieldPath) if err != nil { - return nil, fmt.Errorf("field path err for var: %+v", v) + return nil, fmt.Errorf( + "field specified in var '%v' "+ + "not found in corresponding resource", v) } result[v.Name] = s } else { - // Should this be an error? - log.Printf("var %v defined but not used", v) + return nil, fmt.Errorf( + "var '%v' cannot be mapped to a field "+ + "in the set of known resources", v) } } return result, nil diff --git a/pkg/target/resaccumulator_test.go b/pkg/target/resaccumulator_test.go index 0bf1eedaa..55dab77f6 100644 --- a/pkg/target/resaccumulator_test.go +++ b/pkg/target/resaccumulator_test.go @@ -30,11 +30,11 @@ import ( "sigs.k8s.io/kustomize/pkg/types" ) -func TestResolveVars(t *testing.T) { +func makeResAccumulator() (*ResAccumulator, *resource.Factory, error) { ra := MakeEmptyAccumulator() err := ra.MergeConfig(config.MakeDefaultConfig()) if err != nil { - t.Fatalf("unexpected err: %v", err) + return nil, nil, err } rf := resource.NewFactory( kunstruct.NewKunstructuredFactoryImpl()) @@ -55,8 +55,8 @@ func TestResolveVars(t *testing.T) { map[string]interface{}{ "command": []interface{}{ "myserver", - "--somebackendService $(FOO)", - "--yetAnother $(BAR)", + "--somebackendService $(SERVICE_ONE)", + "--yetAnother $(SERVICE_TWO)", }, }, }, @@ -85,14 +85,23 @@ func TestResolveVars(t *testing.T) { }, }), }) + return ra, rf, nil +} + +func TestResolveVarsHappy(t *testing.T) { + ra, _, err := makeResAccumulator() + if err != nil { + t.Fatalf("unexpected err: %v", err) + } err = ra.MergeVars([]types.Var{ { - Name: "FOO", + Name: "SERVICE_ONE", ObjRef: types.Target{ Gvk: gvk.Gvk{Version: "v1", Kind: "Service"}, Name: "backendOne"}, - }, { - Name: "BAR", + }, + { + Name: "SERVICE_TWO", ObjRef: types.Target{ Gvk: gvk.Gvk{Version: "v1", Kind: "Service"}, Name: "backendTwo"}, @@ -111,6 +120,101 @@ func TestResolveVars(t *testing.T) { } } +func TestResolveVarsVarNeedsDisambiguation(t *testing.T) { + ra, rf, err := makeResAccumulator() + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + ra.MergeResourcesWithErrorOnIdCollision(resmap.ResMap{ + resid.NewResIdWithPrefixNamespace( + gvk.Gvk{Version: "v1", Kind: "Service"}, + "backendOne", "", "fooNamespace"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "Service", + "metadata": map[string]interface{}{ + "name": "backendOne", + }, + }), + }) + + err = ra.MergeVars([]types.Var{ + { + Name: "SERVICE_ONE", + ObjRef: types.Target{ + Gvk: gvk.Gvk{Version: "v1", Kind: "Service"}, + Name: "backendOne", + }, + }, + }) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + err = ra.ResolveVars() + if err == nil { + t.Fatalf("expected error") + } + if !strings.Contains( + err.Error(), "unable to disambiguate") { + t.Fatalf("unexpected err: %v", err) + } +} + +func TestResolveVarsGoodResIdBadField(t *testing.T) { + ra, _, err := makeResAccumulator() + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + err = ra.MergeVars([]types.Var{ + { + Name: "SERVICE_ONE", + ObjRef: types.Target{ + Gvk: gvk.Gvk{Version: "v1", Kind: "Service"}, + Name: "backendOne"}, + FieldRef: types.FieldSelector{FieldPath: "nope_nope_nope"}, + }, + }) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + err = ra.ResolveVars() + if err == nil { + t.Fatalf("expected error") + } + if !strings.Contains( + err.Error(), + "not found in corresponding resource") { + t.Fatalf("unexpected err: %v", err) + } +} + +func TestResolveVarsUnmappableVar(t *testing.T) { + ra, _, err := makeResAccumulator() + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + err = ra.MergeVars([]types.Var{ + { + Name: "SERVICE_THREE", + ObjRef: types.Target{ + Gvk: gvk.Gvk{Version: "v1", Kind: "Service"}, + Name: "doesNotExist"}, + }, + }) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + err = ra.ResolveVars() + if err == nil { + t.Fatalf("expected error") + } + if !strings.Contains( + err.Error(), + "cannot be mapped to a field in the set of known resources") { + t.Fatalf("unexpected err: %v", err) + } +} + func find(name string, resMap resmap.ResMap) *resource.Resource { for k, v := range resMap { if k.Name() == name { From 852e7ed5aad20078a9702aa7259c9ba964906816 Mon Sep 17 00:00:00 2001 From: Ken Maglio Date: Tue, 26 Feb 2019 17:19:33 -0600 Subject: [PATCH 138/317] Typo Fix --- docs/INSTALL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/INSTALL.md b/docs/INSTALL.md index cfe9f8222..206bbd08b 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -8,7 +8,7 @@ manager: brew install kustomize -On windows, you can install kusztomize with Chocolatey package +On windows, you can install kustomize with Chocolatey package manager: choco install kustomize From ff6cd3ca553dcec79bd328a2fea95e4eef01becf Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Tue, 26 Feb 2019 17:19:24 -0800 Subject: [PATCH 139/317] Report unused variables. --- pkg/expansion/expand.go | 5 +- pkg/expansion/expand_test.go | 80 +++++++++++++++++++++++++------ pkg/target/resaccumulator.go | 17 ++++++- pkg/target/resaccumulator_test.go | 47 ++++++++++++++++++ pkg/transformers/refvars.go | 44 +++++++++++------ pkg/transformers/refvars_test.go | 10 ++-- 6 files changed, 167 insertions(+), 36 deletions(-) diff --git a/pkg/expansion/expand.go b/pkg/expansion/expand.go index c4f0e0ba3..de55e4614 100644 --- a/pkg/expansion/expand.go +++ b/pkg/expansion/expand.go @@ -36,11 +36,14 @@ func syntaxWrap(input string) string { // implements the expansion semantics defined in the expansion spec; it // returns the input string wrapped in the expansion syntax if no mapping // for the input is found. -func MappingFuncFor(context ...map[string]string) func(string) string { +func MappingFuncFor( + counts map[string]int, + context ...map[string]string) func(string) string { return func(input string) string { for _, vars := range context { val, ok := vars[input] if ok { + counts[input]++ return val } } diff --git a/pkg/expansion/expand_test.go b/pkg/expansion/expand_test.go index 4b6a98211..2a8a13125 100644 --- a/pkg/expansion/expand_test.go +++ b/pkg/expansion/expand_test.go @@ -14,12 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. */ -package expansion +package expansion_test import ( "testing" + + . "sigs.k8s.io/kustomize/pkg/expansion" ) +type expected struct { + count int + edited string +} + func TestMapReference(t *testing.T) { type env struct { Name string @@ -46,21 +53,23 @@ func TestMapReference(t *testing.T) { "BLU": "$(ZOO)-2", } - mapping := MappingFuncFor(declaredEnv) + counts := make(map[string]int) + mapping := MappingFuncFor(counts, declaredEnv) for _, env := range envs { declaredEnv[env.Name] = Expand(env.Value, mapping) } - expectedEnv := map[string]string{ - "FOO": "bar", - "ZOO": "bar-1", - "BLU": "bar-1-2", + expectedEnv := map[string]expected{ + "FOO": {count: 1, edited: "bar"}, + "ZOO": {count: 1, edited: "bar-1"}, + "BLU": {count: 0, edited: "bar-1-2"}, } for k, v := range expectedEnv { - if e, a := v, declaredEnv[k]; e != a { - t.Errorf("Expected %v, got %v", e, a) + if e, a := v, declaredEnv[k]; e.edited != a || e.count != counts[k] { + t.Errorf("Expected %v count=%d, got %v count=%d", + e.edited, e.count, a, counts[k]) } else { delete(declaredEnv, k) } @@ -79,9 +88,7 @@ func TestMapping(t *testing.T) { "VAR_REF": "$(VAR_A)", "VAR_EMPTY": "", } - mapping := MappingFuncFor(context) - - doExpansionTest(t, mapping) + doExpansionTest(t, context) } func TestMappingDual(t *testing.T) { @@ -94,51 +101,64 @@ func TestMappingDual(t *testing.T) { "VAR_C": "C", "VAR_REF": "$(VAR_A)", } - mapping := MappingFuncFor(context, context2) - doExpansionTest(t, mapping) + doExpansionTest(t, context, context2) } -func doExpansionTest(t *testing.T, mapping func(string) string) { +func doExpansionTest(t *testing.T, context ...map[string]string) { cases := []struct { name string input string expected string + counts map[string]int }{ { name: "whole string", input: "$(VAR_A)", expected: "A", + counts: map[string]int{"VAR_A": 1}, }, { name: "repeat", input: "$(VAR_A)-$(VAR_A)", expected: "A-A", + counts: map[string]int{"VAR_A": 2}, + }, + { + name: "multiple repeats", + input: "$(VAR_A)-$(VAR_B)-$(VAR_B)-$(VAR_B)-$(VAR_A)", + expected: "A-B-B-B-A", + counts: map[string]int{"VAR_A": 2, "VAR_B": 3}, }, { name: "beginning", input: "$(VAR_A)-1", expected: "A-1", + counts: map[string]int{"VAR_A": 1}, }, { name: "middle", input: "___$(VAR_B)___", expected: "___B___", + counts: map[string]int{"VAR_B": 1}, }, { name: "end", input: "___$(VAR_C)", expected: "___C", + counts: map[string]int{"VAR_C": 1}, }, { name: "compound", input: "$(VAR_A)_$(VAR_B)_$(VAR_C)", expected: "A_B_C", + counts: map[string]int{"VAR_A": 1, "VAR_B": 1, "VAR_C": 1}, }, { name: "escape & expand", input: "$$(VAR_B)_$(VAR_A)", expected: "$(VAR_B)_A", + counts: map[string]int{"VAR_A": 1}, }, { name: "compound escape", @@ -154,16 +174,19 @@ func doExpansionTest(t *testing.T, mapping func(string) string) { name: "backslash escape ignored", input: "foo\\$(VAR_C)bar", expected: "foo\\Cbar", + counts: map[string]int{"VAR_C": 1}, }, { name: "backslash escape ignored", input: "foo\\\\$(VAR_C)bar", expected: "foo\\\\Cbar", + counts: map[string]int{"VAR_C": 1}, }, { name: "lots of backslashes", input: "foo\\\\\\\\$(VAR_A)bar", expected: "foo\\\\\\\\Abar", + counts: map[string]int{"VAR_A": 1}, }, { name: "nested var references", @@ -179,16 +202,19 @@ func doExpansionTest(t *testing.T, mapping func(string) string) { name: "value is a reference", input: "$(VAR_REF)", expected: "$(VAR_A)", + counts: map[string]int{"VAR_REF": 1}, }, { name: "value is a reference x 2", input: "%%$(VAR_REF)--$(VAR_REF)%%", expected: "%%$(VAR_A)--$(VAR_A)%%", + counts: map[string]int{"VAR_REF": 2}, }, { name: "empty var", input: "foo$(VAR_EMPTY)bar", expected: "foobar", + counts: map[string]int{"VAR_EMPTY": 1}, }, { name: "unterminated expression", @@ -234,6 +260,7 @@ func doExpansionTest(t *testing.T, mapping func(string) string) { name: "multiple (odd) operators, var defined", input: "$$$$$$$(VAR_A)", expected: "$$$A", + counts: map[string]int{"VAR_A": 1}, }, { name: "missing open expression", @@ -249,16 +276,19 @@ func doExpansionTest(t *testing.T, mapping func(string) string) { name: "trailing incomplete expression not consumed", input: "$(VAR_B)_______$(A", expected: "B_______$(A", + counts: map[string]int{"VAR_B": 1}, }, { name: "trailing incomplete expression, no content, is not consumed", input: "$(VAR_C)_______$(", expected: "C_______$(", + counts: map[string]int{"VAR_C": 1}, }, { name: "operator at end of input string is preserved", input: "$(VAR_A)foobarzab$", expected: "Afoobarzab$", + counts: map[string]int{"VAR_A": 1}, }, { name: "shell escaped incomplete expr", @@ -293,9 +323,31 @@ func doExpansionTest(t *testing.T, mapping func(string) string) { } for _, tc := range cases { + counts := make(map[string]int) + mapping := MappingFuncFor(counts, context...) expanded := Expand(tc.input, mapping) if e, a := tc.expected, expanded; e != a { t.Errorf("%v: expected %q, got %q", tc.name, e, a) } + if len(counts) != len(tc.counts) { + t.Errorf("%v: len(counts)=%d != len(tc.counts)=%d", + tc.name, len(counts), len(tc.counts)) + } + if len(tc.counts) > 0 { + for k, expectedCount := range tc.counts { + c, ok := counts[k] + if ok { + if c != expectedCount { + t.Errorf( + "%v: k=%s, expected count %d, got %d", + tc.name, k, expectedCount, c) + } + } else { + t.Errorf( + "%v: k=%s, expected count %d, got zero", + tc.name, k, expectedCount) + } + } + } } } diff --git a/pkg/target/resaccumulator.go b/pkg/target/resaccumulator.go index 7894a8fb2..b8c45015a 100644 --- a/pkg/target/resaccumulator.go +++ b/pkg/target/resaccumulator.go @@ -18,6 +18,9 @@ package target import ( "fmt" + "log" + "strings" + "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/transformers" @@ -135,8 +138,18 @@ func (ra *ResAccumulator) ResolveVars() error { if err != nil { return err } - return ra.Transform(transformers.NewRefVarTransformer( - replacementMap, ra.tConfig.VarReference)) + if len(replacementMap) == 0 { + return nil + } + t := transformers.NewRefVarTransformer( + replacementMap, ra.tConfig.VarReference) + err = ra.Transform(t) + if len(t.UnusedVars()) > 0 { + log.Printf( + "well-defined vars that were never replaced: %s\n", + strings.Join(t.UnusedVars(), ",")) + } + return err } func (ra *ResAccumulator) FixBackReferences() (err error) { diff --git a/pkg/target/resaccumulator_test.go b/pkg/target/resaccumulator_test.go index 55dab77f6..42b61cc65 100644 --- a/pkg/target/resaccumulator_test.go +++ b/pkg/target/resaccumulator_test.go @@ -17,6 +17,9 @@ limitations under the License. package target_test import ( + "bytes" + "log" + "os" "strings" "testing" @@ -120,6 +123,50 @@ func TestResolveVarsHappy(t *testing.T) { } } +func TestResolveVarsOneUnused(t *testing.T) { + ra, _, err := makeResAccumulator() + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + err = ra.MergeVars([]types.Var{ + { + Name: "SERVICE_ONE", + ObjRef: types.Target{ + Gvk: gvk.Gvk{Version: "v1", Kind: "Service"}, + Name: "backendOne"}, + }, + { + Name: "SERVICE_UNUSED", + ObjRef: types.Target{ + Gvk: gvk.Gvk{Version: "v1", Kind: "Service"}, + Name: "backendTwo"}, + }, + }) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + var buf bytes.Buffer + log.SetOutput(&buf) + defer func() { + log.SetOutput(os.Stderr) + }() + err = ra.ResolveVars() + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + expectLog(t, buf, "well-defined vars that were never replaced: SERVICE_UNUSED") + c := getCommand(find("deploy1", ra.ResMap())) + if c != "myserver --somebackendService backendOne --yetAnother $(SERVICE_TWO)" { + t.Fatalf("unexpected command: %s", c) + } +} + +func expectLog(t *testing.T, log bytes.Buffer, expect string) { + if !strings.Contains(log.String(), expect) { + t.Fatalf("expected log containing '%s', got '%s'", expect, log.String()) + } +} + func TestResolveVarsVarNeedsDisambiguation(t *testing.T) { ra, rf, err := makeResAccumulator() if err != nil { diff --git a/pkg/transformers/refvars.go b/pkg/transformers/refvars.go index cace71f16..b31ec6e7a 100644 --- a/pkg/transformers/refvars.go +++ b/pkg/transformers/refvars.go @@ -2,28 +2,26 @@ package transformers import ( "fmt" - "sigs.k8s.io/kustomize/pkg/expansion" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/transformers/config" ) -type refvarTransformer struct { - fieldSpecs []config.FieldSpec - mappingFunc func(string) string +type RefVarTransformer struct { + varMap map[string]string + replacementCounts map[string]int + fieldSpecs []config.FieldSpec + mappingFunc func(string) string } -// NewRefVarTransformer returns a Transformer that replaces $(VAR) style -// variables with values. +// NewRefVarTransformer returns a new RefVarTransformer +// that replaces $(VAR) style variables with values. // The fieldSpecs are the places to look for occurrences of $(VAR). func NewRefVarTransformer( - varMap map[string]string, fs []config.FieldSpec) Transformer { - if len(varMap) == 0 { - return NewNoOpTransformer() - } - return &refvarTransformer{ - fieldSpecs: fs, - mappingFunc: expansion.MappingFuncFor(varMap), + varMap map[string]string, fs []config.FieldSpec) *RefVarTransformer { + return &RefVarTransformer{ + varMap: varMap, + fieldSpecs: fs, } } @@ -31,7 +29,7 @@ func NewRefVarTransformer( // embedded instances of $VAR style variables, e.g. a container command string. // The function returns the string with the variables expanded to their final // values. -func (rv *refvarTransformer) replaceVars(in interface{}) (interface{}, error) { +func (rv *RefVarTransformer) replaceVars(in interface{}) (interface{}, error) { switch vt := in.(type) { case []interface{}: var xs []string @@ -63,8 +61,24 @@ func (rv *refvarTransformer) replaceVars(in interface{}) (interface{}, error) { } } +// UnusedVars returns slice of Var names that were unused +// after a Transform run. +func (rv *RefVarTransformer) UnusedVars() []string { + var unused []string + for k := range rv.varMap { + _, ok := rv.replacementCounts[k] + if !ok { + unused = append(unused, k) + } + } + return unused +} + // Transform replaces $(VAR) style variables with values. -func (rv *refvarTransformer) Transform(m resmap.ResMap) error { +func (rv *RefVarTransformer) Transform(m resmap.ResMap) error { + rv.replacementCounts = make(map[string]int) + rv.mappingFunc = expansion.MappingFuncFor( + rv.replacementCounts, rv.varMap) for id, res := range m { for _, fieldSpec := range rv.fieldSpecs { if id.Gvk().IsSelected(&fieldSpec.Gvk) { diff --git a/pkg/transformers/refvars_test.go b/pkg/transformers/refvars_test.go index fd2e9695b..6e6826fad 100644 --- a/pkg/transformers/refvars_test.go +++ b/pkg/transformers/refvars_test.go @@ -5,7 +5,6 @@ import ( "testing" "sigs.k8s.io/kustomize/pkg/resid" - "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/transformers/config" ) @@ -17,7 +16,8 @@ func TestVarRef(t *testing.T) { res resmap.ResMap } type expected struct { - res resmap.ResMap + res resmap.ResMap + unused []string } testCases := []struct { description string @@ -28,7 +28,8 @@ func TestVarRef(t *testing.T) { description: "var replacement in map[string]", given: given{ varMap: map[string]string{ - "FOO": "BAR", + "FOO": "replacementForFoo", + "BAR": "replacementForBar", }, fs: []config.FieldSpec{ {Gvk: cmap, Path: "data"}, @@ -58,11 +59,12 @@ func TestVarRef(t *testing.T) { "name": "cm1", }, "data": map[string]interface{}{ - "item1": "BAR", + "item1": "replacementForFoo", "item2": "bla", }, }), }, + unused: []string{"BAR"}, }, }, } From f4eef1dc0bad6b707f07ef3e59045ca32c128cd3 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Wed, 27 Feb 2019 13:26:58 -0800 Subject: [PATCH 140/317] update transformerconfigs/crd example --- examples/transformerconfigs/README.md | 1 - examples/transformerconfigs/crd/README.md | 39 +---------------------- 2 files changed, 1 insertion(+), 39 deletions(-) diff --git a/examples/transformerconfigs/README.md b/examples/transformerconfigs/README.md index d18f1e518..292cc3e4b 100644 --- a/examples/transformerconfigs/README.md +++ b/examples/transformerconfigs/README.md @@ -91,6 +91,5 @@ nameReference: Kustomize has a default set of configurations. They can be saved to local directory through `kustomize config save -d`. Kustomize allows modifying those configuration files and using them in kustomization.yaml file. This tutorial shows how to customize those configurations to - [support a CRD type](crd/README.md) -- disabling adding commonLabels to fields in some kind of resources - add extra fields for variable substitution - add extra fields for name reference diff --git a/examples/transformerconfigs/crd/README.md b/examples/transformerconfigs/crd/README.md index 6943c416e..00aee7f80 100644 --- a/examples/transformerconfigs/crd/README.md +++ b/examples/transformerconfigs/crd/README.md @@ -8,38 +8,6 @@ Create a workspace by DEMO_HOME=$(mktemp -d) ``` -### Get the native config as a starting point - -Get the default transformer configurations using this command: - - -``` -kustomize config save -d $DEMO_HOME/kustomizeconfig -``` -The default configurations are saved -in the directory `$DEMO_HOME/kustomizeconfig` as several files - -> ``` -> commonannotations.yaml -> commonlabels.yaml -> nameprefix.yaml -> namereference.yaml -> namespace.yaml -> varreference.yaml -> ``` - -These files contain the field specifications for native resources -that transformation directives like `namePrefix`, `commonLabels`, etc. -need to do their work. - -These default configurations already include some common -field specifictions for all types: - -- nameprefix is added to `.metadata.name` -- namespace is added to `.metadata.namespace` -- labels is added to `.metadata.labels` -- annotations is added to `.metadata.annotations` - ### Adding a custom resource Consider a CRD of kind `MyKind` with fields @@ -51,6 +19,7 @@ Consider a CRD of kind `MyKind` with fields Add the following file to configure the transformers for the above fields ``` +mkdir $DEMO_HOME/kustomizeconfig cat > $DEMO_HOME/kustomizeconfig/mykind.yaml << EOF commonLabels: @@ -148,12 +117,6 @@ in the kustomization file: cat >> $DEMO_HOME/kustomization.yaml << EOF configurations: - kustomizeconfig/mykind.yaml -- kustomizeconfig/commonannotations.yaml -- kustomizeconfig/commonlabels.yaml -- kustomizeconfig/nameprefix.yaml -- kustomizeconfig/namereference.yaml -- kustomizeconfig/namespace.yaml -- kustomizeconfig/varreference.yaml EOF ``` From b0c3cd75e1dc818c3a011db69ad387f82e8a1b1e Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Wed, 27 Feb 2019 14:11:15 -0800 Subject: [PATCH 141/317] update the doc for crds: the files in this list should be openAPI definition --- docs/kustomization.yaml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index 75e1701fe..668405223 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -201,7 +201,7 @@ patchesJson6902: path: add_service_annotation.yaml # Each entry in this list should be a relative path to -# a file for custom resource definition(CRD). +# a file for custom resource definition(CRD) in openAPI definition. # # The presence of this field is to allow kustomize be # aware of CRDs and apply proper @@ -211,9 +211,17 @@ patchesJson6902: # In kustomization, the ConfigMap object name may change by adding namePrefix, nameSuffix, or hashing # The name reference for this ConfigMap object in CRD object need to be # updated with namePrefix, nameSuffix, or hashing in the same way. +# +# The annotations can be put into openAPI definitions are: +# "x-kubernetes-annotation": "" +# "x-kubernetes-label-selector": "" +# "x-kubernetes-identity": "" +# "x-kubernetes-object-ref-api-version": "v1", +# "x-kubernetes-object-ref-kind": "Secret", +# "x-kubernetes-object-ref-name-key": "name", crds: -- crds/typeA.yaml -- crds/typeB.yaml +- crds/typeA.json +- crds/typeB.json # Vars are used to capture text from one resource's field # and insert that text elsewhere. From bb69e9e70b572ba81292ee22023fb794accff0ab Mon Sep 17 00:00:00 2001 From: Ken Maglio Date: Thu, 28 Feb 2019 21:45:40 -0600 Subject: [PATCH 142/317] Updates documentation for support and source --- docs/INSTALL.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 206bbd08b..1c386951f 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -9,13 +9,19 @@ manager: brew install kustomize On windows, you can install kustomize with Chocolatey package -manager: +manager. choco install kustomize +For support on the chocolatey package and prior releases, please reference the following links: +- [Choco Package](https://chocolatey.org/packages/kustomize) +- [Package Source](https://github.com/kenmaglio/choco-kustomize) + + For all operating systems, download a binary from the [release page]. + Or try this to grab the latest official release using the command line: From 1303ea396960ddd7b0a279be09246d83f708b899 Mon Sep 17 00:00:00 2001 From: Phillip Wittrock Date: Thu, 28 Feb 2019 19:21:59 -0800 Subject: [PATCH 143/317] Run kustomize tests on OSX --- .travis.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7445d9934..2e599473a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,15 @@ +os: +# TODO: Enable this when we can get the tests to work +# - windows + - linux + - osx + +addons: + apt: + packages: tree + homebrew: + packages: tree + language: go go: @@ -17,7 +29,6 @@ env: before_install: - source ./bin/consider-early-travis-exit.sh - - sudo apt-get install tree - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $GOPATH/bin ${GOLANGCI_RELEASE} - go get -u github.com/monopole/mdrip From eb752039266a20ce0ad9e868309a7fc1b9b8f5b6 Mon Sep 17 00:00:00 2001 From: Narayanan Singaram Date: Fri, 1 Mar 2019 23:23:32 -0800 Subject: [PATCH 144/317] Fix for #831 - Ignore domain when finding the image tag --- pkg/transformers/image.go | 13 ++++++++++++- pkg/transformers/image_test.go | 8 ++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/pkg/transformers/image.go b/pkg/transformers/image.go index 734b5aca7..2e0797694 100644 --- a/pkg/transformers/image.go +++ b/pkg/transformers/image.go @@ -143,7 +143,18 @@ func isImageMatched(s, t string) bool { // from the image string using either colon `:` or at `@` separators. // Note that the returned tag keeps its separator. func split(imageName string) (name string, tag string) { - ic := strings.LastIndex(imageName, ":") + // check if image name contains a domain + // if domain is present, ignore domain and check for `:` + ic := -1 + if slashIndex := strings.Index(imageName, "/"); slashIndex < 0 { + ic = strings.LastIndex(imageName, ":") + } else { + lastIc := strings.LastIndex(imageName[slashIndex:], ":") + // set ic only if `:` is present + if lastIc > 0 { + ic = slashIndex + lastIc + } + } ia := strings.LastIndex(imageName, "@") if ic < 0 && ia < 0 { return imageName, "" diff --git a/pkg/transformers/image_test.go b/pkg/transformers/image_test.go index f1bf18351..c62ba3432 100644 --- a/pkg/transformers/image_test.go +++ b/pkg/transformers/image_test.go @@ -118,6 +118,10 @@ func TestImageTransformer(t *testing.T) { "name": "myimage", "image": "myprivaterepohostname:1234/my/image:latest", }, + map[string]interface{}{ + "name": "myimage2", + "image": "myprivaterepohostname:1234/my/image", + }, map[string]interface{}{ "name": "my-app", "image": "my-app-image:v1", @@ -218,6 +222,10 @@ func TestImageTransformer(t *testing.T) { "name": "myimage", "image": "myprivaterepohostname:1234/my/image:v1.0.1", }, + map[string]interface{}{ + "name": "myimage2", + "image": "myprivaterepohostname:1234/my/image:v1.0.1", + }, map[string]interface{}{ "name": "my-app", "image": "gcr.io/my-project/my-app-image:v1", From ea3d5e68db0aa21cadc7619d4258f02fe35e10df Mon Sep 17 00:00:00 2001 From: Narayanan Singaram Date: Sat, 2 Mar 2019 12:23:55 -0800 Subject: [PATCH 145/317] Fix for #818 - Added support for quoted values --- pkg/commands/edit/add/addmetadata.go | 21 ++++++-- pkg/commands/edit/add/addmetadata_test.go | 63 ++++++++++++++++++++++- 2 files changed, 79 insertions(+), 5 deletions(-) diff --git a/pkg/commands/edit/add/addmetadata.go b/pkg/commands/edit/add/addmetadata.go index 633c7566a..f39bc3bb1 100644 --- a/pkg/commands/edit/add/addmetadata.go +++ b/pkg/commands/edit/add/addmetadata.go @@ -135,13 +135,28 @@ func (o *addMetadataOptions) convertToMap(arg string) (map[string]string, error) return nil, o.makeError(input, "empty key") } if len(kv) > 2 { - return nil, o.makeError(input, "too many colons") - } - if len(kv) > 1 { + // more than one colon found + // check if value is quoted + qc := strings.Index(input, ":\"") + if qc >= 1 && input[len(input)-1:] == "\"" { + //value is quoted + result[kv[0]] = input[qc+1:] + } else { + // value is not quoted, return error + return nil, o.makeError(input, "too many colons, quote the values") + } + } else if len(kv) == 2 { result[kv[0]] = kv[1] } else { result[kv[0]] = "" } + + // remove quotes if value is quoted + if len(result[kv[0]]) > 0 && + result[kv[0]][:1] == "\"" && + result[kv[0]][len(result[kv[0]])-1:] == "\"" { + result[kv[0]] = result[kv[0]][1 : len(result[kv[0]])-1] + } } return result, nil } diff --git a/pkg/commands/edit/add/addmetadata_test.go b/pkg/commands/edit/add/addmetadata_test.go index dce543396..8d1041ec3 100644 --- a/pkg/commands/edit/add/addmetadata_test.go +++ b/pkg/commands/edit/add/addmetadata_test.go @@ -17,6 +17,7 @@ limitations under the License. package add import ( + "reflect" "testing" "sigs.k8s.io/kustomize/pkg/commands/kustfile" @@ -103,6 +104,32 @@ func TestAddAnnotationManyArgs(t *testing.T) { } } +func TestAddAnnotationValueQuoted(t *testing.T) { + fakeFS := fs.MakeFakeFS() + fakeFS.WriteTestKustomization() + v := validators.MakeHappyMapValidator(t) + cmd := newCmdAddAnnotation(fakeFS, v.Validator) + args := []string{"k1:\"v1\""} + err := cmd.RunE(cmd, args) + v.VerifyCall() + if err != nil { + t.Errorf("unexpected error: %v", err.Error()) + } +} + +func TestAddAnnotationValueWithColon(t *testing.T) { + fakeFS := fs.MakeFakeFS() + fakeFS.WriteTestKustomization() + v := validators.MakeHappyMapValidator(t) + cmd := newCmdAddAnnotation(fakeFS, v.Validator) + args := []string{"k1:\"v1:v2\""} + err := cmd.RunE(cmd, args) + v.VerifyCall() + if err != nil { + t.Errorf("unexpected error: %v", err.Error()) + } +} + func TestAddAnnotationNoKey(t *testing.T) { fakeFS := fs.MakeFakeFS() v := validators.MakeHappyMapValidator(t) @@ -128,7 +155,7 @@ func TestAddAnnotationTooManyColons(t *testing.T) { if err == nil { t.Errorf("expected an error") } - if err.Error() != "invalid annotation: key:v1:v2 (too many colons)" { + if err.Error() != "invalid annotation: key:v1:v2 (too many colons, quote the values)" { t.Errorf("incorrect error: %v", err.Error()) } } @@ -238,7 +265,7 @@ func TestAddLabelTooManyColons(t *testing.T) { if err == nil { t.Errorf("expected an error") } - if err.Error() != "invalid label: key:v1:v2 (too many colons)" { + if err.Error() != "invalid label: key:v1:v2 (too many colons, quote the values)" { t.Errorf("incorrect error: %v", err.Error()) } } @@ -271,3 +298,35 @@ func TestAddLabelMultipleArgs(t *testing.T) { t.Errorf("incorrect error: %v", err.Error()) } } + +func TestConvertToMap(t *testing.T) { + var o addMetadataOptions + args := "a:b,c:\"d\",e:\"f:g\"" + expected := make(map[string]string) + expected["a"] = "b" + expected["c"] = "d" + expected["e"] = "f:g" + + result, err := o.convertToMap(args) + if err != nil { + t.Errorf("unexpected error: %v", err.Error()) + } + + eq := reflect.DeepEqual(expected, result) + if !eq { + t.Errorf("Converted map does not match expected, expected: %v, result: %v\n", expected, result) + } +} + +func TestConvertToMapError(t *testing.T) { + var o addMetadataOptions + args := "a:b,c:\"d\",e:f:g" + + _, err := o.convertToMap(args) + if err == nil { + t.Errorf("expected an error") + } + if err.Error() != "invalid annotation: e:f:g (too many colons, quote the values)" { + t.Errorf("incorrect error: %v", err.Error()) + } +} From 45ba785641d699cbdb5738c93cbbc23fe9fb97da Mon Sep 17 00:00:00 2001 From: Yujun Zhang Date: Sun, 3 Mar 2019 10:21:03 +0800 Subject: [PATCH 146/317] Add configmaps test for json string --- pkg/target/configmaps_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkg/target/configmaps_test.go b/pkg/target/configmaps_test.go index cad35066b..dd69adb3b 100644 --- a/pkg/target/configmaps_test.go +++ b/pkg/target/configmaps_test.go @@ -35,6 +35,9 @@ configMapGenerator: files: - passphrase=phrase.dat - forces.txt +- name: json + literals: + - 'v2=[{"path": "var/druid/segment-cache"}]' secretGenerator: - name: bob literals: @@ -87,6 +90,13 @@ metadata: name: blah-bob-k772g5db55 --- apiVersion: v1 +data: + v2: '[{"path": "var/druid/segment-cache"}]' +kind: ConfigMap +metadata: + name: blah-json-tkh79m5tbc +--- +apiVersion: v1 data: MOUNTAIN: ZXZlcmVzdA== OCEAN: cGFjaWZpYw== From ed2ad860c69738dc7e2fe876e16f57236ba6790c Mon Sep 17 00:00:00 2001 From: Narayanan Singaram Date: Mon, 4 Mar 2019 13:19:18 -0800 Subject: [PATCH 147/317] Move trim quotes logic to separate function --- pkg/commands/edit/add/addmetadata.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/pkg/commands/edit/add/addmetadata.go b/pkg/commands/edit/add/addmetadata.go index f39bc3bb1..cbb3bc8a7 100644 --- a/pkg/commands/edit/add/addmetadata.go +++ b/pkg/commands/edit/add/addmetadata.go @@ -152,11 +152,7 @@ func (o *addMetadataOptions) convertToMap(arg string) (map[string]string, error) } // remove quotes if value is quoted - if len(result[kv[0]]) > 0 && - result[kv[0]][:1] == "\"" && - result[kv[0]][len(result[kv[0]])-1:] == "\"" { - result[kv[0]] = result[kv[0]][1 : len(result[kv[0]])-1] - } + result[kv[0]] = trimQuotes(result[kv[0]]) } return result, nil } @@ -188,3 +184,12 @@ func (o *addMetadataOptions) writeToMap(m map[string]string, kind kindOfAdd) err func (o *addMetadataOptions) makeError(input string, message string) error { return fmt.Errorf("invalid %s: %s (%s)", o.kind, input, message) } + +func trimQuotes(s string) string { + if len(s) >= 2 { + if s[0] == '"' && s[len(s)-1] == '"' { + return s[1 : len(s)-1] + } + } + return s +} From e666630d36be79d3beef8d150fd4f6f48bb310de Mon Sep 17 00:00:00 2001 From: Narayanan Singaram Date: Mon, 4 Mar 2019 13:50:49 -0800 Subject: [PATCH 148/317] Simplify map conversion logic --- pkg/commands/edit/add/addmetadata.go | 34 ++++++++--------------- pkg/commands/edit/add/addmetadata_test.go | 31 ++++++++++----------- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/pkg/commands/edit/add/addmetadata.go b/pkg/commands/edit/add/addmetadata.go index cbb3bc8a7..d9104f35d 100644 --- a/pkg/commands/edit/add/addmetadata.go +++ b/pkg/commands/edit/add/addmetadata.go @@ -130,29 +130,19 @@ func (o *addMetadataOptions) convertToMap(arg string) (map[string]string, error) result := make(map[string]string) inputs := strings.Split(arg, ",") for _, input := range inputs { - kv := strings.Split(input, ":") - if len(kv[0]) < 1 { - return nil, o.makeError(input, "empty key") - } - if len(kv) > 2 { - // more than one colon found - // check if value is quoted - qc := strings.Index(input, ":\"") - if qc >= 1 && input[len(input)-1:] == "\"" { - //value is quoted - result[kv[0]] = input[qc+1:] - } else { - // value is not quoted, return error - return nil, o.makeError(input, "too many colons, quote the values") - } - } else if len(kv) == 2 { - result[kv[0]] = kv[1] + c := strings.Index(input, ":") + if c == 0 { + // key is not passed + return nil, o.makeError(input, "need k:v pair where v may be quoted") + } else if c < 0 { + // only key passed + result[input] = "" } else { - result[kv[0]] = "" + // both key and value passed + key := input[:c] + value := trimQuotes(input[c+1:]) + result[key] = value } - - // remove quotes if value is quoted - result[kv[0]] = trimQuotes(result[kv[0]]) } return result, nil } @@ -182,7 +172,7 @@ func (o *addMetadataOptions) writeToMap(m map[string]string, kind kindOfAdd) err } func (o *addMetadataOptions) makeError(input string, message string) error { - return fmt.Errorf("invalid %s: %s (%s)", o.kind, input, message) + return fmt.Errorf("invalid %s: '%s' (%s)", o.kind, input, message) } func trimQuotes(s string) string { diff --git a/pkg/commands/edit/add/addmetadata_test.go b/pkg/commands/edit/add/addmetadata_test.go index 8d1041ec3..6c7f0743a 100644 --- a/pkg/commands/edit/add/addmetadata_test.go +++ b/pkg/commands/edit/add/addmetadata_test.go @@ -140,23 +140,21 @@ func TestAddAnnotationNoKey(t *testing.T) { if err == nil { t.Errorf("expected an error") } - if err.Error() != "invalid annotation: :nokey (empty key)" { + if err.Error() != "invalid annotation: ':nokey' (need k:v pair where v may be quoted)" { t.Errorf("incorrect error: %v", err.Error()) } } func TestAddAnnotationTooManyColons(t *testing.T) { fakeFS := fs.MakeFakeFS() + fakeFS.WriteTestKustomization() v := validators.MakeHappyMapValidator(t) cmd := newCmdAddAnnotation(fakeFS, v.Validator) args := []string{"key:v1:v2"} err := cmd.RunE(cmd, args) - v.VerifyNoCall() - if err == nil { - t.Errorf("expected an error") - } - if err.Error() != "invalid annotation: key:v1:v2 (too many colons, quote the values)" { - t.Errorf("incorrect error: %v", err.Error()) + v.VerifyCall() + if err != nil { + t.Errorf("unexpected error: %v", err.Error()) } } @@ -250,23 +248,21 @@ func TestAddLabelNoKey(t *testing.T) { if err == nil { t.Errorf("expected an error") } - if err.Error() != "invalid label: :nokey (empty key)" { + if err.Error() != "invalid label: ':nokey' (need k:v pair where v may be quoted)" { t.Errorf("incorrect error: %v", err.Error()) } } func TestAddLabelTooManyColons(t *testing.T) { fakeFS := fs.MakeFakeFS() + fakeFS.WriteTestKustomization() v := validators.MakeHappyMapValidator(t) cmd := newCmdAddLabel(fakeFS, v.Validator) args := []string{"key:v1:v2"} err := cmd.RunE(cmd, args) - v.VerifyNoCall() - if err == nil { - t.Errorf("expected an error") - } - if err.Error() != "invalid label: key:v1:v2 (too many colons, quote the values)" { - t.Errorf("incorrect error: %v", err.Error()) + v.VerifyCall() + if err != nil { + t.Errorf("unexpected error: %v", err.Error()) } } @@ -301,11 +297,12 @@ func TestAddLabelMultipleArgs(t *testing.T) { func TestConvertToMap(t *testing.T) { var o addMetadataOptions - args := "a:b,c:\"d\",e:\"f:g\"" + args := "a:b,c:\"d\",e:\"f:g\",g:h:k" expected := make(map[string]string) expected["a"] = "b" expected["c"] = "d" expected["e"] = "f:g" + expected["g"] = "h:k" result, err := o.convertToMap(args) if err != nil { @@ -320,13 +317,13 @@ func TestConvertToMap(t *testing.T) { func TestConvertToMapError(t *testing.T) { var o addMetadataOptions - args := "a:b,c:\"d\",e:f:g" + args := "a:b,c:\"d\",:f:g" _, err := o.convertToMap(args) if err == nil { t.Errorf("expected an error") } - if err.Error() != "invalid annotation: e:f:g (too many colons, quote the values)" { + if err.Error() != "invalid annotation: ':f:g' (need k:v pair where v may be quoted)" { t.Errorf("incorrect error: %v", err.Error()) } } From 28cefb3bd1a676ffffed6f70b4fe88bf7fe9aa5d Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Thu, 28 Feb 2019 13:07:44 -0800 Subject: [PATCH 149/317] improve error message for loading files listed under crds --- pkg/transformers/config/factorycrd.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/transformers/config/factorycrd.go b/pkg/transformers/config/factorycrd.go index 8aaa8ee64..66a24dc86 100644 --- a/pkg/transformers/config/factorycrd.go +++ b/pkg/transformers/config/factorycrd.go @@ -22,6 +22,7 @@ import ( "github.com/ghodss/yaml" "github.com/go-openapi/spec" + "github.com/pkg/errors" "k8s.io/kube-openapi/pkg/common" "sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/ifc" @@ -41,7 +42,7 @@ func LoadConfigFromCRDs( } m, err := makeNameToApiMap(content) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "unable to parse open API definition from '%s'", path) } otherTc, err := makeConfigFromApiMap(m) if err != nil { From 78cbff16ef15b5e41d2c10b3baaeb5fffd06d7ed Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Thu, 28 Feb 2019 10:01:02 -0800 Subject: [PATCH 150/317] improve error message in json patch transformer --- pkg/patch/transformer/factory.go | 16 +---- pkg/patch/transformer/patchjson6902json.go | 24 ++++++-- .../transformer/patchjson6902json_test.go | 58 +++++++++++++++++-- 3 files changed, 73 insertions(+), 25 deletions(-) diff --git a/pkg/patch/transformer/factory.go b/pkg/patch/transformer/factory.go index b7eb25839..b373dfb72 100644 --- a/pkg/patch/transformer/factory.go +++ b/pkg/patch/transformer/factory.go @@ -21,8 +21,6 @@ import ( "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/resid" - "github.com/evanphx/json-patch" - "github.com/ghodss/yaml" "sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/patch" "sigs.k8s.io/kustomize/pkg/transformers" @@ -77,19 +75,7 @@ func (f PatchJson6902Factory) makeOnePatchJson6902Transformer(p patch.Json6902) return nil, err } - if !isJsonFormat(rawOp) { - // if it isn't JSON, try to parse it as YAML - rawOp, err = yaml.YAMLToJSON(rawOp) - if err != nil { - return nil, err - } - } - - decodedPatch, err := jsonpatch.DecodePatch(rawOp) - if err != nil { - return nil, err - } - return newPatchJson6902JSONTransformer(targetId, decodedPatch) + return newPatchJson6902JSONTransformer(targetId, rawOp) } func isJsonFormat(data []byte) bool { diff --git a/pkg/patch/transformer/patchjson6902json.go b/pkg/patch/transformer/patchjson6902json.go index c8f6e9e3e..1f09939d1 100644 --- a/pkg/patch/transformer/patchjson6902json.go +++ b/pkg/patch/transformer/patchjson6902json.go @@ -20,6 +20,8 @@ import ( "fmt" "github.com/evanphx/json-patch" + "github.com/ghodss/yaml" + "github.com/pkg/errors" "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" @@ -30,17 +32,31 @@ import ( type patchJson6902JSONTransformer struct { target resid.ResId patch jsonpatch.Patch + rawOp []byte } var _ transformers.Transformer = &patchJson6902JSONTransformer{} // newPatchJson6902JSONTransformer constructs a PatchJson6902 transformer. func newPatchJson6902JSONTransformer( - id resid.ResId, p jsonpatch.Patch) (transformers.Transformer, error) { - if len(p) == 0 { + id resid.ResId, rawOp []byte) (transformers.Transformer, error) { + op := rawOp + var err error + if !isJsonFormat(op) { + // if it isn't JSON, try to parse it as YAML + op, err = yaml.YAMLToJSON(rawOp) + if err != nil { + return nil, err + } + } + decodedPatch, err := jsonpatch.DecodePatch(op) + if err != nil { + return nil, err + } + if len(decodedPatch) == 0 { return transformers.NewNoOpTransformer(), nil } - return &patchJson6902JSONTransformer{target: id, patch: p}, nil + return &patchJson6902JSONTransformer{target: id, patch: decodedPatch, rawOp: rawOp}, nil } // Transform apply the json patches on top of the base resources. @@ -55,7 +71,7 @@ func (t *patchJson6902JSONTransformer) Transform(m resmap.ResMap) error { } modifiedObj, err := t.patch.Apply(rawObj) if err != nil { - return err + return errors.Wrapf(err, "failed to apply json patch '%s'", string(t.rawOp)) } err = obj.UnmarshalJSON(modifiedObj) if err != nil { diff --git a/pkg/patch/transformer/patchjson6902json_test.go b/pkg/patch/transformer/patchjson6902json_test.go index 033ac1603..8e5c751cc 100644 --- a/pkg/patch/transformer/patchjson6902json_test.go +++ b/pkg/patch/transformer/patchjson6902json_test.go @@ -18,9 +18,9 @@ package transformer import ( "reflect" + "strings" "testing" - "github.com/evanphx/json-patch" "sigs.k8s.io/kustomize/k8sdeps/kunstruct" "sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/resid" @@ -67,10 +67,7 @@ func TestJsonPatchJSONTransformer_Transform(t *testing.T) { {"op": "add", "path": "/spec/replica", "value": "3"}, {"op": "add", "path": "/spec/template/spec/containers/0/command", "value": ["arg1", "arg2", "arg3"]} ]`) - patch, err := jsonpatch.DecodePatch(operations) - if err != nil { - t.Fatalf("unexpected error : %v", err) - } + expected := resmap.ResMap{ id: rf.FromMap( map[string]interface{}{ @@ -104,7 +101,7 @@ func TestJsonPatchJSONTransformer_Transform(t *testing.T) { }, }), } - jpt, err := newPatchJson6902JSONTransformer(id, patch) + jpt, err := newPatchJson6902JSONTransformer(id, operations) if err != nil { t.Fatalf("unexpected error : %v", err) } @@ -117,3 +114,52 @@ func TestJsonPatchJSONTransformer_Transform(t *testing.T) { t.Fatalf("actual doesn't match expected: %v", err) } } + +func TestJsonPatchJSONTransformer_UnHappyTransform(t *testing.T) { + rf := resource.NewFactory( + kunstruct.NewKunstructuredFactoryImpl()) + id := resid.NewResId(deploy, "deploy1") + base := resmap.ResMap{ + id: rf.FromMap( + map[string]interface{}{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": map[string]interface{}{ + "name": "deploy1", + }, + "spec": map[string]interface{}{ + "template": map[string]interface{}{ + "metadata": map[string]interface{}{ + "labels": map[string]interface{}{ + "old-label": "old-value", + }, + }, + "spec": map[string]interface{}{ + "containers": []interface{}{ + map[string]interface{}{ + "name": "nginx", + "image": "nginx", + }, + }, + }, + }, + }, + }), + } + + operations := []byte(`[ + {"op": "add", "path": "/spec/template/spec/containers/0/command/", "value": ["arg1", "arg2", "arg3"]} +]`) + + jpt, err := newPatchJson6902JSONTransformer(id, operations) + if err != nil { + t.Fatalf("unexpected error : %v", err) + } + err = jpt.Transform(base) + if err == nil { + t.Fatalf("expected error didn't happen") + } + if !strings.HasPrefix(err.Error(), "failed to apply json patch") || !strings.Contains(err.Error(), string(operations)) { + t.Fatalf("expected error didn't happen, but got %v", err) + } +} From 4f429d6b86f16c1baafc5a29caf919e19c223935 Mon Sep 17 00:00:00 2001 From: Philipp Strube Date: Wed, 6 Mar 2019 19:13:38 +0100 Subject: [PATCH 151/317] Reduce time required for cloning remote bases This commit changes git/cloner.go from cloning the whole history and then checking out the desired ref to a implementation that only downloads the history for the desired ref. It does so by first initializing an empty repository, setting the source repository as a remote, fetching just the desired ref and then hard resetting the empty local repo to that ref. This reduces the time it takes to build the multibases example as a remote base at ref v2.0.3 from an avg of 8s with the current implementation to an avg of 2s out of 10 runs each, by drastically decreasing the data transferred. The improvement should increase as repositories grow. --- pkg/git/cloner.go | 53 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/pkg/git/cloner.go b/pkg/git/cloner.go index 465fdb1d1..cbf176448 100644 --- a/pkg/git/cloner.go +++ b/pkg/git/cloner.go @@ -41,24 +41,61 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error { } cmd := exec.Command( gitProgram, - "clone", - repoSpec.CloneSpec(), + "init", repoSpec.cloneDir.String()) var out bytes.Buffer cmd.Stdout = &out err = cmd.Run() if err != nil { - return errors.Wrapf(err, "trouble cloning %s", repoSpec.raw) + return errors.Wrapf( + err, + "trouble initializing empty git repo in %s", + repoSpec.cloneDir.String()) } - if repoSpec.ref == "" { - return nil - } - cmd = exec.Command(gitProgram, "checkout", repoSpec.ref) + + cmd = exec.Command( + gitProgram, + "remote", + "add", + "origin", + repoSpec.CloneSpec()) + cmd.Stdout = &out cmd.Dir = repoSpec.cloneDir.String() err = cmd.Run() if err != nil { return errors.Wrapf( - err, "trouble checking out href %s", repoSpec.ref) + err, + "trouble adding remote %s", + repoSpec.CloneSpec()) + } + + if repoSpec.ref == "" { + return nil + } + cmd = exec.Command( + gitProgram, + "fetch", + "--depth=1", + "origin", + repoSpec.ref) + cmd.Stdout = &out + cmd.Dir = repoSpec.cloneDir.String() + err = cmd.Run() + if err != nil { + return errors.Wrapf(err, "trouble fetching %s", repoSpec.ref) + } + + cmd = exec.Command( + gitProgram, + "reset", + "--hard", + "FETCH_HEAD") + cmd.Stdout = &out + cmd.Dir = repoSpec.cloneDir.String() + err = cmd.Run() + if err != nil { + return errors.Wrapf( + err, "trouble hard resetting empty repository to %s", repoSpec.ref) } return nil } From 559efd64779a956b680a30d4e24188fe8e1cb064 Mon Sep 17 00:00:00 2001 From: mnatsu31 Date: Fri, 8 Mar 2019 13:20:34 +0900 Subject: [PATCH 152/317] Fix typo in namereference path for cronjobs initContainers. --- pkg/transformers/config/defaultconfig/namereference.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/transformers/config/defaultconfig/namereference.go b/pkg/transformers/config/defaultconfig/namereference.go index 35d4b7de0..fdcfdbbf5 100644 --- a/pkg/transformers/config/defaultconfig/namereference.go +++ b/pkg/transformers/config/defaultconfig/namereference.go @@ -114,7 +114,7 @@ nameReference: kind: CronJob - path: spec/jobTemplate/spec/template/spec/containers/envFrom/configMapRef/name kind: CronJob - - path: spec/jobTemplate/spec/template/spec/initContainers/envFrom/configmapRef/name + - path: spec/jobTemplate/spec/template/spec/initContainers/envFrom/configMapRef/name kind: CronJob - kind: Secret From 3a44508d6f8e0bb8bdcfe53ab1c512ede06a1ba8 Mon Sep 17 00:00:00 2001 From: Yujun Zhang Date: Sat, 9 Mar 2019 16:41:51 +0800 Subject: [PATCH 153/317] Fix error message Closes #862 --- pkg/commands/edit/fix/fix.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/commands/edit/fix/fix.go b/pkg/commands/edit/fix/fix.go index e940d6d34..c0b01b991 100644 --- a/pkg/commands/edit/fix/fix.go +++ b/pkg/commands/edit/fix/fix.go @@ -30,7 +30,7 @@ func NewCmdFix(fSys fs.FileSystem) *cobra.Command { Long: "", Example: ` # Fix the missing and deprecated fields in kustomization file - kustomize fix + kustomize edit fix `, RunE: func(cmd *cobra.Command, args []string) error { @@ -40,6 +40,7 @@ func NewCmdFix(fSys fs.FileSystem) *cobra.Command { return cmd } +// RunFix runs `fix` command func RunFix(fSys fs.FileSystem) error { mf, err := kustfile.NewKustomizationFile(fSys) if err != nil { From 0f571b91207689eac8d5e2d88e1ce6d7795d6e57 Mon Sep 17 00:00:00 2001 From: Yujun Zhang Date: Sat, 9 Mar 2019 16:58:32 +0800 Subject: [PATCH 154/317] Fix field names --- docs/versioningPolicy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/versioningPolicy.md b/docs/versioningPolicy.md index 8017b0f87..6ae7175bf 100644 --- a/docs/versioningPolicy.md +++ b/docs/versioningPolicy.md @@ -64,13 +64,13 @@ deprecations fixable via `edit fix`. With the 2.0.0 release, there were three field removals: -- `imageTag` was deprecated when `image` was +- `imageTag` was deprecated when `images` was introduced, because the latter offers more general features for image data manipulation. `imageTag` was removed in v2.0.0. - `patches` was deprecated and replaced by - `PatchesStrategicMerge` when `PatchesJson6902` + `patchesStrategicMerge` when `patchesJson6902` was introduced, to make a clearer distinction between patch specification formats. `patches` was removed in v2.0.0. From 3d0e29075d0a1432ce212bb74513cbddcea167ab Mon Sep 17 00:00:00 2001 From: Yujun Zhang Date: Sat, 9 Mar 2019 17:02:39 +0800 Subject: [PATCH 155/317] Fix markdownlint warnings --- docs/versioningPolicy.md | 49 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/docs/versioningPolicy.md b/docs/versioningPolicy.md index 6ae7175bf..278348b30 100644 --- a/docs/versioningPolicy.md +++ b/docs/versioningPolicy.md @@ -19,14 +19,14 @@ number are bumped per semver. At the time of writing (circa release of v2.0.0): - - A [kustomization] file is just a YAML file that - can be successfully parsed into a particular Go - struct defined in the `kustomize` binary. +- A [kustomization] file is just a YAML file that + can be successfully parsed into a particular Go + struct defined in the `kustomize` binary. - - This struct does not have a version number, - which is the same as saying that its version - number matches the program's version number, - since it's compiled in. +- This struct does not have a version number, + which is the same as saying that its version + number matches the program's version number, + since it's compiled in. ### Field Change Policy @@ -92,16 +92,16 @@ process for making [changes]. The presence of an `apiVersion` field in a k8s native type signals: - - its reliability level (alpha vs beta vs - generally available), +- its reliability level (alpha vs beta vs + generally available), + +- the existence of code to provide default values + to fields not present in a serialization, + +- the existence of code to provide both forward + and backward conversion between different + versions of types. - - the existence of code to provide default values - to fields not present in a serialization, - - - the existence of code to provide both forward - and backward conversion between different - versions of types. - The k8s API promises a lossless _conversion_ between versions over a specific range. This means that a recent client can write an object @@ -124,13 +124,13 @@ defaulting and conversions). The critical difference between k8s API versioning and kustomization file versioning is - - A k8s API server is able to go _forward_ and - _backward_ in versioning, to work with older - clients, over [some range]. +- A k8s API server is able to go _forward_ and + _backward_ in versioning, to work with older + clients, over [some range]. - - The `kustomize edit fix` command only moves - _forward_ within a _major_ program - version. +- The `kustomize edit fix` command only moves + _forward_ within a _major_ program + version. At the time of writing, the YAML in a kustomization file does not represent a [k8s API] @@ -160,7 +160,7 @@ a kustomization file: [`kind`] and [`apiVersion`]. If either field is present, they both must be, and they must have the following values: -``` +``` yaml kind: Kustomization apiVersion: kustomize.config.k8s.io/v1beta1 ``` @@ -171,7 +171,7 @@ domain-squatting behavior for some future API. A kustomize user gains nothing from adding these fields to a kustomization file. -### Why not require `kind` and `apiVersion`? +### Why not require `kind` and `apiVersion` #### Ease of use and setting proper expectations @@ -203,7 +203,6 @@ locked into `/v1beta1` or `/v1` and the `kind` and `apiVersion` fields can be required from that moment forward. - [field change policy]: #field-change-policy [some range]: https://kubernetes.io/docs/reference/using-api/deprecation-policy [proposal]: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/customresources-versioning.md From 9a4692e6eef6aecad4e5d515396dff0b9e133c98 Mon Sep 17 00:00:00 2001 From: CodeLingo Bot Date: Mon, 11 Mar 2019 00:45:21 +0000 Subject: [PATCH 156/317] Fix function comments based on best practices from Effective Go Signed-off-by: CodeLingo Bot --- pkg/resource/resource.go | 2 +- pkg/types/genargs.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/resource/resource.go b/pkg/resource/resource.go index 1e0e3764b..122fb6d6f 100644 --- a/pkg/resource/resource.go +++ b/pkg/resource/resource.go @@ -54,7 +54,7 @@ func (r *Resource) Behavior() types.GenerationBehavior { return r.options.Behavior() } -// NeedAppendHash checks if the resource need a hash suffix +// NeedHashSuffix checks if the resource need a hash suffix func (r *Resource) NeedHashSuffix() bool { return r.options != nil && r.options.NeedsHashSuffix() } diff --git a/pkg/types/genargs.go b/pkg/types/genargs.go index bef093d35..fc25dcdc9 100644 --- a/pkg/types/genargs.go +++ b/pkg/types/genargs.go @@ -47,7 +47,7 @@ func (g *GenArgs) String() string { "}" } -// NeedHashSuffix returns true if the hash suffix is needed. +// NeedsHashSuffix returns true if the hash suffix is needed. // It is needed when the two conditions are both met // 1) GenArgs is not nil // 2) DisableNameSuffixHash in GeneratorOptions is not set to true From f7cd44be42db1230e97a6b5b98872f68f0e8d04c Mon Sep 17 00:00:00 2001 From: Yordi Pauptit Date: Mon, 11 Mar 2019 15:12:26 +0100 Subject: [PATCH 157/317] add job initcontainer to varreference config --- pkg/transformers/config/defaultconfig/varreference.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/transformers/config/defaultconfig/varreference.go b/pkg/transformers/config/defaultconfig/varreference.go index 71953f576..77bffbeda 100644 --- a/pkg/transformers/config/defaultconfig/varreference.go +++ b/pkg/transformers/config/defaultconfig/varreference.go @@ -88,6 +88,9 @@ varReference: - path: spec/template/spec/containers/env/value kind: Job +- path: spec/template/spec/initContainers/env/value + kind: Job + - path: spec/jobTemplate/spec/template/spec/containers/env/value kind: CronJob From fa552d7773e8c9df2a388e02ce72f36e8c6f274a Mon Sep 17 00:00:00 2001 From: Karen Bradshaw Date: Mon, 11 Mar 2019 17:23:30 -0400 Subject: [PATCH 158/317] fix help msg for set image cmd --- pkg/commands/edit/set/setimage.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/commands/edit/set/setimage.go b/pkg/commands/edit/set/setimage.go index e861504f5..347166fa9 100644 --- a/pkg/commands/edit/set/setimage.go +++ b/pkg/commands/edit/set/setimage.go @@ -60,7 +60,7 @@ The command set image postgres=eu.gcr.io/my-project/postgres:latest my-app=my-registry/my-app@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 will add -image: +images: - name: postgres newName: eu.gcr.io/my-project/postgres newTag: latest @@ -75,7 +75,7 @@ The command set image node:8.15.0 mysql=mariadb alpine@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 will add -image: +images: - name: node newTag: 8.15.0 - name: mysql From 62d3200e4fcff1b2c9d31c937be6988f8406f7a3 Mon Sep 17 00:00:00 2001 From: Yordi Pauptit Date: Thu, 14 Mar 2019 09:36:21 +0100 Subject: [PATCH 159/317] fix typo in namereference where serviceaccount name would not resolve --- pkg/transformers/config/defaultconfig/namereference.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/transformers/config/defaultconfig/namereference.go b/pkg/transformers/config/defaultconfig/namereference.go index fdcfdbbf5..669fc2407 100644 --- a/pkg/transformers/config/defaultconfig/namereference.go +++ b/pkg/transformers/config/defaultconfig/namereference.go @@ -286,7 +286,7 @@ nameReference: - path: spec/jobTemplate/spec/template/spec/serviceAccountName kind: CronJob - path: spec/template/spec/serviceAccountName - kind: job + kind: Job - path: spec/template/spec/serviceAccountName kind: DaemonSet From c06b95077de54fb4ccde7a39db0e1aa17a290c87 Mon Sep 17 00:00:00 2001 From: jregan Date: Tue, 12 Mar 2019 13:16:44 -0700 Subject: [PATCH 160/317] Secret/configmap factory cleanup. --- .../{kv.go => basefactory.go} | 51 +++++++++++++-- .../{kv_test.go => basefactory_test.go} | 3 +- .../configmapandsecret/configmapfactory.go | 65 +++++-------------- .../configmapfactory_test.go | 4 +- k8sdeps/configmapandsecret/secretfactory.go | 61 ++++------------- .../configmapandsecret/secretfactory_test.go | 4 +- k8sdeps/kunstruct/factory.go | 26 ++++---- pkg/commands/edit/add/configmap.go | 7 +- pkg/commands/edit/add/secret.go | 7 +- pkg/ifc/ifc.go | 11 +++- pkg/resmap/factory.go | 19 +++--- pkg/resmap/factory_test.go | 8 +-- pkg/resource/factory.go | 33 ++++++---- pkg/target/kusttarget.go | 16 +++-- 14 files changed, 158 insertions(+), 157 deletions(-) rename k8sdeps/configmapandsecret/{kv.go => basefactory.go} (68%) rename k8sdeps/configmapandsecret/{kv_test.go => basefactory_test.go} (92%) diff --git a/k8sdeps/configmapandsecret/kv.go b/k8sdeps/configmapandsecret/basefactory.go similarity index 68% rename from k8sdeps/configmapandsecret/kv.go rename to k8sdeps/configmapandsecret/basefactory.go index ffc7a1b14..326601673 100644 --- a/k8sdeps/configmapandsecret/kv.go +++ b/k8sdeps/configmapandsecret/basefactory.go @@ -22,10 +22,53 @@ import ( "strings" "github.com/pkg/errors" + "k8s.io/apimachinery/pkg/util/validation" "sigs.k8s.io/kustomize/k8sdeps/kv" "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/types" ) +// baseFactory holds code shared by Factory and SecretFactory. +type baseFactory struct { + ldr ifc.Loader + options *types.GeneratorOptions +} + +func (bf baseFactory) loadKvPairs( + args types.GeneratorArgs) (all []kv.Pair, err error) { + pairs, err := bf.keyValuesFromEnvFile(args.EnvSource) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf( + "env source file: %s", + args.EnvSource)) + } + all = append(all, pairs...) + + pairs, err = keyValuesFromLiteralSources(args.LiteralSources) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf( + "literal sources %v", args.LiteralSources)) + } + all = append(all, pairs...) + + pairs, err = bf.keyValuesFromFileSources(args.FileSources) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf( + "file sources: %v", args.FileSources)) + } + return append(all, pairs...), nil +} + +const keyExistsErrorMsg = "cannot add key %s, another key by that name already exists: %v" + +func errIfInvalidKey(keyName string) error { + if errs := validation.IsConfigMapKey(keyName); len(errs) != 0 { + return fmt.Errorf("%q is not a valid key name: %s", + keyName, strings.Join(errs, ";")) + } + return nil +} + func keyValuesFromLiteralSources(sources []string) ([]kv.Pair, error) { var kvs []kv.Pair for _, s := range sources { @@ -38,14 +81,14 @@ func keyValuesFromLiteralSources(sources []string) ([]kv.Pair, error) { return kvs, nil } -func keyValuesFromFileSources(ldr ifc.Loader, sources []string) ([]kv.Pair, error) { +func (bf baseFactory) keyValuesFromFileSources(sources []string) ([]kv.Pair, error) { var kvs []kv.Pair for _, s := range sources { k, fPath, err := parseFileSource(s) if err != nil { return nil, err } - content, err := ldr.Load(fPath) + content, err := bf.ldr.Load(fPath) if err != nil { return nil, err } @@ -54,11 +97,11 @@ func keyValuesFromFileSources(ldr ifc.Loader, sources []string) ([]kv.Pair, erro return kvs, nil } -func keyValuesFromEnvFile(l ifc.Loader, path string) ([]kv.Pair, error) { +func (bf baseFactory) keyValuesFromEnvFile(path string) ([]kv.Pair, error) { if path == "" { return nil, nil } - content, err := l.Load(path) + content, err := bf.ldr.Load(path) if err != nil { return nil, err } diff --git a/k8sdeps/configmapandsecret/kv_test.go b/k8sdeps/configmapandsecret/basefactory_test.go similarity index 92% rename from k8sdeps/configmapandsecret/kv_test.go rename to k8sdeps/configmapandsecret/basefactory_test.go index 9b19f1515..022fa9360 100644 --- a/k8sdeps/configmapandsecret/kv_test.go +++ b/k8sdeps/configmapandsecret/basefactory_test.go @@ -45,8 +45,9 @@ func TestKeyValuesFromFileSources(t *testing.T) { fSys := fs.MakeFakeFS() fSys.WriteFile("/files/app-init.ini", []byte("FOO=bar")) + bf := baseFactory{loader.NewFileLoaderAtRoot(fSys), nil} for _, tc := range tests { - kvs, err := keyValuesFromFileSources(loader.NewFileLoaderAtRoot(fSys), tc.sources) + kvs, err := bf.keyValuesFromFileSources(tc.sources) if err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/k8sdeps/configmapandsecret/configmapfactory.go b/k8sdeps/configmapandsecret/configmapfactory.go index 56362c24a..03f7abc74 100644 --- a/k8sdeps/configmapandsecret/configmapfactory.go +++ b/k8sdeps/configmapandsecret/configmapfactory.go @@ -19,29 +19,26 @@ package configmapandsecret import ( "fmt" - "strings" "unicode/utf8" - "github.com/pkg/errors" "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/validation" - "sigs.k8s.io/kustomize/k8sdeps/kv" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/types" ) -// ConfigMapFactory makes ConfigMaps. -type ConfigMapFactory struct { - ldr ifc.Loader +// Factory makes ConfigMaps and Secrets. +type Factory struct { + baseFactory } -// NewConfigMapFactory returns a new ConfigMapFactory. -func NewConfigMapFactory(l ifc.Loader) *ConfigMapFactory { - return &ConfigMapFactory{ldr: l} +// NewFactory returns a new Factory. +func NewFactory( + l ifc.Loader, o *types.GeneratorOptions) *Factory { + return &Factory{baseFactory{ldr: l, options: o}} } -func (f *ConfigMapFactory) makeFreshConfigMap( +func makeFreshConfigMap( args *types.ConfigMapArgs) *corev1.ConfigMap { cm := &corev1.ConfigMap{} cm.APIVersion = "v1" @@ -53,43 +50,22 @@ func (f *ConfigMapFactory) makeFreshConfigMap( } // MakeConfigMap returns a new ConfigMap, or nil and an error. -func (f *ConfigMapFactory) MakeConfigMap( - args *types.ConfigMapArgs, options *types.GeneratorOptions) (*corev1.ConfigMap, error) { - var all []kv.Pair - var err error - cm := f.makeFreshConfigMap(args) - - pairs, err := keyValuesFromEnvFile(f.ldr, args.EnvSource) +func (f *Factory) MakeConfigMap( + args *types.ConfigMapArgs) (*corev1.ConfigMap, error) { + all, err := f.loadKvPairs(args.GeneratorArgs) if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf( - "env source file: %s", - args.EnvSource)) + return nil, err } - all = append(all, pairs...) - - pairs, err = keyValuesFromLiteralSources(args.LiteralSources) - if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf( - "literal sources %v", args.LiteralSources)) - } - all = append(all, pairs...) - - pairs, err = keyValuesFromFileSources(f.ldr, args.FileSources) - if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf( - "file sources: %v", args.FileSources)) - } - all = append(all, pairs...) - + cm := makeFreshConfigMap(args) for _, p := range all { err = addKvToConfigMap(cm, p.Key, p.Value) if err != nil { return nil, err } } - if options != nil { - cm.SetLabels(options.Labels) - cm.SetAnnotations(options.Annotations) + if f.options != nil { + cm.SetLabels(f.options.Labels) + cm.SetAnnotations(f.options.Annotations) } return cm, nil } @@ -97,13 +73,9 @@ func (f *ConfigMapFactory) MakeConfigMap( // addKvToConfigMap adds the given key and data to the given config map. // Error if key invalid, or already exists. func addKvToConfigMap(configMap *v1.ConfigMap, keyName, data string) error { - // Note, the rules for ConfigMap keys are the exact same as the ones for SecretKeys. - if errs := validation.IsConfigMapKey(keyName); len(errs) != 0 { - return fmt.Errorf("%q is not a valid key name for a ConfigMap: %s", keyName, strings.Join(errs, ";")) + if err := errIfInvalidKey(keyName); err != nil { + return err } - - keyExistsErrorMsg := "cannot add key %s, another key by that name already exists: %v" - // If the configmap data contains byte sequences that are all in the UTF-8 // range, we will write it to .Data if utf8.Valid([]byte(data)) { @@ -113,7 +85,6 @@ func addKvToConfigMap(configMap *v1.ConfigMap, keyName, data string) error { configMap.Data[keyName] = data return nil } - // otherwise, it's BinaryData if configMap.BinaryData == nil { configMap.BinaryData = map[string][]byte{} diff --git a/k8sdeps/configmapandsecret/configmapfactory_test.go b/k8sdeps/configmapandsecret/configmapfactory_test.go index 3524a7bfd..ba0b528f3 100644 --- a/k8sdeps/configmapandsecret/configmapfactory_test.go +++ b/k8sdeps/configmapandsecret/configmapfactory_test.go @@ -141,9 +141,9 @@ func TestConstructConfigMap(t *testing.T) { fSys.WriteFile("/configmap/app.env", []byte("DB_USERNAME=admin\nDB_PASSWORD=somepw\n")) fSys.WriteFile("/configmap/app-init.ini", []byte("FOO=bar\nBAR=baz\n")) fSys.WriteFile("/configmap/app.bin", []byte{0xff, 0xfd}) - f := NewConfigMapFactory(loader.NewFileLoaderAtRoot(fSys)) for _, tc := range testCases { - cm, err := f.MakeConfigMap(&tc.input, tc.options) + f := NewFactory(loader.NewFileLoaderAtRoot(fSys), tc.options) + cm, err := f.MakeConfigMap(&tc.input) if err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/k8sdeps/configmapandsecret/secretfactory.go b/k8sdeps/configmapandsecret/secretfactory.go index 677c74512..34d36f41d 100644 --- a/k8sdeps/configmapandsecret/secretfactory.go +++ b/k8sdeps/configmapandsecret/secretfactory.go @@ -18,27 +18,13 @@ package configmapandsecret import ( "fmt" - "strings" - "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/validation" - "sigs.k8s.io/kustomize/k8sdeps/kv" - "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/types" ) -// SecretFactory makes Secrets. -type SecretFactory struct { - ldr ifc.Loader -} - -// NewSecretFactory returns a new SecretFactory. -func NewSecretFactory(ldr ifc.Loader) *SecretFactory { - return &SecretFactory{ldr: ldr} -} - -func (f *SecretFactory) makeFreshSecret(args *types.SecretArgs) *corev1.Secret { +func makeFreshSecret( + args *types.SecretArgs) *corev1.Secret { s := &corev1.Secret{} s.APIVersion = "v1" s.Kind = "Secret" @@ -53,53 +39,32 @@ func (f *SecretFactory) makeFreshSecret(args *types.SecretArgs) *corev1.Secret { } // MakeSecret returns a new secret. -func (f *SecretFactory) MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (*corev1.Secret, error) { - var all []kv.Pair - var err error - s := f.makeFreshSecret(args) - - pairs, err := keyValuesFromEnvFile(f.ldr, args.EnvSource) +func (f *Factory) MakeSecret( + args *types.SecretArgs) (*corev1.Secret, error) { + all, err := f.loadKvPairs(args.GeneratorArgs) if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf( - "env source file: %s", - args.EnvSource)) + return nil, err } - all = append(all, pairs...) - - pairs, err = keyValuesFromLiteralSources(args.LiteralSources) - if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf( - "literal sources %v", args.LiteralSources)) - } - all = append(all, pairs...) - - pairs, err = keyValuesFromFileSources(f.ldr, args.FileSources) - if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf( - "file sources: %v", args.FileSources)) - } - all = append(all, pairs...) - + s := makeFreshSecret(args) for _, p := range all { err = addKvToSecret(s, p.Key, p.Value) if err != nil { return nil, err } } - if options != nil { - s.SetLabels(options.Labels) - s.SetAnnotations(options.Annotations) + if f.options != nil { + s.SetLabels(f.options.Labels) + s.SetAnnotations(f.options.Annotations) } return s, nil } func addKvToSecret(secret *corev1.Secret, keyName, data string) error { - // Note, the rules for SecretKeys keys are the exact same as the ones for ConfigMap. - if errs := validation.IsConfigMapKey(keyName); len(errs) != 0 { - return fmt.Errorf("%q is not a valid key name for a Secret: %s", keyName, strings.Join(errs, ";")) + if err := errIfInvalidKey(keyName); err != nil { + return err } if _, entryExists := secret.Data[keyName]; entryExists { - return fmt.Errorf("cannot add key %s, another key by that name already exists", keyName) + return fmt.Errorf(keyExistsErrorMsg, keyName, secret.Data) } secret.Data[keyName] = []byte(data) return nil diff --git a/k8sdeps/configmapandsecret/secretfactory_test.go b/k8sdeps/configmapandsecret/secretfactory_test.go index da405a27f..45505510d 100644 --- a/k8sdeps/configmapandsecret/secretfactory_test.go +++ b/k8sdeps/configmapandsecret/secretfactory_test.go @@ -138,9 +138,9 @@ func TestConstructSecret(t *testing.T) { fSys := fs.MakeFakeFS() fSys.WriteFile("/secret/app.env", []byte("DB_USERNAME=admin\nDB_PASSWORD=somepw\n")) fSys.WriteFile("/secret/app-init.ini", []byte("FOO=bar\nBAR=baz\n")) - f := NewSecretFactory(loader.NewFileLoaderAtRoot(fSys)) for _, tc := range testCases { - cm, err := f.MakeSecret(&tc.input, tc.options) + f := NewFactory(loader.NewFileLoaderAtRoot(fSys), tc.options) + cm, err := f.MakeSecret(&tc.input) if err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/k8sdeps/kunstruct/factory.go b/k8sdeps/kunstruct/factory.go index cfd3ad309..f17a454df 100644 --- a/k8sdeps/kunstruct/factory.go +++ b/k8sdeps/kunstruct/factory.go @@ -31,8 +31,6 @@ import ( // KunstructuredFactoryImpl hides construction using apimachinery types. type KunstructuredFactoryImpl struct { - cmFactory *configmapandsecret.ConfigMapFactory - secretFactory *configmapandsecret.SecretFactory } var _ ifc.KunstructuredFactory = &KunstructuredFactoryImpl{} @@ -79,27 +77,27 @@ func (kf *KunstructuredFactoryImpl) FromMap( } // MakeConfigMap returns an instance of Kunstructured for ConfigMap -func (kf *KunstructuredFactoryImpl) MakeConfigMap(args *types.ConfigMapArgs, options *types.GeneratorOptions) (ifc.Kunstructured, error) { - cm, err := kf.cmFactory.MakeConfigMap(args, options) +func (kf *KunstructuredFactoryImpl) MakeConfigMap( + ldr ifc.Loader, + options *types.GeneratorOptions, + args *types.ConfigMapArgs) (ifc.Kunstructured, error) { + o, err := configmapandsecret.NewFactory(ldr, options).MakeConfigMap(args) if err != nil { return nil, err } - return NewKunstructuredFromObject(cm) + return NewKunstructuredFromObject(o) } // MakeSecret returns an instance of Kunstructured for Secret -func (kf *KunstructuredFactoryImpl) MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (ifc.Kunstructured, error) { - sec, err := kf.secretFactory.MakeSecret(args, options) +func (kf *KunstructuredFactoryImpl) MakeSecret( + ldr ifc.Loader, + options *types.GeneratorOptions, + args *types.SecretArgs) (ifc.Kunstructured, error) { + o, err := configmapandsecret.NewFactory(ldr, options).MakeSecret(args) if err != nil { return nil, err } - return NewKunstructuredFromObject(sec) -} - -// Set sets loader -func (kf *KunstructuredFactoryImpl) Set(ldr ifc.Loader) { - kf.cmFactory = configmapandsecret.NewConfigMapFactory(ldr) - kf.secretFactory = configmapandsecret.NewSecretFactory(ldr) + return NewKunstructuredFromObject(o) } // validate validates that u has kind and name diff --git a/pkg/commands/edit/add/configmap.go b/pkg/commands/edit/add/configmap.go index 7eee21faf..8f78797ba 100644 --- a/pkg/commands/edit/add/configmap.go +++ b/pkg/commands/edit/add/configmap.go @@ -67,8 +67,8 @@ func newCmdAddConfigMap(fSys fs.FileSystem, kf ifc.KunstructuredFactory) *cobra. } // Add the flagsAndArgs map to the kustomization file. - kf.Set(loader.NewFileLoaderAtCwd(fSys)) - err = addConfigMap(kustomization, flags, kf) + err = addConfigMap( + loader.NewFileLoaderAtCwd(fSys), kustomization, flags, kf) if err != nil { return err } @@ -103,6 +103,7 @@ func newCmdAddConfigMap(fSys fs.FileSystem, kf ifc.KunstructuredFactory) *cobra. // Note: error may leave kustomization file in an undefined state. // Suggest passing a copy of kustomization file. func addConfigMap( + ldr ifc.Loader, k *types.Kustomization, flags flagsAndArgs, kf ifc.KunstructuredFactory) error { cmArgs := makeConfigMapArgs(k, flags.Name) @@ -111,7 +112,7 @@ func addConfigMap( return err } // Validate by trying to create corev1.configmap. - _, err = kf.MakeConfigMap(cmArgs, k.GeneratorOptions) + _, err = kf.MakeConfigMap(ldr, k.GeneratorOptions, cmArgs) if err != nil { return err } diff --git a/pkg/commands/edit/add/secret.go b/pkg/commands/edit/add/secret.go index 53f93dbd0..c2a1d198f 100644 --- a/pkg/commands/edit/add/secret.go +++ b/pkg/commands/edit/add/secret.go @@ -67,8 +67,8 @@ func newCmdAddSecret(fSys fs.FileSystem, kf ifc.KunstructuredFactory) *cobra.Com } // Add the flagsAndArgs map to the kustomization file. - kf.Set(loader.NewFileLoaderAtCwd(fSys)) - err = addSecret(kustomization, flags, kf) + err = addSecret( + loader.NewFileLoaderAtCwd(fSys), kustomization, flags, kf) if err != nil { return err } @@ -108,6 +108,7 @@ func newCmdAddSecret(fSys fs.FileSystem, kf ifc.KunstructuredFactory) *cobra.Com // Note: error may leave kustomization file in an undefined state. // Suggest passing a copy of kustomization file. func addSecret( + ldr ifc.Loader, k *types.Kustomization, flags flagsAndArgs, kf ifc.KunstructuredFactory) error { secretArgs := makeSecretArgs(k, flags.Name, flags.Type) @@ -116,7 +117,7 @@ func addSecret( return err } // Validate by trying to create corev1.secret. - _, err = kf.MakeSecret(secretArgs, k.GeneratorOptions) + _, err = kf.MakeSecret(ldr, k.GeneratorOptions, secretArgs) if err != nil { return err } diff --git a/pkg/ifc/ifc.go b/pkg/ifc/ifc.go index e6267cae2..3a1815da8 100644 --- a/pkg/ifc/ifc.go +++ b/pkg/ifc/ifc.go @@ -64,9 +64,14 @@ type Kunstructured interface { type KunstructuredFactory interface { SliceFromBytes([]byte) ([]Kunstructured, error) FromMap(m map[string]interface{}) Kunstructured - MakeConfigMap(args *types.ConfigMapArgs, options *types.GeneratorOptions) (Kunstructured, error) - MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (Kunstructured, error) - Set(ldr Loader) + MakeConfigMap( + ldr Loader, + options *types.GeneratorOptions, + args *types.ConfigMapArgs) (Kunstructured, error) + MakeSecret( + ldr Loader, + options *types.GeneratorOptions, + args *types.SecretArgs) (Kunstructured, error) } // See core.v1.SecretTypeOpaque diff --git a/pkg/resmap/factory.go b/pkg/resmap/factory.go index 923cde232..7209d47b2 100644 --- a/pkg/resmap/factory.go +++ b/pkg/resmap/factory.go @@ -79,10 +79,13 @@ func (rmF *Factory) NewResMapFromBytes(b []byte) (ResMap, error) { // NewResMapFromConfigMapArgs returns a Resource slice given // a configmap metadata slice from kustomization file. -func (rmF *Factory) NewResMapFromConfigMapArgs(argList []types.ConfigMapArgs, options *types.GeneratorOptions) (ResMap, error) { +func (rmF *Factory) NewResMapFromConfigMapArgs( + ldr ifc.Loader, + options *types.GeneratorOptions, + argList []types.ConfigMapArgs) (ResMap, error) { var resources []*resource.Resource for _, args := range argList { - res, err := rmF.resF.MakeConfigMap(&args, options) + res, err := rmF.resF.MakeConfigMap(ldr, options, &args) if err != nil { return nil, errors.Wrap(err, "NewResMapFromConfigMapArgs") } @@ -93,10 +96,13 @@ func (rmF *Factory) NewResMapFromConfigMapArgs(argList []types.ConfigMapArgs, op // NewResMapFromSecretArgs takes a SecretArgs slice, generates // secrets from each entry, and accumulates them in a ResMap. -func (rmF *Factory) NewResMapFromSecretArgs(argsList []types.SecretArgs, options *types.GeneratorOptions) (ResMap, error) { +func (rmF *Factory) NewResMapFromSecretArgs( + ldr ifc.Loader, + options *types.GeneratorOptions, + argsList []types.SecretArgs) (ResMap, error) { var resources []*resource.Resource for _, args := range argsList { - res, err := rmF.resF.MakeSecret(&args, options) + res, err := rmF.resF.MakeSecret(ldr, options, &args) if err != nil { return nil, errors.Wrap(err, "NewResMapFromSecretArgs") } @@ -105,11 +111,6 @@ func (rmF *Factory) NewResMapFromSecretArgs(argsList []types.SecretArgs, options return newResMapFromResourceSlice(resources) } -// Set sets the loader for the underlying factory -func (rmF *Factory) Set(ldr ifc.Loader) { - rmF.resF.Set(ldr) -} - func newResMapFromResourceSlice(resources []*resource.Resource) (ResMap, error) { result := ResMap{} for _, res := range resources { diff --git a/pkg/resmap/factory_test.go b/pkg/resmap/factory_test.go index 272871b0f..985179eed 100644 --- a/pkg/resmap/factory_test.go +++ b/pkg/resmap/factory_test.go @@ -238,12 +238,11 @@ BAR=baz // TODO: add testcase for data coming from multiple sources like // files/literal/env etc. } - rmF.Set(l) for _, tc := range testCases { if ferr := l.AddFile(tc.filepath, []byte(tc.content)); ferr != nil { t.Fatalf("Error adding fake file: %v\n", ferr) } - r, err := rmF.NewResMapFromConfigMapArgs(tc.input, nil) + r, err := rmF.NewResMapFromConfigMapArgs(l, nil, tc.input) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -272,9 +271,8 @@ func TestNewResMapFromSecretArgs(t *testing.T) { } fakeFs := fs.MakeFakeFS() fakeFs.Mkdir(".") - rmF.Set(loader.NewFileLoaderAtRoot(fakeFs)) - actual, err := rmF.NewResMapFromSecretArgs(secrets, nil) - + actual, err := rmF.NewResMapFromSecretArgs( + loader.NewFileLoaderAtRoot(fakeFs), nil, secrets) if err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/pkg/resource/factory.go b/pkg/resource/factory.go index 148323dd6..9c6c2131d 100644 --- a/pkg/resource/factory.go +++ b/pkg/resource/factory.go @@ -124,25 +124,36 @@ func (rf *Factory) SliceFromBytes(in []byte) ([]*Resource, error) { return result, nil } -// Set sets the loader for the underlying factory -func (rf *Factory) Set(ldr ifc.Loader) { - rf.kf.Set(ldr) -} - // MakeConfigMap makes an instance of Resource for ConfigMap -func (rf *Factory) MakeConfigMap(args *types.ConfigMapArgs, options *types.GeneratorOptions) (*Resource, error) { - u, err := rf.kf.MakeConfigMap(args, options) +func (rf *Factory) MakeConfigMap( + ldr ifc.Loader, + options *types.GeneratorOptions, + args *types.ConfigMapArgs) (*Resource, error) { + u, err := rf.kf.MakeConfigMap(ldr, options, args) if err != nil { return nil, err } - return &Resource{Kunstructured: u, options: types.NewGenArgs(&types.GeneratorArgs{Behavior: args.Behavior}, options)}, nil + return &Resource{ + Kunstructured: u, + options: types.NewGenArgs( + &types.GeneratorArgs{Behavior: args.Behavior}, + options), + }, nil } // MakeSecret makes an instance of Resource for Secret -func (rf *Factory) MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (*Resource, error) { - u, err := rf.kf.MakeSecret(args, options) +func (rf *Factory) MakeSecret( + ldr ifc.Loader, + options *types.GeneratorOptions, + args *types.SecretArgs) (*Resource, error) { + u, err := rf.kf.MakeSecret(ldr, options, args) if err != nil { return nil, err } - return &Resource{Kunstructured: u, options: types.NewGenArgs(&types.GeneratorArgs{Behavior: args.Behavior}, options)}, nil + return &Resource{ + Kunstructured: u, + options: types.NewGenArgs( + &types.GeneratorArgs{Behavior: args.Behavior}, + options), + }, nil } diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index f136b2683..5bbd2198c 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -62,7 +62,9 @@ func NewKustTarget( } errs := k.EnforceFields() if len(errs) > 0 { - return nil, fmt.Errorf("Failed to read kustomization file under %s:\n"+strings.Join(errs, "\n"), ldr.Root()) + return nil, fmt.Errorf( + "Failed to read kustomization file under %s:\n"+ + strings.Join(errs, "\n"), ldr.Root()) } return &KustTarget{ kustomization: &k, @@ -102,7 +104,8 @@ func loadKustFile(ldr ifc.Loader) ([]byte, error) { case 1: return content, nil default: - return nil, fmt.Errorf("Found multiple kustomization files under: %s\n", ldr.Root()) + return nil, fmt.Errorf( + "Found multiple kustomization files under: %s\n", ldr.Root()) } } @@ -215,14 +218,17 @@ func (kt *KustTarget) AccumulateTarget() ( func (kt *KustTarget) generateConfigMapsAndSecrets( errs *interror.KustomizationErrors) (resmap.ResMap, error) { - kt.rFactory.Set(kt.ldr) cms, err := kt.rFactory.NewResMapFromConfigMapArgs( - kt.kustomization.ConfigMapGenerator, kt.kustomization.GeneratorOptions) + kt.ldr, + kt.kustomization.GeneratorOptions, + kt.kustomization.ConfigMapGenerator) if err != nil { errs.Append(errors.Wrap(err, "NewResMapFromConfigMapArgs")) } secrets, err := kt.rFactory.NewResMapFromSecretArgs( - kt.kustomization.SecretGenerator, kt.kustomization.GeneratorOptions) + kt.ldr, + kt.kustomization.GeneratorOptions, + kt.kustomization.SecretGenerator) if err != nil { errs.Append(errors.Wrap(err, "NewResMapFromSecretArgs")) } From 18f6328284b9386861d6393f4c06fa70affc98d7 Mon Sep 17 00:00:00 2001 From: Seth Pollack Date: Fri, 15 Mar 2019 14:28:18 -0400 Subject: [PATCH 161/317] add secret and configmap generator plugins --- k8sdeps/configmapandsecret/basefactory.go | 28 ++++++++- .../configmapandsecret/basefactory_test.go | 54 +++++++++++++++- .../configmapandsecret/configmapfactory.go | 7 ++- .../configmapfactory_test.go | 5 +- .../configmapandsecret/secretfactory_test.go | 5 +- k8sdeps/kunstruct/factory.go | 5 +- k8sdeps/kv/plugin/goplugin.go | 63 +++++++++++++++++++ k8sdeps/kv/plugin/plugin.go | 32 ++++++++++ k8sdeps/kv/plugin/registry.go | 54 ++++++++++++++++ k8sdeps/kv/plugin/testonly.go | 43 +++++++++++++ pkg/target/configmaps_test.go | 28 +++++++++ pkg/types/kustomization.go | 10 +++ 12 files changed, 325 insertions(+), 9 deletions(-) create mode 100644 k8sdeps/kv/plugin/goplugin.go create mode 100644 k8sdeps/kv/plugin/plugin.go create mode 100644 k8sdeps/kv/plugin/registry.go create mode 100644 k8sdeps/kv/plugin/testonly.go diff --git a/k8sdeps/configmapandsecret/basefactory.go b/k8sdeps/configmapandsecret/basefactory.go index 326601673..dd1a4d64e 100644 --- a/k8sdeps/configmapandsecret/basefactory.go +++ b/k8sdeps/configmapandsecret/basefactory.go @@ -24,6 +24,7 @@ import ( "github.com/pkg/errors" "k8s.io/apimachinery/pkg/util/validation" "sigs.k8s.io/kustomize/k8sdeps/kv" + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/types" ) @@ -32,11 +33,20 @@ import ( type baseFactory struct { ldr ifc.Loader options *types.GeneratorOptions + reg plugin.Registry } func (bf baseFactory) loadKvPairs( args types.GeneratorArgs) (all []kv.Pair, err error) { - pairs, err := bf.keyValuesFromEnvFile(args.EnvSource) + pairs, err := bf.keyValuesFromPlugins(args.KVSources) + if err != nil { + return nil, errors.Wrap(err, fmt.Sprintf( + "plugins: %s", + args.EnvSource)) + } + all = append(all, pairs...) + + pairs, err = bf.keyValuesFromEnvFile(args.EnvSource) if err != nil { return nil, errors.Wrap(err, fmt.Sprintf( "env source file: %s", @@ -81,6 +91,22 @@ func keyValuesFromLiteralSources(sources []string) ([]kv.Pair, error) { return kvs, nil } +func (bf baseFactory) keyValuesFromPlugins(sources []types.KVSource) ([]kv.Pair, error) { + var allKvs []kv.Pair + for _, s := range sources { + plug, err := bf.reg.Load(s.PluginType, s.Name) + if err != nil { + return nil, err + } + kvs, err := plug.Get(bf.reg.Root(), s.Args) + if err != nil { + return nil, err + } + allKvs = append(allKvs, kvs...) + } + return allKvs, nil +} + func (bf baseFactory) keyValuesFromFileSources(sources []string) ([]kv.Pair, error) { var kvs []kv.Pair for _, s := range sources { diff --git a/k8sdeps/configmapandsecret/basefactory_test.go b/k8sdeps/configmapandsecret/basefactory_test.go index 022fa9360..d96092fc1 100644 --- a/k8sdeps/configmapandsecret/basefactory_test.go +++ b/k8sdeps/configmapandsecret/basefactory_test.go @@ -21,8 +21,10 @@ import ( "testing" "sigs.k8s.io/kustomize/k8sdeps/kv" + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/loader" + "sigs.k8s.io/kustomize/pkg/types" ) func TestKeyValuesFromFileSources(t *testing.T) { @@ -45,7 +47,9 @@ func TestKeyValuesFromFileSources(t *testing.T) { fSys := fs.MakeFakeFS() fSys.WriteFile("/files/app-init.ini", []byte("FOO=bar")) - bf := baseFactory{loader.NewFileLoaderAtRoot(fSys), nil} + ldr := loader.NewFileLoaderAtRoot(fSys) + reg := plugin.NewRegistry(ldr) + bf := baseFactory{loader.NewFileLoaderAtRoot(fSys), nil, reg} for _, tc := range tests { kvs, err := bf.keyValuesFromFileSources(tc.sources) if err != nil { @@ -56,3 +60,51 @@ func TestKeyValuesFromFileSources(t *testing.T) { } } } + +func TestKeyValuesFromPlugins(t *testing.T) { + tests := []struct { + description string + sources []types.KVSource + expected []kv.Pair + }{ + { + description: "Create kv.Pairs from plugin", + sources: []types.KVSource{ + { + PluginType: "testonly", + Name: "testonly", + Args: []string{"FOO", "BAR", "BAZ"}, + }, + }, + expected: []kv.Pair{ + { + Key: "k_FOO", + Value: "v_FOO", + }, + { + Key: "k_BAR", + Value: "v_BAR", + }, + { + Key: "k_BAZ", + Value: "v_BAZ", + }, + }, + }, + } + + fSys := fs.MakeFakeFS() + ldr := loader.NewFileLoaderAtRoot(fSys) + reg := plugin.NewRegistry(ldr) + bf := baseFactory{ldr, nil, reg} + + for _, tc := range tests { + kvs, err := bf.keyValuesFromPlugins(tc.sources) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if !reflect.DeepEqual(kvs, tc.expected) { + t.Fatalf("in testcase: %q updated:\n%#v\ndoesn't match expected:\n%#v\n", tc.description, kvs, tc.expected) + } + } +} diff --git a/k8sdeps/configmapandsecret/configmapfactory.go b/k8sdeps/configmapandsecret/configmapfactory.go index 03f7abc74..a40792258 100644 --- a/k8sdeps/configmapandsecret/configmapfactory.go +++ b/k8sdeps/configmapandsecret/configmapfactory.go @@ -21,8 +21,9 @@ import ( "fmt" "unicode/utf8" - "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/types" ) @@ -34,8 +35,8 @@ type Factory struct { // NewFactory returns a new Factory. func NewFactory( - l ifc.Loader, o *types.GeneratorOptions) *Factory { - return &Factory{baseFactory{ldr: l, options: o}} + l ifc.Loader, o *types.GeneratorOptions, reg plugin.Registry) *Factory { + return &Factory{baseFactory{ldr: l, options: o, reg: reg}} } func makeFreshConfigMap( diff --git a/k8sdeps/configmapandsecret/configmapfactory_test.go b/k8sdeps/configmapandsecret/configmapfactory_test.go index ba0b528f3..08d41b1fb 100644 --- a/k8sdeps/configmapandsecret/configmapfactory_test.go +++ b/k8sdeps/configmapandsecret/configmapfactory_test.go @@ -22,6 +22,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/loader" "sigs.k8s.io/kustomize/pkg/types" @@ -141,8 +142,10 @@ func TestConstructConfigMap(t *testing.T) { fSys.WriteFile("/configmap/app.env", []byte("DB_USERNAME=admin\nDB_PASSWORD=somepw\n")) fSys.WriteFile("/configmap/app-init.ini", []byte("FOO=bar\nBAR=baz\n")) fSys.WriteFile("/configmap/app.bin", []byte{0xff, 0xfd}) + ldr := loader.NewFileLoaderAtRoot(fSys) + reg := plugin.NewRegistry(ldr) for _, tc := range testCases { - f := NewFactory(loader.NewFileLoaderAtRoot(fSys), tc.options) + f := NewFactory(ldr, tc.options, reg) cm, err := f.MakeConfigMap(&tc.input) if err != nil { t.Fatalf("unexpected error: %v", err) diff --git a/k8sdeps/configmapandsecret/secretfactory_test.go b/k8sdeps/configmapandsecret/secretfactory_test.go index 45505510d..281aaff40 100644 --- a/k8sdeps/configmapandsecret/secretfactory_test.go +++ b/k8sdeps/configmapandsecret/secretfactory_test.go @@ -22,6 +22,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/loader" "sigs.k8s.io/kustomize/pkg/types" @@ -138,8 +139,10 @@ func TestConstructSecret(t *testing.T) { fSys := fs.MakeFakeFS() fSys.WriteFile("/secret/app.env", []byte("DB_USERNAME=admin\nDB_PASSWORD=somepw\n")) fSys.WriteFile("/secret/app-init.ini", []byte("FOO=bar\nBAR=baz\n")) + ldr := loader.NewFileLoaderAtRoot(fSys) + reg := plugin.NewRegistry(ldr) for _, tc := range testCases { - f := NewFactory(loader.NewFileLoaderAtRoot(fSys), tc.options) + f := NewFactory(ldr, tc.options, reg) cm, err := f.MakeSecret(&tc.input) if err != nil { t.Fatalf("unexpected error: %v", err) diff --git a/k8sdeps/kunstruct/factory.go b/k8sdeps/kunstruct/factory.go index f17a454df..3c3644c3f 100644 --- a/k8sdeps/kunstruct/factory.go +++ b/k8sdeps/kunstruct/factory.go @@ -25,6 +25,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/util/yaml" "sigs.k8s.io/kustomize/k8sdeps/configmapandsecret" + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/types" ) @@ -81,7 +82,7 @@ func (kf *KunstructuredFactoryImpl) MakeConfigMap( ldr ifc.Loader, options *types.GeneratorOptions, args *types.ConfigMapArgs) (ifc.Kunstructured, error) { - o, err := configmapandsecret.NewFactory(ldr, options).MakeConfigMap(args) + o, err := configmapandsecret.NewFactory(ldr, options, plugin.NewRegistry(ldr)).MakeConfigMap(args) if err != nil { return nil, err } @@ -93,7 +94,7 @@ func (kf *KunstructuredFactoryImpl) MakeSecret( ldr ifc.Loader, options *types.GeneratorOptions, args *types.SecretArgs) (ifc.Kunstructured, error) { - o, err := configmapandsecret.NewFactory(ldr, options).MakeSecret(args) + o, err := configmapandsecret.NewFactory(ldr, options, plugin.NewRegistry(ldr)).MakeSecret(args) if err != nil { return nil, err } diff --git a/k8sdeps/kv/plugin/goplugin.go b/k8sdeps/kv/plugin/goplugin.go new file mode 100644 index 000000000..d316a76cd --- /dev/null +++ b/k8sdeps/kv/plugin/goplugin.go @@ -0,0 +1,63 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package plugin + +import ( + "fmt" + "os" + "plugin" +) + +var _ Factory = &goFactory{} + +const ( + dir = "$HOME/.config/kustomize/plugins/kvsource" +) + +func newGoFactory() *goFactory { + return &goFactory{ + plugins: make(map[string]KVSource), + } +} + +type goFactory struct { + plugins map[string]KVSource +} + +func (p *goFactory) load(name string) (KVSource, error) { + if plug, ok := p.plugins[name]; ok { + return plug, nil + } + + goPlugin, err := plugin.Open(fmt.Sprintf("%s/kustomize-%s.so", os.ExpandEnv(dir), name)) + if err != nil { + return nil, err + } + + symbol, err := goPlugin.Lookup("Plugin") + if err != nil { + return nil, err + } + + plug, ok := symbol.(KVSource) + if !ok { + return nil, fmt.Errorf("plugin %s not found", name) + } + + p.plugins[name] = plug + return plug, nil +} diff --git a/k8sdeps/kv/plugin/plugin.go b/k8sdeps/kv/plugin/plugin.go new file mode 100644 index 000000000..e3e40a9de --- /dev/null +++ b/k8sdeps/kv/plugin/plugin.go @@ -0,0 +1,32 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package plugin provides a plugin abstraction layer. +package plugin + +import ( + "sigs.k8s.io/kustomize/k8sdeps/kv" +) + +// KVSource is the interface for kv source plugins. +type KVSource interface { + Get(root string, args []string) ([]kv.Pair, error) +} + +// Factory is the interface for new kv source plugin implementations. +type Factory interface { + load(string) (KVSource, error) +} diff --git a/k8sdeps/kv/plugin/registry.go b/k8sdeps/kv/plugin/registry.go new file mode 100644 index 000000000..bf6c8ae0a --- /dev/null +++ b/k8sdeps/kv/plugin/registry.go @@ -0,0 +1,54 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package plugin + +import ( + "fmt" + + "sigs.k8s.io/kustomize/pkg/ifc" +) + +// Registry holds all the plugin factories. +type Registry struct { + factories map[string]Factory + ldr ifc.Loader +} + +// NewRegistry returns a new Registry loaded with all the factories. +func NewRegistry(ldr ifc.Loader) Registry { + return Registry{ + ldr: ldr, + factories: map[string]Factory{ + "go": newGoFactory(), + "testonly": newTestonlyFactory(), + }, + } +} + +// Load returns a plugin by type and name, +func (r *Registry) Load(pluginType, name string) (KVSource, error) { + factory, exists := r.factories[pluginType] + if !exists { + return nil, fmt.Errorf("%s is not a valid plugin type", pluginType) + } + return factory.load(name) +} + +// Root returns the root of the plugins kustomization file. +func (r *Registry) Root() string { + return r.ldr.Root() +} diff --git a/k8sdeps/kv/plugin/testonly.go b/k8sdeps/kv/plugin/testonly.go new file mode 100644 index 000000000..a06da588a --- /dev/null +++ b/k8sdeps/kv/plugin/testonly.go @@ -0,0 +1,43 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// testonly is temporary until we have builtin plugins to use in the tests. + +package plugin + +import ( + "sigs.k8s.io/kustomize/k8sdeps/kv" +) + +var _ Factory = &testonlyFactory{} + +func newTestonlyFactory() *testonlyFactory { + return &testonlyFactory{} +} + +type testonlyFactory struct{} + +func (p testonlyFactory) Get(_ string, args []string) ([]kv.Pair, error) { + var kvs []kv.Pair + for _, arg := range args { + kvs = append(kvs, kv.Pair{Key: "k_" + arg, Value: "v_" + arg}) + } + return kvs, nil +} + +func (p *testonlyFactory) load(name string) (KVSource, error) { + return p, nil +} diff --git a/pkg/target/configmaps_test.go b/pkg/target/configmaps_test.go index dd69adb3b..3ba0545d8 100644 --- a/pkg/target/configmaps_test.go +++ b/pkg/target/configmaps_test.go @@ -240,3 +240,31 @@ metadata: name: p2-com2-c4b8md75k9 `) } + +func TestGeneratorPlugins(t *testing.T) { + th := NewKustTestHarness(t, "/app") + th.writeK("/app", ` +secretGenerator: +- name: bob + kvSources: + - pluginType: testonly + name: testonly + args: + - FRUIT + - VEGETABLE +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + k_FRUIT: dl9GUlVJVA== + k_VEGETABLE: dl9WRUdFVEFCTEU= +kind: Secret +metadata: + name: bob-cb9mhbh9gg +type: Opaque +`) +} diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 12d09820f..c92867422 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -189,6 +189,9 @@ type GeneratorArgs struct { // DataSources for the generator. DataSources `json:",inline,omitempty" yaml:",inline,omitempty"` + + // KVSources for the generator. + KVSources []KVSource `json:",inline,omitempty" yaml:",inline,omitempty"` } // ConfigMapArgs contains the metadata of how to generate a configmap. @@ -248,3 +251,10 @@ type GeneratorOptions struct { // resource contents. DisableNameSuffixHash bool `json:"disableNameSuffixHash,omitempty" yaml:"disableNameSuffixHash,omitempty"` } + +// KVSource represents a KV plugin backend. +type KVSource struct { + PluginType string `json:"pluginType,omitempty" yaml:"pluginType,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Args []string `json:"args,omitempty" yaml:"args,omitempty"` +} From 56965a0046854d4a6eb0b1b4721cc3b27492b62e Mon Sep 17 00:00:00 2001 From: Seth Pollack Date: Fri, 15 Mar 2019 17:33:17 -0400 Subject: [PATCH 162/317] fix test --- k8sdeps/kv/plugin/testonly.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k8sdeps/kv/plugin/testonly.go b/k8sdeps/kv/plugin/testonly.go index a06da588a..ecbc36cc8 100644 --- a/k8sdeps/kv/plugin/testonly.go +++ b/k8sdeps/kv/plugin/testonly.go @@ -38,6 +38,6 @@ func (p testonlyFactory) Get(_ string, args []string) ([]kv.Pair, error) { return kvs, nil } -func (p *testonlyFactory) load(name string) (KVSource, error) { +func (p *testonlyFactory) load(_ string) (KVSource, error) { return p, nil } From 7b82154c4c2915b9b91512ca4b426aa8181e45d3 Mon Sep 17 00:00:00 2001 From: Karen Bradshaw Date: Thu, 7 Mar 2019 10:14:07 -0500 Subject: [PATCH 163/317] correct spelling, minor word ordering --- examples/transformerconfigs/README.md | 63 ++++++++++++++++----------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/examples/transformerconfigs/README.md b/examples/transformerconfigs/README.md index 292cc3e4b..ab93ab595 100644 --- a/examples/transformerconfigs/README.md +++ b/examples/transformerconfigs/README.md @@ -1,6 +1,7 @@ # Transformer Configurations -Kustomize computes the resources by applying a series of transformers: +Kustomize computes the configuration of a resource by applying a series of transformers: + - namespace transformer - prefix/suffix transformer - label transformer @@ -8,30 +9,36 @@ Kustomize computes the resources by applying a series of transformers: - name reference transformer - variable reference transformer -Each transformer takes a list of resources and modifies certain fields. The modification is based on the transformer's rule. -The fields to update is the transformer's configuration, which is a list of filedspec that can be represented in YAML format. +Each transformer takes a list of resources and modifies certain fields in the resource based upon the transformer's configuration. A transformer's configuration is a list of `fieldSpec`, represented in YAML format. -## fieldSpec -FieldSpec is a type to represent a path to a field in one kind of resources. It has following format -``` +## FieldSpec + +FieldSpec is a type that represents a path to a field in a resource such as `Job`. Here is the `fieldSpec` format: + +```yaml group: some-group version: some-version kind: some-kind path: path/to/the/field create: false ``` -If `create` is set to true, it indicates the transformer to create the path if it is not found in the resources. This is most useful for label and annotation transformers, where the path for labels or annotations may not be set before the transformation. -## prefix/suffix transformer -Name prefix suffix transformer adds prefix and suffix to the `metadata/name` field for all resources with following configuration: -``` +If `create` is set to `true`, the transformer creates the path to the field in the resource if the path is not already found. This is most useful for label and annotation transformers, where the path for labels or annotations may not be set before the transformation. + +## Prefix/suffix transformer + +The prefix/suffix transformer adds a prefix/suffix to the `metadata/name` field for all resources. Here is an example of a prefix transformer configuration: + +```yaml namePrefix: - path: metadata/name ``` -## label transformer -Label transformer adds labels to `metadata/labels` field for all resources. It also adds labels to `spec/selector` field in all Service and to `spec/selector/matchLabels` field in all Deployment. -``` +## Label transformer + +The label transformer adds labels to the `metadata/labels` field for all resources. It also adds labels to the `spec/selector` field in all Service resources as well as the `spec/selector/matchLabels` field in all Deployment resources. + +```yaml commonLabels: - path: metadata/labels create: true @@ -44,15 +51,17 @@ commonLabels: - path: spec/selector/matchLabels create: true kind: Deployment - (etc.) +# add additional paths to resource fields ``` -## name reference transformer -Name reference transformer's configuration is different from all other transformers. It contains a list of namebackreferences, which represented all the possible fields that a type could be used as a reference in other types of resources. A namebackreference contains a type such as ConfigMap as well as a list of FieldSpecs where ConfigMap is referenced. Here is an example. -``` +## Name reference transformer + +Name reference transformer's configuration is different from all other transformers. It contains a list of `nameReferences`, which represent all of the possible fields that a type could be used as a reference in other types of resources. A `nameReference` contains a type such as ConfigMap as well as a list of `fieldSpecs` where ConfigMap is referenced in other resources. Here is an example. + +```yaml kind: ConfigMap version: v1 -FieldSpecs: +fieldSpecs: - kind: Pod version: v1 path: spec/volumes/configMap/name @@ -60,10 +69,12 @@ FieldSpecs: path: spec/template/spec/volumes/configMap/name - kind: Job path: spec/template/spec/volumes/configMap/name - (etc.) -``` -Name reference transformer configuration contains a list of such namebackreferences for ConfigMap, Secret, Service, Role, ServiceAccount and so on. +# add additional paths to resource fields ``` + +Name reference transformer's configuration contains a list of `nameReferences` for resources such as ConfigMap, Secret, Service, Role, and ServiceAccount. Here is an example configuration: + +```yaml nameReference: - kind: ConfigMap version: v1 @@ -74,7 +85,7 @@ nameReference: - path: spec/containers/env/valueFrom/configMapKeyRef/name version: v1 kind: Pod - (etc.) + # add additional paths to resource fields - kind: Secret version: v1 fieldSpecs: @@ -84,12 +95,14 @@ nameReference: - path: spec/containers/env/valueFrom/secretKeyRef/name version: v1 kind: Pod - (etc.) + # add additional paths to resource fields ``` -## customizing transformer configurations +## Customizing transformer configurations + +Kustomize has a default set of transformer configurations. You can save the default transformer configurations +to a local directory by calling `kustomize config save -d`. Kustomize allows modifying those configuration files and using them in a kustomization.yaml file. This tutorial shows how to customize those configurations to: -Kustomize has a default set of configurations. They can be saved to local directory through `kustomize config save -d`. Kustomize allows modifying those configuration files and using them in kustomization.yaml file. This tutorial shows how to customize those configurations to - [support a CRD type](crd/README.md) - add extra fields for variable substitution - add extra fields for name reference From 942e36e19f8c1ef310f60135a843f4fb9c98f109 Mon Sep 17 00:00:00 2001 From: Karen Bradshaw Date: Tue, 12 Mar 2019 21:18:18 -0400 Subject: [PATCH 164/317] a few more changes --- examples/transformerconfigs/README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/examples/transformerconfigs/README.md b/examples/transformerconfigs/README.md index ab93ab595..536978aaf 100644 --- a/examples/transformerconfigs/README.md +++ b/examples/transformerconfigs/README.md @@ -13,7 +13,7 @@ Each transformer takes a list of resources and modifies certain fields in the re ## FieldSpec -FieldSpec is a type that represents a path to a field in a resource such as `Job`. Here is the `fieldSpec` format: +FieldSpec is a type that represents a path to a field in one kind of resource, such as `Job`. ```yaml group: some-group @@ -27,7 +27,7 @@ If `create` is set to `true`, the transformer creates the path to the field in t ## Prefix/suffix transformer -The prefix/suffix transformer adds a prefix/suffix to the `metadata/name` field for all resources. Here is an example of a prefix transformer configuration: +The prefix/suffix transformer adds a prefix/suffix to the `metadata/name` field for all resources. Here is the default prefix transformer configuration: ```yaml namePrefix: @@ -51,7 +51,6 @@ commonLabels: - path: spec/selector/matchLabels create: true kind: Deployment -# add additional paths to resource fields ``` ## Name reference transformer @@ -69,7 +68,6 @@ fieldSpecs: path: spec/template/spec/volumes/configMap/name - kind: Job path: spec/template/spec/volumes/configMap/name -# add additional paths to resource fields ``` Name reference transformer's configuration contains a list of `nameReferences` for resources such as ConfigMap, Secret, Service, Role, and ServiceAccount. Here is an example configuration: @@ -95,13 +93,13 @@ nameReference: - path: spec/containers/env/valueFrom/secretKeyRef/name version: v1 kind: Pod - # add additional paths to resource fields ``` ## Customizing transformer configurations -Kustomize has a default set of transformer configurations. You can save the default transformer configurations -to a local directory by calling `kustomize config save -d`. Kustomize allows modifying those configuration files and using them in a kustomization.yaml file. This tutorial shows how to customize those configurations to: +Kustomize has a default set of transformer configurations. You can view the default transformer configurations by saving them to a local directory by calling kustomize config save -d. + +Kustomize also supports adding extra transformer configurations by adding configuration files in the kustomization.yaml file. This tutorial shows how to customize those configurations to: - [support a CRD type](crd/README.md) - add extra fields for variable substitution From 65886f12581c106b20a8ffc7c0401b19e5b4e829 Mon Sep 17 00:00:00 2001 From: Karen Bradshaw Date: Fri, 15 Mar 2019 16:34:47 -0400 Subject: [PATCH 165/317] address comments --- examples/transformerconfigs/README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/transformerconfigs/README.md b/examples/transformerconfigs/README.md index 536978aaf..293ae7332 100644 --- a/examples/transformerconfigs/README.md +++ b/examples/transformerconfigs/README.md @@ -1,19 +1,21 @@ # Transformer Configurations -Kustomize computes the configuration of a resource by applying a series of transformers: +Kustomize creates new resources by applying a series of transformations to an original +set of resources. Kustomize provides the following default transformers: -- namespace transformer -- prefix/suffix transformer -- label transformer -- annotation transformer -- name reference transformer -- variable reference transformer +- namespace +- prefix/suffix +- label +- annotation +- name reference +- variable reference -Each transformer takes a list of resources and modifies certain fields in the resource based upon the transformer's configuration. A transformer's configuration is a list of `fieldSpec`, represented in YAML format. +A `fieldSpec` list, in a transformer's configuration, determines which resource types and which fields +within those types the transformer can modify. ## FieldSpec -FieldSpec is a type that represents a path to a field in one kind of resource, such as `Job`. +FieldSpec is a type that represents a path to a field in one kind of resource. ```yaml group: some-group @@ -97,10 +99,8 @@ nameReference: ## Customizing transformer configurations -Kustomize has a default set of transformer configurations. You can view the default transformer configurations by saving them to a local directory by calling kustomize config save -d. - -Kustomize also supports adding extra transformer configurations by adding configuration files in the kustomization.yaml file. This tutorial shows how to customize those configurations to: +Kustomize has a default set of transformer configurations. You can save the default transformer configurations to a local directory by calling `kustomize config save -d`, and then modify and use these configurations. Kustomize also supports adding new transformer configurations to kustomization.yaml. This tutorial shows how to customize those configurations to: - [support a CRD type](crd/README.md) - add extra fields for variable substitution -- add extra fields for name reference +- add extra fields for name reference \ No newline at end of file From f850ca63f4311712a1b7f1d39dd7ccfefaa2c139 Mon Sep 17 00:00:00 2001 From: Karen Bradshaw Date: Sat, 16 Mar 2019 16:49:16 -0400 Subject: [PATCH 166/317] remove extra comment --- examples/transformerconfigs/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/transformerconfigs/README.md b/examples/transformerconfigs/README.md index 293ae7332..dcab70902 100644 --- a/examples/transformerconfigs/README.md +++ b/examples/transformerconfigs/README.md @@ -57,7 +57,7 @@ commonLabels: ## Name reference transformer -Name reference transformer's configuration is different from all other transformers. It contains a list of `nameReferences`, which represent all of the possible fields that a type could be used as a reference in other types of resources. A `nameReference` contains a type such as ConfigMap as well as a list of `fieldSpecs` where ConfigMap is referenced in other resources. Here is an example. +Name reference transformer's configuration is different from all other transformers. It contains a list of `nameReferences`, which represent all of the possible fields that a type could be used as a reference in other types of resources. A `nameReference` contains a type such as ConfigMap as well as a list of `fieldSpecs` where ConfigMap is referenced in other resources. Here is an example: ```yaml kind: ConfigMap @@ -85,7 +85,7 @@ nameReference: - path: spec/containers/env/valueFrom/configMapKeyRef/name version: v1 kind: Pod - # add additional paths to resource fields + # ... - kind: Secret version: v1 fieldSpecs: @@ -99,7 +99,7 @@ nameReference: ## Customizing transformer configurations -Kustomize has a default set of transformer configurations. You can save the default transformer configurations to a local directory by calling `kustomize config save -d`, and then modify and use these configurations. Kustomize also supports adding new transformer configurations to kustomization.yaml. This tutorial shows how to customize those configurations to: +Kustomize has a default set of transformer configurations. You can save the default transformer configurations to a local directory by calling `kustomize config save -d`, and modify and use these configurations. Kustomize also supports adding new transformer configurations to kustomization.yaml. This tutorial shows how to customize those configurations to: - [support a CRD type](crd/README.md) - add extra fields for variable substitution From 5c4719651ef39f94452ebf10283daf0dd2cf368e Mon Sep 17 00:00:00 2001 From: Seth Pollack Date: Sat, 16 Mar 2019 20:46:37 -0400 Subject: [PATCH 167/317] honor XDG_CONFIG_HOME --- k8sdeps/kv/plugin/goplugin.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/k8sdeps/kv/plugin/goplugin.go b/k8sdeps/kv/plugin/goplugin.go index d316a76cd..09351fa1a 100644 --- a/k8sdeps/kv/plugin/goplugin.go +++ b/k8sdeps/kv/plugin/goplugin.go @@ -25,7 +25,7 @@ import ( var _ Factory = &goFactory{} const ( - dir = "$HOME/.config/kustomize/plugins/kvsource" + pluginDir = "kustomize/plugins/kvsource" ) func newGoFactory() *goFactory { @@ -38,12 +38,20 @@ type goFactory struct { plugins map[string]KVSource } +func configDir() string { + xdghome := os.Getenv("XDG_CONFIG_HOME") + if len(xdghome) == 0 { + return os.ExpandEnv("$HOME/.config") + } + return xdghome +} + func (p *goFactory) load(name string) (KVSource, error) { if plug, ok := p.plugins[name]; ok { return plug, nil } - goPlugin, err := plugin.Open(fmt.Sprintf("%s/kustomize-%s.so", os.ExpandEnv(dir), name)) + goPlugin, err := plugin.Open(fmt.Sprintf("%s/%s/kustomize-%s.so", configDir(), pluginDir, name)) if err != nil { return nil, err } From 388d5c2d7ccecba1b1de72c2177d1b38f66972de Mon Sep 17 00:00:00 2001 From: Seth Pollack Date: Sat, 16 Mar 2019 21:21:15 -0400 Subject: [PATCH 168/317] add builtin plugins --- .../configmapandsecret/basefactory_test.go | 20 +++---- k8sdeps/kv/plugin/builtin/literals.go | 59 +++++++++++++++++++ .../plugin/{testonly.go => builtinplugin.go} | 32 +++++----- k8sdeps/kv/plugin/registry.go | 4 +- pkg/target/configmaps_test.go | 14 ++--- 5 files changed, 93 insertions(+), 36 deletions(-) create mode 100644 k8sdeps/kv/plugin/builtin/literals.go rename k8sdeps/kv/plugin/{testonly.go => builtinplugin.go} (53%) diff --git a/k8sdeps/configmapandsecret/basefactory_test.go b/k8sdeps/configmapandsecret/basefactory_test.go index d96092fc1..3f0a545d5 100644 --- a/k8sdeps/configmapandsecret/basefactory_test.go +++ b/k8sdeps/configmapandsecret/basefactory_test.go @@ -68,26 +68,22 @@ func TestKeyValuesFromPlugins(t *testing.T) { expected []kv.Pair }{ { - description: "Create kv.Pairs from plugin", + description: "Create kv.Pairs from builtin literals plugin", sources: []types.KVSource{ { - PluginType: "testonly", - Name: "testonly", - Args: []string{"FOO", "BAR", "BAZ"}, + PluginType: "builtin", + Name: "literals", + Args: []string{"FOO=bar", "BAR=baz"}, }, }, expected: []kv.Pair{ { - Key: "k_FOO", - Value: "v_FOO", + Key: "FOO", + Value: "bar", }, { - Key: "k_BAR", - Value: "v_BAR", - }, - { - Key: "k_BAZ", - Value: "v_BAZ", + Key: "BAR", + Value: "baz", }, }, }, diff --git a/k8sdeps/kv/plugin/builtin/literals.go b/k8sdeps/kv/plugin/builtin/literals.go new file mode 100644 index 000000000..bb79744f8 --- /dev/null +++ b/k8sdeps/kv/plugin/builtin/literals.go @@ -0,0 +1,59 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package builtin + +import ( + "fmt" + "strings" + + "sigs.k8s.io/kustomize/k8sdeps/kv" +) + +// Literals takes a list of literals. +// Each literal source should be a key and literal value, +// e.g. `somekey=somevalue` +// It will be similar to kubectl create configmap|secret --from-literal +type Literals struct{} + +// Get implements the interface for kv plugins. +func (p Literals) Get(root string, args []string) ([]kv.Pair, error) { + var kvs []kv.Pair + for _, s := range args { + k, v, err := parseLiteralSource(s) + if err != nil { + return nil, err + } + kvs = append(kvs, kv.Pair{Key: k, Value: v}) + } + return kvs, nil +} + +// parseLiteralSource parses the source key=val pair into its component pieces. +// This functionality is distinguished from strings.SplitN(source, "=", 2) since +// it returns an error in the case of empty keys, values, or a missing equals sign. +func parseLiteralSource(source string) (keyName, value string, err error) { + // leading equal is invalid + if strings.Index(source, "=") == 0 { + return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source) + } + // split after the first equal (so values can have the = character) + items := strings.SplitN(source, "=", 2) + if len(items) != 2 { + return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source) + } + return items[0], strings.Trim(items[1], "\"'"), nil +} diff --git a/k8sdeps/kv/plugin/testonly.go b/k8sdeps/kv/plugin/builtinplugin.go similarity index 53% rename from k8sdeps/kv/plugin/testonly.go rename to k8sdeps/kv/plugin/builtinplugin.go index ecbc36cc8..67aeb39fb 100644 --- a/k8sdeps/kv/plugin/testonly.go +++ b/k8sdeps/kv/plugin/builtinplugin.go @@ -14,30 +14,32 @@ See the License for the specific language governing permissions and limitations under the License. */ -// testonly is temporary until we have builtin plugins to use in the tests. - package plugin import ( - "sigs.k8s.io/kustomize/k8sdeps/kv" + "fmt" + + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin/builtin" + "sigs.k8s.io/kustomize/pkg/ifc" ) -var _ Factory = &testonlyFactory{} +var _ Factory = &builtinFactory{} -func newTestonlyFactory() *testonlyFactory { - return &testonlyFactory{} +type builtinFactory struct { + plugins map[string]KVSource } -type testonlyFactory struct{} - -func (p testonlyFactory) Get(_ string, args []string) ([]kv.Pair, error) { - var kvs []kv.Pair - for _, arg := range args { - kvs = append(kvs, kv.Pair{Key: "k_" + arg, Value: "v_" + arg}) +func newBuiltinFactory(ldr ifc.Loader) *builtinFactory { + return &builtinFactory{ + plugins: map[string]KVSource{ + "literals": builtin.Literals{}, + }, } - return kvs, nil } -func (p *testonlyFactory) load(_ string) (KVSource, error) { - return p, nil +func (p *builtinFactory) load(name string) (KVSource, error) { + if plug, ok := p.plugins[name]; ok { + return plug, nil + } + return nil, fmt.Errorf("plugin %s not found", name) } diff --git a/k8sdeps/kv/plugin/registry.go b/k8sdeps/kv/plugin/registry.go index bf6c8ae0a..3883922c7 100644 --- a/k8sdeps/kv/plugin/registry.go +++ b/k8sdeps/kv/plugin/registry.go @@ -33,8 +33,8 @@ func NewRegistry(ldr ifc.Loader) Registry { return Registry{ ldr: ldr, factories: map[string]Factory{ - "go": newGoFactory(), - "testonly": newTestonlyFactory(), + "go": newGoFactory(), + "builtin": newBuiltinFactory(ldr), }, } } diff --git a/pkg/target/configmaps_test.go b/pkg/target/configmaps_test.go index 3ba0545d8..c482b6a7d 100644 --- a/pkg/target/configmaps_test.go +++ b/pkg/target/configmaps_test.go @@ -247,11 +247,11 @@ func TestGeneratorPlugins(t *testing.T) { secretGenerator: - name: bob kvSources: - - pluginType: testonly - name: testonly + - pluginType: builtin + name: literals args: - - FRUIT - - VEGETABLE + - FRUIT=apple + - VEGETABLE=carrot `) m, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { @@ -260,11 +260,11 @@ secretGenerator: th.assertActualEqualsExpected(m, ` apiVersion: v1 data: - k_FRUIT: dl9GUlVJVA== - k_VEGETABLE: dl9WRUdFVEFCTEU= + FRUIT: YXBwbGU= + VEGETABLE: Y2Fycm90 kind: Secret metadata: - name: bob-cb9mhbh9gg + name: bob-bgtct8h699 type: Opaque `) } From 3011f18047210dd4668517780f5279ad46289090 Mon Sep 17 00:00:00 2001 From: Jesse Dubay Date: Sat, 16 Mar 2019 19:11:42 -0700 Subject: [PATCH 169/317] Sort default varReference config by kind, path --- .../config/defaultconfig/varreference.go | 200 +++++++++--------- 1 file changed, 100 insertions(+), 100 deletions(-) diff --git a/pkg/transformers/config/defaultconfig/varreference.go b/pkg/transformers/config/defaultconfig/varreference.go index 77bffbeda..cead95708 100644 --- a/pkg/transformers/config/defaultconfig/varreference.go +++ b/pkg/transformers/config/defaultconfig/varreference.go @@ -19,98 +19,68 @@ package defaultconfig const ( varReferenceFieldSpecs = ` varReference: -- path: spec/template/spec/initContainers/command - kind: StatefulSet - -- path: spec/template/spec/containers/command - kind: StatefulSet - -- path: spec/template/spec/initContainers/command - kind: Deployment - -- path: spec/template/spec/containers/command - kind: Deployment - -- path: spec/template/spec/initContainers/command - kind: DaemonSet - -- path: spec/template/spec/containers/command - kind: DaemonSet - -- path: spec/template/spec/containers/command - kind: Job +- path: spec/jobTemplate/spec/template/spec/containers/args + kind: CronJob - path: spec/jobTemplate/spec/template/spec/containers/command kind: CronJob -- path: spec/template/spec/initContainers/args - kind: StatefulSet - -- path: spec/template/spec/containers/args - kind: StatefulSet - -- path: spec/template/spec/initContainers/args - kind: Deployment - -- path: spec/template/spec/containers/args - kind: Deployment - -- path: spec/template/spec/initContainers/args - kind: DaemonSet - -- path: spec/template/spec/containers/args - kind: DaemonSet - -- path: spec/template/spec/containers/args - kind: Job - -- path: spec/jobTemplate/spec/template/spec/containers/args - kind: CronJob - -- path: spec/template/spec/initContainers/env/value - kind: StatefulSet - -- path: spec/template/spec/containers/env/value - kind: StatefulSet - -- path: spec/template/spec/initContainers/env/value - kind: Deployment - -- path: spec/template/spec/containers/env/value - kind: Deployment - -- path: spec/template/spec/initContainers/env/value - kind: DaemonSet - -- path: spec/template/spec/containers/env/value - kind: DaemonSet - -- path: spec/template/spec/containers/env/value - kind: Job - -- path: spec/template/spec/initContainers/env/value - kind: Job - - path: spec/jobTemplate/spec/template/spec/containers/env/value kind: CronJob -- path: spec/containers/command - kind: Pod +- path: spec/template/spec/containers/volumeMounts/mountPath + kind: CronJob -- path: spec/containers/args - kind: Pod +- path: spec/template/spec/initContainers/volumeMounts/mountPath + kind: CronJob -- path: spec/containers/env/value - kind: Pod +- path: spec/template/spec/containers/args + kind: DaemonSet -- path: spec/initContainers/command - kind: Pod +- path: spec/template/spec/containers/command + kind: DaemonSet -- path: spec/initContainers/args - kind: Pod +- path: spec/template/spec/containers/env/value + kind: DaemonSet -- path: spec/initContainers/env/value - kind: Pod +- path: spec/template/spec/containers/volumeMounts/mountPath + kind: DaemonSet + +- path: spec/template/spec/initContainers/args + kind: DaemonSet + +- path: spec/template/spec/initContainers/command + kind: DaemonSet + +- path: spec/template/spec/initContainers/env/value + kind: DaemonSet + +- path: spec/template/spec/initContainers/volumeMounts/mountPath + kind: DaemonSet + +- path: spec/template/spec/containers/args + kind: Deployment + +- path: spec/template/spec/containers/command + kind: Deployment + +- path: spec/template/spec/containers/env/value + kind: Deployment + +- path: spec/template/spec/containers/volumeMounts/mountPath + kind: Deployment + +- path: spec/template/spec/initContainers/args + kind: Deployment + +- path: spec/template/spec/initContainers/command + kind: Deployment + +- path: spec/template/spec/initContainers/env/value + kind: Deployment + +- path: spec/template/spec/initContainers/volumeMounts/mountPath + kind: Deployment - path: spec/rules/host kind: Ingress @@ -118,15 +88,45 @@ varReference: - path: spec/tls/hosts kind: Ingress +- path: spec/template/spec/containers/args + kind: Job + +- path: spec/template/spec/containers/command + kind: Job + +- path: spec/template/spec/containers/env/value + kind: Job + - path: spec/template/spec/containers/volumeMounts/mountPath - kind: StatefulSet + kind: Job + +- path: spec/template/spec/initContainers/env/value + kind: Job - path: spec/template/spec/initContainers/volumeMounts/mountPath - kind: StatefulSet + kind: Job + +- path: spec/containers/args + kind: Pod + +- path: spec/containers/command + kind: Pod + +- path: spec/containers/env/value + kind: Pod - path: spec/containers/volumeMounts/mountPath kind: Pod +- path: spec/initContainers/args + kind: Pod + +- path: spec/initContainers/command + kind: Pod + +- path: spec/initContainers/env/value + kind: Pod + - path: spec/initContainers/volumeMounts/mountPath kind: Pod @@ -136,29 +136,29 @@ varReference: - path: spec/template/spec/initContainers/volumeMounts/mountPath kind: ReplicaSet -- path: spec/template/spec/containers/volumeMounts/mountPath - kind: Job +- path: spec/template/spec/containers/args + kind: StatefulSet -- path: spec/template/spec/initContainers/volumeMounts/mountPath - kind: Job +- path: spec/template/spec/containers/command + kind: StatefulSet + +- path: spec/template/spec/containers/env/value + kind: StatefulSet - path: spec/template/spec/containers/volumeMounts/mountPath - kind: CronJob + kind: StatefulSet + +- path: spec/template/spec/initContainers/args + kind: StatefulSet + +- path: spec/template/spec/initContainers/command + kind: StatefulSet + +- path: spec/template/spec/initContainers/env/value + kind: StatefulSet - path: spec/template/spec/initContainers/volumeMounts/mountPath - kind: CronJob - -- path: spec/template/spec/containers/volumeMounts/mountPath - kind: DaemonSet - -- path: spec/template/spec/initContainers/volumeMounts/mountPath - kind: DaemonSet - -- path: spec/template/spec/containers/volumeMounts/mountPath - kind: Deployment - -- path: spec/template/spec/initContainers/volumeMounts/mountPath - kind: Deployment + kind: StatefulSet - path: metadata/labels ` From e207ae4c01aef23e099a4e7732bc46488fd3fdcc Mon Sep 17 00:00:00 2001 From: Jesse Dubay Date: Sat, 16 Mar 2019 19:12:58 -0700 Subject: [PATCH 170/317] Fix incorrect default varrefs for CronJob volumeMounts --- pkg/transformers/config/defaultconfig/varreference.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/transformers/config/defaultconfig/varreference.go b/pkg/transformers/config/defaultconfig/varreference.go index cead95708..9314eb7db 100644 --- a/pkg/transformers/config/defaultconfig/varreference.go +++ b/pkg/transformers/config/defaultconfig/varreference.go @@ -28,10 +28,10 @@ varReference: - path: spec/jobTemplate/spec/template/spec/containers/env/value kind: CronJob -- path: spec/template/spec/containers/volumeMounts/mountPath +- path: spec/jobTemplate/spec/template/spec/containers/volumeMounts/mountPath kind: CronJob -- path: spec/template/spec/initContainers/volumeMounts/mountPath +- path: spec/jobTemplate/spec/template/spec/initContainers/volumeMounts/mountPath kind: CronJob - path: spec/template/spec/containers/args From 31091a8df2004786697e708770d28b5658de5b09 Mon Sep 17 00:00:00 2001 From: Jesse Dubay Date: Sat, 16 Mar 2019 19:15:56 -0700 Subject: [PATCH 171/317] Fix missing varrefs for CronJob, Job, ReplicaSet --- .../config/defaultconfig/varreference.go | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/pkg/transformers/config/defaultconfig/varreference.go b/pkg/transformers/config/defaultconfig/varreference.go index 9314eb7db..5f89dfd4f 100644 --- a/pkg/transformers/config/defaultconfig/varreference.go +++ b/pkg/transformers/config/defaultconfig/varreference.go @@ -31,6 +31,15 @@ varReference: - path: spec/jobTemplate/spec/template/spec/containers/volumeMounts/mountPath kind: CronJob +- path: spec/jobTemplate/spec/template/spec/initContainers/args + kind: CronJob + +- path: spec/jobTemplate/spec/template/spec/initContainers/command + kind: CronJob + +- path: spec/jobTemplate/spec/template/spec/initContainers/env/value + kind: CronJob + - path: spec/jobTemplate/spec/template/spec/initContainers/volumeMounts/mountPath kind: CronJob @@ -100,6 +109,12 @@ varReference: - path: spec/template/spec/containers/volumeMounts/mountPath kind: Job +- path: spec/template/spec/initContainers/args + kind: Job + +- path: spec/template/spec/initContainers/command + kind: Job + - path: spec/template/spec/initContainers/env/value kind: Job @@ -130,9 +145,27 @@ varReference: - path: spec/initContainers/volumeMounts/mountPath kind: Pod +- path: spec/template/spec/containers/args + kind: ReplicaSet + +- path: spec/template/spec/containers/command + kind: ReplicaSet + +- path: spec/template/spec/containers/env/value + kind: ReplicaSet + - path: spec/template/spec/containers/volumeMounts/mountPath kind: ReplicaSet +- path: spec/template/spec/initContainers/args + kind: ReplicaSet + +- path: spec/template/spec/initContainers/command + kind: ReplicaSet + +- path: spec/template/spec/initContainers/env/value + kind: ReplicaSet + - path: spec/template/spec/initContainers/volumeMounts/mountPath kind: ReplicaSet From d0cf0473815db1d2e99aacd7468114e26c652fde Mon Sep 17 00:00:00 2001 From: Yujun Zhang Date: Sun, 17 Mar 2019 16:18:46 +0800 Subject: [PATCH 172/317] Convert image transformer test to a more readable format --- pkg/target/transformersimage_test.go | 170 +++++++++++++++++ pkg/transformers/image_test.go | 266 --------------------------- 2 files changed, 170 insertions(+), 266 deletions(-) create mode 100644 pkg/target/transformersimage_test.go delete mode 100644 pkg/transformers/image_test.go diff --git a/pkg/target/transformersimage_test.go b/pkg/target/transformersimage_test.go new file mode 100644 index 000000000..7d09bdf49 --- /dev/null +++ b/pkg/target/transformersimage_test.go @@ -0,0 +1,170 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target_test + +import ( + "testing" +) + +func makeTransfomersImageBase(th *KustTestHarness) { + th.writeK("/app/base", ` +resources: +- deploy1.yaml +- random.yaml +images: +- name: nginx + newTag: v2 +- name: my-nginx + newTag: previous +- name: myprivaterepohostname:1234/my/image + newTag: v1.0.1 +- name: foobar + digest: sha256:24a0c4b4 +- name: alpine + newName: myprivaterepohostname:1234/my/cool-alpine +- name: gcr.io:8080/my-project/my-cool-app + newName: my-cool-app +- name: postgres + newName: my-postgres + newTag: v3 +- name: docker + newName: my-docker + digest: sha256:25a0d4b4 +`) + th.writeF("/app/base/deploy1.yaml", ` +group: apps +apiVersion: v1 +kind: Deployment +metadata: + name: deploy1 +spec: + template: + spec: + initContainers: + - name: nginx2 + image: my-nginx:1.8.0 + - name: init-alpine + image: alpine:1.8.0 + containers: + - name: ngnix + image: nginx:1.7.9 + - name: repliaced-with-digest + image: foobar:1 + - name: postgresdb + image: postgres:1.8.0 +`) + th.writeF("/app/base/random.yaml", ` +kind: randomKind +metadata: + name: random +spec: + template: + spec: + containers: + - name: ngnix1 + image: nginx +spec2: + template: + spec: + containers: + - name: nginx3 + image: nginx:v1 + - name: nginx4 + image: my-nginx:latest +spec3: + template: + spec: + initContainers: + - name: postgresdb + image: postgres:alpine-9 + - name: init-docker + image: docker:17-git + - name: myImage + image: myprivaterepohostname:1234/my/image:latest + - name: myImage2 + image: myprivaterepohostname:1234/my/image + - name: my-app + image: my-app-image:v1 + - name: my-cool-app + image: gcr.io:8080/my-project/my-cool-app:latest +`) +} + +func TestTransfomersImageDefaultConfig(t *testing.T) { + th := NewKustTestHarness(t, "/app/base") + makeTransfomersImageBase(th) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +group: apps +kind: Deployment +metadata: + name: deploy1 +spec: + template: + spec: + containers: + - image: nginx:v2 + name: ngnix + - image: foobar@sha256:24a0c4b4 + name: repliaced-with-digest + - image: my-postgres:v3 + name: postgresdb + initContainers: + - image: my-nginx:previous + name: nginx2 + - image: myprivaterepohostname:1234/my/cool-alpine:1.8.0 + name: init-alpine +--- +kind: randomKind +metadata: + name: random +spec: + template: + spec: + containers: + - image: nginx:v2 + name: ngnix1 +spec2: + template: + spec: + containers: + - image: nginx:v2 + name: nginx3 + - image: my-nginx:previous + name: nginx4 +spec3: + template: + spec: + initContainers: + - image: my-postgres:v3 + name: postgresdb + - image: my-docker@sha256:25a0d4b4 + name: init-docker + - image: myprivaterepohostname:1234/my/image:v1.0.1 + name: myImage + - image: myprivaterepohostname:1234/my/image:v1.0.1 + name: myImage2 + - image: my-app-image:v1 + name: my-app + - image: my-cool-app:latest + name: my-cool-app +`) +} diff --git a/pkg/transformers/image_test.go b/pkg/transformers/image_test.go deleted file mode 100644 index c62ba3432..000000000 --- a/pkg/transformers/image_test.go +++ /dev/null @@ -1,266 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package transformers - -import ( - "reflect" - "testing" - - "sigs.k8s.io/kustomize/k8sdeps/kunstruct" - "sigs.k8s.io/kustomize/pkg/gvk" - "sigs.k8s.io/kustomize/pkg/image" - "sigs.k8s.io/kustomize/pkg/resid" - "sigs.k8s.io/kustomize/pkg/resmap" - "sigs.k8s.io/kustomize/pkg/resource" -) - -func TestImageTransformer(t *testing.T) { - var rf = resource.NewFactory( - kunstruct.NewKunstructuredFactoryImpl()) - - m := resmap.ResMap{ - resid.NewResId(deploy, "deploy1"): rf.FromMap( - map[string]interface{}{ - "group": "apps", - "apiVersion": "v1", - "kind": "Deployment", - "metadata": map[string]interface{}{ - "name": "deploy1", - }, - "spec": map[string]interface{}{ - "template": map[string]interface{}{ - "spec": map[string]interface{}{ - "initContainers": []interface{}{ - map[string]interface{}{ - "name": "nginx2", - "image": "my-nginx:1.8.0", - }, - map[string]interface{}{ - "name": "init-alpine", - "image": "alpine:1.8.0", - }, - }, - "containers": []interface{}{ - map[string]interface{}{ - "name": "nginx", - "image": "nginx:1.7.9", - }, - map[string]interface{}{ - "name": "replaced-with-digest", - "image": "foobar:1", - }, - map[string]interface{}{ - "name": "postgresdb", - "image": "postgres:1.8.0", - }, - }, - }, - }, - }, - }), - resid.NewResId(gvk.Gvk{Kind: "randomKind"}, "random"): rf.FromMap( - map[string]interface{}{ - "spec": map[string]interface{}{ - "template": map[string]interface{}{ - "spec": map[string]interface{}{ - "containers": []interface{}{ - map[string]interface{}{ - "name": "nginx1", - "image": "nginx", - }, - }, - }, - }, - }, - "spec2": map[string]interface{}{ - "template": map[string]interface{}{ - "spec": map[string]interface{}{ - "containers": []interface{}{ - map[string]interface{}{ - "name": "nginx3", - "image": "nginx:v1", - }, - map[string]interface{}{ - "name": "nginx4", - "image": "my-nginx:latest", - }, - }, - }, - }, - }, - "spec3": map[string]interface{}{ - "template": map[string]interface{}{ - "spec": map[string]interface{}{ - "initContainers": []interface{}{ - map[string]interface{}{ - "name": "postgresdb", - "image": "postgres:alpine-9", - }, - map[string]interface{}{ - "name": "init-docker", - "image": "docker:17-git", - }, - map[string]interface{}{ - "name": "myimage", - "image": "myprivaterepohostname:1234/my/image:latest", - }, - map[string]interface{}{ - "name": "myimage2", - "image": "myprivaterepohostname:1234/my/image", - }, - map[string]interface{}{ - "name": "my-app", - "image": "my-app-image:v1", - }, - map[string]interface{}{ - "name": "my-cool-app", - "image": "gcr.io:8080/my-project/my-cool-app:latest", - }, - }, - }, - }, - }, - }), - } - expected := resmap.ResMap{ - resid.NewResId(deploy, "deploy1"): rf.FromMap( - map[string]interface{}{ - "group": "apps", - "apiVersion": "v1", - "kind": "Deployment", - "metadata": map[string]interface{}{ - "name": "deploy1", - }, - "spec": map[string]interface{}{ - "template": map[string]interface{}{ - "spec": map[string]interface{}{ - "initContainers": []interface{}{ - map[string]interface{}{ - "name": "nginx2", - "image": "my-nginx:previous", - }, - map[string]interface{}{ - "name": "init-alpine", - "image": "myprivaterepohostname:1234/my/cool-alpine:1.8.0", - }, - }, - "containers": []interface{}{ - map[string]interface{}{ - "name": "nginx", - "image": "nginx:v2", - }, - map[string]interface{}{ - "name": "replaced-with-digest", - "image": "foobar@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3", - }, - map[string]interface{}{ - "name": "postgresdb", - "image": "my-postgres:v3", - }, - }, - }, - }, - }, - }), - resid.NewResId(gvk.Gvk{Kind: "randomKind"}, "random"): rf.FromMap( - map[string]interface{}{ - "spec": map[string]interface{}{ - "template": map[string]interface{}{ - "spec": map[string]interface{}{ - "containers": []interface{}{ - map[string]interface{}{ - "name": "nginx1", - "image": "nginx:v2", - }, - }, - }, - }, - }, - "spec2": map[string]interface{}{ - "template": map[string]interface{}{ - "spec": map[string]interface{}{ - "containers": []interface{}{ - map[string]interface{}{ - "name": "nginx3", - "image": "nginx:v2", - }, - map[string]interface{}{ - "name": "nginx4", - "image": "my-nginx:previous", - }, - }, - }, - }, - }, - "spec3": map[string]interface{}{ - "template": map[string]interface{}{ - "spec": map[string]interface{}{ - "initContainers": []interface{}{ - map[string]interface{}{ - "name": "postgresdb", - "image": "my-postgres:v3", - }, - map[string]interface{}{ - "name": "init-docker", - "image": "my-docker@sha256:25a0d4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3", - }, - map[string]interface{}{ - "name": "myimage", - "image": "myprivaterepohostname:1234/my/image:v1.0.1", - }, - map[string]interface{}{ - "name": "myimage2", - "image": "myprivaterepohostname:1234/my/image:v1.0.1", - }, - map[string]interface{}{ - "name": "my-app", - "image": "gcr.io/my-project/my-app-image:v1", - }, - map[string]interface{}{ - "name": "my-cool-app", - "image": "my-cool-app:latest", - }, - }, - }, - }, - }, - }), - } - - it, err := NewImageTransformer([]image.Image{ - {Name: "nginx", NewTag: "v2"}, - {Name: "my-nginx", NewTag: "previous"}, - {Name: "myprivaterepohostname:1234/my/image", NewTag: "v1.0.1"}, - {Name: "foobar", Digest: "sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"}, - {Name: "alpine", NewName: "myprivaterepohostname:1234/my/cool-alpine"}, - {Name: "my-app-image", NewName: "gcr.io/my-project/my-app-image"}, - {Name: "gcr.io:8080/my-project/my-cool-app", NewName: "my-cool-app"}, - {Name: "postgres", NewName: "my-postgres", NewTag: "v3"}, - {Name: "docker", NewName: "my-docker", Digest: "sha256:25a0d4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"}, - }) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - err = it.Transform(m) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if !reflect.DeepEqual(m, expected) { - err = expected.ErrorIfNotEqual(m) - t.Fatalf("actual doesn't match expected: %v. Actual %+v", err, m) - } -} From 3e85c4589b5743662375f424979006271c442eb9 Mon Sep 17 00:00:00 2001 From: Yujun Zhang Date: Sat, 2 Mar 2019 19:50:27 +0800 Subject: [PATCH 173/317] Load default config for image transformer --- pkg/target/kusttarget.go | 2 +- .../config/defaultconfig/defaultconfig.go | 2 ++ .../config/defaultconfig/image.go | 25 +++++++++++++++++++ pkg/transformers/config/transformerconfig.go | 6 +++++ pkg/transformers/image.go | 12 +++++---- 5 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 pkg/transformers/config/defaultconfig/image.go diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 5bbd2198c..d916df6fb 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -312,7 +312,7 @@ func (kt *KustTarget) newTransformer( return nil, err } r = append(r, t) - t, err = transformers.NewImageTransformer(kt.kustomization.Images) + t, err = transformers.NewImageTransformer(kt.kustomization.Images, tConfig.Images) if err != nil { return nil, err } diff --git a/pkg/transformers/config/defaultconfig/defaultconfig.go b/pkg/transformers/config/defaultconfig/defaultconfig.go index d96639a8a..10fe504ac 100644 --- a/pkg/transformers/config/defaultconfig/defaultconfig.go +++ b/pkg/transformers/config/defaultconfig/defaultconfig.go @@ -31,6 +31,7 @@ func GetDefaultFieldSpecs() []byte { []byte(namespaceFieldSpecs), []byte(varReferenceFieldSpecs), []byte(nameReferenceFieldSpecs), + []byte(imageFieldSpecs), } return bytes.Join(configData, []byte("\n")) } @@ -45,5 +46,6 @@ func GetDefaultFieldSpecsAsMap() map[string]string { result["namespace"] = namespaceFieldSpecs result["varreference"] = varReferenceFieldSpecs result["namereference"] = nameReferenceFieldSpecs + result["image"] = imageFieldSpecs return result } diff --git a/pkg/transformers/config/defaultconfig/image.go b/pkg/transformers/config/defaultconfig/image.go new file mode 100644 index 000000000..d571c46aa --- /dev/null +++ b/pkg/transformers/config/defaultconfig/image.go @@ -0,0 +1,25 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package defaultconfig + +const ( + imageFieldSpecs = ` +image: +- path: containers +- path: initContainers +` +) diff --git a/pkg/transformers/config/transformerconfig.go b/pkg/transformers/config/transformerconfig.go index 556f0b814..7ba048524 100644 --- a/pkg/transformers/config/transformerconfig.go +++ b/pkg/transformers/config/transformerconfig.go @@ -34,6 +34,7 @@ type TransformerConfig struct { CommonAnnotations fsSlice `json:"commonAnnotations,omitempty" yaml:"commonAnnotations,omitempty"` NameReference nbrSlice `json:"nameReference,omitempty" yaml:"nameReference,omitempty"` VarReference fsSlice `json:"varReference,omitempty" yaml:"varReference,omitempty"` + Images fsSlice `json:"image,omitempty" yaml:"image,omitempty"` } // MakeEmptyConfig returns an empty TransformerConfig object @@ -59,6 +60,7 @@ func (t *TransformerConfig) sortFields() { sort.Sort(t.CommonAnnotations) sort.Sort(t.NameReference) sort.Sort(t.VarReference) + sort.Sort(t.Images) } // AddPrefixFieldSpec adds a FieldSpec to NamePrefix @@ -129,6 +131,10 @@ func (t *TransformerConfig) Merge(input *TransformerConfig) ( if err != nil { return nil, err } + merged.Images, err = t.Images.mergeAll(input.Images) + if err != nil { + return nil, err + } merged.sortFields() return merged, nil } diff --git a/pkg/transformers/image.go b/pkg/transformers/image.go index 2e0797694..5ca3b86a1 100644 --- a/pkg/transformers/image.go +++ b/pkg/transformers/image.go @@ -23,18 +23,20 @@ import ( "sigs.k8s.io/kustomize/pkg/image" "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/transformers/config" ) // imageTransformer replace image names and tags type imageTransformer struct { - images []image.Image + images []image.Image + fieldSpecs []config.FieldSpec } var _ Transformer = &imageTransformer{} // NewImageTransformer constructs an imageTransformer. -func NewImageTransformer(slice []image.Image) (Transformer, error) { - return &imageTransformer{slice}, nil +func NewImageTransformer(slice []image.Image, fs []config.FieldSpec) (Transformer, error) { + return &imageTransformer{slice, fs}, nil } // Transform finds the matching images and replaces name, tag and/or digest @@ -58,9 +60,9 @@ func (pt *imageTransformer) Transform(resources resmap.ResMap) error { finds matched ones and update the image name and tag name */ func (pt *imageTransformer) findAndReplaceImage(obj map[string]interface{}) error { - paths := []string{"containers", "initContainers"} found := false - for _, path := range paths { + for _, fs := range pt.fieldSpecs { + path := fs.Path _, found = obj[path] if found { err := pt.updateContainers(obj, path) From f311ba8d4f0cc6b5c307ef4cd5255e41c735eda9 Mon Sep 17 00:00:00 2001 From: Yujun Zhang Date: Sat, 9 Mar 2019 12:04:18 +0800 Subject: [PATCH 174/317] Support custom config for image transformer --- .../config/defaultconfig/defaultconfig.go | 4 +- .../defaultconfig/{image.go => images.go} | 14 ++-- pkg/transformers/config/transformerconfig.go | 2 +- pkg/transformers/image.go | 67 ++++--------------- 4 files changed, 26 insertions(+), 61 deletions(-) rename pkg/transformers/config/defaultconfig/{image.go => images.go} (73%) diff --git a/pkg/transformers/config/defaultconfig/defaultconfig.go b/pkg/transformers/config/defaultconfig/defaultconfig.go index 10fe504ac..d34d9a934 100644 --- a/pkg/transformers/config/defaultconfig/defaultconfig.go +++ b/pkg/transformers/config/defaultconfig/defaultconfig.go @@ -31,7 +31,7 @@ func GetDefaultFieldSpecs() []byte { []byte(namespaceFieldSpecs), []byte(varReferenceFieldSpecs), []byte(nameReferenceFieldSpecs), - []byte(imageFieldSpecs), + []byte(imagesFieldSpecs), } return bytes.Join(configData, []byte("\n")) } @@ -46,6 +46,6 @@ func GetDefaultFieldSpecsAsMap() map[string]string { result["namespace"] = namespaceFieldSpecs result["varreference"] = varReferenceFieldSpecs result["namereference"] = nameReferenceFieldSpecs - result["image"] = imageFieldSpecs + result["images"] = imagesFieldSpecs return result } diff --git a/pkg/transformers/config/defaultconfig/image.go b/pkg/transformers/config/defaultconfig/images.go similarity index 73% rename from pkg/transformers/config/defaultconfig/image.go rename to pkg/transformers/config/defaultconfig/images.go index d571c46aa..f67521183 100644 --- a/pkg/transformers/config/defaultconfig/image.go +++ b/pkg/transformers/config/defaultconfig/images.go @@ -17,9 +17,15 @@ limitations under the License. package defaultconfig const ( - imageFieldSpecs = ` -image: -- path: containers -- path: initContainers + imagesFieldSpecs = ` +images: +- kind: Pod + path: spec/initContainers +- kind: Pod + path: spec/containers +- kind: Deployment + path: spec/template/spec/initContainers +- kind: Deployment + path: spec/template/spec/containers ` ) diff --git a/pkg/transformers/config/transformerconfig.go b/pkg/transformers/config/transformerconfig.go index 7ba048524..a00c6da66 100644 --- a/pkg/transformers/config/transformerconfig.go +++ b/pkg/transformers/config/transformerconfig.go @@ -34,7 +34,7 @@ type TransformerConfig struct { CommonAnnotations fsSlice `json:"commonAnnotations,omitempty" yaml:"commonAnnotations,omitempty"` NameReference nbrSlice `json:"nameReference,omitempty" yaml:"nameReference,omitempty"` VarReference fsSlice `json:"varReference,omitempty" yaml:"varReference,omitempty"` - Images fsSlice `json:"image,omitempty" yaml:"image,omitempty"` + Images fsSlice `json:"images,omitempty" yaml:"images,omitempty"` } // MakeEmptyConfig returns an empty TransformerConfig object diff --git a/pkg/transformers/image.go b/pkg/transformers/image.go index 5ca3b86a1..c60f0eeb8 100644 --- a/pkg/transformers/image.go +++ b/pkg/transformers/image.go @@ -40,47 +40,30 @@ func NewImageTransformer(slice []image.Image, fs []config.FieldSpec) (Transforme } // Transform finds the matching images and replaces name, tag and/or digest -func (pt *imageTransformer) Transform(resources resmap.ResMap) error { +func (pt *imageTransformer) Transform(m resmap.ResMap) error { if len(pt.images) == 0 { return nil } - for _, res := range resources { - err := pt.findAndReplaceImage(res.Map()) - if err != nil { - return err - } - } - return nil -} - -/* - findAndReplaceImage replaces the image name and tags inside one object - It searches the object for container session - then loops though all images inside containers session, - finds matched ones and update the image name and tag name -*/ -func (pt *imageTransformer) findAndReplaceImage(obj map[string]interface{}) error { - found := false - for _, fs := range pt.fieldSpecs { - path := fs.Path - _, found = obj[path] - if found { - err := pt.updateContainers(obj, path) + for id := range m { + objMap := m[id].Map() + for _, path := range pt.fieldSpecs { + if !id.Gvk().IsSelected(&path.Gvk) { + continue + } + err := mutateField(objMap, path.PathSlice(), false, pt.updateContainers) if err != nil { return err } + } } - if !found { - return pt.findContainers(obj) - } return nil } -func (pt *imageTransformer) updateContainers(obj map[string]interface{}, path string) error { - containers, ok := obj[path].([]interface{}) +func (pt *imageTransformer) updateContainers(in interface{}) (interface{}, error) { + containers, ok := in.([]interface{}) if !ok { - return fmt.Errorf("containers path is not of type []interface{} but %T", obj[path]) + return nil, fmt.Errorf("containers path is not of type []interface{} but %T", in) } for i := range containers { container := containers[i].(map[string]interface{}) @@ -108,31 +91,7 @@ func (pt *imageTransformer) updateContainers(obj map[string]interface{}, path st break } } - return nil -} - -func (pt *imageTransformer) findContainers(obj map[string]interface{}) error { - for key := range obj { - switch typedV := obj[key].(type) { - case map[string]interface{}: - err := pt.findAndReplaceImage(typedV) - if err != nil { - return err - } - case []interface{}: - for i := range typedV { - item := typedV[i] - typedItem, ok := item.(map[string]interface{}) - if ok { - err := pt.findAndReplaceImage(typedItem) - if err != nil { - return err - } - } - } - } - } - return nil + return containers, nil } func isImageMatched(s, t string) bool { From abf538d80d85da1f1739f0b42f59139210d8c10b Mon Sep 17 00:00:00 2001 From: Yujun Zhang Date: Tue, 12 Mar 2019 20:11:56 +0800 Subject: [PATCH 175/317] Keep backward compatibility for image transformer --- pkg/transformers/image.go | 54 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/pkg/transformers/image.go b/pkg/transformers/image.go index c60f0eeb8..ba8dbab50 100644 --- a/pkg/transformers/image.go +++ b/pkg/transformers/image.go @@ -54,8 +54,36 @@ func (pt *imageTransformer) Transform(m resmap.ResMap) error { if err != nil { return err } - } + // Keep for backward compatibility + err := pt.findAndReplaceImage(objMap) + if err != nil { + return err + } + } + return nil +} + +/* + findAndReplaceImage replaces the image name and tags inside one object + It searches the object for container session + then loops though all images inside containers session, + finds matched ones and update the image name and tag name +*/ +func (pt *imageTransformer) findAndReplaceImage(obj map[string]interface{}) error { + paths := []string{"containers", "initContainers"} + found := false + for _, path := range paths { + containers, found := obj[path] + if found { + _, err := pt.updateContainers(containers) + if err != nil { + return err + } + } + } + if !found { + return pt.findContainers(obj) } return nil } @@ -94,6 +122,30 @@ func (pt *imageTransformer) updateContainers(in interface{}) (interface{}, error return containers, nil } +func (pt *imageTransformer) findContainers(obj map[string]interface{}) error { + for key := range obj { + switch typedV := obj[key].(type) { + case map[string]interface{}: + err := pt.findAndReplaceImage(typedV) + if err != nil { + return err + } + case []interface{}: + for i := range typedV { + item := typedV[i] + typedItem, ok := item.(map[string]interface{}) + if ok { + err := pt.findAndReplaceImage(typedItem) + if err != nil { + return err + } + } + } + } + } + return nil +} + func isImageMatched(s, t string) bool { // Tag values are limited to [a-zA-Z0-9_.-]. pattern, _ := regexp.Compile("^" + t + "(:[a-zA-Z0-9_.-]*)?$") From 7130e3ff1d656d0a616fffa3c67adf828bec3bbb Mon Sep 17 00:00:00 2001 From: Yujun Zhang Date: Sun, 17 Mar 2019 08:51:14 +0800 Subject: [PATCH 176/317] Leave defautconfig empty for images `containers` and `initContainers` of *ANY* kind in *ANY* path are builtin supported in code --- pkg/transformers/config/defaultconfig/images.go | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/pkg/transformers/config/defaultconfig/images.go b/pkg/transformers/config/defaultconfig/images.go index f67521183..7612b616c 100644 --- a/pkg/transformers/config/defaultconfig/images.go +++ b/pkg/transformers/config/defaultconfig/images.go @@ -17,15 +17,7 @@ limitations under the License. package defaultconfig const ( - imagesFieldSpecs = ` -images: -- kind: Pod - path: spec/initContainers -- kind: Pod - path: spec/containers -- kind: Deployment - path: spec/template/spec/initContainers -- kind: Deployment - path: spec/template/spec/containers -` + // imageFieldSpecs is left empty since `containers` and `initContainers` + // of *ANY* kind in *ANY* path are builtin supported in code + imagesFieldSpecs = `` ) From e6c1b1410897a13d39983044c31e30db6c4f1e1a Mon Sep 17 00:00:00 2001 From: Yujun Zhang Date: Sun, 17 Mar 2019 16:54:50 +0800 Subject: [PATCH 177/317] Add test for transformers/image custom config --- pkg/target/transformersimage_test.go | 115 +++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/pkg/target/transformersimage_test.go b/pkg/target/transformersimage_test.go index 7d09bdf49..3f12e0cb7 100644 --- a/pkg/target/transformersimage_test.go +++ b/pkg/target/transformersimage_test.go @@ -168,3 +168,118 @@ spec3: name: my-cool-app `) } + +func makeTransfomersImageCustomBase(th *KustTestHarness) { + th.writeK("/app/base", ` +resources: +- custom.yaml +configurations: +- config/custom.yaml +images: +- name: nginx + newTag: v2 +- name: my-nginx + newTag: previous +- name: myprivaterepohostname:1234/my/image + newTag: v1.0.1 +- name: foobar + digest: sha256:24a0c4b4 +- name: alpine + newName: myprivaterepohostname:1234/my/cool-alpine +- name: gcr.io:8080/my-project/my-cool-app + newName: my-cool-app +- name: postgres + newName: my-postgres + newTag: v3 +- name: docker + newName: my-docker + digest: sha256:25a0d4b4 +`) + th.writeF("/app/base/custom.yaml", ` +kind: customKind +metadata: + name: custom +spec: + template: + spec: + myContainers: + - name: ngnix1 + image: nginx +spec2: + template: + spec: + myContainers: + - name: nginx3 + image: nginx:v1 + - name: nginx4 + image: my-nginx:latest +spec3: + template: + spec: + myInitContainers: + - name: postgresdb + image: postgres:alpine-9 + - name: init-docker + image: docker:17-git + - name: myImage + image: myprivaterepohostname:1234/my/image:latest + - name: myImage2 + image: myprivaterepohostname:1234/my/image + - name: my-app + image: my-app-image:v1 + - name: my-cool-app + image: gcr.io:8080/my-project/my-cool-app:latest +`) + th.writeF("/app/base/config/custom.yaml", ` +images: +- kind: Custom + path: spec/template/spec/myContainers +- kind: Custom + path: spec2/template/spec/myContainers +- kind: Custom + path: spec3/template/spec/myInitContainers +`) +} +func TestTransfomersImageCustomConfig(t *testing.T) { + th := NewKustTestHarness(t, "/app/base") + makeTransfomersImageCustomBase(th) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +kind: customKind +metadata: + name: custom +spec: + template: + spec: + myContainers: + - image: nginx + name: ngnix1 +spec2: + template: + spec: + myContainers: + - image: nginx:v1 + name: nginx3 + - image: my-nginx:latest + name: nginx4 +spec3: + template: + spec: + myInitContainers: + - image: postgres:alpine-9 + name: postgresdb + - image: docker:17-git + name: init-docker + - image: myprivaterepohostname:1234/my/image:latest + name: myImage + - image: myprivaterepohostname:1234/my/image + name: myImage2 + - image: my-app-image:v1 + name: my-app + - image: gcr.io:8080/my-project/my-cool-app:latest + name: my-cool-app +`) +} From 1bd7afe6e745a1924bfcfa477e43c7c9d695ccab Mon Sep 17 00:00:00 2001 From: Seth Pollack Date: Sun, 17 Mar 2019 08:53:49 -0400 Subject: [PATCH 178/317] fix linter --- k8sdeps/kv/plugin/builtinplugin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k8sdeps/kv/plugin/builtinplugin.go b/k8sdeps/kv/plugin/builtinplugin.go index 67aeb39fb..3af666dd4 100644 --- a/k8sdeps/kv/plugin/builtinplugin.go +++ b/k8sdeps/kv/plugin/builtinplugin.go @@ -29,7 +29,7 @@ type builtinFactory struct { plugins map[string]KVSource } -func newBuiltinFactory(ldr ifc.Loader) *builtinFactory { +func newBuiltinFactory(_ ifc.Loader) *builtinFactory { return &builtinFactory{ plugins: map[string]KVSource{ "literals": builtin.Literals{}, From 29cbec37b88f79da6a220a8d083f0f65730a3a2e Mon Sep 17 00:00:00 2001 From: Seth Pollack Date: Sun, 17 Mar 2019 09:53:38 -0400 Subject: [PATCH 179/317] move parse helpers to util --- k8sdeps/configmapandsecret/basefactory.go | 46 +--------------- k8sdeps/kv/plugin/builtin/literals.go | 22 +------- k8sdeps/kv/util.go | 65 +++++++++++++++++++++++ 3 files changed, 68 insertions(+), 65 deletions(-) create mode 100644 k8sdeps/kv/util.go diff --git a/k8sdeps/configmapandsecret/basefactory.go b/k8sdeps/configmapandsecret/basefactory.go index dd1a4d64e..b1bad0bcf 100644 --- a/k8sdeps/configmapandsecret/basefactory.go +++ b/k8sdeps/configmapandsecret/basefactory.go @@ -18,7 +18,6 @@ package configmapandsecret import ( "fmt" - "path" "strings" "github.com/pkg/errors" @@ -82,7 +81,7 @@ func errIfInvalidKey(keyName string) error { func keyValuesFromLiteralSources(sources []string) ([]kv.Pair, error) { var kvs []kv.Pair for _, s := range sources { - k, v, err := parseLiteralSource(s) + k, v, err := kv.ParseLiteralSource(s) if err != nil { return nil, err } @@ -110,7 +109,7 @@ func (bf baseFactory) keyValuesFromPlugins(sources []types.KVSource) ([]kv.Pair, func (bf baseFactory) keyValuesFromFileSources(sources []string) ([]kv.Pair, error) { var kvs []kv.Pair for _, s := range sources { - k, fPath, err := parseFileSource(s) + k, fPath, err := kv.ParseFileSource(s) if err != nil { return nil, err } @@ -133,44 +132,3 @@ func (bf baseFactory) keyValuesFromEnvFile(path string) ([]kv.Pair, error) { } return kv.KeyValuesFromLines(content) } - -// parseFileSource parses the source given. -// -// Acceptable formats include: -// 1. source-path: the basename will become the key name -// 2. source-name=source-path: the source-name will become the key name and -// source-path is the path to the key file. -// -// Key names cannot include '='. -func parseFileSource(source string) (keyName, filePath string, err error) { - numSeparators := strings.Count(source, "=") - switch { - case numSeparators == 0: - return path.Base(source), source, nil - case numSeparators == 1 && strings.HasPrefix(source, "="): - return "", "", fmt.Errorf("key name for file path %v missing", strings.TrimPrefix(source, "=")) - case numSeparators == 1 && strings.HasSuffix(source, "="): - return "", "", fmt.Errorf("file path for key name %v missing", strings.TrimSuffix(source, "=")) - case numSeparators > 1: - return "", "", errors.New("key names or file paths cannot contain '='") - default: - components := strings.Split(source, "=") - return components[0], components[1], nil - } -} - -// parseLiteralSource parses the source key=val pair into its component pieces. -// This functionality is distinguished from strings.SplitN(source, "=", 2) since -// it returns an error in the case of empty keys, values, or a missing equals sign. -func parseLiteralSource(source string) (keyName, value string, err error) { - // leading equal is invalid - if strings.Index(source, "=") == 0 { - return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source) - } - // split after the first equal (so values can have the = character) - items := strings.SplitN(source, "=", 2) - if len(items) != 2 { - return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source) - } - return items[0], strings.Trim(items[1], "\"'"), nil -} diff --git a/k8sdeps/kv/plugin/builtin/literals.go b/k8sdeps/kv/plugin/builtin/literals.go index bb79744f8..8896e7104 100644 --- a/k8sdeps/kv/plugin/builtin/literals.go +++ b/k8sdeps/kv/plugin/builtin/literals.go @@ -17,23 +17,19 @@ limitations under the License. package builtin import ( - "fmt" - "strings" - "sigs.k8s.io/kustomize/k8sdeps/kv" ) // Literals takes a list of literals. // Each literal source should be a key and literal value, // e.g. `somekey=somevalue` -// It will be similar to kubectl create configmap|secret --from-literal type Literals struct{} // Get implements the interface for kv plugins. func (p Literals) Get(root string, args []string) ([]kv.Pair, error) { var kvs []kv.Pair for _, s := range args { - k, v, err := parseLiteralSource(s) + k, v, err := kv.ParseLiteralSource(s) if err != nil { return nil, err } @@ -41,19 +37,3 @@ func (p Literals) Get(root string, args []string) ([]kv.Pair, error) { } return kvs, nil } - -// parseLiteralSource parses the source key=val pair into its component pieces. -// This functionality is distinguished from strings.SplitN(source, "=", 2) since -// it returns an error in the case of empty keys, values, or a missing equals sign. -func parseLiteralSource(source string) (keyName, value string, err error) { - // leading equal is invalid - if strings.Index(source, "=") == 0 { - return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source) - } - // split after the first equal (so values can have the = character) - items := strings.SplitN(source, "=", 2) - if len(items) != 2 { - return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source) - } - return items[0], strings.Trim(items[1], "\"'"), nil -} diff --git a/k8sdeps/kv/util.go b/k8sdeps/kv/util.go new file mode 100644 index 000000000..0fe67ed35 --- /dev/null +++ b/k8sdeps/kv/util.go @@ -0,0 +1,65 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kv + +import ( + "errors" + "fmt" + "path" + "strings" +) + +// ParseFileSource parses the source given. +// +// Acceptable formats include: +// 1. source-path: the basename will become the key name +// 2. source-name=source-path: the source-name will become the key name and +// source-path is the path to the key file. +// +// Key names cannot include '='. +func ParseFileSource(source string) (keyName, filePath string, err error) { + numSeparators := strings.Count(source, "=") + switch { + case numSeparators == 0: + return path.Base(source), source, nil + case numSeparators == 1 && strings.HasPrefix(source, "="): + return "", "", fmt.Errorf("key name for file path %v missing", strings.TrimPrefix(source, "=")) + case numSeparators == 1 && strings.HasSuffix(source, "="): + return "", "", fmt.Errorf("file path for key name %v missing", strings.TrimSuffix(source, "=")) + case numSeparators > 1: + return "", "", errors.New("key names or file paths cannot contain '='") + default: + components := strings.Split(source, "=") + return components[0], components[1], nil + } +} + +// ParseLiteralSource parses the source key=val pair into its component pieces. +// This functionality is distinguished from strings.SplitN(source, "=", 2) since +// it returns an error in the case of empty keys, values, or a missing equals sign. +func ParseLiteralSource(source string) (keyName, value string, err error) { + // leading equal is invalid + if strings.Index(source, "=") == 0 { + return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source) + } + // split after the first equal (so values can have the = character) + items := strings.SplitN(source, "=", 2) + if len(items) != 2 { + return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source) + } + return items[0], strings.Trim(items[1], "\"'"), nil +} From 103c1b3a4fd10c7afa2b3447cf5fe93027770ba3 Mon Sep 17 00:00:00 2001 From: jregan Date: Sun, 17 Mar 2019 07:18:42 -0700 Subject: [PATCH 180/317] Put goplugins behind flag. --- .../configmapandsecret/configmapfactory.go | 9 ++- k8sdeps/factory.go | 34 ----------- k8sdeps/kunstruct/factory.go | 20 ++++++- k8sdeps/kv/plugin/goplugin.go | 50 +++++++++++++---- k8sdeps/kv/plugin/registry.go | 29 ++++++++-- kustomize.go | 3 +- pkg/commands/build/build.go | 6 +- pkg/commands/build/build_test.go | 4 +- pkg/commands/commands.go | 44 +++++++++++---- pkg/commands/edit/add/addmetadata.go | 6 +- pkg/commands/kustfile/kustomizationfile.go | 6 +- .../kustfile/kustomizationfile_test.go | 6 +- pkg/factory/factory.go | 39 ------------- pkg/fs/fakefs.go | 6 +- pkg/loader/fileloader_test.go | 4 +- pkg/pgmconfig/config.go | 54 ++++++++++++++++++ pkg/pgmconfig/config_test.go | 56 +++++++++++++++++++ pkg/{constants => pgmconfig}/constants.go | 14 +++-- pkg/target/generatoroptions_test.go | 47 ++++++++++++++++ pkg/target/kusttarget.go | 6 +- pkg/target/kusttestharness_test.go | 15 ++++- pkg/types/kustomization.go | 19 +++++++ 22 files changed, 337 insertions(+), 140 deletions(-) delete mode 100644 k8sdeps/factory.go delete mode 100644 pkg/factory/factory.go create mode 100644 pkg/pgmconfig/config.go create mode 100644 pkg/pgmconfig/config_test.go rename pkg/{constants => pgmconfig}/constants.go (76%) diff --git a/k8sdeps/configmapandsecret/configmapfactory.go b/k8sdeps/configmapandsecret/configmapfactory.go index a40792258..27897c705 100644 --- a/k8sdeps/configmapandsecret/configmapfactory.go +++ b/k8sdeps/configmapandsecret/configmapfactory.go @@ -21,8 +21,7 @@ import ( "fmt" "unicode/utf8" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/core/v1" + "k8s.io/api/core/v1" "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/types" @@ -40,8 +39,8 @@ func NewFactory( } func makeFreshConfigMap( - args *types.ConfigMapArgs) *corev1.ConfigMap { - cm := &corev1.ConfigMap{} + args *types.ConfigMapArgs) *v1.ConfigMap { + cm := &v1.ConfigMap{} cm.APIVersion = "v1" cm.Kind = "ConfigMap" cm.Name = args.Name @@ -52,7 +51,7 @@ func makeFreshConfigMap( // MakeConfigMap returns a new ConfigMap, or nil and an error. func (f *Factory) MakeConfigMap( - args *types.ConfigMapArgs) (*corev1.ConfigMap, error) { + args *types.ConfigMapArgs) (*v1.ConfigMap, error) { all, err := f.loadKvPairs(args.GeneratorArgs) if err != nil { return nil, err diff --git a/k8sdeps/factory.go b/k8sdeps/factory.go deleted file mode 100644 index a422b25a4..000000000 --- a/k8sdeps/factory.go +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package k8sdeps provides kustomize factory with k8s dependencies -package k8sdeps - -import ( - "sigs.k8s.io/kustomize/k8sdeps/kunstruct" - "sigs.k8s.io/kustomize/k8sdeps/transformer" - "sigs.k8s.io/kustomize/k8sdeps/validator" - "sigs.k8s.io/kustomize/pkg/factory" -) - -// NewFactory creates an instance of KustFactory using k8sdeps factories -func NewFactory() *factory.KustFactory { - return factory.NewKustFactory( - kunstruct.NewKunstructuredFactoryImpl(), - validator.NewKustValidator(), - transformer.NewFactoryImpl(), - ) -} diff --git a/k8sdeps/kunstruct/factory.go b/k8sdeps/kunstruct/factory.go index 3c3644c3f..ef40209b9 100644 --- a/k8sdeps/kunstruct/factory.go +++ b/k8sdeps/kunstruct/factory.go @@ -32,13 +32,21 @@ import ( // KunstructuredFactoryImpl hides construction using apimachinery types. type KunstructuredFactoryImpl struct { + generatorMetaArgs *types.GeneratorMetaArgs } var _ ifc.KunstructuredFactory = &KunstructuredFactoryImpl{} // NewKunstructuredFactoryImpl returns a factory. func NewKunstructuredFactoryImpl() ifc.KunstructuredFactory { - return &KunstructuredFactoryImpl{} + return NewKunstructuredFactoryWithGeneratorArgs( + &types.GeneratorMetaArgs{}) +} + +// NewKunstructuredFactoryWithGeneratorArgs returns a factory. +func NewKunstructuredFactoryWithGeneratorArgs( + gma *types.GeneratorMetaArgs) ifc.KunstructuredFactory { + return &KunstructuredFactoryImpl{gma} } // SliceFromBytes returns a slice of Kunstructured. @@ -82,7 +90,10 @@ func (kf *KunstructuredFactoryImpl) MakeConfigMap( ldr ifc.Loader, options *types.GeneratorOptions, args *types.ConfigMapArgs) (ifc.Kunstructured, error) { - o, err := configmapandsecret.NewFactory(ldr, options, plugin.NewRegistry(ldr)).MakeConfigMap(args) + o, err := configmapandsecret.NewFactory( + ldr, options, + plugin.NewConfiguredRegistry( + ldr, &kf.generatorMetaArgs.PluginConfig)).MakeConfigMap(args) if err != nil { return nil, err } @@ -94,7 +105,10 @@ func (kf *KunstructuredFactoryImpl) MakeSecret( ldr ifc.Loader, options *types.GeneratorOptions, args *types.SecretArgs) (ifc.Kunstructured, error) { - o, err := configmapandsecret.NewFactory(ldr, options, plugin.NewRegistry(ldr)).MakeSecret(args) + o, err := configmapandsecret.NewFactory( + ldr, options, + plugin.NewConfiguredRegistry( + ldr, &kf.generatorMetaArgs.PluginConfig)).MakeSecret(args) if err != nil { return nil, err } diff --git a/k8sdeps/kv/plugin/goplugin.go b/k8sdeps/kv/plugin/goplugin.go index 09351fa1a..4b67f9dd2 100644 --- a/k8sdeps/kv/plugin/goplugin.go +++ b/k8sdeps/kv/plugin/goplugin.go @@ -18,40 +18,66 @@ package plugin import ( "fmt" - "os" + "path/filepath" "plugin" + + "sigs.k8s.io/kustomize/pkg/types" ) var _ Factory = &goFactory{} const ( - pluginDir = "kustomize/plugins/kvsource" + kvSourcesDir = "kvSources" + EnableGoPluginsFlagName = "enable_alpha_goplugins_accept_panic_risk" + EnableGoPluginsFlagHelp = ` +Warning: the main program may panic and exit on an +attempt to use a goplugin that was compiled under +conditions differing from the those in effect when +main was compiled. It's safest to use this flag in +the context of a container image holding both the +main and the goplugins it needs, all built on the +same machine, with the same transitive libs and +the same compiler version. +` + errorFmt = ` +enable go plugins by specifying flag + --%s +Place .so files in + %s +%s +` ) -func newGoFactory() *goFactory { +func newGoFactory(c *types.PluginConfig) *goFactory { return &goFactory{ + config: c, plugins: make(map[string]KVSource), } } type goFactory struct { + config *types.PluginConfig plugins map[string]KVSource } -func configDir() string { - xdghome := os.Getenv("XDG_CONFIG_HOME") - if len(xdghome) == 0 { - return os.ExpandEnv("$HOME/.config") - } - return xdghome -} - func (p *goFactory) load(name string) (KVSource, error) { if plug, ok := p.plugins[name]; ok { return plug, nil } - goPlugin, err := plugin.Open(fmt.Sprintf("%s/%s/kustomize-%s.so", configDir(), pluginDir, name)) + dir := filepath.Join( + p.config.DirectoryPath, + kvSourcesDir) + if !p.config.GoEnabled { + return nil, fmt.Errorf( + errorFmt, + EnableGoPluginsFlagName, + dir, + EnableGoPluginsFlagHelp) + } + + goPlugin, err := plugin.Open( + filepath.Join(dir, name+".so")) if err != nil { return nil, err } diff --git a/k8sdeps/kv/plugin/registry.go b/k8sdeps/kv/plugin/registry.go index bf6c8ae0a..9e7447f29 100644 --- a/k8sdeps/kv/plugin/registry.go +++ b/k8sdeps/kv/plugin/registry.go @@ -18,8 +18,10 @@ package plugin import ( "fmt" - + "path/filepath" "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/pgmconfig" + "sigs.k8s.io/kustomize/pkg/types" ) // Registry holds all the plugin factories. @@ -28,17 +30,36 @@ type Registry struct { ldr ifc.Loader } -// NewRegistry returns a new Registry loaded with all the factories. -func NewRegistry(ldr ifc.Loader) Registry { +const ( + PluginsDir = "plugins" +) + +func DefaultPluginConfig() types.PluginConfig { + return types.PluginConfig{ + GoEnabled: false, + DirectoryPath: filepath.Join( + pgmconfig.ConfigRoot(), PluginsDir), + } +} + +// NewConfiguredRegistry returns a new Registry loaded +// with all the factories and a custom PluginConfig. +func NewConfiguredRegistry( + ldr ifc.Loader, pc *types.PluginConfig) Registry { return Registry{ ldr: ldr, factories: map[string]Factory{ - "go": newGoFactory(), + "go": newGoFactory(pc), "testonly": newTestonlyFactory(), }, } } +// NewRegistry returns a new Registry with default config. +func NewRegistry(ldr ifc.Loader) Registry { + return NewConfiguredRegistry(ldr, &types.PluginConfig{}) +} + // Load returns a plugin by type and name, func (r *Registry) Load(pluginType, name string) (KVSource, error) { factory, exists := r.factories[pluginType] diff --git a/kustomize.go b/kustomize.go index e17481de9..584b559e8 100644 --- a/kustomize.go +++ b/kustomize.go @@ -19,12 +19,11 @@ package main import ( "os" - "sigs.k8s.io/kustomize/k8sdeps" "sigs.k8s.io/kustomize/pkg/commands" ) func main() { - if err := commands.NewDefaultCommand(k8sdeps.NewFactory()).Execute(); err != nil { + if err := commands.NewDefaultCommand().Execute(); err != nil { os.Exit(1) } os.Exit(0) diff --git a/pkg/commands/build/build.go b/pkg/commands/build/build.go index e62747e32..1176f25b1 100644 --- a/pkg/commands/build/build.go +++ b/pkg/commands/build/build.go @@ -21,10 +21,10 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" - "sigs.k8s.io/kustomize/pkg/constants" "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/ifc/transformer" "sigs.k8s.io/kustomize/pkg/loader" + "sigs.k8s.io/kustomize/pkg/pgmconfig" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/target" ) @@ -67,7 +67,7 @@ func NewCmdBuild( cmd := &cobra.Command{ Use: "build [path]", - Short: "Print current configuration per contents of " + constants.KustomizationFileNames[0], + Short: "Print current configuration per contents of " + pgmconfig.KustomizationFileNames[0], Example: examples, SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) error { @@ -88,7 +88,7 @@ func NewCmdBuild( // Validate validates build command. func (o *Options) Validate(args []string) error { if len(args) > 1 { - return errors.New("specify one path to " + constants.KustomizationFileNames[0]) + return errors.New("specify one path to " + pgmconfig.KustomizationFileNames[0]) } if len(args) == 0 { o.kustomizationPath = "./" diff --git a/pkg/commands/build/build_test.go b/pkg/commands/build/build_test.go index b06ccdea2..792d95aac 100644 --- a/pkg/commands/build/build_test.go +++ b/pkg/commands/build/build_test.go @@ -19,7 +19,7 @@ package build import ( "testing" - "sigs.k8s.io/kustomize/pkg/constants" + "sigs.k8s.io/kustomize/pkg/pgmconfig" ) func TestNewOptionsToSilenceCodeInspectionError(t *testing.T) { @@ -39,7 +39,7 @@ func TestBuildValidate(t *testing.T) { {"file", []string{"beans"}, "beans", ""}, {"path", []string{"a/b/c"}, "a/b/c", ""}, {"path", []string{"too", "many"}, - "", "specify one path to " + constants.KustomizationFileNames[0]}, + "", "specify one path to " + pgmconfig.KustomizationFileNames[0]}, } for _, mycase := range cases { opts := Options{} diff --git a/pkg/commands/commands.go b/pkg/commands/commands.go index 3651ae6cf..5a4ff0d05 100644 --- a/pkg/commands/commands.go +++ b/pkg/commands/commands.go @@ -20,35 +20,57 @@ package commands import ( "flag" "os" + "sigs.k8s.io/kustomize/pkg/pgmconfig" "github.com/spf13/cobra" + "sigs.k8s.io/kustomize/k8sdeps/kunstruct" + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" + "sigs.k8s.io/kustomize/k8sdeps/transformer" + "sigs.k8s.io/kustomize/k8sdeps/validator" "sigs.k8s.io/kustomize/pkg/commands/build" "sigs.k8s.io/kustomize/pkg/commands/edit" "sigs.k8s.io/kustomize/pkg/commands/misc" - "sigs.k8s.io/kustomize/pkg/factory" "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/resource" + "sigs.k8s.io/kustomize/pkg/types" ) // NewDefaultCommand returns the default (aka root) command for kustomize command. -func NewDefaultCommand(f *factory.KustFactory) *cobra.Command { - fsys := fs.MakeRealFS() +func NewDefaultCommand() *cobra.Command { + fSys := fs.MakeRealFS() stdOut := os.Stdout c := &cobra.Command{ - Use: "kustomize", - Short: "kustomize manages declarative configuration of Kubernetes", + Use: pgmconfig.PgmName, + Short: "Manages declarative configuration of Kubernetes", Long: ` -kustomize manages declarative configuration of Kubernetes. - +Manages declarative configuration of Kubernetes. See https://sigs.k8s.io/kustomize `, } + // Configuration for ConfigMap and Secret generators. + genMetaArgs := types.GeneratorMetaArgs{ + PluginConfig: plugin.DefaultPluginConfig(), + } + + c.Flags().BoolVar( + &genMetaArgs.PluginConfig.GoEnabled, + plugin.EnableGoPluginsFlagName, + false, plugin.EnableGoPluginsFlagHelp) + // Not advertising this alpha feature. + c.Flags().MarkHidden(plugin.EnableGoPluginsFlagName) + + uf := kunstruct.NewKunstructuredFactoryWithGeneratorArgs(&genMetaArgs) + c.AddCommand( - // TODO: Make consistent API for newCmd* functions. - build.NewCmdBuild(stdOut, fsys, f.ResmapF, f.TransformerF), - edit.NewCmdEdit(fsys, f.ValidatorF, f.UnstructF), - misc.NewCmdConfig(fsys), + build.NewCmdBuild( + stdOut, fSys, + resmap.NewFactory(resource.NewFactory(uf)), + transformer.NewFactoryImpl()), + edit.NewCmdEdit(fSys, validator.NewKustValidator(), uf), + misc.NewCmdConfig(fSys), misc.NewCmdVersion(stdOut), ) c.PersistentFlags().AddGoFlagSet(flag.CommandLine) diff --git a/pkg/commands/edit/add/addmetadata.go b/pkg/commands/edit/add/addmetadata.go index d9104f35d..b4e14f34e 100644 --- a/pkg/commands/edit/add/addmetadata.go +++ b/pkg/commands/edit/add/addmetadata.go @@ -22,8 +22,8 @@ import ( "github.com/spf13/cobra" "sigs.k8s.io/kustomize/pkg/commands/kustfile" - "sigs.k8s.io/kustomize/pkg/constants" "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/pgmconfig" "sigs.k8s.io/kustomize/pkg/types" ) @@ -59,7 +59,7 @@ func newCmdAddAnnotation(fSys fs.FileSystem, v func(map[string]string) error) *c o.mapValidator = v cmd := &cobra.Command{ Use: "annotation", - Short: "Adds one or more commonAnnotations to " + constants.KustomizationFileNames[0], + Short: "Adds one or more commonAnnotations to " + pgmconfig.KustomizationFileNames[0], Example: ` add annotation {annotationKey1:annotationValue1},{annotationKey2:annotationValue2}`, RunE: func(cmd *cobra.Command, args []string) error { @@ -76,7 +76,7 @@ func newCmdAddLabel(fSys fs.FileSystem, v func(map[string]string) error) *cobra. o.mapValidator = v cmd := &cobra.Command{ Use: "label", - Short: "Adds one or more commonLabels to " + constants.KustomizationFileNames[0], + Short: "Adds one or more commonLabels to " + pgmconfig.KustomizationFileNames[0], Example: ` add label {labelKey1:labelValue1},{labelKey2:labelValue2}`, RunE: func(cmd *cobra.Command, args []string) error { diff --git a/pkg/commands/kustfile/kustomizationfile.go b/pkg/commands/kustfile/kustomizationfile.go index cf66745ec..42b93d789 100644 --- a/pkg/commands/kustfile/kustomizationfile.go +++ b/pkg/commands/kustfile/kustomizationfile.go @@ -27,8 +27,8 @@ import ( "strings" "github.com/ghodss/yaml" - "sigs.k8s.io/kustomize/pkg/constants" "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/pgmconfig" "sigs.k8s.io/kustomize/pkg/types" ) @@ -129,7 +129,7 @@ func NewKustomizationFile(fSys fs.FileSystem) (*kustomizationFile, error) { // n func (mf *kustomizationFile) validate() error { match := 0 var path []string - for _, kfilename := range constants.KustomizationFileNames { + for _, kfilename := range pgmconfig.KustomizationFileNames { if mf.fSys.Exists(kfilename) { match += 1 path = append(path, kfilename) @@ -138,7 +138,7 @@ func (mf *kustomizationFile) validate() error { switch match { case 0: - return fmt.Errorf("Missing kustomization file '%s'.\n", constants.KustomizationFileNames[0]) + return fmt.Errorf("Missing kustomization file '%s'.\n", pgmconfig.KustomizationFileNames[0]) case 1: mf.path = path[0] default: diff --git a/pkg/commands/kustfile/kustomizationfile_test.go b/pkg/commands/kustfile/kustomizationfile_test.go index 79e3a5da3..0795986c3 100644 --- a/pkg/commands/kustfile/kustomizationfile_test.go +++ b/pkg/commands/kustfile/kustomizationfile_test.go @@ -21,8 +21,8 @@ import ( "strings" "testing" - "sigs.k8s.io/kustomize/pkg/constants" "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/pgmconfig" "sigs.k8s.io/kustomize/pkg/types" ) @@ -112,12 +112,12 @@ configMapGenerator: name: my-configmap ` fakeFS := fs.MakeFakeFS() - fakeFS.WriteFile(constants.KustomizationFileNames[1], []byte(kcontent)) + fakeFS.WriteFile(pgmconfig.KustomizationFileNames[1], []byte(kcontent)) k, err := NewKustomizationFile(fakeFS) if err != nil { t.Fatalf("Unexpected Error: %v", err) } - if k.path != constants.KustomizationFileNames[1] { + if k.path != pgmconfig.KustomizationFileNames[1] { t.Fatalf("Load incorrect file path %s", k.path) } } diff --git a/pkg/factory/factory.go b/pkg/factory/factory.go deleted file mode 100644 index e71669a87..000000000 --- a/pkg/factory/factory.go +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -// Package factory provides factories for kustomize. -package factory - -import ( - "sigs.k8s.io/kustomize/pkg/ifc" - "sigs.k8s.io/kustomize/pkg/ifc/transformer" - "sigs.k8s.io/kustomize/pkg/resmap" - "sigs.k8s.io/kustomize/pkg/resource" -) - -// KustFactory provides different factories for kustomize -type KustFactory struct { - ResmapF *resmap.Factory - TransformerF transformer.Factory - ValidatorF ifc.Validator - UnstructF ifc.KunstructuredFactory -} - -// NewKustFactory creats a KustFactory instance -func NewKustFactory(u ifc.KunstructuredFactory, v ifc.Validator, t transformer.Factory) *KustFactory { - return &KustFactory{ - ResmapF: resmap.NewFactory(resource.NewFactory(u)), - TransformerF: t, - ValidatorF: v, - UnstructF: u, - } -} diff --git a/pkg/fs/fakefs.go b/pkg/fs/fakefs.go index 59c0966b2..0f2a4eedf 100644 --- a/pkg/fs/fakefs.go +++ b/pkg/fs/fakefs.go @@ -22,7 +22,7 @@ import ( "sort" "strings" - "sigs.k8s.io/kustomize/pkg/constants" + "sigs.k8s.io/kustomize/pkg/pgmconfig" ) var _ FileSystem = &fakeFs{} @@ -158,7 +158,7 @@ func (fs *fakeFs) ReadFile(name string) ([]byte, error) { } func (fs *fakeFs) ReadTestKustomization() ([]byte, error) { - return fs.ReadFile(constants.KustomizationFileNames[0]) + return fs.ReadFile(pgmconfig.KustomizationFileNames[0]) } // WriteFile always succeeds and does nothing. @@ -176,7 +176,7 @@ func (fs *fakeFs) WriteTestKustomization() { // WriteTestKustomizationWith writes a standard test file. func (fs *fakeFs) WriteTestKustomizationWith(bytes []byte) { - fs.WriteFile(constants.KustomizationFileNames[0], bytes) + fs.WriteFile(pgmconfig.KustomizationFileNames[0], bytes) } func (fs *fakeFs) pathMatch(path, pattern string) bool { diff --git a/pkg/loader/fileloader_test.go b/pkg/loader/fileloader_test.go index b8affe10e..68114f368 100644 --- a/pkg/loader/fileloader_test.go +++ b/pkg/loader/fileloader_test.go @@ -25,8 +25,8 @@ import ( "strings" "testing" - "sigs.k8s.io/kustomize/pkg/constants" "sigs.k8s.io/kustomize/pkg/git" + "sigs.k8s.io/kustomize/pkg/pgmconfig" "sigs.k8s.io/kustomize/pkg/fs" "sigs.k8s.io/kustomize/pkg/ifc" @@ -341,7 +341,7 @@ func TestNewLoaderAtGitClone(t *testing.T) { fSys.MkdirAll(coRoot) fSys.MkdirAll(coRoot + "/" + pathInRepo) fSys.WriteFile( - coRoot+"/"+pathInRepo+"/"+constants.KustomizationFileNames[0], + coRoot+"/"+pathInRepo+"/"+pgmconfig.KustomizationFileNames[0], []byte(` whatever `)) diff --git a/pkg/pgmconfig/config.go b/pkg/pgmconfig/config.go new file mode 100644 index 000000000..d7a27422a --- /dev/null +++ b/pkg/pgmconfig/config.go @@ -0,0 +1,54 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package commands holds the CLI glue mapping textual commands/args to method calls. +package pgmconfig + +import ( + "os" + "path/filepath" + "runtime" +) + +const ( + XDG_CONFIG_HOME = "XDG_CONFIG_HOME" + defaultConfigSubdir = ".config" +) + +// Use https://github.com/kirsle/configdir instead? +func ConfigRoot() string { + dir := os.Getenv(XDG_CONFIG_HOME) + if len(dir) == 0 { + dir = filepath.Join( + homeDir(), defaultConfigSubdir) + } + return filepath.Join(dir, PgmName) +} + +func homeDir() string { + home := os.Getenv(homeEnv()) + if len(home) > 0 { + return home + } + return "~" +} + +func homeEnv() string { + if runtime.GOOS == "windows" { + return "USERPROFILE" + } + return "HOME" +} diff --git a/pkg/pgmconfig/config_test.go b/pkg/pgmconfig/config_test.go new file mode 100644 index 000000000..2833afea7 --- /dev/null +++ b/pkg/pgmconfig/config_test.go @@ -0,0 +1,56 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package pgmconfig + +import ( + "os" + "path/filepath" + "strings" + "testing" +) + +func TestConfigDirNoXdg(t *testing.T) { + xdg, isSet := os.LookupEnv(XDG_CONFIG_HOME) + if isSet { + os.Unsetenv(XDG_CONFIG_HOME) + } + s := ConfigRoot() + if isSet { + os.Setenv(XDG_CONFIG_HOME, xdg) + } + if !strings.HasSuffix( + s, + rootedPath(defaultConfigSubdir, PgmName)) { + t.Fatalf("unexpected config dir: %s", s) + } +} + +func rootedPath(elem ...string) string { + return string(filepath.Separator) + filepath.Join(elem...) +} + +func TestConfigDirWithXdg(t *testing.T) { + xdg, isSet := os.LookupEnv(XDG_CONFIG_HOME) + os.Setenv(XDG_CONFIG_HOME, rootedPath("blah")) + s := ConfigRoot() + if isSet { + os.Setenv(XDG_CONFIG_HOME, xdg) + } + if s != rootedPath("blah", PgmName) { + t.Fatalf("unexpected config dir: %s", s) + } +} diff --git a/pkg/constants/constants.go b/pkg/pgmconfig/constants.go similarity index 76% rename from pkg/constants/constants.go rename to pkg/pgmconfig/constants.go index dd50230fb..008b69da9 100644 --- a/pkg/constants/constants.go +++ b/pkg/pgmconfig/constants.go @@ -15,14 +15,18 @@ limitations under the License. */ // Package constants holds global constants for the kustomize tool. -package constants +package pgmconfig -// KustomizationFileNames is a list of filenames that can be recognized and consumbed -// by Kustomize. -// In each directory, Kustomize searches for file with the name in this list. -// Only one match is allowed. +// KustomizationFileNames is a list of filenames +// that kustomize recognizes. +// To avoid ambiguity, a directory cannot contain +// more than one match to this list. var KustomizationFileNames = []string{ "kustomization.yaml", "kustomization.yml", "Kustomization", } + +const ( + PgmName = "kustomize" +) diff --git a/pkg/target/generatoroptions_test.go b/pkg/target/generatoroptions_test.go index 4dbdbb588..fc1bd792e 100644 --- a/pkg/target/generatoroptions_test.go +++ b/pkg/target/generatoroptions_test.go @@ -14,6 +14,9 @@ limitations under the License. package target_test import ( + "path/filepath" + "sigs.k8s.io/kustomize/pkg/types" + "strings" "testing" ) @@ -69,3 +72,47 @@ metadata: name: shouldNotHaveHash `) } + +func TestGoPluginNotEnabled(t *testing.T) { + th := NewKustTestHarness(t, "/app") + th.writeK("/app", ` +secretGenerator: +- name: attemptGoPlugin + kvSources: + - name: foo + pluginType: go + args: + - someArg + - someOtherArg +`) + _, err := th.makeKustTarget().MakeCustomizedResMap() + if err == nil { + t.Fatalf("expected error") + } + if !strings.Contains(err.Error(), "enable go plugins by ") { + t.Fatalf("unexpected err: %v", err) + } +} + +func TestGoPluginDoesNotExist(t *testing.T) { + th := NewKustTestHarnessWithPluginConfig( + t, "/app", types.PluginConfig{GoEnabled: true}) + th.writeK("/app", ` +secretGenerator: +- name: attemptGoPlugin + kvSources: + - name: foo + pluginType: go + args: + - someArg + - someOtherArg +`) + _, err := th.makeKustTarget().MakeCustomizedResMap() + if err == nil { + t.Fatalf("expected error") + } + if !strings.Contains(err.Error(), + filepath.Join("kvSources", "foo.so")) { + t.Fatalf("unexpected err: %v", err) + } +} diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 5bbd2198c..6a6eb952b 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -25,11 +25,11 @@ import ( "github.com/ghodss/yaml" "github.com/pkg/errors" - "sigs.k8s.io/kustomize/pkg/constants" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/ifc/transformer" interror "sigs.k8s.io/kustomize/pkg/internal/error" patchtransformer "sigs.k8s.io/kustomize/pkg/patch/transformer" + "sigs.k8s.io/kustomize/pkg/pgmconfig" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" "sigs.k8s.io/kustomize/pkg/transformers" @@ -89,7 +89,7 @@ func commaOr(q []string) string { func loadKustFile(ldr ifc.Loader) ([]byte, error) { var content []byte match := 0 - for _, kf := range constants.KustomizationFileNames { + for _, kf := range pgmconfig.KustomizationFileNames { c, err := ldr.Load(kf) if err == nil { match += 1 @@ -100,7 +100,7 @@ func loadKustFile(ldr ifc.Loader) ([]byte, error) { case 0: return nil, fmt.Errorf( "unable to find one of %v in directory '%s'", - commaOr(quoted(constants.KustomizationFileNames)), ldr.Root()) + commaOr(quoted(pgmconfig.KustomizationFileNames)), ldr.Root()) case 1: return content, nil default: diff --git a/pkg/target/kusttestharness_test.go b/pkg/target/kusttestharness_test.go index 74cbab348..ea3b712bd 100644 --- a/pkg/target/kusttestharness_test.go +++ b/pkg/target/kusttestharness_test.go @@ -21,13 +21,14 @@ package target_test import ( "fmt" "path/filepath" + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" "strings" "testing" "sigs.k8s.io/kustomize/k8sdeps/kunstruct" "sigs.k8s.io/kustomize/k8sdeps/transformer" - "sigs.k8s.io/kustomize/pkg/constants" "sigs.k8s.io/kustomize/pkg/internal/loadertest" + "sigs.k8s.io/kustomize/pkg/pgmconfig" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" . "sigs.k8s.io/kustomize/pkg/target" @@ -42,10 +43,18 @@ type KustTestHarness struct { } func NewKustTestHarness(t *testing.T, path string) *KustTestHarness { + return NewKustTestHarnessWithPluginConfig( + t, path, plugin.DefaultPluginConfig()) +} + +func NewKustTestHarnessWithPluginConfig( + t *testing.T, path string, + config types.PluginConfig) *KustTestHarness { return &KustTestHarness{ t: t, rf: resmap.NewFactory(resource.NewFactory( - kunstruct.NewKunstructuredFactoryImpl())), + kunstruct.NewKunstructuredFactoryWithGeneratorArgs( + &types.GeneratorMetaArgs{PluginConfig: config}))), ldr: loadertest.NewFakeLoader(path)} } @@ -66,7 +75,7 @@ func (th *KustTestHarness) writeF(dir string, content string) { } func (th *KustTestHarness) writeK(dir string, content string) { - th.writeF(filepath.Join(dir, constants.KustomizationFileNames[0]), ` + th.writeF(filepath.Join(dir, pgmconfig.KustomizationFileNames[0]), ` apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization `+content) diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index c92867422..39a08700d 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -194,6 +194,25 @@ type GeneratorArgs struct { KVSources []KVSource `json:",inline,omitempty" yaml:",inline,omitempty"` } +// GeneratorMetaArgs contains arguments common to generators +// that come from somewhere other than a kustomization file. +type GeneratorMetaArgs struct { + PluginConfig PluginConfig +} + +// PluginConfig holds plugin configuration. +type PluginConfig struct { + // DirectoryPath is an absolute path to a + // directory containing kustomize plugins. + // This directory may contain subdirectories + // further categorizing plugins. + DirectoryPath string + + // GoEnabled is true if goplugins are enabled. + // See https://golang.org/pkg/plugin + GoEnabled bool +} + // ConfigMapArgs contains the metadata of how to generate a configmap. type ConfigMapArgs struct { // GeneratorArgs for the configmap. From a8465c95e14d2bf3a71e16c45439507cdef3c5c1 Mon Sep 17 00:00:00 2001 From: Seth Pollack Date: Sun, 17 Mar 2019 17:22:52 -0400 Subject: [PATCH 181/317] add builtin files plugin --- .../configmapandsecret/basefactory_test.go | 17 ++++++ k8sdeps/kv/plugin/builtin/files.go | 49 ++++++++++++++++ k8sdeps/kv/plugin/builtinplugin.go | 3 +- pkg/target/builtinplugins_test.go | 58 +++++++++++++++++++ pkg/target/configmaps_test.go | 28 --------- 5 files changed, 126 insertions(+), 29 deletions(-) create mode 100644 k8sdeps/kv/plugin/builtin/files.go create mode 100644 pkg/target/builtinplugins_test.go diff --git a/k8sdeps/configmapandsecret/basefactory_test.go b/k8sdeps/configmapandsecret/basefactory_test.go index 3f0a545d5..c96fdbfda 100644 --- a/k8sdeps/configmapandsecret/basefactory_test.go +++ b/k8sdeps/configmapandsecret/basefactory_test.go @@ -87,9 +87,26 @@ func TestKeyValuesFromPlugins(t *testing.T) { }, }, }, + { + description: "Create kv.Pairs from builtin files plugin", + sources: []types.KVSource{ + { + PluginType: "builtin", + Name: "files", + Args: []string{"files/app-init.ini"}, + }, + }, + expected: []kv.Pair{ + { + Key: "app-init.ini", + Value: "FOO=bar", + }, + }, + }, } fSys := fs.MakeFakeFS() + fSys.WriteFile("/files/app-init.ini", []byte("FOO=bar")) ldr := loader.NewFileLoaderAtRoot(fSys) reg := plugin.NewRegistry(ldr) bf := baseFactory{ldr, nil, reg} diff --git a/k8sdeps/kv/plugin/builtin/files.go b/k8sdeps/kv/plugin/builtin/files.go new file mode 100644 index 000000000..48276d786 --- /dev/null +++ b/k8sdeps/kv/plugin/builtin/files.go @@ -0,0 +1,49 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package builtin + +import ( + "sigs.k8s.io/kustomize/k8sdeps/kv" + "sigs.k8s.io/kustomize/pkg/ifc" +) + +// Files is a list of file sources. +// Each file source can be specified using its file path, in which case file +// basename will be used as configmap key, or optionally with a key and file +// path, in which case the given key will be used. +// Specifying a directory will iterate each named file in the directory +// whose basename is a valid configmap key. +type Files struct { + Ldr ifc.Loader +} + +// Get implements the interface for kv plugins. +func (p Files) Get(root string, args []string) ([]kv.Pair, error) { + var kvs []kv.Pair + for _, s := range args { + k, fPath, err := kv.ParseFileSource(s) + if err != nil { + return nil, err + } + content, err := p.Ldr.Load(fPath) + if err != nil { + return nil, err + } + kvs = append(kvs, kv.Pair{Key: k, Value: string(content)}) + } + return kvs, nil +} diff --git a/k8sdeps/kv/plugin/builtinplugin.go b/k8sdeps/kv/plugin/builtinplugin.go index 3af666dd4..395445fc4 100644 --- a/k8sdeps/kv/plugin/builtinplugin.go +++ b/k8sdeps/kv/plugin/builtinplugin.go @@ -29,10 +29,11 @@ type builtinFactory struct { plugins map[string]KVSource } -func newBuiltinFactory(_ ifc.Loader) *builtinFactory { +func newBuiltinFactory(ldr ifc.Loader) *builtinFactory { return &builtinFactory{ plugins: map[string]KVSource{ "literals": builtin.Literals{}, + "files": builtin.Files{Ldr: ldr}, }, } } diff --git a/pkg/target/builtinplugins_test.go b/pkg/target/builtinplugins_test.go new file mode 100644 index 000000000..ca09cb1e1 --- /dev/null +++ b/pkg/target/builtinplugins_test.go @@ -0,0 +1,58 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target_test + +import ( + "testing" +) + +func TestBuiltinPlugins(t *testing.T) { + th := NewKustTestHarness(t, "/app") + th.writeK("/app", ` +secretGenerator: +- name: bob + kvSources: + - pluginType: builtin + name: literals + args: + - FRUIT=apple + - VEGETABLE=carrot + - pluginType: builtin + name: files + args: + - foo.env +`) + th.writeF("/app/foo.env", ` +MOUNTAIN=everest +OCEAN=pacific +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + FRUIT: YXBwbGU= + VEGETABLE: Y2Fycm90 + foo.env: Ck1PVU5UQUlOPWV2ZXJlc3QKT0NFQU49cGFjaWZpYwo= +kind: Secret +metadata: + name: bob-hhdkd5cbt9 +type: Opaque +`) +} diff --git a/pkg/target/configmaps_test.go b/pkg/target/configmaps_test.go index c482b6a7d..dd69adb3b 100644 --- a/pkg/target/configmaps_test.go +++ b/pkg/target/configmaps_test.go @@ -240,31 +240,3 @@ metadata: name: p2-com2-c4b8md75k9 `) } - -func TestGeneratorPlugins(t *testing.T) { - th := NewKustTestHarness(t, "/app") - th.writeK("/app", ` -secretGenerator: -- name: bob - kvSources: - - pluginType: builtin - name: literals - args: - - FRUIT=apple - - VEGETABLE=carrot -`) - m, err := th.makeKustTarget().MakeCustomizedResMap() - if err != nil { - t.Fatalf("Err: %v", err) - } - th.assertActualEqualsExpected(m, ` -apiVersion: v1 -data: - FRUIT: YXBwbGU= - VEGETABLE: Y2Fycm90 -kind: Secret -metadata: - name: bob-bgtct8h699 -type: Opaque -`) -} From dd59eb38d03b8f47abadf6c876ffe76080fcecc7 Mon Sep 17 00:00:00 2001 From: Seth Pollack Date: Sun, 17 Mar 2019 20:44:07 -0400 Subject: [PATCH 182/317] add test case --- pkg/target/builtinplugins_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/target/builtinplugins_test.go b/pkg/target/builtinplugins_test.go index ca09cb1e1..62e6d432e 100644 --- a/pkg/target/builtinplugins_test.go +++ b/pkg/target/builtinplugins_test.go @@ -35,11 +35,13 @@ secretGenerator: name: files args: - foo.env + - passphrase=phrase.dat `) th.writeF("/app/foo.env", ` MOUNTAIN=everest OCEAN=pacific `) + th.writeF("/app/phrase.dat", "dat phrase") m, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { t.Fatalf("Err: %v", err) @@ -50,9 +52,10 @@ data: FRUIT: YXBwbGU= VEGETABLE: Y2Fycm90 foo.env: Ck1PVU5UQUlOPWV2ZXJlc3QKT0NFQU49cGFjaWZpYwo= + passphrase: ZGF0IHBocmFzZQ== kind: Secret metadata: - name: bob-hhdkd5cbt9 + name: bob-t98kdk9767 type: Opaque `) } From 3a7c8a03f4f988c183cf2d6775cf9d3be0381d09 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Mon, 18 Mar 2019 10:17:55 -0700 Subject: [PATCH 183/317] Make builtin the default pluginType --- k8sdeps/kv/plugin/registry.go | 24 +++++++----- pkg/target/builtinplugins_test.go | 63 ++++++++++++++++++++++--------- pkg/types/kustomization.go | 12 ++++-- 3 files changed, 70 insertions(+), 29 deletions(-) diff --git a/k8sdeps/kv/plugin/registry.go b/k8sdeps/kv/plugin/registry.go index 183ed16e3..f505a3766 100644 --- a/k8sdeps/kv/plugin/registry.go +++ b/k8sdeps/kv/plugin/registry.go @@ -26,12 +26,14 @@ import ( // Registry holds all the plugin factories. type Registry struct { - factories map[string]Factory + factories map[types.PluginType]Factory ldr ifc.Loader } const ( - PluginsDir = "plugins" + PluginsDir = "plugins" + pluginTypeGo = types.PluginType("go") + pluginTypeBuiltIn = types.PluginType("builtin") ) func DefaultPluginConfig() types.PluginConfig { @@ -48,9 +50,9 @@ func NewConfiguredRegistry( ldr ifc.Loader, pc *types.PluginConfig) Registry { return Registry{ ldr: ldr, - factories: map[string]Factory{ - "go": newGoFactory(pc), - "builtin": newBuiltinFactory(ldr), + factories: map[types.PluginType]Factory{ + pluginTypeGo: newGoFactory(pc), + pluginTypeBuiltIn: newBuiltinFactory(ldr), }, } } @@ -60,11 +62,15 @@ func NewRegistry(ldr ifc.Loader) Registry { return NewConfiguredRegistry(ldr, &types.PluginConfig{}) } -// Load returns a plugin by type and name, -func (r *Registry) Load(pluginType, name string) (KVSource, error) { - factory, exists := r.factories[pluginType] +// Load returns a plugin by type and name. +func (r *Registry) Load( + pt types.PluginType, name string) (KVSource, error) { + if pt.IsUndefined() { + pt = pluginTypeBuiltIn + } + factory, exists := r.factories[pt] if !exists { - return nil, fmt.Errorf("%s is not a valid plugin type", pluginType) + return nil, fmt.Errorf("%s is not a valid plugin type", pt) } return factory.load(name) } diff --git a/pkg/target/builtinplugins_test.go b/pkg/target/builtinplugins_test.go index 62e6d432e..07bf3bfa9 100644 --- a/pkg/target/builtinplugins_test.go +++ b/pkg/target/builtinplugins_test.go @@ -20,6 +20,27 @@ import ( "testing" ) +const result = ` +apiVersion: v1 +data: + FRUIT: YXBwbGU= + VEGETABLE: Y2Fycm90 + foo.env: Ck1PVU5UQUlOPWV2ZXJlc3QKT0NFQU49cGFjaWZpYwo= + passphrase: ZGF0IHBocmFzZQ== +kind: Secret +metadata: + name: bob-t98kdk9767 +type: Opaque +` + +func writeDataFiles(th *KustTestHarness) { + th.writeF("/app/foo.env", ` +MOUNTAIN=everest +OCEAN=pacific +`) + th.writeF("/app/phrase.dat", "dat phrase") +} + func TestBuiltinPlugins(t *testing.T) { th := NewKustTestHarness(t, "/app") th.writeK("/app", ` @@ -37,25 +58,33 @@ secretGenerator: - foo.env - passphrase=phrase.dat `) - th.writeF("/app/foo.env", ` -MOUNTAIN=everest -OCEAN=pacific -`) - th.writeF("/app/phrase.dat", "dat phrase") + writeDataFiles(th) m, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { t.Fatalf("Err: %v", err) } - th.assertActualEqualsExpected(m, ` -apiVersion: v1 -data: - FRUIT: YXBwbGU= - VEGETABLE: Y2Fycm90 - foo.env: Ck1PVU5UQUlOPWV2ZXJlc3QKT0NFQU49cGFjaWZpYwo= - passphrase: ZGF0IHBocmFzZQ== -kind: Secret -metadata: - name: bob-t98kdk9767 -type: Opaque -`) + th.assertActualEqualsExpected(m, result) +} + +func TestBuiltinIsTheDefault(t *testing.T) { + th := NewKustTestHarness(t, "/app") + th.writeK("/app", ` +secretGenerator: +- name: bob + kvSources: + - name: literals + args: + - FRUIT=apple + - VEGETABLE=carrot + - name: files + args: + - foo.env + - passphrase=phrase.dat +`) + writeDataFiles(th) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, result) } diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 39a08700d..37b07f58f 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -271,9 +271,15 @@ type GeneratorOptions struct { DisableNameSuffixHash bool `json:"disableNameSuffixHash,omitempty" yaml:"disableNameSuffixHash,omitempty"` } +type PluginType string + +func (p PluginType) IsUndefined() bool { + return p == PluginType("") +} + // KVSource represents a KV plugin backend. type KVSource struct { - PluginType string `json:"pluginType,omitempty" yaml:"pluginType,omitempty"` - Name string `json:"name,omitempty" yaml:"name,omitempty"` - Args []string `json:"args,omitempty" yaml:"args,omitempty"` + PluginType PluginType `json:"pluginType,omitempty" yaml:"pluginType,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Args []string `json:"args,omitempty" yaml:"args,omitempty"` } From 9fc4d388ce3b09ecb7b509780e533355e8db6c07 Mon Sep 17 00:00:00 2001 From: Seth Pollack Date: Mon, 18 Mar 2019 13:58:38 -0400 Subject: [PATCH 184/317] add builtin envfiles plugin --- .../configmapandsecret/basefactory_test.go | 16 ++++++ k8sdeps/kv/plugin/builtin/envfiles.go | 49 +++++++++++++++++++ k8sdeps/kv/plugin/builtinplugin.go | 1 + pkg/target/builtinplugins_test.go | 11 ++++- 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 k8sdeps/kv/plugin/builtin/envfiles.go diff --git a/k8sdeps/configmapandsecret/basefactory_test.go b/k8sdeps/configmapandsecret/basefactory_test.go index c96fdbfda..75d5eda9e 100644 --- a/k8sdeps/configmapandsecret/basefactory_test.go +++ b/k8sdeps/configmapandsecret/basefactory_test.go @@ -103,6 +103,22 @@ func TestKeyValuesFromPlugins(t *testing.T) { }, }, }, + { + description: "Create kv.Pairs from builtin envfiles plugin", + sources: []types.KVSource{ + { + PluginType: "builtin", + Name: "envfiles", + Args: []string{"files/app-init.ini"}, + }, + }, + expected: []kv.Pair{ + { + Key: "FOO", + Value: "bar", + }, + }, + }, } fSys := fs.MakeFakeFS() diff --git a/k8sdeps/kv/plugin/builtin/envfiles.go b/k8sdeps/kv/plugin/builtin/envfiles.go new file mode 100644 index 000000000..ad3993dff --- /dev/null +++ b/k8sdeps/kv/plugin/builtin/envfiles.go @@ -0,0 +1,49 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package builtin + +import ( + "sigs.k8s.io/kustomize/k8sdeps/kv" + "sigs.k8s.io/kustomize/pkg/ifc" +) + +// Envfiles format should be a path to a file to read lines of key=val +// pairs to create a configmap. +// i.e. a Docker .env file or a .ini file. +type Envfiles struct { + Ldr ifc.Loader +} + +// Get implements the interface for kv plugins. +func (p Envfiles) Get(root string, args []string) ([]kv.Pair, error) { + var all []kv.Pair + for _, path := range args { + if path == "" { + return nil, nil + } + content, err := p.Ldr.Load(path) + if err != nil { + return nil, err + } + kvs, err := kv.KeyValuesFromLines(content) + if err != nil { + return nil, err + } + all = append(all, kvs...) + } + return all, nil +} diff --git a/k8sdeps/kv/plugin/builtinplugin.go b/k8sdeps/kv/plugin/builtinplugin.go index 395445fc4..ec2045ca7 100644 --- a/k8sdeps/kv/plugin/builtinplugin.go +++ b/k8sdeps/kv/plugin/builtinplugin.go @@ -34,6 +34,7 @@ func newBuiltinFactory(ldr ifc.Loader) *builtinFactory { plugins: map[string]KVSource{ "literals": builtin.Literals{}, "files": builtin.Files{Ldr: ldr}, + "envfiles": builtin.Envfiles{Ldr: ldr}, }, } } diff --git a/pkg/target/builtinplugins_test.go b/pkg/target/builtinplugins_test.go index 07bf3bfa9..90fc27f76 100644 --- a/pkg/target/builtinplugins_test.go +++ b/pkg/target/builtinplugins_test.go @@ -24,12 +24,14 @@ const result = ` apiVersion: v1 data: FRUIT: YXBwbGU= + MOUNTAIN: ZXZlcmVzdA== + OCEAN: cGFjaWZpYw== VEGETABLE: Y2Fycm90 foo.env: Ck1PVU5UQUlOPWV2ZXJlc3QKT0NFQU49cGFjaWZpYwo= passphrase: ZGF0IHBocmFzZQ== kind: Secret metadata: - name: bob-t98kdk9767 + name: bob-kf5c9fccbt type: Opaque ` @@ -57,6 +59,10 @@ secretGenerator: args: - foo.env - passphrase=phrase.dat + - pluginType: builtin + name: envfiles + args: + - foo.env `) writeDataFiles(th) m, err := th.makeKustTarget().MakeCustomizedResMap() @@ -80,6 +86,9 @@ secretGenerator: args: - foo.env - passphrase=phrase.dat + - name: envfiles + args: + - foo.env `) writeDataFiles(th) m, err := th.makeKustTarget().MakeCustomizedResMap() From bfc3655badfd608e097b90c0c1bcc6f4536dc64e Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Tue, 19 Mar 2019 14:53:29 -0700 Subject: [PATCH 185/317] skip adding namespace when the object is empty --- pkg/transformers/namespace.go | 16 ++++++++++------ pkg/transformers/namespace_test.go | 6 ++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/pkg/transformers/namespace.go b/pkg/transformers/namespace.go index 5f0c06482..3087ad8e7 100644 --- a/pkg/transformers/namespace.go +++ b/pkg/transformers/namespace.go @@ -70,12 +70,16 @@ func (o *namespaceTransformer) Transform(m resmap.ResMap) error { if !id.Gvk().IsSelected(&path.Gvk) { continue } - - err := mutateField(objMap, path.PathSlice(), path.CreateIfNotPresent, func(_ interface{}) (interface{}, error) { - return o.namespace, nil - }) - if err != nil { - return err + // make sure the object is non empty + if len(objMap) > 0 { + err := mutateField( + objMap, path.PathSlice(), path.CreateIfNotPresent, + func(_ interface{}) (interface{}, error) { + return o.namespace, nil + }) + if err != nil { + return err + } } newid := id.CopyWithNewNamespace(o.namespace) m[newid] = mf[id] diff --git a/pkg/transformers/namespace_test.go b/pkg/transformers/namespace_test.go index d3ced2825..34beed5d0 100644 --- a/pkg/transformers/namespace_test.go +++ b/pkg/transformers/namespace_test.go @@ -47,6 +47,9 @@ func TestNamespaceRun(t *testing.T) { "namespace": "foo", }, }), + resid.NewResId(cmap, "cm3"): rf.FromMap( + map[string]interface{}{}, + ), resid.NewResId(ns, "ns1"): rf.FromMap( map[string]interface{}{ "apiVersion": "v1", @@ -134,6 +137,9 @@ func TestNamespaceRun(t *testing.T) { "namespace": "test", }, }), + resid.NewResIdWithPrefixNamespace(cmap, "cm3", "", "test"): rf.FromMap( + map[string]interface{}{}, + ), resid.NewResIdWithPrefixNamespace(sa, "default", "", "test"): rf.FromMap( map[string]interface{}{ "apiVersion": "v1", From b60fca05bd579c7f4b750aecd59edd108cd7ec59 Mon Sep 17 00:00:00 2001 From: Seth Pollack Date: Wed, 20 Mar 2019 09:24:10 -0400 Subject: [PATCH 186/317] update edit add secrets/configmaps to use plugins --- pkg/commands/edit/add/configmap.go | 30 +++++++-------- pkg/commands/edit/add/configmap_test.go | 51 +++++++++---------------- pkg/commands/edit/add/secret.go | 30 +++++++-------- pkg/commands/edit/add/secret_test.go | 51 +++++++++---------------- 4 files changed, 66 insertions(+), 96 deletions(-) diff --git a/pkg/commands/edit/add/configmap.go b/pkg/commands/edit/add/configmap.go index 8f78797ba..27e352561 100644 --- a/pkg/commands/edit/add/configmap.go +++ b/pkg/commands/edit/add/configmap.go @@ -17,8 +17,6 @@ limitations under the License. package add import ( - "fmt" - "github.com/spf13/cobra" "sigs.k8s.io/kustomize/pkg/commands/kustfile" "sigs.k8s.io/kustomize/pkg/fs" @@ -107,12 +105,9 @@ func addConfigMap( k *types.Kustomization, flags flagsAndArgs, kf ifc.KunstructuredFactory) error { cmArgs := makeConfigMapArgs(k, flags.Name) - err := mergeFlagsIntoCmArgs(&cmArgs.DataSources, flags) - if err != nil { - return err - } + mergeFlagsIntoCmArgs(&cmArgs.KVSources, flags) // Validate by trying to create corev1.configmap. - _, err = kf.MakeConfigMap(ldr, k.GeneratorOptions, cmArgs) + _, err := kf.MakeConfigMap(ldr, k.GeneratorOptions, cmArgs) if err != nil { return err } @@ -131,12 +126,17 @@ func makeConfigMapArgs(m *types.Kustomization, name string) *types.ConfigMapArgs return &m.ConfigMapGenerator[len(m.ConfigMapGenerator)-1] } -func mergeFlagsIntoCmArgs(src *types.DataSources, flags flagsAndArgs) error { - src.LiteralSources = append(src.LiteralSources, flags.LiteralSources...) - src.FileSources = append(src.FileSources, flags.FileSources...) - if src.EnvSource != "" && src.EnvSource != flags.EnvFileSource { - return fmt.Errorf("updating existing env source '%s' not allowed", src.EnvSource) - } - src.EnvSource = flags.EnvFileSource - return nil +func mergeFlagsIntoCmArgs(src *[]types.KVSource, flags flagsAndArgs) { + *src = append(*src, types.KVSource{ + Name: "literals", + Args: flags.LiteralSources, + }) + *src = append(*src, types.KVSource{ + Name: "files", + Args: flags.FileSources, + }) + *src = append(*src, types.KVSource{ + Name: "envfiles", + Args: []string{flags.EnvFileSource}, + }) } diff --git a/pkg/commands/edit/add/configmap_test.go b/pkg/commands/edit/add/configmap_test.go index f55d1198a..23c3cf1a6 100644 --- a/pkg/commands/edit/add/configmap_test.go +++ b/pkg/commands/edit/add/configmap_test.go @@ -65,45 +65,33 @@ func TestMakeConfigMapArgs(t *testing.T) { } func TestMergeFlagsIntoCmArgs_LiteralSources(t *testing.T) { - ds := &types.DataSources{} + kv := []types.KVSource{} - err := mergeFlagsIntoCmArgs(ds, flagsAndArgs{LiteralSources: []string{"k1=v1"}}) - if err != nil { - t.Fatalf("Merge initial literal source should not return error") - } + mergeFlagsIntoCmArgs(&kv, flagsAndArgs{LiteralSources: []string{"k1=v1"}}) - if len(ds.LiteralSources) != 1 { + if len(kv) != 1 { t.Fatalf("Initial literal source should have been added") } - err = mergeFlagsIntoCmArgs(ds, flagsAndArgs{LiteralSources: []string{"k2=v2"}}) - if err != nil { - t.Fatalf("Merge second literal source should not return error") - } + mergeFlagsIntoCmArgs(&kv, flagsAndArgs{LiteralSources: []string{"k2=v2"}}) - if len(ds.LiteralSources) != 2 { + if len(kv) != 2 { t.Fatalf("Second literal source should have been added") } } func TestMergeFlagsIntoCmArgs_FileSources(t *testing.T) { - ds := &types.DataSources{} + kv := []types.KVSource{} - err := mergeFlagsIntoCmArgs(ds, flagsAndArgs{FileSources: []string{"file1"}}) - if err != nil { - t.Fatalf("Merge initial file source should not return error") - } + mergeFlagsIntoCmArgs(&kv, flagsAndArgs{FileSources: []string{"file1"}}) - if len(ds.FileSources) != 1 { + if len(kv) != 1 { t.Fatalf("Initial file source should have been added") } - err = mergeFlagsIntoCmArgs(ds, flagsAndArgs{FileSources: []string{"file2"}}) - if err != nil { - t.Fatalf("Merge second file source should not return error") - } + mergeFlagsIntoCmArgs(&kv, flagsAndArgs{FileSources: []string{"file2"}}) - if len(ds.FileSources) != 2 { + if len(kv) != 2 { t.Fatalf("Second file source should have been added") } } @@ -111,19 +99,16 @@ func TestMergeFlagsIntoCmArgs_FileSources(t *testing.T) { func TestMergeFlagsIntoCmArgs_EnvSource(t *testing.T) { envFileName := "env1" envFileName2 := "env2" - ds := &types.DataSources{} + kv := []types.KVSource{} - err := mergeFlagsIntoCmArgs(ds, flagsAndArgs{EnvFileSource: envFileName}) - if err != nil { - t.Fatalf("Merge initial env source should not return error") + mergeFlagsIntoCmArgs(&kv, flagsAndArgs{EnvFileSource: envFileName}) + + if len(kv) != 1 { + t.Fatalf("Initial env source should have been added") } - if ds.EnvSource != envFileName { - t.Fatalf("Initial env source filename should have been added") - } - - err = mergeFlagsIntoCmArgs(ds, flagsAndArgs{EnvFileSource: envFileName2}) - if err == nil { - t.Fatalf("Updating env source should return an error") + mergeFlagsIntoCmArgs(&kv, flagsAndArgs{EnvFileSource: envFileName2}) + if len(kv) != 2 { + t.Fatalf("Second env source should have been added") } } diff --git a/pkg/commands/edit/add/secret.go b/pkg/commands/edit/add/secret.go index c2a1d198f..213475ca6 100644 --- a/pkg/commands/edit/add/secret.go +++ b/pkg/commands/edit/add/secret.go @@ -17,8 +17,6 @@ limitations under the License. package add import ( - "fmt" - "github.com/spf13/cobra" "sigs.k8s.io/kustomize/pkg/commands/kustfile" "sigs.k8s.io/kustomize/pkg/fs" @@ -112,12 +110,9 @@ func addSecret( k *types.Kustomization, flags flagsAndArgs, kf ifc.KunstructuredFactory) error { secretArgs := makeSecretArgs(k, flags.Name, flags.Type) - err := mergeFlagsIntoSecretArgs(&secretArgs.DataSources, flags) - if err != nil { - return err - } + mergeFlagsIntoSecretArgs(&secretArgs.KVSources, flags) // Validate by trying to create corev1.secret. - _, err = kf.MakeSecret(ldr, k.GeneratorOptions, secretArgs) + _, err := kf.MakeSecret(ldr, k.GeneratorOptions, secretArgs) if err != nil { return err } @@ -136,12 +131,17 @@ func makeSecretArgs(m *types.Kustomization, name, secretType string) *types.Secr return &m.SecretGenerator[len(m.SecretGenerator)-1] } -func mergeFlagsIntoSecretArgs(src *types.DataSources, flags flagsAndArgs) error { - src.LiteralSources = append(src.LiteralSources, flags.LiteralSources...) - src.FileSources = append(src.FileSources, flags.FileSources...) - if src.EnvSource != "" && src.EnvSource != flags.EnvFileSource { - return fmt.Errorf("updating existing env source '%s' not allowed", src.EnvSource) - } - src.EnvSource = flags.EnvFileSource - return nil +func mergeFlagsIntoSecretArgs(src *[]types.KVSource, flags flagsAndArgs) { + *src = append(*src, types.KVSource{ + Name: "literals", + Args: flags.LiteralSources, + }) + *src = append(*src, types.KVSource{ + Name: "files", + Args: flags.FileSources, + }) + *src = append(*src, types.KVSource{ + Name: "envfiles", + Args: []string{flags.EnvFileSource}, + }) } diff --git a/pkg/commands/edit/add/secret_test.go b/pkg/commands/edit/add/secret_test.go index 47ba26489..ecbaa704d 100644 --- a/pkg/commands/edit/add/secret_test.go +++ b/pkg/commands/edit/add/secret_test.go @@ -67,45 +67,33 @@ func TestMakeSecretArgs(t *testing.T) { } func TestMergeFlagsIntoSecretArgs_LiteralSources(t *testing.T) { - ds := &types.DataSources{} + kv := []types.KVSource{} - err := mergeFlagsIntoSecretArgs(ds, flagsAndArgs{LiteralSources: []string{"k1=v1"}}) - if err != nil { - t.Fatalf("Merge initial literal source should not return error") - } + mergeFlagsIntoSecretArgs(&kv, flagsAndArgs{LiteralSources: []string{"k1=v1"}}) - if len(ds.LiteralSources) != 1 { + if len(kv) != 1 { t.Fatalf("Initial literal source should have been added") } - err = mergeFlagsIntoSecretArgs(ds, flagsAndArgs{LiteralSources: []string{"k2=v2"}}) - if err != nil { - t.Fatalf("Merge second literal source should not return error") - } + mergeFlagsIntoSecretArgs(&kv, flagsAndArgs{LiteralSources: []string{"k2=v2"}}) - if len(ds.LiteralSources) != 2 { + if len(kv) != 2 { t.Fatalf("Second literal source should have been added") } } func TestMergeFlagsIntoSecretArgs_FileSources(t *testing.T) { - ds := &types.DataSources{} + kv := []types.KVSource{} - err := mergeFlagsIntoSecretArgs(ds, flagsAndArgs{FileSources: []string{"file1"}}) - if err != nil { - t.Fatalf("Merge initial file source should not return error") - } + mergeFlagsIntoSecretArgs(&kv, flagsAndArgs{FileSources: []string{"file1"}}) - if len(ds.FileSources) != 1 { + if len(kv) != 1 { t.Fatalf("Initial file source should have been added") } - err = mergeFlagsIntoSecretArgs(ds, flagsAndArgs{FileSources: []string{"file2"}}) - if err != nil { - t.Fatalf("Merge second file source should not return error") - } + mergeFlagsIntoSecretArgs(&kv, flagsAndArgs{FileSources: []string{"file2"}}) - if len(ds.FileSources) != 2 { + if len(kv) != 2 { t.Fatalf("Second file source should have been added") } } @@ -113,19 +101,16 @@ func TestMergeFlagsIntoSecretArgs_FileSources(t *testing.T) { func TestMergeFlagsIntoSecretArgs_EnvSource(t *testing.T) { envFileName := "env1" envFileName2 := "env2" - ds := &types.DataSources{} + kv := []types.KVSource{} - err := mergeFlagsIntoSecretArgs(ds, flagsAndArgs{EnvFileSource: envFileName}) - if err != nil { - t.Fatalf("Merge initial env source should not return error") + mergeFlagsIntoSecretArgs(&kv, flagsAndArgs{EnvFileSource: envFileName}) + + if len(kv) != 1 { + t.Fatalf("Initial env source should have been added") } - if ds.EnvSource != envFileName { - t.Fatalf("Initial env source filename should have been added") - } - - err = mergeFlagsIntoSecretArgs(ds, flagsAndArgs{EnvFileSource: envFileName2}) - if err == nil { - t.Fatalf("Updating env source should return an error") + mergeFlagsIntoSecretArgs(&kv, flagsAndArgs{EnvFileSource: envFileName2}) + if len(kv) != 2 { + t.Fatalf("Second env source should have been added") } } From 822420e4ab86863603f7e9ad2bf31ba3703a29eb Mon Sep 17 00:00:00 2001 From: Seth Pollack Date: Thu, 21 Mar 2019 14:58:06 -0400 Subject: [PATCH 187/317] fix mergeFlags --- pkg/commands/edit/add/configmap.go | 30 ++++++++++++++++++------------ pkg/commands/edit/add/secret.go | 30 ++++++++++++++++++------------ 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/pkg/commands/edit/add/configmap.go b/pkg/commands/edit/add/configmap.go index 27e352561..5e8361bdc 100644 --- a/pkg/commands/edit/add/configmap.go +++ b/pkg/commands/edit/add/configmap.go @@ -127,16 +127,22 @@ func makeConfigMapArgs(m *types.Kustomization, name string) *types.ConfigMapArgs } func mergeFlagsIntoCmArgs(src *[]types.KVSource, flags flagsAndArgs) { - *src = append(*src, types.KVSource{ - Name: "literals", - Args: flags.LiteralSources, - }) - *src = append(*src, types.KVSource{ - Name: "files", - Args: flags.FileSources, - }) - *src = append(*src, types.KVSource{ - Name: "envfiles", - Args: []string{flags.EnvFileSource}, - }) + if len(flags.LiteralSources) > 0 { + *src = append(*src, types.KVSource{ + Name: "literals", + Args: flags.LiteralSources, + }) + } + if len(flags.FileSources) > 0 { + *src = append(*src, types.KVSource{ + Name: "files", + Args: flags.FileSources, + }) + } + if flags.EnvFileSource != "" { + *src = append(*src, types.KVSource{ + Name: "envfiles", + Args: []string{flags.EnvFileSource}, + }) + } } diff --git a/pkg/commands/edit/add/secret.go b/pkg/commands/edit/add/secret.go index 213475ca6..aaaf2267b 100644 --- a/pkg/commands/edit/add/secret.go +++ b/pkg/commands/edit/add/secret.go @@ -132,16 +132,22 @@ func makeSecretArgs(m *types.Kustomization, name, secretType string) *types.Secr } func mergeFlagsIntoSecretArgs(src *[]types.KVSource, flags flagsAndArgs) { - *src = append(*src, types.KVSource{ - Name: "literals", - Args: flags.LiteralSources, - }) - *src = append(*src, types.KVSource{ - Name: "files", - Args: flags.FileSources, - }) - *src = append(*src, types.KVSource{ - Name: "envfiles", - Args: []string{flags.EnvFileSource}, - }) + if len(flags.LiteralSources) > 0 { + *src = append(*src, types.KVSource{ + Name: "literals", + Args: flags.LiteralSources, + }) + } + if len(flags.FileSources) > 0 { + *src = append(*src, types.KVSource{ + Name: "files", + Args: flags.FileSources, + }) + } + if flags.EnvFileSource != "" { + *src = append(*src, types.KVSource{ + Name: "envfiles", + Args: []string{flags.EnvFileSource}, + }) + } } From 9a12b55139d50e3f9db1afb8e904769bf00875f9 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Tue, 26 Mar 2019 09:43:50 -0700 Subject: [PATCH 188/317] Move accumulator code to its own package. --- pkg/{target => accumulator}/resaccumulator.go | 10 +++++----- pkg/{target => accumulator}/resaccumulator_test.go | 4 ++-- pkg/commands/edit/add/configmap_test.go | 6 +++--- pkg/commands/edit/add/secret_test.go | 6 +++--- pkg/target/kusttarget.go | 9 +++++---- 5 files changed, 18 insertions(+), 17 deletions(-) rename pkg/{target => accumulator}/resaccumulator.go (93%) rename pkg/{target => accumulator}/resaccumulator_test.go (99%) diff --git a/pkg/target/resaccumulator.go b/pkg/accumulator/resaccumulator.go similarity index 93% rename from pkg/target/resaccumulator.go rename to pkg/accumulator/resaccumulator.go index b8c45015a..5f26bf862 100644 --- a/pkg/target/resaccumulator.go +++ b/pkg/accumulator/resaccumulator.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target +package accumulator import ( "fmt" @@ -30,10 +30,6 @@ import ( // ResAccumulator accumulates resources and the rules // used to customize those resources. -// TODO(monopole): Move to "accumulator" package and make members private. -// This will make a better separation between KustTarget, which should -// be mainly concerned with data loading, and this class, which could -// become the home of all transformation data and logic. type ResAccumulator struct { resMap resmap.ResMap tConfig *config.TransformerConfig @@ -82,6 +78,10 @@ func (ra *ResAccumulator) MergeConfig( return err } +func (ra *ResAccumulator) GetTransformerConfig() *config.TransformerConfig { + return ra.tConfig +} + func (ra *ResAccumulator) MergeVars(incoming []types.Var) error { return ra.varSet.MergeSlice(incoming) } diff --git a/pkg/target/resaccumulator_test.go b/pkg/accumulator/resaccumulator_test.go similarity index 99% rename from pkg/target/resaccumulator_test.go rename to pkg/accumulator/resaccumulator_test.go index 42b61cc65..0f187463b 100644 --- a/pkg/target/resaccumulator_test.go +++ b/pkg/accumulator/resaccumulator_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package target_test +package accumulator_test import ( "bytes" @@ -24,11 +24,11 @@ import ( "testing" "sigs.k8s.io/kustomize/k8sdeps/kunstruct" + . "sigs.k8s.io/kustomize/pkg/accumulator" "sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" - . "sigs.k8s.io/kustomize/pkg/target" "sigs.k8s.io/kustomize/pkg/transformers/config" "sigs.k8s.io/kustomize/pkg/types" ) diff --git a/pkg/commands/edit/add/configmap_test.go b/pkg/commands/edit/add/configmap_test.go index 23c3cf1a6..2aaa99e8f 100644 --- a/pkg/commands/edit/add/configmap_test.go +++ b/pkg/commands/edit/add/configmap_test.go @@ -65,7 +65,7 @@ func TestMakeConfigMapArgs(t *testing.T) { } func TestMergeFlagsIntoCmArgs_LiteralSources(t *testing.T) { - kv := []types.KVSource{} + var kv []types.KVSource mergeFlagsIntoCmArgs(&kv, flagsAndArgs{LiteralSources: []string{"k1=v1"}}) @@ -81,7 +81,7 @@ func TestMergeFlagsIntoCmArgs_LiteralSources(t *testing.T) { } func TestMergeFlagsIntoCmArgs_FileSources(t *testing.T) { - kv := []types.KVSource{} + var kv []types.KVSource mergeFlagsIntoCmArgs(&kv, flagsAndArgs{FileSources: []string{"file1"}}) @@ -99,7 +99,7 @@ func TestMergeFlagsIntoCmArgs_FileSources(t *testing.T) { func TestMergeFlagsIntoCmArgs_EnvSource(t *testing.T) { envFileName := "env1" envFileName2 := "env2" - kv := []types.KVSource{} + var kv []types.KVSource mergeFlagsIntoCmArgs(&kv, flagsAndArgs{EnvFileSource: envFileName}) diff --git a/pkg/commands/edit/add/secret_test.go b/pkg/commands/edit/add/secret_test.go index ecbaa704d..476e48ac1 100644 --- a/pkg/commands/edit/add/secret_test.go +++ b/pkg/commands/edit/add/secret_test.go @@ -67,7 +67,7 @@ func TestMakeSecretArgs(t *testing.T) { } func TestMergeFlagsIntoSecretArgs_LiteralSources(t *testing.T) { - kv := []types.KVSource{} + var kv []types.KVSource mergeFlagsIntoSecretArgs(&kv, flagsAndArgs{LiteralSources: []string{"k1=v1"}}) @@ -83,7 +83,7 @@ func TestMergeFlagsIntoSecretArgs_LiteralSources(t *testing.T) { } func TestMergeFlagsIntoSecretArgs_FileSources(t *testing.T) { - kv := []types.KVSource{} + var kv []types.KVSource mergeFlagsIntoSecretArgs(&kv, flagsAndArgs{FileSources: []string{"file1"}}) @@ -101,7 +101,7 @@ func TestMergeFlagsIntoSecretArgs_FileSources(t *testing.T) { func TestMergeFlagsIntoSecretArgs_EnvSource(t *testing.T) { envFileName := "env1" envFileName2 := "env2" - kv := []types.KVSource{} + var kv []types.KVSource mergeFlagsIntoSecretArgs(&kv, flagsAndArgs{EnvFileSource: envFileName}) diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 2232a1e80..25e5aff9e 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -25,6 +25,7 @@ import ( "github.com/ghodss/yaml" "github.com/pkg/errors" + "sigs.k8s.io/kustomize/pkg/accumulator" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/ifc/transformer" interror "sigs.k8s.io/kustomize/pkg/internal/error" @@ -151,7 +152,7 @@ func (kt *KustTarget) shouldAddHashSuffixesToGeneratedResources() bool { // to do so. The name back references and vars are // not yet fixed. func (kt *KustTarget) AccumulateTarget() ( - ra *ResAccumulator, err error) { + ra *accumulator.ResAccumulator, err error) { // TODO(monopole): Get rid of the KustomizationErrors accumulator. // It's not consistently used, and complicates tests. errs := &interror.KustomizationErrors{} @@ -205,7 +206,7 @@ func (kt *KustTarget) AccumulateTarget() ( if len(errs.Get()) > 0 { return nil, errs } - t, err := kt.newTransformer(patches, ra.tConfig) + t, err := kt.newTransformer(patches, ra.GetTransformerConfig()) if err != nil { return nil, err } @@ -240,9 +241,9 @@ func (kt *KustTarget) generateConfigMapsAndSecrets( // used to customized them from only the _bases_ // of this KustTarget. func (kt *KustTarget) accumulateBases() ( - ra *ResAccumulator, errs *interror.KustomizationErrors) { + ra *accumulator.ResAccumulator, errs *interror.KustomizationErrors) { errs = &interror.KustomizationErrors{} - ra = MakeEmptyAccumulator() + ra = accumulator.MakeEmptyAccumulator() for _, path := range kt.kustomization.Bases { ldr, err := kt.ldr.New(path) From 267eec55096436eafd530a79aeea18d3e4fa9445 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Tue, 26 Mar 2019 10:47:31 -0700 Subject: [PATCH 189/317] Fix 918 --- pkg/transformers/image.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/transformers/image.go b/pkg/transformers/image.go index ba8dbab50..ef7f28d74 100644 --- a/pkg/transformers/image.go +++ b/pkg/transformers/image.go @@ -72,7 +72,7 @@ func (pt *imageTransformer) Transform(m resmap.ResMap) error { */ func (pt *imageTransformer) findAndReplaceImage(obj map[string]interface{}) error { paths := []string{"containers", "initContainers"} - found := false + updated := false for _, path := range paths { containers, found := obj[path] if found { @@ -80,9 +80,10 @@ func (pt *imageTransformer) findAndReplaceImage(obj map[string]interface{}) erro if err != nil { return err } + updated = true } } - if !found { + if !updated { return pt.findContainers(obj) } return nil From c1dea6676f715c47689f2b30b2ca0f8b8fe13bff Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Thu, 28 Mar 2019 09:42:18 -0700 Subject: [PATCH 190/317] Update travis file. --- .travis.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2e599473a..92e842f6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,14 +6,16 @@ os: addons: apt: - packages: tree + packages: + - tree homebrew: - packages: tree + packages: + - tree language: go go: - - 1.11.x + - 1.12.1 go_import_path: sigs.k8s.io/kustomize @@ -25,7 +27,7 @@ git: depth: 1 env: -- GOLANGCI_RELEASE="v1.10.2" +- GOLANGCI_RELEASE="v1.12.1" before_install: - source ./bin/consider-early-travis-exit.sh From 99391157ecf7489b0b766b8019d162de17273eb9 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Tue, 26 Mar 2019 17:49:11 -0700 Subject: [PATCH 191/317] Add goplugin KV generator example. --- examples/README.md | 10 +- examples/kvSourceGoPlugin.md | 279 ++++++++++++++++++++++ k8sdeps/configmapandsecret/basefactory.go | 8 +- k8sdeps/kv/plugin/builtin/envfiles.go | 12 +- k8sdeps/kv/plugin/builtin/files.go | 6 +- k8sdeps/kv/plugin/builtin/literals.go | 6 +- k8sdeps/kv/plugin/builtinplugin.go | 2 +- k8sdeps/kv/plugin/goplugin.go | 23 +- k8sdeps/kv/plugin/plugin.go | 6 +- pkg/commands/commands.go | 4 +- pkg/pgmconfig/config.go | 1 + 11 files changed, 319 insertions(+), 38 deletions(-) create mode 100644 examples/kvSourceGoPlugin.md diff --git a/examples/README.md b/examples/README.md index 5b94edadb..e33c220de 100644 --- a/examples/README.md +++ b/examples/README.md @@ -28,14 +28,18 @@ go get sigs.k8s.io/kustomize (e.g. devops/SRE and developers). * [configGenerations](configGeneration.md) - - Rolling update when ConfigMapGenerator changes + Rolling update when ConfigMapGenerator changes. + + * [secret generation](kvSourceGoPlugin.md) - Generating secrets. - * [generatorOptions](generatorOptions.md) - Modifying behavior of all ConfigMap and Secret generators. + * [generatorOptions](generatorOptions.md) - + Modifying behavior of all ConfigMap and Secret generators. * [breakfast](breakfast.md) - Customize breakfast for Alice and Bob. - * [vars](wordpress/README.md) - Injecting k8s runtime data into container arguments (e.g. to point wordpress to a SQL service) by vars. + * [vars](wordpress/README.md) - Injecting k8s runtime data into + container arguments (e.g. to point wordpress to a SQL service) by vars. * [image names and tags](image.md) - Updating image names and tags without applying a patch. diff --git a/examples/kvSourceGoPlugin.md b/examples/kvSourceGoPlugin.md new file mode 100644 index 000000000..37ae6769b --- /dev/null +++ b/examples/kvSourceGoPlugin.md @@ -0,0 +1,279 @@ +[Secrets]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#secret-v1-core +[ConfigMaps]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#configmap-v1-core +[base64]: https://tools.ietf.org/html/rfc4648#section-4 +[Go plugin]: https://golang.org/pkg/plugin +[v2.0.3]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.0.3 + +# Generating Secrets + +## What's a Secret? + +Kubernetes [ConfigMaps] and [Secrets] are both +key:value (KV) maps, but the latter is intended to +signal that its values have a sensitive nature - +e.g. ssh keys or passwords. + +Kubernetes assumes that the values in a Secret are +[base64] encoded, and decodes them before actual +use (as, say, the argument to a container +command). The user that creates the Secret must +base64 encode the data, or use a tool that does it +for them. This encoding doesn't protect the +secret from anything other than an +over-the-shoulder glance. + +Protecting the actual secrecy of a Secret value is +up to the cluster operator. They must lock down +the cluster (and its `etcd` data store) as tightly +as desired, and likewise protect the bytes that +feed into the cluster to ultimately become the +content of a Secret value. + +## Make a place to work + + +``` +DEMO_HOME=$(mktemp -d) +``` + +## Secret values from local files + +kustomize has three different ways to generate a secret +from local files: + + * get them from so-called _env_ files (`NAME=VALUE`, one per line), + * consume the entire contents of a file to make one secret value, + * get literal values from the kustomization file itself. + +Here's an example combining all three methods: + +Make an env file with some short secrets: + + +``` +cat <<'EOF' >$DEMO_HOME/foo.env +ROUTER_PASSWORD=admin +DB_PASSWORD=iloveyou +EOF +``` + +Make a text file with a long secret: + + +``` +cat <<'EOF' >$DEMO_HOME/longsecret.txt +Lorem ipsum dolor sit amet, +consectetur adipiscing elit, +sed do eiusmod tempor incididunt +ut labore et dolore magna aliqua. +EOF +``` + +And make a kustomization file referring to the +above and additionally defining some literal KV +pairs: + + +``` +cat <<'EOF' >$DEMO_HOME/kustomization.yaml +secretGenerator: +- name: mysecrets + kvSources: + - name: envfiles + pluginType: builtin + args: + - foo.env + - name: files + pluginType: builtin + args: + - longsecret.txt + - name: literals + pluginType: builtin + args: + - FRUIT=apple + - VEGETABLE=carrot +EOF +``` + +> The above syntax is _alpha_ behavior at HEAD, for v2.1+. +> +> The default value of `pluginType` is `builtin`, so the +> `pluginType` fields could be omitted. +> +> The equivalent [v2.0.3] syntax (still supported) is +> ``` +> secretGenerator: +> - name: mysecrets +> env: foo.env +> files: +> - longsecret.txt +> literals: +> - FRUIT=apple +> - VEGETABLE=carrot +> ``` + +Now generate the Secret: + + +``` +result=$(kustomize build $DEMO_HOME) +echo "$result" +test 1 == $(echo "$result" | grep -c "FRUIT: YXBwbGU=") +``` + +This emits something like + +> ``` +> apiVersion: v1 +> kind: Secret +> metadata: +> name: mysecrets-hfb5df789h +> type: Opaque +> data: +> FRUIT: YXBwbGU= +> VEGETABLE: Y2Fycm90 +> ROUTER_PASSWORD: YWRtaW4= +> DB_PASSWORD: aWxvdmV5b3U= +> longsecret.txt: TG9yZW0gaXBzdW0gZG9sb3Igc2l0I... (elided) +> ``` + +The name of the resource is a prefix, `mysecrets` +(as specfied in the kustomization file), followed +by a hash of its contents. + +Use your favorite base64 decoder to confirm the raw +versions of any of these values. + +The problem that these three approaches share is +that the purported secrets must live on disk. + +This adds additional security questions - who can +see the files, who installs them, who deletes +them, etc. + + +## Secret values from anywhere + +> New _alpha_ behavior at HEAD, for v2.1+ + +A general alternative is to enshrine secret +value generation in a Go plugin. + +The values can then come in via, say, an +authenticated and authorized RPC to a password +vault service. + +Here's a trivial plugin that provides +hardcoded values: + + +``` +cat <<'EOF' >$DEMO_HOME/kvMaker.go +package main +var database = map[string]string{ + "TREE": "oak", + "ROCKET": "Saturn V", + "FRUIT": "apple", + "VEGETABLE": "carrot", + "SIMPSON": "homer", +} + +type plugin struct{} +var KVSource plugin +func (p plugin) Get(root string, args []string) (map[string]string, error) { + r := make(map[string]string) + for _, k := range args { + v, ok := database[k] + if ok { + r[k] = v + } + } + return r, nil +} +EOF +``` + + +The two crucial items needed to +load and query the plugin are + 1) the public symbol `KVSource`, + 1) its public `Get` method and signature. + +Plugins that generate KV pairs for kustomize +must be installed at + +> ``` +> $XDG_CONFIG_HOME/kustomize/plugins/kvSource +> ``` + +`XDG_CONFIG_HOME` is an environment variable +used by many programs as the root of a +configuration directory. If unspecified, the +default `$HOME/.config` is used. The rest of +the required directory path establishes that +the files found there are kustomize plugins +for generating KV pairs. + +Compile and install the plugin: + + +``` +kvSources=$DEMO_HOME/kustomize/plugins/kvSources +mkdir -p $kvSources +GOPATH=$DEMO_HOME:$GOPATH go build \ + -buildmode plugin \ + -o $kvSources/kvMaker.so \ + $DEMO_HOME/kvMaker.go +``` + +Create a new kustomization file +referencing this plugin: + + +``` +cat <<'EOF' >$DEMO_HOME/kustomization.yaml +secretGenerator: +- name: mysecrets + kvSources: + - name: kvMaker + pluginType: go + args: + - FRUIT + - VEGETABLE +EOF +``` + +Finally, generate the secret, setting +`XDG_CONFIG_HOME` appropriately: + + +``` +result=$(XDG_CONFIG_HOME=$DEMO_HOME kustomize \ + --enable_alpha_goplugins_accept_panic_risk \ + build $DEMO_HOME) +echo "$result" +test 1 == $(echo "$result" | grep -c "FRUIT: YXBwbGU=") +``` + +Specify the `--enable_...` flag to enable Go +plugins, which may fail if not compiled under +the same conditions as the main program. Try +this command without the flag to see more +explanation. + +This should emit something like: + +> ``` +> apiVersion: v1 +> kind: Secret +> metadata: +> name: mysecrets-bdt27dbkd6 +> type: Opaque +> data: +> FRUIT: YXBwbGU= +> VEGETABLE: Y2Fycm90 +> ``` + +i.e. a subset of the same values as above. + + diff --git a/k8sdeps/configmapandsecret/basefactory.go b/k8sdeps/configmapandsecret/basefactory.go index b1bad0bcf..7bd88836a 100644 --- a/k8sdeps/configmapandsecret/basefactory.go +++ b/k8sdeps/configmapandsecret/basefactory.go @@ -91,7 +91,7 @@ func keyValuesFromLiteralSources(sources []string) ([]kv.Pair, error) { } func (bf baseFactory) keyValuesFromPlugins(sources []types.KVSource) ([]kv.Pair, error) { - var allKvs []kv.Pair + var result []kv.Pair for _, s := range sources { plug, err := bf.reg.Load(s.PluginType, s.Name) if err != nil { @@ -101,9 +101,11 @@ func (bf baseFactory) keyValuesFromPlugins(sources []types.KVSource) ([]kv.Pair, if err != nil { return nil, err } - allKvs = append(allKvs, kvs...) + for k, v := range kvs { + result = append(result, kv.Pair{Key: k, Value: v}) + } } - return allKvs, nil + return result, nil } func (bf baseFactory) keyValuesFromFileSources(sources []string) ([]kv.Pair, error) { diff --git a/k8sdeps/kv/plugin/builtin/envfiles.go b/k8sdeps/kv/plugin/builtin/envfiles.go index ad3993dff..816464f4f 100644 --- a/k8sdeps/kv/plugin/builtin/envfiles.go +++ b/k8sdeps/kv/plugin/builtin/envfiles.go @@ -21,16 +21,16 @@ import ( "sigs.k8s.io/kustomize/pkg/ifc" ) -// Envfiles format should be a path to a file to read lines of key=val +// EnvFiles format should be a path to a file to read lines of key=val // pairs to create a configmap. // i.e. a Docker .env file or a .ini file. -type Envfiles struct { +type EnvFiles struct { Ldr ifc.Loader } // Get implements the interface for kv plugins. -func (p Envfiles) Get(root string, args []string) ([]kv.Pair, error) { - var all []kv.Pair +func (p EnvFiles) Get(root string, args []string) (map[string]string, error) { + all := make(map[string]string) for _, path := range args { if path == "" { return nil, nil @@ -43,7 +43,9 @@ func (p Envfiles) Get(root string, args []string) ([]kv.Pair, error) { if err != nil { return nil, err } - all = append(all, kvs...) + for _, pair := range kvs { + all[pair.Key] = pair.Value + } } return all, nil } diff --git a/k8sdeps/kv/plugin/builtin/files.go b/k8sdeps/kv/plugin/builtin/files.go index 48276d786..626dfb88c 100644 --- a/k8sdeps/kv/plugin/builtin/files.go +++ b/k8sdeps/kv/plugin/builtin/files.go @@ -32,8 +32,8 @@ type Files struct { } // Get implements the interface for kv plugins. -func (p Files) Get(root string, args []string) ([]kv.Pair, error) { - var kvs []kv.Pair +func (p Files) Get(root string, args []string) (map[string]string, error) { + kvs := make(map[string]string) for _, s := range args { k, fPath, err := kv.ParseFileSource(s) if err != nil { @@ -43,7 +43,7 @@ func (p Files) Get(root string, args []string) ([]kv.Pair, error) { if err != nil { return nil, err } - kvs = append(kvs, kv.Pair{Key: k, Value: string(content)}) + kvs[k] = string(content) } return kvs, nil } diff --git a/k8sdeps/kv/plugin/builtin/literals.go b/k8sdeps/kv/plugin/builtin/literals.go index 8896e7104..364c1e8ff 100644 --- a/k8sdeps/kv/plugin/builtin/literals.go +++ b/k8sdeps/kv/plugin/builtin/literals.go @@ -26,14 +26,14 @@ import ( type Literals struct{} // Get implements the interface for kv plugins. -func (p Literals) Get(root string, args []string) ([]kv.Pair, error) { - var kvs []kv.Pair +func (p Literals) Get(root string, args []string) (map[string]string, error) { + kvs := make(map[string]string) for _, s := range args { k, v, err := kv.ParseLiteralSource(s) if err != nil { return nil, err } - kvs = append(kvs, kv.Pair{Key: k, Value: v}) + kvs[k] = v } return kvs, nil } diff --git a/k8sdeps/kv/plugin/builtinplugin.go b/k8sdeps/kv/plugin/builtinplugin.go index ec2045ca7..225de4d40 100644 --- a/k8sdeps/kv/plugin/builtinplugin.go +++ b/k8sdeps/kv/plugin/builtinplugin.go @@ -34,7 +34,7 @@ func newBuiltinFactory(ldr ifc.Loader) *builtinFactory { plugins: map[string]KVSource{ "literals": builtin.Literals{}, "files": builtin.Files{Ldr: ldr}, - "envfiles": builtin.Envfiles{Ldr: ldr}, + "envfiles": builtin.EnvFiles{Ldr: ldr}, }, } } diff --git a/k8sdeps/kv/plugin/goplugin.go b/k8sdeps/kv/plugin/goplugin.go index 4b67f9dd2..a4970f75f 100644 --- a/k8sdeps/kv/plugin/goplugin.go +++ b/k8sdeps/kv/plugin/goplugin.go @@ -29,23 +29,20 @@ var _ Factory = &goFactory{} const ( kvSourcesDir = "kvSources" EnableGoPluginsFlagName = "enable_alpha_goplugins_accept_panic_risk" - EnableGoPluginsFlagHelp = ` -Warning: the main program may panic and exit on an -attempt to use a goplugin that was compiled under -conditions differing from the those in effect when -main was compiled. It's safest to use this flag in -the context of a container image holding both the -main and the goplugins it needs, all built on the -same machine, with the same transitive libs and -the same compiler version. -` + EnableGoPluginsFlagHelp = `The main program may panic and exit on an attempt +to use a goplugin that was compiled under conditions +differing from the those in effect when main was +compiled. It's safest to use this flag in the +context of a container image holding both the main +and the goplugins it needs, all built on the same +machine, with the same transitive libs and the same +compiler version.` errorFmt = ` enable go plugins by specifying flag --%s Place .so files in %s -%s -` +%s` ) func newGoFactory(c *types.PluginConfig) *goFactory { @@ -82,7 +79,7 @@ func (p *goFactory) load(name string) (KVSource, error) { return nil, err } - symbol, err := goPlugin.Lookup("Plugin") + symbol, err := goPlugin.Lookup("KVSource") if err != nil { return nil, err } diff --git a/k8sdeps/kv/plugin/plugin.go b/k8sdeps/kv/plugin/plugin.go index e3e40a9de..29975999b 100644 --- a/k8sdeps/kv/plugin/plugin.go +++ b/k8sdeps/kv/plugin/plugin.go @@ -17,13 +17,9 @@ limitations under the License. // Package plugin provides a plugin abstraction layer. package plugin -import ( - "sigs.k8s.io/kustomize/k8sdeps/kv" -) - // KVSource is the interface for kv source plugins. type KVSource interface { - Get(root string, args []string) ([]kv.Pair, error) + Get(root string, args []string) (map[string]string, error) } // Factory is the interface for new kv source plugin implementations. diff --git a/pkg/commands/commands.go b/pkg/commands/commands.go index 5a4ff0d05..e2109249e 100644 --- a/pkg/commands/commands.go +++ b/pkg/commands/commands.go @@ -55,12 +55,12 @@ See https://sigs.k8s.io/kustomize PluginConfig: plugin.DefaultPluginConfig(), } - c.Flags().BoolVar( + c.PersistentFlags().BoolVar( &genMetaArgs.PluginConfig.GoEnabled, plugin.EnableGoPluginsFlagName, false, plugin.EnableGoPluginsFlagHelp) // Not advertising this alpha feature. - c.Flags().MarkHidden(plugin.EnableGoPluginsFlagName) + c.PersistentFlags().MarkHidden(plugin.EnableGoPluginsFlagName) uf := kunstruct.NewKunstructuredFactoryWithGeneratorArgs(&genMetaArgs) diff --git a/pkg/pgmconfig/config.go b/pkg/pgmconfig/config.go index d7a27422a..c0f8522b4 100644 --- a/pkg/pgmconfig/config.go +++ b/pkg/pgmconfig/config.go @@ -23,6 +23,7 @@ import ( "runtime" ) +//noinspection GoSnakeCaseUsage const ( XDG_CONFIG_HOME = "XDG_CONFIG_HOME" defaultConfigSubdir = ".config" From 58d9a510400888b129e0b792a8cec0ae329bfdee Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Thu, 28 Mar 2019 12:36:10 -0700 Subject: [PATCH 192/317] Improve plugin doc. --- examples/kvSourceGoPlugin.md | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/examples/kvSourceGoPlugin.md b/examples/kvSourceGoPlugin.md index 37ae6769b..8112a46b6 100644 --- a/examples/kvSourceGoPlugin.md +++ b/examples/kvSourceGoPlugin.md @@ -118,6 +118,7 @@ Now generate the Secret: ``` result=$(kustomize build $DEMO_HOME) echo "$result" +# Spot check the result: test 1 == $(echo "$result" | grep -c "FRUIT: YXBwbGU=") ``` @@ -157,7 +158,7 @@ them, etc. > New _alpha_ behavior at HEAD, for v2.1+ A general alternative is to enshrine secret -value generation in a Go plugin. +value generation in a [Go plugin]. The values can then come in via, say, an authenticated and authorized RPC to a password @@ -180,7 +181,8 @@ var database = map[string]string{ type plugin struct{} var KVSource plugin -func (p plugin) Get(root string, args []string) (map[string]string, error) { +func (p plugin) Get( + root string, args []string) (map[string]string, error) { r := make(map[string]string) for _, k := range args { v, ok := database[k] @@ -220,8 +222,7 @@ Compile and install the plugin: ``` kvSources=$DEMO_HOME/kustomize/plugins/kvSources mkdir -p $kvSources -GOPATH=$DEMO_HOME:$GOPATH go build \ - -buildmode plugin \ +go build -buildmode plugin \ -o $kvSources/kvMaker.so \ $DEMO_HOME/kvMaker.go ``` @@ -248,19 +249,16 @@ Finally, generate the secret, setting ``` -result=$(XDG_CONFIG_HOME=$DEMO_HOME kustomize \ +result=$( \ + XDG_CONFIG_HOME=$DEMO_HOME \ + kustomize \ --enable_alpha_goplugins_accept_panic_risk \ - build $DEMO_HOME) + build $DEMO_HOME ) echo "$result" +# Spot check the result: test 1 == $(echo "$result" | grep -c "FRUIT: YXBwbGU=") ``` -Specify the `--enable_...` flag to enable Go -plugins, which may fail if not compiled under -the same conditions as the main program. Try -this command without the flag to see more -explanation. - This should emit something like: > ``` @@ -276,4 +274,17 @@ This should emit something like: i.e. a subset of the same values as above. +Go plugins work well, but their usage may +fail (the program may crash) if there's +too much skew between _main program_ and +_plugin_ compilation conditions. For +this reason, their use is protected by an +annoyingly long opt-in flag +(`--enable_alpha_goplugins_accept_panic_risk`) +intended to make the user aware of this risk. +It's safest to use Go plugins in the +context of a container image holding both +the main and the Go plugins it needs, all built +on the same machine, with the same transitive +libs and the same compiler version. From 53a22cbe9b74f94a5a0a6552b980fda1cd3fc6c9 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Thu, 28 Mar 2019 15:22:49 -0700 Subject: [PATCH 193/317] add note for availability in kubectl --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 0efbb13a1..631a5b580 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,11 @@ inspired by [DAM]. page], or see these [install] notes. Then try one of the tested [examples]. +**Note** Kustomize is now available on kubectl v1.14 and can be used by specifying a directory containing a `kustomization.yaml`: +```shell +kubectl apply -k dir/ +``` + ## Usage From 4848987a1fb23612371093816c30d91f88dceb3a Mon Sep 17 00:00:00 2001 From: Michael Heyvaert Date: Thu, 28 Mar 2019 15:19:28 +0100 Subject: [PATCH 194/317] fix configmap/secret name references for cronjobs with projected volumes --- .../config/defaultconfig/namereference.go | 4 + pkg/transformers/namereference_test.go | 74 +++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/pkg/transformers/config/defaultconfig/namereference.go b/pkg/transformers/config/defaultconfig/namereference.go index 669fc2407..6704f0063 100644 --- a/pkg/transformers/config/defaultconfig/namereference.go +++ b/pkg/transformers/config/defaultconfig/namereference.go @@ -108,6 +108,8 @@ nameReference: kind: Job - path: spec/jobTemplate/spec/template/spec/volumes/configMap/name kind: CronJob + - path: spec/jobTemplate/spec/template/spec/volumes/projected/sources/configMap/name + kind: CronJob - path: spec/jobTemplate/spec/template/spec/containers/env/valueFrom/configMapKeyRef/name kind: CronJob - path: spec/jobTemplate/spec/template/spec/initContainers/env/valueFrom/configMapKeyRef/name @@ -204,6 +206,8 @@ nameReference: kind: Job - path: spec/jobTemplate/spec/template/spec/volumes/secret/secretName kind: CronJob + - path: spec/jobTemplate/spec/template/spec/volumes/projected/sources/secret/name + kind: CronJob - path: spec/jobTemplate/spec/template/spec/containers/env/valueFrom/secretKeyRef/name kind: CronJob - path: spec/jobTemplate/spec/template/spec/initContainers/env/valueFrom/secretKeyRef/name diff --git a/pkg/transformers/namereference_test.go b/pkg/transformers/namereference_test.go index 4cdeab011..dd16c8980 100644 --- a/pkg/transformers/namereference_test.go +++ b/pkg/transformers/namereference_test.go @@ -241,6 +241,43 @@ func TestNameReferenceHappyRun(t *testing.T) { }, }, }), + resid.NewResId(cronjob, "cronjob1"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "batch/v1beta1", + "kind": "CronJob", + "metadata": map[string]interface{}{ + "name": "cronjob1", + }, + "spec": map[string]interface{}{ + "schedule": "0 14 * * *", + "jobTemplate": map[string]interface{}{ + "spec": map[string]interface{}{ + "template": map[string]interface{}{ + "spec": map[string]interface{}{ + "containers": []interface{}{ + map[string]interface{}{ + "name": "main", + "image": "myimage", + }, + }, + "volumes": map[string]interface{}{ + "projected": map[string]interface{}{ + "sources": map[string]interface{}{ + "configMap": map[string]interface{}{ + "name": "cm2", + }, + "secret": map[string]interface{}{ + "name": "secret1", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }), } expected := resmap.ResMap{} @@ -417,6 +454,43 @@ func TestNameReferenceHappyRun(t *testing.T) { }, }, }) + expected[resid.NewResId(cronjob, "cronjob1")] = rf.FromMap( + map[string]interface{}{ + "apiVersion": "batch/v1beta1", + "kind": "CronJob", + "metadata": map[string]interface{}{ + "name": "cronjob1", + }, + "spec": map[string]interface{}{ + "schedule": "0 14 * * *", + "jobTemplate": map[string]interface{}{ + "spec": map[string]interface{}{ + "template": map[string]interface{}{ + "spec": map[string]interface{}{ + "containers": []interface{}{ + map[string]interface{}{ + "name": "main", + "image": "myimage", + }, + }, + "volumes": map[string]interface{}{ + "projected": map[string]interface{}{ + "sources": map[string]interface{}{ + "configMap": map[string]interface{}{ + "name": "someprefix-cm2-somehash", + }, + "secret": map[string]interface{}{ + "name": "someprefix-secret1-somehash", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }) nrt := NewNameReferenceTransformer(defaultTransformerConfig.NameReference) err := nrt.Transform(m) if err != nil { From 21a0cba43e5cc9960fd60f0b3df260d19d26648c Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Fri, 29 Mar 2019 13:10:11 -0700 Subject: [PATCH 195/317] fix the regression of building remote url (#935) --- examples/remoteBuild.md | 2 +- pkg/git/cloner.go | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/remoteBuild.md b/examples/remoteBuild.md index 747724fca..1e3a42ac7 100644 --- a/examples/remoteBuild.md +++ b/examples/remoteBuild.md @@ -10,7 +10,7 @@ Running `kustomize build` against the url gives the same output. ``` -target=github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6 +target=github.com/kubernetes-sigs/kustomize//examples/multibases test 3 == \ $(kustomize build $target | grep cluster-a-.*-myapp-pod | wc -l); \ echo $? diff --git a/pkg/git/cloner.go b/pkg/git/cloner.go index cbf176448..f5d92418f 100644 --- a/pkg/git/cloner.go +++ b/pkg/git/cloner.go @@ -68,9 +68,8 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error { "trouble adding remote %s", repoSpec.CloneSpec()) } - if repoSpec.ref == "" { - return nil + repoSpec.ref = "master" } cmd = exec.Command( gitProgram, From 2490e605c3ef61053b684e19639b6972b338f58b Mon Sep 17 00:00:00 2001 From: Yujun Zhang Date: Sat, 30 Mar 2019 04:11:07 +0800 Subject: [PATCH 196/317] Updates in image transformer (#911) - Decouple `mutateImage` from `updateContainers` to be reused as `mutateFunc` - Ignore default image transform error for CRD which may contain non-array type `containers` field Related to #890, #904, fixes #890 --- pkg/target/crd_test.go | 61 ++++++++++++++++++++++++++++ pkg/target/transformersimage_test.go | 59 +++++++++++++++++++++++++-- pkg/transformers/image.go | 49 ++++++++++++++-------- 3 files changed, 150 insertions(+), 19 deletions(-) diff --git a/pkg/target/crd_test.go b/pkg/target/crd_test.go index 7bd71083c..6ffa923ba 100644 --- a/pkg/target/crd_test.go +++ b/pkg/target/crd_test.go @@ -320,3 +320,64 @@ spec: action: makehoney `) } + +func TestCrdWithContainers(t *testing.T) { + th := NewKustTestHarness(t, "/app/crd/containers") + th.writeK("/app/crd/containers", ` +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - crd.yaml + +images: + - name: test/test + newName: registry.gitlab.com/test + newTag: latest +`) + th.writeF("/app/crd/containers/crd.yaml", ` +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: crontabs.stable.example.com +spec: + group: stable.example.com + scope: Namespaced + names: + plural: crontabs + singular: crontab + kind: CronTab + shortNames: + - ct + validation: + openAPIV3Schema: + properties: + spec: + containers: + description: Containers allows injecting additional containers + `) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: crontabs.stable.example.com +spec: + group: stable.example.com + names: + kind: CronTab + plural: crontabs + shortNames: + - ct + singular: crontab + scope: Namespaced + validation: + openAPIV3Schema: + properties: + spec: + containers: + description: Containers allows injecting additional containers +`) +} diff --git a/pkg/target/transformersimage_test.go b/pkg/target/transformersimage_test.go index 3f12e0cb7..450129274 100644 --- a/pkg/target/transformersimage_test.go +++ b/pkg/target/transformersimage_test.go @@ -233,11 +233,11 @@ spec3: th.writeF("/app/base/config/custom.yaml", ` images: - kind: Custom - path: spec/template/spec/myContainers + path: spec/template/spec/myContainers/image - kind: Custom - path: spec2/template/spec/myContainers + path: spec2/template/spec/myContainers/image - kind: Custom - path: spec3/template/spec/myInitContainers + path: spec3/template/spec/myInitContainers/image `) } func TestTransfomersImageCustomConfig(t *testing.T) { @@ -283,3 +283,56 @@ spec3: name: my-cool-app `) } + +func makeTransfomersImageKnativeBase(th *KustTestHarness) { + th.writeK("/app/base", ` +resources: +- knative.yaml +configurations: +- config/knative.yaml +images: +- name: solsa-echo + newTag: foo +`) + th.writeF("/app/base/knative.yaml", ` +apiVersion: serving.knative.dev/v1alpha1 +kind: Service +metadata: + name: echo +spec: + runLatest: + configuration: + revisionTemplate: + spec: + container: + image: solsa-echo +`) + th.writeF("/app/base/config/knative.yaml", ` +images: +- path: spec/runLatest/configuration/revisionTemplate/spec/container/image + apiVersion: serving.knative.dev/v1alpha1 + kind: Service +`) +} + +func TestTransfomersImageKnativeConfig(t *testing.T) { + th := NewKustTestHarness(t, "/app/base") + makeTransfomersImageKnativeBase(th) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: serving.knative.dev/v1alpha1 +kind: Service +metadata: + name: echo +spec: + runLatest: + configuration: + revisionTemplate: + spec: + container: + image: solsa-echo:foo +`) +} diff --git a/pkg/transformers/image.go b/pkg/transformers/image.go index ef7f28d74..e92c78fc6 100644 --- a/pkg/transformers/image.go +++ b/pkg/transformers/image.go @@ -50,20 +50,44 @@ func (pt *imageTransformer) Transform(m resmap.ResMap) error { if !id.Gvk().IsSelected(&path.Gvk) { continue } - err := mutateField(objMap, path.PathSlice(), false, pt.updateContainers) + err := mutateField(objMap, path.PathSlice(), false, pt.mutateImage) if err != nil { return err } } - // Keep for backward compatibility - err := pt.findAndReplaceImage(objMap) - if err != nil { + // Kept for backward compatibility + if err := pt.findAndReplaceImage(objMap); err != nil && id.Gvk().Kind != `CustomResourceDefinition` { return err } } return nil } +func (pt *imageTransformer) mutateImage(in interface{}) (interface{}, error) { + image, ok := in.(string) + if !ok { + return nil, fmt.Errorf("image path is not of type string but %T", in) + } + + for _, img := range pt.images { + if !isImageMatched(image, img.Name) { + continue + } + name, tag := split(image) + if img.NewName != "" { + name = img.NewName + } + if img.NewTag != "" { + tag = ":" + img.NewTag + } + if img.Digest != "" { + tag = "@" + img.Digest + } + return name + tag, nil + } + return image, nil +} + /* findAndReplaceImage replaces the image name and tags inside one object It searches the object for container session @@ -76,8 +100,7 @@ func (pt *imageTransformer) findAndReplaceImage(obj map[string]interface{}) erro for _, path := range paths { containers, found := obj[path] if found { - _, err := pt.updateContainers(containers) - if err != nil { + if _, err := pt.updateContainers(containers); err != nil { return err } updated = true @@ -106,17 +129,11 @@ func (pt *imageTransformer) updateContainers(in interface{}) (interface{}, error if !isImageMatched(imageName, img.Name) { continue } - name, tag := split(imageName) - if img.NewName != "" { - name = img.NewName + newImage, err := pt.mutateImage(imageName) + if err != nil { + return nil, err } - if img.NewTag != "" { - tag = ":" + img.NewTag - } - if img.Digest != "" { - tag = "@" + img.Digest - } - container["image"] = name + tag + container["image"] = newImage break } } From 7971ac1cb89305913f17aaa218d9813d2856e5f8 Mon Sep 17 00:00:00 2001 From: jregan Date: Sat, 30 Mar 2019 17:06:42 -0700 Subject: [PATCH 197/317] Tweak secret docs. --- examples/kvSourceGoPlugin.md | 136 ++++++++++++++++++++++++++++------- 1 file changed, 112 insertions(+), 24 deletions(-) diff --git a/examples/kvSourceGoPlugin.md b/examples/kvSourceGoPlugin.md index 8112a46b6..76a41d721 100644 --- a/examples/kvSourceGoPlugin.md +++ b/examples/kvSourceGoPlugin.md @@ -1,8 +1,13 @@ -[Secrets]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#secret-v1-core [ConfigMaps]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#configmap-v1-core -[base64]: https://tools.ietf.org/html/rfc4648#section-4 +[ELF]: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format [Go plugin]: https://golang.org/pkg/plugin +[Secrets]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#secret-v1-core +[base64]: https://tools.ietf.org/html/rfc4648#section-4 +[configuration directory]: https://wiki.archlinux.org/index.php/XDG_Base_Directory#Specification +[grpc]: https://grpc.io +[tag]: https://github.com/kubernetes-sigs/kustomize/releases [v2.0.3]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.0.3 +[`exec.Command`]: https://golang.org/pkg/os/exec/#Command # Generating Secrets @@ -44,7 +49,7 @@ from local files: * get them from so-called _env_ files (`NAME=VALUE`, one per line), * consume the entire contents of a file to make one secret value, * get literal values from the kustomization file itself. - + Here's an example combining all three methods: Make an env file with some short secrets: @@ -84,7 +89,7 @@ secretGenerator: args: - foo.env - name: files - pluginType: builtin + pluginType: builtin args: - longsecret.txt - name: literals @@ -209,12 +214,14 @@ must be installed at > ``` `XDG_CONFIG_HOME` is an environment variable -used by many programs as the root of a -configuration directory. If unspecified, the -default `$HOME/.config` is used. The rest of -the required directory path establishes that -the files found there are kustomize plugins -for generating KV pairs. +honored by many programs as the root of a +[configuration directory]. If the variable is +undefined, the convention is to fall back to +`$HOME/.config`. + +The rest of the required directory path +establishes that the files found there are +kustomize plugins for generating KV pairs. Compile and install the plugin: @@ -245,7 +252,8 @@ EOF ``` Finally, generate the secret, setting -`XDG_CONFIG_HOME` appropriately: +`XDG_CONFIG_HOME` so that the plugin +can be found under `$DEMO_HOME`: ``` @@ -274,17 +282,97 @@ This should emit something like: i.e. a subset of the same values as above. -Go plugins work well, but their usage may -fail (the program may crash) if there's -too much skew between _main program_ and -_plugin_ compilation conditions. For -this reason, their use is protected by an -annoyingly long opt-in flag -(`--enable_alpha_goplugins_accept_panic_risk`) -intended to make the user aware of this risk. +### Go Plugin Caveats -It's safest to use Go plugins in the -context of a container image holding both -the main and the Go plugins it needs, all built -on the same machine, with the same transitive -libs and the same compiler version. +Kustomize supports Go plugins to allow someone to +extend kustomize in type-safe fashion against a +documented Go interface type, without having to +get their code merged into the kustomize +repository, and without having to maintain a +permanent fork. + +Go plugins work well, but fall short of what many +people think of when they hear the word _plugin_. + +Go plugin compilation creates an [ELF] formatted +`.so` file, which by definition has no information +about the _provenance_ of the file. One cannot +know which version of Go was used, which packages +were imported (and their version), what value of +`GOOS` and `GOARCH` were used, etc. If the skew +between the compilation conditions of the main +program ELF and the plugin ELF are too great, the +program will crash. Also, there's no certificate +to check in a `.so` file, so no way to know who +wrote it or what it does. A bare `.so` file, not +packaged with provenance information, is not a +suitable distrubution format. It's not what +people expect from decades of adding features +IDEs, browsers, CAD tools, graphics tools, etc. +via things called _plugins_. + +There's no reason why someone couldn't build a +`.so` packaging mechanism into `go` to emit an ELF +packaged with provenance allowing ELF +compatibility checks, but this isn't supported in +kustomize (or Go) at the time of writing. + +To avoid provenance issues simply compile your Go +plugins and the main program at the same time. +Bundle them into a container image for use by +downstream users and/or your continuous delivery +bot. This is the intended usage idiom for Go +plugins. + +A `kustomize build` attempt with Go plugins that omits +the flag + +> `--enable_alpha_goplugins_accept_panic_risk` + +will fail with an error message about skew risks. +Flag use is an opt-in acknowledging the absence of +`.so` provenance, an absence that doesn't matter +to someone building the code from source. + + +### Leveraging Go plugins to run non-Go code + + +#### external services + +For particular (user-created) transformations or +generations, kustomize could prepare a request, +send it to some service, and process a response. +How to do this is a [solved problem][grpc]. The +communication is struct-to-struct type safe - no +need to write parsing code. + +If the service is written in Go, and one can +vendor its code, it's simplest to write a small Go +plugin that calls it like a library rather than +running the service as an independent process. + +If the service is not written in Go, or if the +source code is unavailable, one can use a small Go +plugin to make the RPC. + + +#### subprocesses (also known as `exec` plugins) + +In this approach one arranges for executable files +to be identified by name or location, and runs +them as a kustomize subprocess, sending a +'request' to the subprocess its `stdin`, and +obtaining a 'response' via its `stdout`. + +An immediate way to use an arbitrary executable +with arbitrary i/o requirements is through a Go +plugin that runs the executable via +[`exec.Command`]. Each special purpose +tranformation or generation - needed by `kustomize +build` - will require it's own `stdin`/`stdout` +processing to convert from/to the Go types that +kustomize uses. + +The Go plugin provides this translation layer, and +handles process exit codes. From 237c54f47e1ba516f0e800c758a4b2332ade00a8 Mon Sep 17 00:00:00 2001 From: Karen Bradshaw Date: Sun, 31 Mar 2019 16:26:11 -0400 Subject: [PATCH 198/317] add tutorial for custom images transformer --- examples/transformerconfigs/README.md | 74 +++++++++- examples/transformerconfigs/images/README.md | 128 ++++++++++++++++++ .../images/kustomization.yaml | 19 +++ .../transformerconfigs/images/mykind.yaml | 3 + .../transformerconfigs/images/resources.yaml | 27 ++++ 5 files changed, 245 insertions(+), 6 deletions(-) create mode 100644 examples/transformerconfigs/images/README.md create mode 100644 examples/transformerconfigs/images/kustomization.yaml create mode 100644 examples/transformerconfigs/images/mykind.yaml create mode 100644 examples/transformerconfigs/images/resources.yaml diff --git a/examples/transformerconfigs/README.md b/examples/transformerconfigs/README.md index dcab70902..5b0cd7046 100644 --- a/examples/transformerconfigs/README.md +++ b/examples/transformerconfigs/README.md @@ -3,11 +3,12 @@ Kustomize creates new resources by applying a series of transformations to an original set of resources. Kustomize provides the following default transformers: +- annotations +- images +- labels +- name reference - namespace - prefix/suffix -- label -- annotation -- name reference - variable reference A `fieldSpec` list, in a transformer's configuration, determines which resource types and which fields @@ -27,6 +28,31 @@ create: false If `create` is set to `true`, the transformer creates the path to the field in the resource if the path is not already found. This is most useful for label and annotation transformers, where the path for labels or annotations may not be set before the transformation. +## Images transformer + +The default images transformer updates the specified image key values found in paths that include +`containers` and `initcontainers` sub-paths. +If found, the `image` key value is customized by the values set in the `newName`, `newTag`, and `digest` fields. +The `name` field should match the `image` key value in a resource. + +Example kustomization.yaml: + +```yaml +images: + - name: postgres + newName: my-registry/my-postgres + newTag: v1 + - name: nginx + newTag: 1.8.0 + - name: my-demo-app + newName: my-app + - name: alpine + digest: sha256:25a0d4 +``` + +Image transformer configurations can be customized by creating a list of `images` containing the `path` and `kind` fields. +The images transformation tutorial shows how to specify the default images transformer and customize the [images transformer configuration](images/README.md). + ## Prefix/suffix transformer The prefix/suffix transformer adds a prefix/suffix to the `metadata/name` field for all resources. Here is the default prefix transformer configuration: @@ -36,9 +62,22 @@ namePrefix: - path: metadata/name ``` -## Label transformer +Example kustomization.yaml: -The label transformer adds labels to the `metadata/labels` field for all resources. It also adds labels to the `spec/selector` field in all Service resources as well as the `spec/selector/matchLabels` field in all Deployment resources. +```yaml + +namePrefix: + alices- + +nameSuffix: + -v2 +``` + +## Labels transformer + +The labels transformer adds labels to the `metadata/labels` field for all resources. It also adds labels to the `spec/selector` field in all Service resources as well as the `spec/selector/matchLabels` field in all Deployment resources. + +Example: ```yaml commonLabels: @@ -55,6 +94,29 @@ commonLabels: kind: Deployment ``` +Example kustomization.yaml: + +```yaml +commonLabels: + someName: someValue + owner: alice + app: bingo +``` + +## Annotations transformer + +The annotations transformer adds annotations to the `metadata/annotations` field for all resources. +Annotations are also added to `spec/template/metadata/annotations` for Deployment, +ReplicaSet, DaemonSet, StatefulSet, Job, and CronJob resources, and `spec/jobTemplate/spec/template/metadata/annotations` +for CronJob resources. + +Example kustomization.yaml + +```yaml +commonAnnotations: + oncallPager: 800-555-1212 +``` + ## Name reference transformer Name reference transformer's configuration is different from all other transformers. It contains a list of `nameReferences`, which represent all of the possible fields that a type could be used as a reference in other types of resources. A `nameReference` contains a type such as ConfigMap as well as a list of `fieldSpecs` where ConfigMap is referenced in other resources. Here is an example: @@ -99,7 +161,7 @@ nameReference: ## Customizing transformer configurations -Kustomize has a default set of transformer configurations. You can save the default transformer configurations to a local directory by calling `kustomize config save -d`, and modify and use these configurations. Kustomize also supports adding new transformer configurations to kustomization.yaml. This tutorial shows how to customize those configurations to: +In addition to the default transformers, you can create custom transformer configurations. Save the default transformer configurations to a local directory by calling `kustomize config save -d`, and modify and use these configurations. This tutorial shows how to create custom transformer configurations: - [support a CRD type](crd/README.md) - add extra fields for variable substitution diff --git a/examples/transformerconfigs/images/README.md b/examples/transformerconfigs/images/README.md new file mode 100644 index 000000000..ce7d190d3 --- /dev/null +++ b/examples/transformerconfigs/images/README.md @@ -0,0 +1,128 @@ +## Images transformations + +This tutorial shows how to modify images in resources, and create a custom images transformer configuration. + +Create a workspace by + +``` +DEMO_HOME=$(mktemp -d) +``` + +### Adding a custom resource + +Consider a Custom Resource Definition(CRD) of kind `MyKind` with field +- `.spec.runLatest.container.image` referencing an image + +Add the following file to configure the images transformer for the CRD: + + +``` +mkdir $DEMO_HOME/kustomizeconfig +cat > $DEMO_HOME/kustomizeconfig/mykind.yaml << EOF + +images: +- path: spec/runLatest/container/image + kind: MyKind +EOF +``` + +### Apply config + +Create a file with some resources that includes an instance of `MyKind`: + + +``` +cat > $DEMO_HOME/resources.yaml << EOF + +apiVersion: config/v1 +kind: MyKind +metadata: + name: testSvc +spec: + runLatest: + container: + image: crd-image + containers: + - image: docker + name: ecosystem + - image: my-mysql + name: testing-1 +--- +group: apps +apiVersion: v1 +kind: Deployment +metadata: + name: deploy1 +spec: + template: + spec: + initContainers: + - name: nginx2 + image: my-app + - name: init-alpine + image: alpine:1.8.0 +EOF +``` + +Create a kustomization.yaml referring to it: + + +``` +cat > $DEMO_HOME/kustomization.yaml << EOF +resources: +- resources.yaml + +images: +- name: crd-image + newName: new-crd-image + newTag: new-v1-tag +- name: my-app + newName: new-app-1 + newTag: MYNEWTAG-1 +- name: my-mysql + newName: prod-mysql + newTag: v3 +- name: docker + newName: my-docker2 + digest: sha256:25a0d4 +EOF +``` + +Use the customized transformer configurations by specifying them +in the kustomization file: + +``` +cat >> $DEMO_HOME/kustomization.yaml << EOF +configurations: +- kustomizeconfig/mykind.yaml +EOF +``` + +Run `kustomize build` and verify that the images have been updated. + + +``` +test 1 == \ +$(kustomize build $DEMO_HOME | grep -A 2 ".*image" | grep "new-crd-image:new-v1-tag" | wc -l); \ +echo $? +``` + + +``` +test 2 == \ +$(kustomize build $DEMO_HOME | grep -A 2 ".*image" | grep "new-app-1:MYNEWTAG-1" | wc -l); \ +echo $? +``` + + +``` +test 3 == \ +$(kustomize build $DEMO_HOME | grep -A 2 ".*image" | grep "my-docker2@sha" | wc -l); \ +echo $? +``` + +``` +test 4 == \ +$(kustomize build $DEMO_HOME | grep -A 2 ".*image" | grep "prod-mysql:v3" | wc -l); \ +echo $? +``` \ No newline at end of file diff --git a/examples/transformerconfigs/images/kustomization.yaml b/examples/transformerconfigs/images/kustomization.yaml new file mode 100644 index 000000000..db2bb4d5d --- /dev/null +++ b/examples/transformerconfigs/images/kustomization.yaml @@ -0,0 +1,19 @@ +resources: +- resources.yaml + +configurations: +- kustomizeconfig/mykind.yaml + +images: +- name: crd-image + newName: new-crd-image + newTag: new-v1-tag +- name: my-app + newName: new-app-1 + newTag: MYNEWTAG-1 +- name: my-mysql + newName: prod-mysql + newTag: v3 +- name: docker + newName: my-docker2 + digest: sha256:25a0d4 \ No newline at end of file diff --git a/examples/transformerconfigs/images/mykind.yaml b/examples/transformerconfigs/images/mykind.yaml new file mode 100644 index 000000000..422697a35 --- /dev/null +++ b/examples/transformerconfigs/images/mykind.yaml @@ -0,0 +1,3 @@ +images: +- path: spec/runLatest/container/image + kind: MyKind \ No newline at end of file diff --git a/examples/transformerconfigs/images/resources.yaml b/examples/transformerconfigs/images/resources.yaml new file mode 100644 index 000000000..b62bab72d --- /dev/null +++ b/examples/transformerconfigs/images/resources.yaml @@ -0,0 +1,27 @@ +apiVersion: config/v1 +kind: MyKind +metadata: + name: testSvc +spec: + runLatest: + container: + image: crd-image + containers: + - image: docker + name: ecosystem + - image: my-mysql + name: testing-1 +--- +group: apps +apiVersion: v1 +kind: Deployment +metadata: + name: deploy1 +spec: + template: + spec: + initContainers: + - name: nginx2 + image: my-app + - name: init-alpine + image: alpine:1.8.0 \ No newline at end of file From 927b497febdb4117293c79a0e48e3c5cdd876407 Mon Sep 17 00:00:00 2001 From: Karen Bradshaw Date: Sun, 31 Mar 2019 19:05:35 -0400 Subject: [PATCH 199/317] fix tests --- examples/transformerconfigs/images/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/transformerconfigs/images/README.md b/examples/transformerconfigs/images/README.md index ce7d190d3..22283b009 100644 --- a/examples/transformerconfigs/images/README.md +++ b/examples/transformerconfigs/images/README.md @@ -109,20 +109,20 @@ echo $? ``` -test 2 == \ +test 1 == \ $(kustomize build $DEMO_HOME | grep -A 2 ".*image" | grep "new-app-1:MYNEWTAG-1" | wc -l); \ echo $? ``` ``` -test 3 == \ +test 1 == \ $(kustomize build $DEMO_HOME | grep -A 2 ".*image" | grep "my-docker2@sha" | wc -l); \ echo $? ``` ``` -test 4 == \ +test 1 == \ $(kustomize build $DEMO_HOME | grep -A 2 ".*image" | grep "prod-mysql:v3" | wc -l); \ echo $? ``` \ No newline at end of file From deaf0779a1ad5f004d299712190f333251a3aab2 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Wed, 3 Apr 2019 14:05:25 -0700 Subject: [PATCH 200/317] add generators/transformers fields in kusotmization.yaml --- pkg/commands/kustfile/kustomizationfile.go | 2 ++ pkg/commands/kustfile/kustomizationfile_test.go | 2 ++ pkg/types/kustomization.go | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/pkg/commands/kustfile/kustomizationfile.go b/pkg/commands/kustfile/kustomizationfile.go index 42b93d789..b31fc8464 100644 --- a/pkg/commands/kustfile/kustomizationfile.go +++ b/pkg/commands/kustfile/kustomizationfile.go @@ -67,6 +67,8 @@ func determineFieldOrder() []string { "Vars", "Images", "Configurations", + "Generators", + "Transformers", } // Add deprecated fields here. diff --git a/pkg/commands/kustfile/kustomizationfile_test.go b/pkg/commands/kustfile/kustomizationfile_test.go index 0795986c3..20751ab74 100644 --- a/pkg/commands/kustfile/kustomizationfile_test.go +++ b/pkg/commands/kustfile/kustomizationfile_test.go @@ -46,6 +46,8 @@ func TestFieldOrder(t *testing.T) { "Vars", "Images", "Configurations", + "Generators", + "Transformers", } actual := determineFieldOrder() if len(expected) != len(actual) { diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 37b07f58f..68d3a8e36 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -130,6 +130,12 @@ type Kustomization struct { // Configurations is a list of transformer configuration files Configurations []string `json:"configurations,omitempty" yaml:"configurations,omitempty"` + + // Generators is a list of files containing custom generators + Generators []string `json:"generators,omitempty" yaml:"generators,omitempty"` + + // Transformers is a list of files containing transformers + Transformers []string `json:"transformers,omitempty" yaml:"transformers,omitempty"` } // DealWithMissingFields fills the missing fields From 440d03617676cd3364a93c52b76d69ff4de57971 Mon Sep 17 00:00:00 2001 From: jregan Date: Thu, 4 Apr 2019 13:21:42 -0700 Subject: [PATCH 201/317] some transformer plugins --- pkg/target/kusttarget.go | 56 +++++++++++++ pkg/target/transformerplugin_test.go | 119 +++++++++++++++++++++++++++ pkg/transformers/transformer.go | 9 +- plugins/DatePrefixer.go | 30 +++++++ plugins/StringPrefixer.go | 44 ++++++++++ plugins/kvMaker.go | 24 ++++++ 6 files changed, 281 insertions(+), 1 deletion(-) create mode 100644 pkg/target/transformerplugin_test.go create mode 100644 plugins/DatePrefixer.go create mode 100644 plugins/StringPrefixer.go create mode 100644 plugins/kvMaker.go diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 25e5aff9e..e476cecdd 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -21,6 +21,9 @@ import ( "bytes" "encoding/json" "fmt" + "os" + "path/filepath" + "plugin" "strings" "github.com/ghodss/yaml" @@ -318,5 +321,58 @@ func (kt *KustTarget) newTransformer( return nil, err } r = append(r, t) + + tp, err := kt.loadTransformerPlugins() + if err != nil { + return nil, err + } + r = append(r, tp...) return transformers.NewMultiTransformer(r), nil } + +func (kt *KustTarget) loadTransformerPlugins() ([]transformers.Transformer, error) { + var result []transformers.Transformer + + pc := types.PluginConfig{ + DirectoryPath: os.Getenv("GOPATH"), + GoEnabled: true} + + root := filepath.Join( + pc.DirectoryPath, "src", "sigs.k8s.io", "kustomize", "plugins") + + if !pc.GoEnabled { + return nil, fmt.Errorf("plugins not enabled") + } + + transformerPluginConfigs, err := kt.rFactory.FromFiles( + kt.ldr, kt.kustomization.Transformers) + + for id, res := range transformerPluginConfigs { + fileName := filepath.Join(root, id.Gvk().Kind+".so") + goPlugin, err := plugin.Open(fileName) + if err != nil { + return nil, fmt.Errorf("plugin %s file not opened", fileName) + } + symbol, err := goPlugin.Lookup("Transformer") + if err != nil { + return nil, fmt.Errorf("plugin %s fails lookup", fileName) + } + c, ok := symbol.(transformers.Configurable) + if !ok { + return nil, fmt.Errorf("plugin %s not configurable", fileName) + } + err = c.Config(res) + if err != nil { + return nil, errors.Wrapf(err, "plugin %s fails configuration", fileName) + } + t, ok := c.(transformers.Transformer) + if !ok { + return nil, fmt.Errorf("plugin %s not a transformer", fileName) + } + + result = append(result, t) + fmt.Printf("Added plugin %s\n", fileName) + + } + return result, err +} diff --git a/pkg/target/transformerplugin_test.go b/pkg/target/transformerplugin_test.go new file mode 100644 index 000000000..9c050b0cf --- /dev/null +++ b/pkg/target/transformerplugin_test.go @@ -0,0 +1,119 @@ +/* +Copyright 2019 The Kubernetes Authors. + Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target_test + +import ( + "sigs.k8s.io/kustomize/pkg/types" + "testing" +) + +func writeDeployment(th *KustTestHarness, path string) { + th.writeF(path, ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: myDeployment +spec: + template: + metadata: + labels: + backend: awesome + spec: + containers: + - name: whatever + image: whatever +`) +} + +func writeStringPrefixer(th *KustTestHarness, path string) { + th.writeF(path, ` +apiVersion: strings.microwoosh.com/v1 +kind: StringPrefixer +metadata: + name: myStringPrefixer +prefix: apple- +`) +} + +func writeDatePrefixer(th *KustTestHarness, path string) { + th.writeF(path, ` +apiVersion: team.dater.com/v1 +kind: DatePrefixer +metadata: + name: myDatePrefixer +`) +} + +func TestOrderedTransformers(t *testing.T) { + th := NewKustTestHarnessWithPluginConfig( + t, "/app", types.PluginConfig{GoEnabled: true}) + th.writeK("/app", ` +resources: +- deployment.yaml +transformers: +- stringPrefixer.yaml +`) + writeDeployment(th, "/app/deployment.yaml") + writeStringPrefixer(th, "/app/stringPrefixer.yaml") + writeDatePrefixer(th, "/app/datePrefixer.yaml") + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: apple-myDeployment +spec: + template: + metadata: + labels: + backend: awesome + spec: + containers: + - image: whatever + name: whatever +`) +} + +func xTestTransformedTransformers(t *testing.T) { + th := NewKustTestHarnessWithPluginConfig( + t, "/app/overlay", types.PluginConfig{GoEnabled: true}) + + th.writeK("/app/base", ` +resources: +- stringPrefixer.yaml +transformers: +- datePrefixer.yaml +`) + writeStringPrefixer(th, "/app/base/stringPrefixer.yaml") + writeDatePrefixer(th, "/app/base/datePrefixer.yaml") + + th.writeK("/app/overlay", ` +resources: +- deployment.yaml +transformers: +- ../base +`) + writeDeployment(th, "/app/overlay/deployment.yaml") + + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +HEY +`) +} diff --git a/pkg/transformers/transformer.go b/pkg/transformers/transformer.go index dc6f8807c..93288646c 100644 --- a/pkg/transformers/transformer.go +++ b/pkg/transformers/transformer.go @@ -17,10 +17,17 @@ limitations under the License. // Package transformers has implementations of resmap.ResMap transformers. package transformers -import "sigs.k8s.io/kustomize/pkg/resmap" +import ( + "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/resmap" +) // A Transformer modifies an instance of resmap.ResMap. type Transformer interface { // Transform modifies data in the argument, e.g. adding labels to resources that can be labelled. Transform(m resmap.ResMap) error } + +type Configurable interface { + Config(k ifc.Kunstructured) error +} diff --git a/plugins/DatePrefixer.go b/plugins/DatePrefixer.go new file mode 100644 index 000000000..8f7daf93f --- /dev/null +++ b/plugins/DatePrefixer.go @@ -0,0 +1,30 @@ +// +build plugin + +package main + +import ( + "time" + + "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/transformers" + "sigs.k8s.io/kustomize/pkg/transformers/config" +) + +type plugin struct{} + +var Transformer plugin + +func (p *plugin) Config(k ifc.Kunstructured) error { + return nil +} + +func (p *plugin) Transform(m resmap.ResMap) error { + tr, err := transformers.NewNamePrefixSuffixTransformer( + time.Now().Format("2006-01-02")+"-", "", + config.MakeDefaultConfig().NamePrefix) + if err != nil { + return err + } + return tr.Transform(m) +} diff --git a/plugins/StringPrefixer.go b/plugins/StringPrefixer.go new file mode 100644 index 000000000..0c8de29f9 --- /dev/null +++ b/plugins/StringPrefixer.go @@ -0,0 +1,44 @@ +// +build plugin + +// Assuming GOPATH is something like +// ~/gopath +// and this source file is located at +// $GOPATH/src/sigs.k8s.io/kustomize/plugins/StringPrefixer.go, +// build it like this: +// dir=$GOPATH/src/sigs.k8s.io/kustomize/plugins +// go build -buildmode plugin -tags=plugin \ +// -o $dir/StringPrefixer.so $dir/StringPrefixer.go + +package main + +import ( + "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/transformers" + "sigs.k8s.io/kustomize/pkg/transformers/config" +) + +type plugin struct{ + prefix string +} + +var Transformer plugin + +func (p *plugin) Config(k ifc.Kunstructured) error { + var err error + p.prefix, err = k.GetFieldValue("prefix") + if err != nil { + return err + } + return nil +} + +func (p *plugin) Transform(m resmap.ResMap) error { + tr, err := transformers.NewNamePrefixSuffixTransformer( + p.prefix, "", + config.MakeDefaultConfig().NamePrefix) + if err != nil { + return err + } + return tr.Transform(m) +} diff --git a/plugins/kvMaker.go b/plugins/kvMaker.go new file mode 100644 index 000000000..2250f3e46 --- /dev/null +++ b/plugins/kvMaker.go @@ -0,0 +1,24 @@ +// +build plugin + +package main +var database = map[string]string{ + "TREE": "oak", + "ROCKET": "Saturn V", + "FRUIT": "apple", + "VEGETABLE": "carrot", + "SIMPSON": "homer", +} + +type plugin struct{} +var KVSource plugin +func (p plugin) Get( + root string, args []string) (map[string]string, error) { + r := make(map[string]string) + for _, k := range args { + v, ok := database[k] + if ok { + r[k] = v + } + } + return r, nil +} From cefb64b6a919f6c0a132b10e9a8812cf34552327 Mon Sep 17 00:00:00 2001 From: Daiki Hayakawa Date: Fri, 5 Apr 2019 18:02:37 +0900 Subject: [PATCH 202/317] Fix path --- docs/kustomization.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/kustomization.yaml b/docs/kustomization.yaml index 668405223..277122978 100644 --- a/docs/kustomization.yaml +++ b/docs/kustomization.yaml @@ -142,9 +142,9 @@ generatorOptions: # etc. that differ from the common base). bases: - ../../base -- github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6 +- github.com/kubernetes-sigs/kustomize/examples/multibases?ref=v1.0.6 - github.com/Liujingfang1/mysql -- github.com/Liujingfang1/kustomize//examples/helloWorld?ref=test-branch +- github.com/Liujingfang1/kustomize/examples/helloWorld?ref=test-branch # Each entry in this list should resolve to # a partial or complete resource definition file. From 4f1a2350cecee6b5758fc321836f1932b0e25161 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Thu, 4 Apr 2019 16:48:29 -0700 Subject: [PATCH 203/317] add transformer plugins --- pkg/commands/build/build.go | 10 +-- pkg/commands/commands.go | 2 +- pkg/pgmconfig/constants.go | 3 +- pkg/plugins/transformers.go | 95 ++++++++++++++++++++++++++++ pkg/target/kusttarget.go | 72 ++++++--------------- pkg/target/kusttarget_test.go | 2 +- pkg/target/kusttestharness_test.go | 6 +- pkg/target/transformerplugin_test.go | 46 +++++++++++++- pkg/transformers/transformer.go | 5 -- 9 files changed, 172 insertions(+), 69 deletions(-) create mode 100644 pkg/plugins/transformers.go diff --git a/pkg/commands/build/build.go b/pkg/commands/build/build.go index 1176f25b1..cf4945d32 100644 --- a/pkg/commands/build/build.go +++ b/pkg/commands/build/build.go @@ -62,7 +62,8 @@ url examples: func NewCmdBuild( out io.Writer, fs fs.FileSystem, rf *resmap.Factory, - ptf transformer.Factory) *cobra.Command { + ptf transformer.Factory, + b bool) *cobra.Command { var o Options cmd := &cobra.Command{ @@ -75,7 +76,7 @@ func NewCmdBuild( if err != nil { return err } - return o.RunBuild(out, fs, rf, ptf) + return o.RunBuild(out, fs, rf, ptf, b) }, } cmd.Flags().StringVarP( @@ -102,13 +103,14 @@ func (o *Options) Validate(args []string) error { // RunBuild runs build command. func (o *Options) RunBuild( out io.Writer, fSys fs.FileSystem, - rf *resmap.Factory, ptf transformer.Factory) error { + rf *resmap.Factory, ptf transformer.Factory, + b bool) error { ldr, err := loader.NewLoader(o.kustomizationPath, fSys) if err != nil { return err } defer ldr.Cleanup() - kt, err := target.NewKustTarget(ldr, rf, ptf) + kt, err := target.NewKustTarget(ldr, rf, ptf, b) if err != nil { return err } diff --git a/pkg/commands/commands.go b/pkg/commands/commands.go index e2109249e..d327bd230 100644 --- a/pkg/commands/commands.go +++ b/pkg/commands/commands.go @@ -68,7 +68,7 @@ See https://sigs.k8s.io/kustomize build.NewCmdBuild( stdOut, fSys, resmap.NewFactory(resource.NewFactory(uf)), - transformer.NewFactoryImpl()), + transformer.NewFactoryImpl(), genMetaArgs.PluginConfig.GoEnabled), edit.NewCmdEdit(fSys, validator.NewKustValidator(), uf), misc.NewCmdConfig(fSys), misc.NewCmdVersion(stdOut), diff --git a/pkg/pgmconfig/constants.go b/pkg/pgmconfig/constants.go index 008b69da9..8418a75ce 100644 --- a/pkg/pgmconfig/constants.go +++ b/pkg/pgmconfig/constants.go @@ -28,5 +28,6 @@ var KustomizationFileNames = []string{ } const ( - PgmName = "kustomize" + PgmName = "kustomize" + PluginsDir = "plugins" ) diff --git a/pkg/plugins/transformers.go b/pkg/plugins/transformers.go new file mode 100644 index 000000000..aae6895be --- /dev/null +++ b/pkg/plugins/transformers.go @@ -0,0 +1,95 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package plugins + +import ( + "fmt" + "path/filepath" + "plugin" + + "github.com/pkg/errors" + "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/pgmconfig" + "sigs.k8s.io/kustomize/pkg/resid" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/resource" + "sigs.k8s.io/kustomize/pkg/transformers" +) + +const transformerSymbol = "Transformer" + +type Configurable interface { + Config(k ifc.Kunstructured) error +} + +type transformerLoader struct { + pluginDir string + enabled bool +} + +func NewTransformerLoader(b bool) transformerLoader { + return transformerLoader{ + pluginDir: filepath.Join(pgmconfig.ConfigRoot(), pgmconfig.PluginsDir), + enabled: b, + } +} + +func (l transformerLoader) Load(rm resmap.ResMap) ([]transformers.Transformer, error) { + if len(rm) == 0 { + return nil, nil + } + if !l.enabled { + return nil, fmt.Errorf("plugin is not enabled") + } + var result []transformers.Transformer + for id, res := range rm { + t, err := l.load(id, res) + if err != nil { + return nil, err + } + result = append(result, t) + } + return result, nil +} + +func (l transformerLoader) load(id resid.ResId, res *resource.Resource) (transformers.Transformer, error) { + fileName := filepath.Join(l.pluginDir, id.Gvk().Kind+".so") + goPlugin, err := plugin.Open(fileName) + if err != nil { + return nil, fmt.Errorf("plugin %s file not opened", fileName) + } + + symbol, err := goPlugin.Lookup(transformerSymbol) + if err != nil { + return nil, fmt.Errorf("plugin %s fails lookup", fileName) + } + + c, ok := symbol.(Configurable) + if !ok { + return nil, fmt.Errorf("plugin %s not configurable", fileName) + } + err = c.Config(res) + if err != nil { + return nil, errors.Wrapf(err, "plugin %s fails configuration", fileName) + } + + t, ok := c.(transformers.Transformer) + if !ok { + return nil, fmt.Errorf("plugin %s not a transformer", fileName) + } + return t, nil +} diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index e476cecdd..3dfb02adb 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -21,9 +21,6 @@ import ( "bytes" "encoding/json" "fmt" - "os" - "path/filepath" - "plugin" "strings" "github.com/ghodss/yaml" @@ -34,6 +31,7 @@ import ( interror "sigs.k8s.io/kustomize/pkg/internal/error" patchtransformer "sigs.k8s.io/kustomize/pkg/patch/transformer" "sigs.k8s.io/kustomize/pkg/pgmconfig" + "sigs.k8s.io/kustomize/pkg/plugins" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" "sigs.k8s.io/kustomize/pkg/transformers" @@ -43,17 +41,19 @@ import ( // KustTarget encapsulates the entirety of a kustomization build. type KustTarget struct { - kustomization *types.Kustomization - ldr ifc.Loader - rFactory *resmap.Factory - tFactory transformer.Factory + kustomization *types.Kustomization + ldr ifc.Loader + rFactory *resmap.Factory + tFactory transformer.Factory + goPluginEnabled bool } // NewKustTarget returns a new instance of KustTarget primed with a Loader. func NewKustTarget( ldr ifc.Loader, rFactory *resmap.Factory, - tFactory transformer.Factory) (*KustTarget, error) { + tFactory transformer.Factory, + b bool) (*KustTarget, error) { content, err := loadKustFile(ldr) if err != nil { return nil, err @@ -71,10 +71,11 @@ func NewKustTarget( strings.Join(errs, "\n"), ldr.Root()) } return &KustTarget{ - kustomization: &k, - ldr: ldr, - rFactory: rFactory, - tFactory: tFactory, + kustomization: &k, + ldr: ldr, + rFactory: rFactory, + tFactory: tFactory, + goPluginEnabled: b, }, nil } @@ -255,7 +256,7 @@ func (kt *KustTarget) accumulateBases() ( continue } subKt, err := NewKustTarget( - ldr, kt.rFactory, kt.tFactory) + ldr, kt.rFactory, kt.tFactory, kt.goPluginEnabled) if err != nil { errs.Append(errors.Wrap(err, "couldn't make target for "+path)) ldr.Cleanup() @@ -331,48 +332,11 @@ func (kt *KustTarget) newTransformer( } func (kt *KustTarget) loadTransformerPlugins() ([]transformers.Transformer, error) { - var result []transformers.Transformer - - pc := types.PluginConfig{ - DirectoryPath: os.Getenv("GOPATH"), - GoEnabled: true} - - root := filepath.Join( - pc.DirectoryPath, "src", "sigs.k8s.io", "kustomize", "plugins") - - if !pc.GoEnabled { - return nil, fmt.Errorf("plugins not enabled") - } - transformerPluginConfigs, err := kt.rFactory.FromFiles( kt.ldr, kt.kustomization.Transformers) - - for id, res := range transformerPluginConfigs { - fileName := filepath.Join(root, id.Gvk().Kind+".so") - goPlugin, err := plugin.Open(fileName) - if err != nil { - return nil, fmt.Errorf("plugin %s file not opened", fileName) - } - symbol, err := goPlugin.Lookup("Transformer") - if err != nil { - return nil, fmt.Errorf("plugin %s fails lookup", fileName) - } - c, ok := symbol.(transformers.Configurable) - if !ok { - return nil, fmt.Errorf("plugin %s not configurable", fileName) - } - err = c.Config(res) - if err != nil { - return nil, errors.Wrapf(err, "plugin %s fails configuration", fileName) - } - t, ok := c.(transformers.Transformer) - if !ok { - return nil, fmt.Errorf("plugin %s not a transformer", fileName) - } - - result = append(result, t) - fmt.Printf("Added plugin %s\n", fileName) - + if err != nil { + return nil, err } - return result, err + tl := plugins.NewTransformerLoader(kt.goPluginEnabled) + return tl.Load(transformerPluginConfigs) } diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index e57fe0f37..cde95b544 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -204,7 +204,7 @@ func TestResources(t *testing.T) { } func TestKustomizationNotFound(t *testing.T) { - _, err := NewKustTarget(loadertest.NewFakeLoader("/foo"), nil, nil) + _, err := NewKustTarget(loadertest.NewFakeLoader("/foo"), nil, nil, false) if err == nil { t.Fatalf("expected an error") } diff --git a/pkg/target/kusttestharness_test.go b/pkg/target/kusttestharness_test.go index ea3b712bd..70f997862 100644 --- a/pkg/target/kusttestharness_test.go +++ b/pkg/target/kusttestharness_test.go @@ -40,6 +40,7 @@ type KustTestHarness struct { t *testing.T rf *resmap.Factory ldr loadertest.FakeLoader + b bool } func NewKustTestHarness(t *testing.T, path string) *KustTestHarness { @@ -55,12 +56,13 @@ func NewKustTestHarnessWithPluginConfig( rf: resmap.NewFactory(resource.NewFactory( kunstruct.NewKunstructuredFactoryWithGeneratorArgs( &types.GeneratorMetaArgs{PluginConfig: config}))), - ldr: loadertest.NewFakeLoader(path)} + ldr: loadertest.NewFakeLoader(path), + b: config.GoEnabled} } func (th *KustTestHarness) makeKustTarget() *KustTarget { kt, err := NewKustTarget( - th.ldr, th.rf, transformer.NewFactoryImpl()) + th.ldr, th.rf, transformer.NewFactoryImpl(), th.b) if err != nil { th.t.Fatalf("Unexpected construction error %v", err) } diff --git a/pkg/target/transformerplugin_test.go b/pkg/target/transformerplugin_test.go index 9c050b0cf..1345d9cdf 100644 --- a/pkg/target/transformerplugin_test.go +++ b/pkg/target/transformerplugin_test.go @@ -14,8 +14,14 @@ limitations under the License. package target_test import ( - "sigs.k8s.io/kustomize/pkg/types" + "os" + "os/exec" + "path/filepath" "testing" + + "fmt" + "sigs.k8s.io/kustomize/pkg/pgmconfig" + "sigs.k8s.io/kustomize/pkg/types" ) func writeDeployment(th *KustTestHarness, path string) { @@ -55,7 +61,45 @@ metadata: `) } +func buildGoPlugins(dir, filename string) error { + commands := []string{ + "build", + "-buildmode", + "plugin", + "-tags=plugin", + "-o", + filename + ".so", + filename + ".go", + } + goBin := filepath.Join(os.Getenv("GOROOT"), "bin", "go") + if _, err := os.Stat(goBin); err != nil { + return fmt.Errorf("go binary not found %s", goBin) + } + cmd := exec.Command(goBin, commands...) + cmd.Env = os.Environ() + cmd.Dir = filepath.Join(dir, "kustomize", "plugins") + + return cmd.Run() +} + func TestOrderedTransformers(t *testing.T) { + dir, err := filepath.Abs("../../..") + if err != nil { + t.Errorf("unexpected error %v", err) + } + os.Setenv(pgmconfig.XDG_CONFIG_HOME, dir) + defer os.Unsetenv(pgmconfig.XDG_CONFIG_HOME) + + err = buildGoPlugins(dir, "StringPrefixer") + if err != nil { + t.Errorf("unexpected error %v", err) + } + + err = buildGoPlugins(dir, "DatePrefixer") + if err != nil { + t.Errorf("unexpected error %v", err) + } + th := NewKustTestHarnessWithPluginConfig( t, "/app", types.PluginConfig{GoEnabled: true}) th.writeK("/app", ` diff --git a/pkg/transformers/transformer.go b/pkg/transformers/transformer.go index 93288646c..fc0803fce 100644 --- a/pkg/transformers/transformer.go +++ b/pkg/transformers/transformer.go @@ -18,7 +18,6 @@ limitations under the License. package transformers import ( - "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/resmap" ) @@ -27,7 +26,3 @@ type Transformer interface { // Transform modifies data in the argument, e.g. adding labels to resources that can be labelled. Transform(m resmap.ResMap) error } - -type Configurable interface { - Config(k ifc.Kunstructured) error -} From 2cf8371add99861599dcf270ef9bb2007a71c9ea Mon Sep 17 00:00:00 2001 From: Alfonso Acosta Date: Fri, 5 Apr 2019 22:10:48 +0200 Subject: [PATCH 204/317] Add --force flag to modify annotations and labels This change adds a new flag (`--force`) to commands `edit add annotation` and `edit add label` so that annotations and labels are modified if they already existed. --- pkg/commands/edit/add/addmetadata.go | 9 ++- pkg/commands/edit/add/addmetadata_test.go | 68 +++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/pkg/commands/edit/add/addmetadata.go b/pkg/commands/edit/add/addmetadata.go index b4e14f34e..c129c1e6d 100644 --- a/pkg/commands/edit/add/addmetadata.go +++ b/pkg/commands/edit/add/addmetadata.go @@ -47,6 +47,7 @@ func (k kindOfAdd) String() string { } type addMetadataOptions struct { + force bool metadata map[string]string mapValidator func(map[string]string) error kind kindOfAdd @@ -66,6 +67,9 @@ func newCmdAddAnnotation(fSys fs.FileSystem, v func(map[string]string) error) *c return o.runE(args, fSys, o.addAnnotations) }, } + cmd.Flags().BoolVarP(&o.force, "force", "f", false, + "overwrite commonAnnotation if it already exists", + ) return cmd } @@ -83,6 +87,9 @@ func newCmdAddLabel(fSys fs.FileSystem, v func(map[string]string) error) *cobra. return o.runE(args, fSys, o.addLabels) }, } + cmd.Flags().BoolVarP(&o.force, "force", "f", false, + "overwrite commonLabel if it already exists", + ) return cmd } @@ -163,7 +170,7 @@ func (o *addMetadataOptions) addLabels(m *types.Kustomization) error { func (o *addMetadataOptions) writeToMap(m map[string]string, kind kindOfAdd) error { for k, v := range o.metadata { - if _, ok := m[k]; ok { + if _, ok := m[k]; ok && !o.force { return fmt.Errorf("%s %s already in kustomization file", kind, k) } m[k] = v diff --git a/pkg/commands/edit/add/addmetadata_test.go b/pkg/commands/edit/add/addmetadata_test.go index 6c7f0743a..289d2581f 100644 --- a/pkg/commands/edit/add/addmetadata_test.go +++ b/pkg/commands/edit/add/addmetadata_test.go @@ -187,6 +187,40 @@ func TestAddAnnotationMultipleArgs(t *testing.T) { } } +func TestAddAnnotationForce(t *testing.T) { + fakeFS := fs.MakeFakeFS() + fakeFS.WriteTestKustomization() + v := validators.MakeHappyMapValidator(t) + cmd := newCmdAddAnnotation(fakeFS, v.Validator) + args := []string{"key:foo"} + err := cmd.RunE(cmd, args) + v.VerifyCall() + if err != nil { + t.Errorf("unexpected error: %v", err.Error()) + } + // trying to add the same annotation again should not work + args = []string{"key:bar"} + v = validators.MakeHappyMapValidator(t) + cmd = newCmdAddAnnotation(fakeFS, v.Validator) + err = cmd.RunE(cmd, args) + v.VerifyCall() + if err == nil { + t.Errorf("expected an error") + } + if err.Error() != "annotation key already in kustomization file" { + t.Errorf("expected an error") + } + // but trying to add it with --force should + v = validators.MakeHappyMapValidator(t) + cmd = newCmdAddAnnotation(fakeFS, v.Validator) + cmd.Flag("force").Value.Set("true") + err = cmd.RunE(cmd, args) + v.VerifyCall() + if err != nil { + t.Errorf("unexpected error: %v", err.Error()) + } +} + func TestRunAddLabel(t *testing.T) { var o addMetadataOptions o.metadata = map[string]string{"owls": "cute", "otters": "adorable"} @@ -295,6 +329,40 @@ func TestAddLabelMultipleArgs(t *testing.T) { } } +func TestAddLabelForce(t *testing.T) { + fakeFS := fs.MakeFakeFS() + fakeFS.WriteTestKustomization() + v := validators.MakeHappyMapValidator(t) + cmd := newCmdAddLabel(fakeFS, v.Validator) + args := []string{"key:foo"} + err := cmd.RunE(cmd, args) + v.VerifyCall() + if err != nil { + t.Errorf("unexpected error: %v", err.Error()) + } + // trying to add the same label again should not work + args = []string{"key:bar"} + v = validators.MakeHappyMapValidator(t) + cmd = newCmdAddLabel(fakeFS, v.Validator) + err = cmd.RunE(cmd, args) + v.VerifyCall() + if err == nil { + t.Errorf("expected an error") + } + if err.Error() != "label key already in kustomization file" { + t.Errorf("expected an error") + } + // but trying to add it with --force should + v = validators.MakeHappyMapValidator(t) + cmd = newCmdAddLabel(fakeFS, v.Validator) + cmd.Flag("force").Value.Set("true") + err = cmd.RunE(cmd, args) + v.VerifyCall() + if err != nil { + t.Errorf("unexpected error: %v", err.Error()) + } +} + func TestConvertToMap(t *testing.T) { var o addMetadataOptions args := "a:b,c:\"d\",e:\"f:g\",g:h:k" From 749373217633e53b29d5d095aa0c73d102230eff Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Fri, 5 Apr 2019 13:51:56 -0700 Subject: [PATCH 205/317] add generator plugins --- pkg/plugins/generators.go | 98 ++++++++++++++++++++++++++++++ pkg/target/generatorplugin_test.go | 73 ++++++++++++++++++++++ pkg/target/kusttarget.go | 23 ++++++- plugins/ServiceGenerator.go | 57 +++++++++++++++++ 4 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 pkg/plugins/generators.go create mode 100644 pkg/target/generatorplugin_test.go create mode 100644 plugins/ServiceGenerator.go diff --git a/pkg/plugins/generators.go b/pkg/plugins/generators.go new file mode 100644 index 000000000..ab704b0ac --- /dev/null +++ b/pkg/plugins/generators.go @@ -0,0 +1,98 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package plugins + +import ( + "fmt" + "path/filepath" + "plugin" + + "github.com/pkg/errors" + "sigs.k8s.io/kustomize/pkg/pgmconfig" + "sigs.k8s.io/kustomize/pkg/resid" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/resource" +) + +const generatorSymbol = "Generator" + +type Generatable interface { + Generate() (resmap.ResMap, error) +} + +type generatorLoader struct { + pluginDir string + enabled bool + rf *resmap.Factory +} + +func NewGeneratorLoader(b bool, f *resmap.Factory) generatorLoader { + return generatorLoader{ + pluginDir: filepath.Join(pgmconfig.ConfigRoot(), pgmconfig.PluginsDir), + enabled: b, + rf: f, + } +} + +func (l generatorLoader) Load(rm resmap.ResMap) (resmap.ResMap, error) { + if len(rm) == 0 { + return nil, nil + } + if !l.enabled { + return nil, fmt.Errorf("plugin is not enabled") + } + var result resmap.ResMap + for id, res := range rm { + r, err := l.load(id, res) + if err != nil { + return nil, err + } + result, err = resmap.MergeWithErrorOnIdCollision(result, r) + if err != nil { + return nil, err + } + } + return result, nil +} + +func (l generatorLoader) load(id resid.ResId, res *resource.Resource) (resmap.ResMap, error) { + fileName := filepath.Join(l.pluginDir, id.Gvk().Kind+".so") + goPlugin, err := plugin.Open(fileName) + if err != nil { + return nil, fmt.Errorf("plugin %s file not opened", fileName) + } + + symbol, err := goPlugin.Lookup(generatorSymbol) + if err != nil { + return nil, fmt.Errorf("plugin %s fails lookup", fileName) + } + + c, ok := symbol.(Configurable) + if !ok { + return nil, fmt.Errorf("plugin %s not configurable", fileName) + } + err = c.Config(res) + if err != nil { + return nil, errors.Wrapf(err, "plugin %s fails configuration", fileName) + } + + g, ok := c.(Generatable) + if !ok { + return nil, fmt.Errorf("plugin %s not a transformer", fileName) + } + return g.Generate() +} diff --git a/pkg/target/generatorplugin_test.go b/pkg/target/generatorplugin_test.go new file mode 100644 index 000000000..23bd47f15 --- /dev/null +++ b/pkg/target/generatorplugin_test.go @@ -0,0 +1,73 @@ +/* +Copyright 2019 The Kubernetes Authors. + Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target_test + +import ( + "os" + "path/filepath" + "testing" + + "sigs.k8s.io/kustomize/pkg/pgmconfig" + "sigs.k8s.io/kustomize/pkg/types" +) + +func writeGenerator(th *KustTestHarness, path string) { + th.writeF(path, ` +apiVersion: strings.microwoosh.com/v1 +kind: ServiceGenerator +metadata: + name: myServiceGenerator +service: my-service +port: "12345" +`) +} + +func TestGeneratorPlugin(t *testing.T) { + dir, err := filepath.Abs("../../..") + if err != nil { + t.Errorf("unexpected error %v", err) + } + os.Setenv(pgmconfig.XDG_CONFIG_HOME, dir) + defer os.Unsetenv(pgmconfig.XDG_CONFIG_HOME) + + err = buildGoPlugins(dir, "ServiceGenerator") + if err != nil { + t.Errorf("unexpected error %v", err) + } + + th := NewKustTestHarnessWithPluginConfig( + t, "/app", types.PluginConfig{GoEnabled: true}) + th.writeK("/app", ` +generators: +- serviceGenerator.yaml +`) + writeGenerator(th, "/app/serviceGenerator.yaml") + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +kind: Service +metadata: + labels: + app: dev + name: my-service +spec: + ports: + - port: 12345 + selector: + app: dev +`) +} diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 3dfb02adb..4cdf24ac0 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -155,7 +155,7 @@ func (kt *KustTarget) shouldAddHashSuffixesToGeneratedResources() bool { // holding customized resources and the data/rules used // to do so. The name back references and vars are // not yet fixed. -func (kt *KustTarget) AccumulateTarget() ( +func (kt *KustTarget) AccumulateTarget() ( // nolint: gocyclo ra *accumulator.ResAccumulator, err error) { // TODO(monopole): Get rid of the KustomizationErrors accumulator. // It's not consistently used, and complicates tests. @@ -173,6 +173,17 @@ func (kt *KustTarget) AccumulateTarget() ( if err != nil { errs.Append(errors.Wrap(err, "MergeResourcesWithErrorOnIdCollision")) } + resourceFromGenerators, err := kt.loadGeneratorPlugins() + if err != nil { + errs.Append(errors.Wrap(err, "failed to load resources from generators")) + } + if len(errs.Get()) > 0 { + return ra, errs + } + err = ra.MergeResourcesWithErrorOnIdCollision(resourceFromGenerators) + if err != nil { + errs.Append(errors.Wrap(err, "MergeResourcesWithErrorOnIdCollision")) + } tConfig, err := config.MakeTransformerConfig( kt.ldr, kt.kustomization.Configurations) if err != nil { @@ -340,3 +351,13 @@ func (kt *KustTarget) loadTransformerPlugins() ([]transformers.Transformer, erro tl := plugins.NewTransformerLoader(kt.goPluginEnabled) return tl.Load(transformerPluginConfigs) } + +func (kt *KustTarget) loadGeneratorPlugins() (resmap.ResMap, error) { + generatorPluginConfigs, err := kt.rFactory.FromFiles( + kt.ldr, kt.kustomization.Generators) + if err != nil { + return nil, err + } + gl := plugins.NewGeneratorLoader(kt.goPluginEnabled, kt.rFactory) + return gl.Load(generatorPluginConfigs) +} diff --git a/plugins/ServiceGenerator.go b/plugins/ServiceGenerator.go new file mode 100644 index 000000000..4367daa5e --- /dev/null +++ b/plugins/ServiceGenerator.go @@ -0,0 +1,57 @@ +package main + +import ( + "bytes" + "text/template" + + "sigs.k8s.io/kustomize/k8sdeps/kunstruct" + "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/resource" +) + +type plugin struct { + ServiceName string + Port string +} + +var Generator plugin + +var manifest = ` +apiVersion: v1 +kind: Service +metadata: + labels: + app: dev + name: {{.ServiceName}} +spec: + ports: + - port: {{.Port}} + selector: + app: dev +` + +func (p *plugin) Config(k ifc.Kunstructured) error { + var err error + p.ServiceName, err = k.GetFieldValue("service") + if err != nil { + return err + } + p.Port, err = k.GetFieldValue("port") + if err != nil { + return err + } + return nil +} + +func (p *plugin) Generate() (resmap.ResMap, error) { + var buf bytes.Buffer + + temp := template.Must(template.New("manifest").Parse(manifest)) + err := temp.Execute(&buf, p) + if err != nil { + return nil, err + } + rf := resmap.NewFactory(resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())) + return rf.NewResMapFromBytes(buf.Bytes()) +} From 16fe7ced6a191c10546f5835929ac9888deb5fd2 Mon Sep 17 00:00:00 2001 From: jregan Date: Fri, 5 Apr 2019 12:06:48 -0700 Subject: [PATCH 206/317] Cleanup plugin builds. --- k8sdeps/configmapandsecret/basefactory.go | 16 +- .../configmapandsecret/basefactory_test.go | 8 +- k8sdeps/kunstruct/factory.go | 4 +- k8sdeps/kv/plugin/registry.go | 12 +- pkg/commands/build/build.go | 9 +- pkg/commands/commands.go | 15 +- pkg/pgmconfig/constants.go | 4 +- pkg/plugins/transformers.go | 28 ++- pkg/target/generatoroptions_test.go | 5 +- pkg/target/kusttarget.go | 37 ++-- pkg/target/kusttarget_test.go | 5 +- pkg/target/kusttestharness_test.go | 12 +- pkg/target/testenvcontroller_test.go | 165 ++++++++++++++++++ pkg/target/transformerplugin_test.go | 56 ++---- pkg/types/kustomization.go | 2 +- .../v1}/DatePrefixer.go | 0 .../v1}/StringPrefixer.go | 0 .../{ => someteam.example.com/v1}/kvMaker.go | 0 18 files changed, 267 insertions(+), 111 deletions(-) create mode 100644 pkg/target/testenvcontroller_test.go rename plugins/{ => someteam.example.com/v1}/DatePrefixer.go (100%) rename plugins/{ => someteam.example.com/v1}/StringPrefixer.go (100%) rename plugins/{ => someteam.example.com/v1}/kvMaker.go (100%) diff --git a/k8sdeps/configmapandsecret/basefactory.go b/k8sdeps/configmapandsecret/basefactory.go index 7bd88836a..8e0d767f1 100644 --- a/k8sdeps/configmapandsecret/basefactory.go +++ b/k8sdeps/configmapandsecret/basefactory.go @@ -18,6 +18,7 @@ package configmapandsecret import ( "fmt" + "sort" "strings" "github.com/pkg/errors" @@ -101,13 +102,24 @@ func (bf baseFactory) keyValuesFromPlugins(sources []types.KVSource) ([]kv.Pair, if err != nil { return nil, err } - for k, v := range kvs { - result = append(result, kv.Pair{Key: k, Value: v}) + for _, k := range sortedKeys(kvs) { + result = append(result, kv.Pair{Key: k, Value: kvs[k]}) } } return result, nil } +func sortedKeys(m map[string]string) []string { + keys := make([]string, len(m)) + i := 0 + for k := range m { + keys[i] = k + i++ + } + sort.Strings(keys) + return keys +} + func (bf baseFactory) keyValuesFromFileSources(sources []string) ([]kv.Pair, error) { var kvs []kv.Pair for _, s := range sources { diff --git a/k8sdeps/configmapandsecret/basefactory_test.go b/k8sdeps/configmapandsecret/basefactory_test.go index 75d5eda9e..eca544f06 100644 --- a/k8sdeps/configmapandsecret/basefactory_test.go +++ b/k8sdeps/configmapandsecret/basefactory_test.go @@ -77,14 +77,14 @@ func TestKeyValuesFromPlugins(t *testing.T) { }, }, expected: []kv.Pair{ - { - Key: "FOO", - Value: "bar", - }, { Key: "BAR", Value: "baz", }, + { + Key: "FOO", + Value: "bar", + }, }, }, { diff --git a/k8sdeps/kunstruct/factory.go b/k8sdeps/kunstruct/factory.go index ef40209b9..4cd945932 100644 --- a/k8sdeps/kunstruct/factory.go +++ b/k8sdeps/kunstruct/factory.go @@ -93,7 +93,7 @@ func (kf *KunstructuredFactoryImpl) MakeConfigMap( o, err := configmapandsecret.NewFactory( ldr, options, plugin.NewConfiguredRegistry( - ldr, &kf.generatorMetaArgs.PluginConfig)).MakeConfigMap(args) + ldr, kf.generatorMetaArgs.PluginConfig)).MakeConfigMap(args) if err != nil { return nil, err } @@ -108,7 +108,7 @@ func (kf *KunstructuredFactoryImpl) MakeSecret( o, err := configmapandsecret.NewFactory( ldr, options, plugin.NewConfiguredRegistry( - ldr, &kf.generatorMetaArgs.PluginConfig)).MakeSecret(args) + ldr, kf.generatorMetaArgs.PluginConfig)).MakeSecret(args) if err != nil { return nil, err } diff --git a/k8sdeps/kv/plugin/registry.go b/k8sdeps/kv/plugin/registry.go index f505a3766..6d4f407cc 100644 --- a/k8sdeps/kv/plugin/registry.go +++ b/k8sdeps/kv/plugin/registry.go @@ -19,6 +19,7 @@ package plugin import ( "fmt" "path/filepath" + "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/pgmconfig" "sigs.k8s.io/kustomize/pkg/types" @@ -31,13 +32,20 @@ type Registry struct { } const ( + TransformerSymbol = "Transformer" PluginsDir = "plugins" pluginTypeGo = types.PluginType("go") pluginTypeBuiltIn = types.PluginType("builtin") ) -func DefaultPluginConfig() types.PluginConfig { - return types.PluginConfig{ +func ActivePluginConfig() *types.PluginConfig { + pc := DefaultPluginConfig() + pc.GoEnabled = true + return pc +} + +func DefaultPluginConfig() *types.PluginConfig { + return &types.PluginConfig{ GoEnabled: false, DirectoryPath: filepath.Join( pgmconfig.ConfigRoot(), PluginsDir), diff --git a/pkg/commands/build/build.go b/pkg/commands/build/build.go index cf4945d32..2267f61f5 100644 --- a/pkg/commands/build/build.go +++ b/pkg/commands/build/build.go @@ -27,6 +27,7 @@ import ( "sigs.k8s.io/kustomize/pkg/pgmconfig" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/target" + "sigs.k8s.io/kustomize/pkg/types" ) // Options contain the options for running a build @@ -63,7 +64,7 @@ func NewCmdBuild( out io.Writer, fs fs.FileSystem, rf *resmap.Factory, ptf transformer.Factory, - b bool) *cobra.Command { + pc *types.PluginConfig) *cobra.Command { var o Options cmd := &cobra.Command{ @@ -76,7 +77,7 @@ func NewCmdBuild( if err != nil { return err } - return o.RunBuild(out, fs, rf, ptf, b) + return o.RunBuild(out, fs, rf, ptf, pc) }, } cmd.Flags().StringVarP( @@ -104,13 +105,13 @@ func (o *Options) Validate(args []string) error { func (o *Options) RunBuild( out io.Writer, fSys fs.FileSystem, rf *resmap.Factory, ptf transformer.Factory, - b bool) error { + pc *types.PluginConfig) error { ldr, err := loader.NewLoader(o.kustomizationPath, fSys) if err != nil { return err } defer ldr.Cleanup() - kt, err := target.NewKustTarget(ldr, rf, ptf, b) + kt, err := target.NewKustTarget(ldr, rf, ptf, pc) if err != nil { return err } diff --git a/pkg/commands/commands.go b/pkg/commands/commands.go index d327bd230..33e18683b 100644 --- a/pkg/commands/commands.go +++ b/pkg/commands/commands.go @@ -20,7 +20,6 @@ package commands import ( "flag" "os" - "sigs.k8s.io/kustomize/pkg/pgmconfig" "github.com/spf13/cobra" "sigs.k8s.io/kustomize/k8sdeps/kunstruct" @@ -31,6 +30,7 @@ import ( "sigs.k8s.io/kustomize/pkg/commands/edit" "sigs.k8s.io/kustomize/pkg/commands/misc" "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/pkg/pgmconfig" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" "sigs.k8s.io/kustomize/pkg/types" @@ -50,25 +50,26 @@ See https://sigs.k8s.io/kustomize `, } - // Configuration for ConfigMap and Secret generators. - genMetaArgs := types.GeneratorMetaArgs{ - PluginConfig: plugin.DefaultPluginConfig(), - } + pluginConfig := plugin.DefaultPluginConfig() c.PersistentFlags().BoolVar( - &genMetaArgs.PluginConfig.GoEnabled, + &pluginConfig.GoEnabled, plugin.EnableGoPluginsFlagName, false, plugin.EnableGoPluginsFlagHelp) // Not advertising this alpha feature. c.PersistentFlags().MarkHidden(plugin.EnableGoPluginsFlagName) + // Configuration for ConfigMap and Secret generators. + genMetaArgs := types.GeneratorMetaArgs{ + PluginConfig: pluginConfig, + } uf := kunstruct.NewKunstructuredFactoryWithGeneratorArgs(&genMetaArgs) c.AddCommand( build.NewCmdBuild( stdOut, fSys, resmap.NewFactory(resource.NewFactory(uf)), - transformer.NewFactoryImpl(), genMetaArgs.PluginConfig.GoEnabled), + transformer.NewFactoryImpl(), pluginConfig), edit.NewCmdEdit(fSys, validator.NewKustValidator(), uf), misc.NewCmdConfig(fSys), misc.NewCmdVersion(stdOut), diff --git a/pkg/pgmconfig/constants.go b/pkg/pgmconfig/constants.go index 8418a75ce..2aecd4fbf 100644 --- a/pkg/pgmconfig/constants.go +++ b/pkg/pgmconfig/constants.go @@ -28,6 +28,6 @@ var KustomizationFileNames = []string{ } const ( - PgmName = "kustomize" - PluginsDir = "plugins" + PgmName = "kustomize" + Repo = "sigs.k8s.io" ) diff --git a/pkg/plugins/transformers.go b/pkg/plugins/transformers.go index aae6895be..de962acc5 100644 --- a/pkg/plugins/transformers.go +++ b/pkg/plugins/transformers.go @@ -22,38 +22,33 @@ import ( "plugin" "github.com/pkg/errors" + kplugin "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" "sigs.k8s.io/kustomize/pkg/ifc" - "sigs.k8s.io/kustomize/pkg/pgmconfig" "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resource" "sigs.k8s.io/kustomize/pkg/transformers" + "sigs.k8s.io/kustomize/pkg/types" ) -const transformerSymbol = "Transformer" - type Configurable interface { Config(k ifc.Kunstructured) error } type transformerLoader struct { - pluginDir string - enabled bool + pc *types.PluginConfig } -func NewTransformerLoader(b bool) transformerLoader { - return transformerLoader{ - pluginDir: filepath.Join(pgmconfig.ConfigRoot(), pgmconfig.PluginsDir), - enabled: b, - } +func NewTransformerLoader(pc *types.PluginConfig) transformerLoader { + return transformerLoader{pc: pc} } func (l transformerLoader) Load(rm resmap.ResMap) ([]transformers.Transformer, error) { if len(rm) == 0 { return nil, nil } - if !l.enabled { - return nil, fmt.Errorf("plugin is not enabled") + if !l.pc.GoEnabled { + return nil, fmt.Errorf("plugins not enabled") } var result []transformers.Transformer for id, res := range rm { @@ -66,14 +61,17 @@ func (l transformerLoader) Load(rm resmap.ResMap) ([]transformers.Transformer, e return result, nil } -func (l transformerLoader) load(id resid.ResId, res *resource.Resource) (transformers.Transformer, error) { - fileName := filepath.Join(l.pluginDir, id.Gvk().Kind+".so") +func (l transformerLoader) load( + id resid.ResId, res *resource.Resource) (transformers.Transformer, error) { + fileName := filepath.Join( + l.pc.DirectoryPath, + id.Gvk().Group, id.Gvk().Version, id.Gvk().Kind+".so") goPlugin, err := plugin.Open(fileName) if err != nil { return nil, fmt.Errorf("plugin %s file not opened", fileName) } - symbol, err := goPlugin.Lookup(transformerSymbol) + symbol, err := goPlugin.Lookup(kplugin.TransformerSymbol) if err != nil { return nil, fmt.Errorf("plugin %s fails lookup", fileName) } diff --git a/pkg/target/generatoroptions_test.go b/pkg/target/generatoroptions_test.go index fc1bd792e..d1b9e9006 100644 --- a/pkg/target/generatoroptions_test.go +++ b/pkg/target/generatoroptions_test.go @@ -15,9 +15,10 @@ package target_test import ( "path/filepath" - "sigs.k8s.io/kustomize/pkg/types" "strings" "testing" + + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" ) func TestGeneratorOptionsWithBases(t *testing.T) { @@ -96,7 +97,7 @@ secretGenerator: func TestGoPluginDoesNotExist(t *testing.T) { th := NewKustTestHarnessWithPluginConfig( - t, "/app", types.PluginConfig{GoEnabled: true}) + t, "/app", plugin.ActivePluginConfig()) th.writeK("/app", ` secretGenerator: - name: attemptGoPlugin diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 3dfb02adb..3ed6599f7 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -41,11 +41,11 @@ import ( // KustTarget encapsulates the entirety of a kustomization build. type KustTarget struct { - kustomization *types.Kustomization - ldr ifc.Loader - rFactory *resmap.Factory - tFactory transformer.Factory - goPluginEnabled bool + kustomization *types.Kustomization + ldr ifc.Loader + rFactory *resmap.Factory + tFactory transformer.Factory + pluginConfig *types.PluginConfig } // NewKustTarget returns a new instance of KustTarget primed with a Loader. @@ -53,7 +53,7 @@ func NewKustTarget( ldr ifc.Loader, rFactory *resmap.Factory, tFactory transformer.Factory, - b bool) (*KustTarget, error) { + pc *types.PluginConfig) (*KustTarget, error) { content, err := loadKustFile(ldr) if err != nil { return nil, err @@ -71,11 +71,11 @@ func NewKustTarget( strings.Join(errs, "\n"), ldr.Root()) } return &KustTarget{ - kustomization: &k, - ldr: ldr, - rFactory: rFactory, - tFactory: tFactory, - goPluginEnabled: b, + kustomization: &k, + ldr: ldr, + rFactory: rFactory, + tFactory: tFactory, + pluginConfig: pc, }, nil } @@ -256,7 +256,7 @@ func (kt *KustTarget) accumulateBases() ( continue } subKt, err := NewKustTarget( - ldr, kt.rFactory, kt.tFactory, kt.goPluginEnabled) + ldr, kt.rFactory, kt.tFactory, kt.pluginConfig) if err != nil { errs.Append(errors.Wrap(err, "couldn't make target for "+path)) ldr.Cleanup() @@ -323,11 +323,13 @@ func (kt *KustTarget) newTransformer( } r = append(r, t) - tp, err := kt.loadTransformerPlugins() - if err != nil { - return nil, err + if kt.pluginConfig.GoEnabled { + tp, err := kt.loadTransformerPlugins() + if err != nil { + return nil, err + } + r = append(r, tp...) } - r = append(r, tp...) return transformers.NewMultiTransformer(r), nil } @@ -337,6 +339,5 @@ func (kt *KustTarget) loadTransformerPlugins() ([]transformers.Transformer, erro if err != nil { return nil, err } - tl := plugins.NewTransformerLoader(kt.goPluginEnabled) - return tl.Load(transformerPluginConfigs) + return plugins.NewTransformerLoader(kt.pluginConfig).Load(transformerPluginConfigs) } diff --git a/pkg/target/kusttarget_test.go b/pkg/target/kusttarget_test.go index cde95b544..8770b4117 100644 --- a/pkg/target/kusttarget_test.go +++ b/pkg/target/kusttarget_test.go @@ -23,6 +23,7 @@ import ( "strings" "testing" + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" "sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/internal/loadertest" @@ -204,7 +205,9 @@ func TestResources(t *testing.T) { } func TestKustomizationNotFound(t *testing.T) { - _, err := NewKustTarget(loadertest.NewFakeLoader("/foo"), nil, nil, false) + _, err := NewKustTarget( + loadertest.NewFakeLoader("/foo"), + nil, nil, plugin.DefaultPluginConfig()) if err == nil { t.Fatalf("expected an error") } diff --git a/pkg/target/kusttestharness_test.go b/pkg/target/kusttestharness_test.go index 70f997862..d7a760d88 100644 --- a/pkg/target/kusttestharness_test.go +++ b/pkg/target/kusttestharness_test.go @@ -21,11 +21,11 @@ package target_test import ( "fmt" "path/filepath" - "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" "strings" "testing" "sigs.k8s.io/kustomize/k8sdeps/kunstruct" + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" "sigs.k8s.io/kustomize/k8sdeps/transformer" "sigs.k8s.io/kustomize/pkg/internal/loadertest" "sigs.k8s.io/kustomize/pkg/pgmconfig" @@ -40,7 +40,7 @@ type KustTestHarness struct { t *testing.T rf *resmap.Factory ldr loadertest.FakeLoader - b bool + pc *types.PluginConfig } func NewKustTestHarness(t *testing.T, path string) *KustTestHarness { @@ -50,19 +50,19 @@ func NewKustTestHarness(t *testing.T, path string) *KustTestHarness { func NewKustTestHarnessWithPluginConfig( t *testing.T, path string, - config types.PluginConfig) *KustTestHarness { + pc *types.PluginConfig) *KustTestHarness { return &KustTestHarness{ t: t, rf: resmap.NewFactory(resource.NewFactory( kunstruct.NewKunstructuredFactoryWithGeneratorArgs( - &types.GeneratorMetaArgs{PluginConfig: config}))), + &types.GeneratorMetaArgs{PluginConfig: pc}))), ldr: loadertest.NewFakeLoader(path), - b: config.GoEnabled} + pc: pc} } func (th *KustTestHarness) makeKustTarget() *KustTarget { kt, err := NewKustTarget( - th.ldr, th.rf, transformer.NewFactoryImpl(), th.b) + th.ldr, th.rf, transformer.NewFactoryImpl(), th.pc) if err != nil { th.t.Fatalf("Unexpected construction error %v", err) } diff --git a/pkg/target/testenvcontroller_test.go b/pkg/target/testenvcontroller_test.go new file mode 100644 index 000000000..37d8dd223 --- /dev/null +++ b/pkg/target/testenvcontroller_test.go @@ -0,0 +1,165 @@ +/* +Copyright 2019 The Kubernetes Authors. + Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target_test + +import ( + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "testing" + "time" + + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" + "sigs.k8s.io/kustomize/pkg/pgmconfig" +) + +// TestEnvController manages the KustTarget test environment. +// It sets/resets XDG_CONFIG_HOME, makes/removes a temp objRoot. +type TestEnvController struct { + t *testing.T + xdgConfigHome string + oldXdg string + wasSet bool +} + +func NewTestEnvController(t *testing.T) *TestEnvController { + return &TestEnvController{t: t} +} + +func (x *TestEnvController) Set() *TestEnvController { + x.makeTmpConfigHomeDir() + x.makeObjectRootDir() + x.setEnv() + return x +} + +func (x *TestEnvController) Reset() { + x.resetEnv() + x.removeTmpConfigHomeDir() +} + +func (x *TestEnvController) fileExists(name string) bool { + if _, err := os.Stat(name); err != nil { + if os.IsNotExist(err) { + return false + } + } + return true +} + +func (x *TestEnvController) recentFileExists(path string) bool { + fi, err := os.Stat(path) + if err != nil { + if os.IsNotExist(err) { + return false + } + } + age := time.Now().Sub(fi.ModTime()) + return age.Minutes() < 1 +} + +func (x *TestEnvController) BuildGoPlugin(plugin ...string) { + obj := filepath.Join( + append([]string{x.ObjectRoot()}, plugin...)...) + ".so" + if x.recentFileExists(obj) { + // Skip rebuilding it. + return + } + src := filepath.Join( + append([]string{x.SrcRoot()}, plugin...)...) + ".go" + if !x.fileExists(src) { + x.t.Errorf("cannot find go plugin source %s", src) + } + commands := []string{ + "build", + "-buildmode", + "plugin", + "-tags=plugin", + "-o", obj, src, + } + goBin := filepath.Join(os.Getenv("GOROOT"), "bin", "go") + if !x.fileExists(src) { + x.t.Errorf("cannot find go compiler %s", goBin) + } + cmd := exec.Command(goBin, commands...) + cmd.Env = os.Environ() + // cmd.Dir = filepath.Join(dir, "kustomize", "plugins") + + if err := cmd.Run(); err != nil { + x.t.Errorf("compiler error building %s: %v", src, err) + } +} + +// ObjectRoot is the objRoot dir for plugin object files. +func (x *TestEnvController) ObjectRoot() string { + return filepath.Join( + x.xdgConfigHome, pgmconfig.PgmName, plugin.PluginsDir) +} + +// SrcRoot is a objRoot directory for plugin source code +// used by tests. +// +// Plugin object code files have to be in a particular +// location to be found and loaded for security reasons, +// but placement of plugin source code is up to the user. +// +// This function returns a location for storing example +// plugins for tests. And maybe builtins at some point. +func (x *TestEnvController) SrcRoot() string { + dir := filepath.Join( + os.Getenv("GOPATH"), "src", + pgmconfig.Repo, pgmconfig.PgmName, plugin.PluginsDir) + if _, err := os.Stat(dir); err != nil { + x.t.Errorf("plugin source objRoot '%s' not found", dir) + } + return dir +} + +func (x *TestEnvController) makeTmpConfigHomeDir() { + var err error + x.xdgConfigHome, err = ioutil.TempDir("", "kustomizetests") + if err != nil { + x.t.Errorf("failed to make temp objRoot: %v", err) + } +} + +func (x *TestEnvController) makeObjectRootDir() { + err := os.MkdirAll(x.ObjectRoot(), os.ModePerm) + if err != nil { + x.t.Errorf( + "making temp object objRoot %s: %v", x.ObjectRoot(), err) + } +} + +func (x *TestEnvController) removeTmpConfigHomeDir() { + err := os.RemoveAll(x.xdgConfigHome) + if err != nil { + x.t.Errorf( + "removing temp object objRoot: %s %v", x.xdgConfigHome, err) + } +} + +func (x *TestEnvController) setEnv() { + x.oldXdg, x.wasSet = os.LookupEnv(pgmconfig.XDG_CONFIG_HOME) + os.Setenv(pgmconfig.XDG_CONFIG_HOME, x.xdgConfigHome) +} + +func (x *TestEnvController) resetEnv() { + if x.wasSet { + os.Setenv(pgmconfig.XDG_CONFIG_HOME, x.oldXdg) + } else { + os.Unsetenv(pgmconfig.XDG_CONFIG_HOME) + } +} diff --git a/pkg/target/transformerplugin_test.go b/pkg/target/transformerplugin_test.go index 1345d9cdf..84a6bf227 100644 --- a/pkg/target/transformerplugin_test.go +++ b/pkg/target/transformerplugin_test.go @@ -14,14 +14,9 @@ limitations under the License. package target_test import ( - "os" - "os/exec" - "path/filepath" "testing" - "fmt" - "sigs.k8s.io/kustomize/pkg/pgmconfig" - "sigs.k8s.io/kustomize/pkg/types" + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" ) func writeDeployment(th *KustTestHarness, path string) { @@ -44,7 +39,7 @@ spec: func writeStringPrefixer(th *KustTestHarness, path string) { th.writeF(path, ` -apiVersion: strings.microwoosh.com/v1 +apiVersion: someteam.example.com/v1 kind: StringPrefixer metadata: name: myStringPrefixer @@ -54,54 +49,25 @@ prefix: apple- func writeDatePrefixer(th *KustTestHarness, path string) { th.writeF(path, ` -apiVersion: team.dater.com/v1 +apiVersion: someteam.example.com/v1 kind: DatePrefixer metadata: name: myDatePrefixer `) } -func buildGoPlugins(dir, filename string) error { - commands := []string{ - "build", - "-buildmode", - "plugin", - "-tags=plugin", - "-o", - filename + ".so", - filename + ".go", - } - goBin := filepath.Join(os.Getenv("GOROOT"), "bin", "go") - if _, err := os.Stat(goBin); err != nil { - return fmt.Errorf("go binary not found %s", goBin) - } - cmd := exec.Command(goBin, commands...) - cmd.Env = os.Environ() - cmd.Dir = filepath.Join(dir, "kustomize", "plugins") - - return cmd.Run() -} - func TestOrderedTransformers(t *testing.T) { - dir, err := filepath.Abs("../../..") - if err != nil { - t.Errorf("unexpected error %v", err) - } - os.Setenv(pgmconfig.XDG_CONFIG_HOME, dir) - defer os.Unsetenv(pgmconfig.XDG_CONFIG_HOME) + tc := NewTestEnvController(t).Set() + defer tc.Reset() - err = buildGoPlugins(dir, "StringPrefixer") - if err != nil { - t.Errorf("unexpected error %v", err) - } + tc.BuildGoPlugin( + "someteam.example.com", "v1", "StringPrefixer") - err = buildGoPlugins(dir, "DatePrefixer") - if err != nil { - t.Errorf("unexpected error %v", err) - } + tc.BuildGoPlugin( + "someteam.example.com", "v1", "DatePrefixer") th := NewKustTestHarnessWithPluginConfig( - t, "/app", types.PluginConfig{GoEnabled: true}) + t, "/app", plugin.ActivePluginConfig()) th.writeK("/app", ` resources: - deployment.yaml @@ -134,7 +100,7 @@ spec: func xTestTransformedTransformers(t *testing.T) { th := NewKustTestHarnessWithPluginConfig( - t, "/app/overlay", types.PluginConfig{GoEnabled: true}) + t, "/app/overlay", plugin.ActivePluginConfig()) th.writeK("/app/base", ` resources: diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 68d3a8e36..0cbbc0f42 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -203,7 +203,7 @@ type GeneratorArgs struct { // GeneratorMetaArgs contains arguments common to generators // that come from somewhere other than a kustomization file. type GeneratorMetaArgs struct { - PluginConfig PluginConfig + PluginConfig *PluginConfig } // PluginConfig holds plugin configuration. diff --git a/plugins/DatePrefixer.go b/plugins/someteam.example.com/v1/DatePrefixer.go similarity index 100% rename from plugins/DatePrefixer.go rename to plugins/someteam.example.com/v1/DatePrefixer.go diff --git a/plugins/StringPrefixer.go b/plugins/someteam.example.com/v1/StringPrefixer.go similarity index 100% rename from plugins/StringPrefixer.go rename to plugins/someteam.example.com/v1/StringPrefixer.go diff --git a/plugins/kvMaker.go b/plugins/someteam.example.com/v1/kvMaker.go similarity index 100% rename from plugins/kvMaker.go rename to plugins/someteam.example.com/v1/kvMaker.go From b32e041bfe546f175e4f017a3e739798eda38b81 Mon Sep 17 00:00:00 2001 From: jregan Date: Sat, 6 Apr 2019 16:04:04 -0700 Subject: [PATCH 207/317] Remove some duped code. --- k8sdeps/kv/plugin/registry.go | 6 +- pkg/plugins/generators.go | 73 ++++--------------- pkg/plugins/transformers.go | 35 +++++---- pkg/target/generatorplugin_test.go | 23 ++---- pkg/target/kusttarget.go | 48 +++++++----- pkg/target/testenvcontroller_test.go | 4 +- pkg/transformers/transformer.go | 5 ++ .../someteam.example.com/v1/DatePrefixer.go | 2 +- .../v1}/ServiceGenerator.go | 4 +- .../someteam.example.com/v1/StringPrefixer.go | 4 +- plugins/someteam.example.com/v1/kvMaker.go | 31 ++++---- 11 files changed, 106 insertions(+), 129 deletions(-) rename plugins/{ => someteam.example.com/v1}/ServiceGenerator.go (95%) diff --git a/k8sdeps/kv/plugin/registry.go b/k8sdeps/kv/plugin/registry.go index 6d4f407cc..342692725 100644 --- a/k8sdeps/kv/plugin/registry.go +++ b/k8sdeps/kv/plugin/registry.go @@ -32,8 +32,8 @@ type Registry struct { } const ( - TransformerSymbol = "Transformer" - PluginsDir = "plugins" + PluginSymbol = "KustomizePlugin" + PluginRoot = "plugins" pluginTypeGo = types.PluginType("go") pluginTypeBuiltIn = types.PluginType("builtin") ) @@ -48,7 +48,7 @@ func DefaultPluginConfig() *types.PluginConfig { return &types.PluginConfig{ GoEnabled: false, DirectoryPath: filepath.Join( - pgmconfig.ConfigRoot(), PluginsDir), + pgmconfig.ConfigRoot(), PluginRoot), } } diff --git a/pkg/plugins/generators.go b/pkg/plugins/generators.go index ab704b0ac..45c23e2e8 100644 --- a/pkg/plugins/generators.go +++ b/pkg/plugins/generators.go @@ -18,81 +18,40 @@ package plugins import ( "fmt" - "path/filepath" - "plugin" + "sigs.k8s.io/kustomize/pkg/transformers" + "sigs.k8s.io/kustomize/pkg/types" - "github.com/pkg/errors" - "sigs.k8s.io/kustomize/pkg/pgmconfig" - "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" - "sigs.k8s.io/kustomize/pkg/resource" ) -const generatorSymbol = "Generator" - -type Generatable interface { - Generate() (resmap.ResMap, error) -} - type generatorLoader struct { - pluginDir string - enabled bool - rf *resmap.Factory + pc *types.PluginConfig } -func NewGeneratorLoader(b bool, f *resmap.Factory) generatorLoader { - return generatorLoader{ - pluginDir: filepath.Join(pgmconfig.ConfigRoot(), pgmconfig.PluginsDir), - enabled: b, - rf: f, - } +func NewGeneratorLoader(pc *types.PluginConfig) generatorLoader { + return generatorLoader{pc: pc} } -func (l generatorLoader) Load(rm resmap.ResMap) (resmap.ResMap, error) { +func (l generatorLoader) Load( + rm resmap.ResMap) ([]transformers.Generator, error) { if len(rm) == 0 { return nil, nil } - if !l.enabled { - return nil, fmt.Errorf("plugin is not enabled") + if !l.pc.GoEnabled { + return nil, fmt.Errorf("plugins not enabled") } - var result resmap.ResMap + var result []transformers.Generator for id, res := range rm { - r, err := l.load(id, res) + fileName := pluginFileName(l.pc, id) + c, err := loadAndConfigurePlugin(fileName, res) if err != nil { return nil, err } - result, err = resmap.MergeWithErrorOnIdCollision(result, r) - if err != nil { - return nil, err + g, ok := c.(transformers.Generator) + if !ok { + return nil, fmt.Errorf("plugin %s not a generator", fileName) } + result = append(result, g) } return result, nil } - -func (l generatorLoader) load(id resid.ResId, res *resource.Resource) (resmap.ResMap, error) { - fileName := filepath.Join(l.pluginDir, id.Gvk().Kind+".so") - goPlugin, err := plugin.Open(fileName) - if err != nil { - return nil, fmt.Errorf("plugin %s file not opened", fileName) - } - - symbol, err := goPlugin.Lookup(generatorSymbol) - if err != nil { - return nil, fmt.Errorf("plugin %s fails lookup", fileName) - } - - c, ok := symbol.(Configurable) - if !ok { - return nil, fmt.Errorf("plugin %s not configurable", fileName) - } - err = c.Config(res) - if err != nil { - return nil, errors.Wrapf(err, "plugin %s fails configuration", fileName) - } - - g, ok := c.(Generatable) - if !ok { - return nil, fmt.Errorf("plugin %s not a transformer", fileName) - } - return g.Generate() -} diff --git a/pkg/plugins/transformers.go b/pkg/plugins/transformers.go index de962acc5..b6cf28864 100644 --- a/pkg/plugins/transformers.go +++ b/pkg/plugins/transformers.go @@ -43,7 +43,8 @@ func NewTransformerLoader(pc *types.PluginConfig) transformerLoader { return transformerLoader{pc: pc} } -func (l transformerLoader) Load(rm resmap.ResMap) ([]transformers.Transformer, error) { +func (l transformerLoader) Load( + rm resmap.ResMap) ([]transformers.Transformer, error) { if len(rm) == 0 { return nil, nil } @@ -52,30 +53,37 @@ func (l transformerLoader) Load(rm resmap.ResMap) ([]transformers.Transformer, e } var result []transformers.Transformer for id, res := range rm { - t, err := l.load(id, res) + fileName := pluginFileName(l.pc, id) + c, err := loadAndConfigurePlugin(fileName, res) if err != nil { return nil, err } + t, ok := c.(transformers.Transformer) + if !ok { + return nil, fmt.Errorf("plugin %s not a transformer", fileName) + } result = append(result, t) } return result, nil } -func (l transformerLoader) load( - id resid.ResId, res *resource.Resource) (transformers.Transformer, error) { - fileName := filepath.Join( - l.pc.DirectoryPath, +func pluginFileName(pc *types.PluginConfig, id resid.ResId) string { + return filepath.Join( + pc.DirectoryPath, id.Gvk().Group, id.Gvk().Version, id.Gvk().Kind+".so") +} + +func loadAndConfigurePlugin( + fileName string, res *resource.Resource) (Configurable, error) { goPlugin, err := plugin.Open(fileName) if err != nil { return nil, fmt.Errorf("plugin %s file not opened", fileName) } - - symbol, err := goPlugin.Lookup(kplugin.TransformerSymbol) + symbol, err := goPlugin.Lookup(kplugin.PluginSymbol) if err != nil { - return nil, fmt.Errorf("plugin %s fails lookup", fileName) + return nil, fmt.Errorf( + "plugin %s doesn't have symbol %s", fileName, kplugin.PluginSymbol) } - c, ok := symbol.(Configurable) if !ok { return nil, fmt.Errorf("plugin %s not configurable", fileName) @@ -84,10 +92,5 @@ func (l transformerLoader) load( if err != nil { return nil, errors.Wrapf(err, "plugin %s fails configuration", fileName) } - - t, ok := c.(transformers.Transformer) - if !ok { - return nil, fmt.Errorf("plugin %s not a transformer", fileName) - } - return t, nil + return c, nil } diff --git a/pkg/target/generatorplugin_test.go b/pkg/target/generatorplugin_test.go index 23bd47f15..a0d3b5140 100644 --- a/pkg/target/generatorplugin_test.go +++ b/pkg/target/generatorplugin_test.go @@ -14,17 +14,14 @@ limitations under the License. package target_test import ( - "os" - "path/filepath" "testing" - "sigs.k8s.io/kustomize/pkg/pgmconfig" - "sigs.k8s.io/kustomize/pkg/types" + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" ) func writeGenerator(th *KustTestHarness, path string) { th.writeF(path, ` -apiVersion: strings.microwoosh.com/v1 +apiVersion: someteam.example.com/v1 kind: ServiceGenerator metadata: name: myServiceGenerator @@ -34,20 +31,14 @@ port: "12345" } func TestGeneratorPlugin(t *testing.T) { - dir, err := filepath.Abs("../../..") - if err != nil { - t.Errorf("unexpected error %v", err) - } - os.Setenv(pgmconfig.XDG_CONFIG_HOME, dir) - defer os.Unsetenv(pgmconfig.XDG_CONFIG_HOME) + tc := NewTestEnvController(t).Set() + defer tc.Reset() - err = buildGoPlugins(dir, "ServiceGenerator") - if err != nil { - t.Errorf("unexpected error %v", err) - } + tc.BuildGoPlugin( + "someteam.example.com", "v1", "ServiceGenerator") th := NewKustTestHarnessWithPluginConfig( - t, "/app", types.PluginConfig{GoEnabled: true}) + t, "/app", plugin.ActivePluginConfig()) th.writeK("/app", ` generators: - serviceGenerator.yaml diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index c01bf63ee..ac5589927 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -173,17 +173,6 @@ func (kt *KustTarget) AccumulateTarget() ( // nolint: gocyclo if err != nil { errs.Append(errors.Wrap(err, "MergeResourcesWithErrorOnIdCollision")) } - resourceFromGenerators, err := kt.loadGeneratorPlugins() - if err != nil { - errs.Append(errors.Wrap(err, "failed to load resources from generators")) - } - if len(errs.Get()) > 0 { - return ra, errs - } - err = ra.MergeResourcesWithErrorOnIdCollision(resourceFromGenerators) - if err != nil { - errs.Append(errors.Wrap(err, "MergeResourcesWithErrorOnIdCollision")) - } tConfig, err := config.MakeTransformerConfig( kt.ldr, kt.kustomization.Configurations) if err != nil { @@ -213,6 +202,12 @@ func (kt *KustTarget) AccumulateTarget() ( // nolint: gocyclo if err != nil { return nil, err } + if kt.pluginConfig.GoEnabled { + kt.generateFromPlugins(ra, errs) + if len(errs.Get()) > 0 { + return ra, errs + } + } patches, err := kt.rFactory.RF().SliceFromPatches( kt.ldr, kt.kustomization.PatchesStrategicMerge) if err != nil { @@ -232,6 +227,26 @@ func (kt *KustTarget) AccumulateTarget() ( // nolint: gocyclo return ra, nil } +func (kt *KustTarget) generateFromPlugins( + ra *accumulator.ResAccumulator, + errs *interror.KustomizationErrors) { + generators, err := kt.loadGeneratorPlugins() + if err != nil { + errs.Append(err) + } + for _, g := range generators { + resMap, err := g.Generate() + if err != nil { + errs.Append(err) + } else { + err = ra.MergeResourcesWithErrorOnIdCollision(resMap) + if err != nil { + errs.Append(errors.Wrap(err, "from plugin")) + } + } + } +} + func (kt *KustTarget) generateConfigMapsAndSecrets( errs *interror.KustomizationErrors) (resmap.ResMap, error) { cms, err := kt.rFactory.NewResMapFromConfigMapArgs( @@ -345,20 +360,19 @@ func (kt *KustTarget) newTransformer( } func (kt *KustTarget) loadTransformerPlugins() ([]transformers.Transformer, error) { - transformerPluginConfigs, err := kt.rFactory.FromFiles( + configs, err := kt.rFactory.FromFiles( kt.ldr, kt.kustomization.Transformers) if err != nil { return nil, err } - return plugins.NewTransformerLoader(kt.pluginConfig).Load(transformerPluginConfigs) + return plugins.NewTransformerLoader(kt.pluginConfig).Load(configs) } -func (kt *KustTarget) loadGeneratorPlugins() (resmap.ResMap, error) { - generatorPluginConfigs, err := kt.rFactory.FromFiles( +func (kt *KustTarget) loadGeneratorPlugins() ([]transformers.Generator, error) { + configs, err := kt.rFactory.FromFiles( kt.ldr, kt.kustomization.Generators) if err != nil { return nil, err } - gl := plugins.NewGeneratorLoader(kt.goPluginEnabled, kt.rFactory) - return gl.Load(generatorPluginConfigs) + return plugins.NewGeneratorLoader(kt.pluginConfig).Load(configs) } diff --git a/pkg/target/testenvcontroller_test.go b/pkg/target/testenvcontroller_test.go index 37d8dd223..bdf0bfad1 100644 --- a/pkg/target/testenvcontroller_test.go +++ b/pkg/target/testenvcontroller_test.go @@ -105,7 +105,7 @@ func (x *TestEnvController) BuildGoPlugin(plugin ...string) { // ObjectRoot is the objRoot dir for plugin object files. func (x *TestEnvController) ObjectRoot() string { return filepath.Join( - x.xdgConfigHome, pgmconfig.PgmName, plugin.PluginsDir) + x.xdgConfigHome, pgmconfig.PgmName, plugin.PluginRoot) } // SrcRoot is a objRoot directory for plugin source code @@ -120,7 +120,7 @@ func (x *TestEnvController) ObjectRoot() string { func (x *TestEnvController) SrcRoot() string { dir := filepath.Join( os.Getenv("GOPATH"), "src", - pgmconfig.Repo, pgmconfig.PgmName, plugin.PluginsDir) + pgmconfig.Repo, pgmconfig.PgmName, plugin.PluginRoot) if _, err := os.Stat(dir); err != nil { x.t.Errorf("plugin source objRoot '%s' not found", dir) } diff --git a/pkg/transformers/transformer.go b/pkg/transformers/transformer.go index fc0803fce..301fdf7bf 100644 --- a/pkg/transformers/transformer.go +++ b/pkg/transformers/transformer.go @@ -26,3 +26,8 @@ type Transformer interface { // Transform modifies data in the argument, e.g. adding labels to resources that can be labelled. Transform(m resmap.ResMap) error } + +// A Generator creates an instance of resmap.ResMap. +type Generator interface { + Generate() (resmap.ResMap, error) +} diff --git a/plugins/someteam.example.com/v1/DatePrefixer.go b/plugins/someteam.example.com/v1/DatePrefixer.go index 8f7daf93f..df389b283 100644 --- a/plugins/someteam.example.com/v1/DatePrefixer.go +++ b/plugins/someteam.example.com/v1/DatePrefixer.go @@ -13,7 +13,7 @@ import ( type plugin struct{} -var Transformer plugin +var KustomizePlugin plugin func (p *plugin) Config(k ifc.Kunstructured) error { return nil diff --git a/plugins/ServiceGenerator.go b/plugins/someteam.example.com/v1/ServiceGenerator.go similarity index 95% rename from plugins/ServiceGenerator.go rename to plugins/someteam.example.com/v1/ServiceGenerator.go index 4367daa5e..eb80a84de 100644 --- a/plugins/ServiceGenerator.go +++ b/plugins/someteam.example.com/v1/ServiceGenerator.go @@ -1,3 +1,5 @@ +// +build plugin + package main import ( @@ -15,7 +17,7 @@ type plugin struct { Port string } -var Generator plugin +var KustomizePlugin plugin var manifest = ` apiVersion: v1 diff --git a/plugins/someteam.example.com/v1/StringPrefixer.go b/plugins/someteam.example.com/v1/StringPrefixer.go index 0c8de29f9..78961e375 100644 --- a/plugins/someteam.example.com/v1/StringPrefixer.go +++ b/plugins/someteam.example.com/v1/StringPrefixer.go @@ -18,11 +18,11 @@ import ( "sigs.k8s.io/kustomize/pkg/transformers/config" ) -type plugin struct{ +type plugin struct { prefix string } -var Transformer plugin +var KustomizePlugin plugin func (p *plugin) Config(k ifc.Kunstructured) error { var err error diff --git a/plugins/someteam.example.com/v1/kvMaker.go b/plugins/someteam.example.com/v1/kvMaker.go index 2250f3e46..584beb431 100644 --- a/plugins/someteam.example.com/v1/kvMaker.go +++ b/plugins/someteam.example.com/v1/kvMaker.go @@ -1,24 +1,27 @@ // +build plugin package main + var database = map[string]string{ - "TREE": "oak", - "ROCKET": "Saturn V", - "FRUIT": "apple", - "VEGETABLE": "carrot", - "SIMPSON": "homer", + "TREE": "oak", + "ROCKET": "Saturn V", + "FRUIT": "apple", + "VEGETABLE": "carrot", + "SIMPSON": "homer", } type plugin struct{} + var KVSource plugin + func (p plugin) Get( - root string, args []string) (map[string]string, error) { - r := make(map[string]string) - for _, k := range args { - v, ok := database[k] - if ok { - r[k] = v - } - } - return r, nil + root string, args []string) (map[string]string, error) { + r := make(map[string]string) + for _, k := range args { + v, ok := database[k] + if ok { + r[k] = v + } + } + return r, nil } From ffc16d51e04ec4661b60e22db594f117c247c783 Mon Sep 17 00:00:00 2001 From: jregan Date: Sat, 6 Apr 2019 18:27:14 -0700 Subject: [PATCH 208/317] Add secret generator. --- k8sdeps/kunstruct/kunstruct.go | 14 ++++ pkg/ifc/ifc.go | 1 + pkg/plugins/generators.go | 17 +++-- pkg/plugins/transformers.go | 19 +++-- pkg/target/generatorplugin_test.go | 71 ++++++++++++++++++- pkg/target/kusttarget.go | 6 +- .../v1/SecretGenerator.go | 62 ++++++++++++++++ .../someteam.example.com/v1/DatePrefixer.go | 3 +- .../v1/ServiceGenerator.go | 3 +- .../someteam.example.com/v1/StringPrefixer.go | 3 +- 10 files changed, 178 insertions(+), 21 deletions(-) create mode 100644 plugins/kustomize.config.k8s.io/v1/SecretGenerator.go diff --git a/k8sdeps/kunstruct/kunstruct.go b/k8sdeps/kunstruct/kunstruct.go index 5ad306bf5..9fa0b67eb 100644 --- a/k8sdeps/kunstruct/kunstruct.go +++ b/k8sdeps/kunstruct/kunstruct.go @@ -90,3 +90,17 @@ func (fs *UnstructAdapter) GetFieldValue(path string) (string, error) { } return "", fmt.Errorf("no field named '%s'", path) } + +// GetStringSlice returns value at the given fieldpath. +func (fs *UnstructAdapter) GetStringSlice(path string) ([]string, error) { + fields, err := parseFields(path) + if err != nil { + return []string{}, err + } + s, found, err := unstructured.NestedStringSlice( + fs.UnstructuredContent(), fields...) + if found || err != nil { + return s, err + } + return []string{}, fmt.Errorf("no field named '%s'", path) +} diff --git a/pkg/ifc/ifc.go b/pkg/ifc/ifc.go index 3a1815da8..d0251f224 100644 --- a/pkg/ifc/ifc.go +++ b/pkg/ifc/ifc.go @@ -48,6 +48,7 @@ type Kunstructured interface { SetMap(map[string]interface{}) Copy() Kunstructured GetFieldValue(string) (string, error) + GetStringSlice(string) ([]string, error) MarshalJSON() ([]byte, error) UnmarshalJSON([]byte) error GetGvk() gvk.Gvk diff --git a/pkg/plugins/generators.go b/pkg/plugins/generators.go index 45c23e2e8..d40707e44 100644 --- a/pkg/plugins/generators.go +++ b/pkg/plugins/generators.go @@ -18,18 +18,23 @@ package plugins import ( "fmt" + + "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/transformers" "sigs.k8s.io/kustomize/pkg/types" - - "sigs.k8s.io/kustomize/pkg/resmap" ) type generatorLoader struct { - pc *types.PluginConfig + pc *types.PluginConfig + ldr ifc.Loader + rf *resmap.Factory } -func NewGeneratorLoader(pc *types.PluginConfig) generatorLoader { - return generatorLoader{pc: pc} +func NewGeneratorLoader( + pc *types.PluginConfig, + ldr ifc.Loader, rf *resmap.Factory) generatorLoader { + return generatorLoader{pc: pc, ldr: ldr, rf: rf} } func (l generatorLoader) Load( @@ -43,7 +48,7 @@ func (l generatorLoader) Load( var result []transformers.Generator for id, res := range rm { fileName := pluginFileName(l.pc, id) - c, err := loadAndConfigurePlugin(fileName, res) + c, err := loadAndConfigurePlugin(fileName, l.ldr, l.rf, res) if err != nil { return nil, err } diff --git a/pkg/plugins/transformers.go b/pkg/plugins/transformers.go index b6cf28864..0bf13d392 100644 --- a/pkg/plugins/transformers.go +++ b/pkg/plugins/transformers.go @@ -32,15 +32,19 @@ import ( ) type Configurable interface { - Config(k ifc.Kunstructured) error + Config(ldr ifc.Loader, rf *resmap.Factory, k ifc.Kunstructured) error } type transformerLoader struct { - pc *types.PluginConfig + pc *types.PluginConfig + ldr ifc.Loader + rf *resmap.Factory } -func NewTransformerLoader(pc *types.PluginConfig) transformerLoader { - return transformerLoader{pc: pc} +func NewTransformerLoader( + pc *types.PluginConfig, + ldr ifc.Loader, rf *resmap.Factory) transformerLoader { + return transformerLoader{pc: pc, ldr: ldr, rf: rf} } func (l transformerLoader) Load( @@ -54,7 +58,7 @@ func (l transformerLoader) Load( var result []transformers.Transformer for id, res := range rm { fileName := pluginFileName(l.pc, id) - c, err := loadAndConfigurePlugin(fileName, res) + c, err := loadAndConfigurePlugin(fileName, l.ldr, l.rf, res) if err != nil { return nil, err } @@ -74,7 +78,8 @@ func pluginFileName(pc *types.PluginConfig, id resid.ResId) string { } func loadAndConfigurePlugin( - fileName string, res *resource.Resource) (Configurable, error) { + fileName string, ldr ifc.Loader, + rf *resmap.Factory, res *resource.Resource) (Configurable, error) { goPlugin, err := plugin.Open(fileName) if err != nil { return nil, fmt.Errorf("plugin %s file not opened", fileName) @@ -88,7 +93,7 @@ func loadAndConfigurePlugin( if !ok { return nil, fmt.Errorf("plugin %s not configurable", fileName) } - err = c.Config(res) + err = c.Config(ldr, rf, res) if err != nil { return nil, errors.Wrapf(err, "plugin %s fails configuration", fileName) } diff --git a/pkg/target/generatorplugin_test.go b/pkg/target/generatorplugin_test.go index a0d3b5140..097417efd 100644 --- a/pkg/target/generatorplugin_test.go +++ b/pkg/target/generatorplugin_test.go @@ -14,12 +14,13 @@ limitations under the License. package target_test import ( + "path/filepath" "testing" "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" ) -func writeGenerator(th *KustTestHarness, path string) { +func writeServiceGenerator(th *KustTestHarness, path string) { th.writeF(path, ` apiVersion: someteam.example.com/v1 kind: ServiceGenerator @@ -30,7 +31,7 @@ port: "12345" `) } -func TestGeneratorPlugin(t *testing.T) { +func TestServiceGeneratorPlugin(t *testing.T) { tc := NewTestEnvController(t).Set() defer tc.Reset() @@ -43,7 +44,7 @@ func TestGeneratorPlugin(t *testing.T) { generators: - serviceGenerator.yaml `) - writeGenerator(th, "/app/serviceGenerator.yaml") + writeServiceGenerator(th, "/app/serviceGenerator.yaml") m, err := th.makeKustTarget().MakeCustomizedResMap() if err != nil { t.Fatalf("Err: %v", err) @@ -62,3 +63,67 @@ spec: app: dev `) } + +func writeSecretGeneratorConfig(th *KustTestHarness, root string) { + th.writeF(filepath.Join(root, "secretGenerator.yaml"), ` +apiVersion: kustomize.config.k8s.io/v1 +kind: SecretGenerator +metadata: + name: secretGenerator +name: mySecret +behavior: merge +envFiles: +- a.env +- b.env +valueFiles: +- longsecret.txt +literals: +- FRUIT=apple +- VEGETABLE=carrot +`) + th.writeF(filepath.Join(root, "a.env"), ` +ROUTER_PASSWORD=admin +`) + th.writeF(filepath.Join(root, "b.env"), ` +DB_PASSWORD=iloveyou +`) + th.writeF(filepath.Join(root, "longsecret.txt"), ` +Lorem ipsum dolor sit amet, +consectetur adipiscing elit, +sed do eiusmod tempor incididunt +ut labore et dolore magna aliqua. +`) +} + +// nolint:lll +func TestSecretGenerator(t *testing.T) { + tc := NewTestEnvController(t).Set() + defer tc.Reset() + + tc.BuildGoPlugin( + "kustomize.config.k8s.io", "v1", "SecretGenerator") + + th := NewKustTestHarnessWithPluginConfig( + t, "/app", plugin.ActivePluginConfig()) + th.writeK("/app", ` +generators: +- secretGenerator.yaml +`) + writeSecretGeneratorConfig(th, "/app") + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + FRUIT: YXBwbGU= + ROUTER_PASSWORD: YWRtaW4= + VEGETABLE: Y2Fycm90 + longsecret.txt: CkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LApjb25zZWN0ZXR1ciBhZGlwaXNjaW5nIGVsaXQsCnNlZCBkbyBlaXVzbW9kIHRlbXBvciBpbmNpZGlkdW50CnV0IGxhYm9yZSBldCBkb2xvcmUgbWFnbmEgYWxpcXVhLgo= +kind: Secret +metadata: + name: -2kt2h55789 +type: Opaque +`) +} diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index ac5589927..cb5e2e3c2 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -365,7 +365,8 @@ func (kt *KustTarget) loadTransformerPlugins() ([]transformers.Transformer, erro if err != nil { return nil, err } - return plugins.NewTransformerLoader(kt.pluginConfig).Load(configs) + return plugins.NewTransformerLoader( + kt.pluginConfig, kt.ldr, kt.rFactory).Load(configs) } func (kt *KustTarget) loadGeneratorPlugins() ([]transformers.Generator, error) { @@ -374,5 +375,6 @@ func (kt *KustTarget) loadGeneratorPlugins() ([]transformers.Generator, error) { if err != nil { return nil, err } - return plugins.NewGeneratorLoader(kt.pluginConfig).Load(configs) + return plugins.NewGeneratorLoader( + kt.pluginConfig, kt.ldr, kt.rFactory).Load(configs) } diff --git a/plugins/kustomize.config.k8s.io/v1/SecretGenerator.go b/plugins/kustomize.config.k8s.io/v1/SecretGenerator.go new file mode 100644 index 000000000..500e24b9d --- /dev/null +++ b/plugins/kustomize.config.k8s.io/v1/SecretGenerator.go @@ -0,0 +1,62 @@ +// +build plugin + +package main + +import ( + "fmt" + + "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/types" +) + +type plugin struct { + ldr ifc.Loader + rf *resmap.Factory + options types.GeneratorOptions + args types.SecretArgs +} + +var KustomizePlugin plugin + +func (p *plugin) Config( + ldr ifc.Loader, rf *resmap.Factory, k ifc.Kunstructured) error { + p.ldr = ldr + p.rf = rf + + var err error + // TODO: Should validate this. + p.args.Behavior, err = k.GetFieldValue("behavior") + if err != nil { + return err + } + + envFiles, err := k.GetStringSlice("envFiles") + if err != nil { + return err + } + if len(envFiles) > 2 { + // TODO: refactor to allow this + return fmt.Errorf("cannot yet accept more than one envFile") + } + if len(envFiles) > 0 { + p.args.EnvSource = envFiles[0] + } + + p.args.FileSources, err = k.GetStringSlice("valueFiles") + if err != nil { + return err + } + p.args.LiteralSources, err = k.GetStringSlice("literals") + if err != nil { + return err + } + + return nil +} + +func (p *plugin) Generate() (resmap.ResMap, error) { + argsList := make([]types.SecretArgs, 1) + argsList[0] = p.args + return p.rf.NewResMapFromSecretArgs(p.ldr, &p.options, argsList) +} diff --git a/plugins/someteam.example.com/v1/DatePrefixer.go b/plugins/someteam.example.com/v1/DatePrefixer.go index df389b283..7c316034d 100644 --- a/plugins/someteam.example.com/v1/DatePrefixer.go +++ b/plugins/someteam.example.com/v1/DatePrefixer.go @@ -15,7 +15,8 @@ type plugin struct{} var KustomizePlugin plugin -func (p *plugin) Config(k ifc.Kunstructured) error { +func (p *plugin) Config( + ldr ifc.Loader, rf *resmap.Factory, k ifc.Kunstructured) error { return nil } diff --git a/plugins/someteam.example.com/v1/ServiceGenerator.go b/plugins/someteam.example.com/v1/ServiceGenerator.go index eb80a84de..baf077087 100644 --- a/plugins/someteam.example.com/v1/ServiceGenerator.go +++ b/plugins/someteam.example.com/v1/ServiceGenerator.go @@ -33,7 +33,8 @@ spec: app: dev ` -func (p *plugin) Config(k ifc.Kunstructured) error { +func (p *plugin) Config( + ldr ifc.Loader, rf *resmap.Factory, k ifc.Kunstructured) error { var err error p.ServiceName, err = k.GetFieldValue("service") if err != nil { diff --git a/plugins/someteam.example.com/v1/StringPrefixer.go b/plugins/someteam.example.com/v1/StringPrefixer.go index 78961e375..230bcd697 100644 --- a/plugins/someteam.example.com/v1/StringPrefixer.go +++ b/plugins/someteam.example.com/v1/StringPrefixer.go @@ -24,7 +24,8 @@ type plugin struct { var KustomizePlugin plugin -func (p *plugin) Config(k ifc.Kunstructured) error { +func (p *plugin) Config( + ldr ifc.Loader, rf *resmap.Factory, k ifc.Kunstructured) error { var err error p.prefix, err = k.GetFieldValue("prefix") if err != nil { From 826affb8ddda27704f98e3a92cb5491083eb4d85 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Fri, 5 Apr 2019 16:13:15 -0700 Subject: [PATCH 209/317] generate configmap for pruning --- k8sdeps/transformer/factory.go | 6 + k8sdeps/transformer/hash/hash.go | 16 ++ k8sdeps/transformer/hash/hash_test.go | 22 +++ k8sdeps/transformer/prune/prune.go | 110 +++++++++++ k8sdeps/transformer/prune/prune_test.go | 171 +++++++++++++++++ pkg/commands/build/build.go | 54 ++++++ pkg/commands/kustfile/kustomizationfile.go | 1 + .../kustfile/kustomizationfile_test.go | 1 + pkg/ifc/transformer/factory.go | 2 + pkg/resid/resid.go | 10 + pkg/resource/resource.go | 23 ++- pkg/resource/resource_test.go | 18 ++ pkg/target/kusttarget.go | 42 +++- pkg/target/pruneconfigmap_test.go | 180 ++++++++++++++++++ pkg/transformers/namereference.go | 7 +- pkg/transformers/namereference_test.go | 1 + pkg/types/kustomization.go | 13 ++ 17 files changed, 673 insertions(+), 4 deletions(-) create mode 100644 k8sdeps/transformer/prune/prune.go create mode 100644 k8sdeps/transformer/prune/prune_test.go create mode 100644 pkg/target/pruneconfigmap_test.go diff --git a/k8sdeps/transformer/factory.go b/k8sdeps/transformer/factory.go index 7388b634d..f88d2bdf4 100644 --- a/k8sdeps/transformer/factory.go +++ b/k8sdeps/transformer/factory.go @@ -20,8 +20,10 @@ package transformer import ( "sigs.k8s.io/kustomize/k8sdeps/transformer/hash" "sigs.k8s.io/kustomize/k8sdeps/transformer/patch" + "sigs.k8s.io/kustomize/k8sdeps/transformer/prune" "sigs.k8s.io/kustomize/pkg/resource" "sigs.k8s.io/kustomize/pkg/transformers" + "sigs.k8s.io/kustomize/pkg/types" ) // FactoryImpl makes patch transformer and name hash transformer @@ -41,3 +43,7 @@ func (p *FactoryImpl) MakePatchTransformer(slice []*resource.Resource, rf *resou func (p *FactoryImpl) MakeHashTransformer() transformers.Transformer { return hash.NewNameHashTransformer() } + +func (p *FactoryImpl) MakePruneTransformer(arg *types.Prune, namespace string, append bool) transformers.Transformer { + return prune.NewPruneTransformer(arg, namespace, append) +} diff --git a/k8sdeps/transformer/hash/hash.go b/k8sdeps/transformer/hash/hash.go index 17e24ff3e..cdab7244b 100644 --- a/k8sdeps/transformer/hash/hash.go +++ b/k8sdeps/transformer/hash/hash.go @@ -20,6 +20,7 @@ import ( "crypto/sha256" "encoding/json" "fmt" + "sort" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -86,6 +87,21 @@ func SecretHash(sec *v1.Secret) (string, error) { return h, nil } +// SortArrayAndComputeHash sorts a string array and +// returns a hash for it +func SortArrayAndComputeHash(s []string) (string, error) { + sort.Strings(s) + data, err := json.Marshal(s) + if err != nil { + return "", err + } + h, err := encodeHash(hash(string(data))) + if err != nil { + return "", err + } + return h, nil +} + // encodeConfigMap encodes a ConfigMap. // Data, Kind, and Name are taken into account. func encodeConfigMap(cm *v1.ConfigMap) (string, error) { diff --git a/k8sdeps/transformer/hash/hash_test.go b/k8sdeps/transformer/hash/hash_test.go index 2d336f35a..4a3c9365c 100644 --- a/k8sdeps/transformer/hash/hash_test.go +++ b/k8sdeps/transformer/hash/hash_test.go @@ -90,6 +90,28 @@ func TestSecretHash(t *testing.T) { } } +func TestArrayHash(t *testing.T) { + array1 := []string{"a", "b", "c"} + array2 := []string{"c", "b", "a"} + h1, err := SortArrayAndComputeHash(array1) + if err != nil { + t.Errorf("unexpected error %v", err) + } + if h1 == "" { + t.Errorf("failed to hash %v", array1) + } + h2, err := SortArrayAndComputeHash(array2) + if err != nil { + t.Errorf("unexpected error %v", err) + } + if h2 == "" { + t.Errorf("failed to hash %v", array2) + } + if h1 != h2 { + t.Errorf("hash is not consistent with reordered list: %s %s", h1, h2) + } +} + func TestEncodeConfigMap(t *testing.T) { cases := []struct { desc string diff --git a/k8sdeps/transformer/prune/prune.go b/k8sdeps/transformer/prune/prune.go new file mode 100644 index 000000000..def29ad51 --- /dev/null +++ b/k8sdeps/transformer/prune/prune.go @@ -0,0 +1,110 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package prune + +import ( + "fmt" + "sigs.k8s.io/kustomize/k8sdeps/kunstruct" + "sigs.k8s.io/kustomize/k8sdeps/transformer/hash" + "sigs.k8s.io/kustomize/pkg/gvk" + "sigs.k8s.io/kustomize/pkg/resid" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/resource" + "sigs.k8s.io/kustomize/pkg/transformers" + "sigs.k8s.io/kustomize/pkg/types" +) + +//const PruneAnnotation = "kustomize.k8s.io/PruneRevision" +const PruneAnnotation = "current" + +// pruneTransformer compute the ConfigMap used in prune +type pruneTransformer struct { + append bool + cmName string + cmNamespace string +} + +var _ transformers.Transformer = &pruneTransformer{} + +// NewPruneTransformer makes a pruneTransformer. +func NewPruneTransformer(p *types.Prune, namespace string, append bool) transformers.Transformer { + if p == nil || p.Type != "alphaConfigMap" || p.AlphaConfigMap.Namespace != namespace { + return transformers.NewNoOpTransformer() + } + return &pruneTransformer{ + append: append, + cmName: p.AlphaConfigMap.Name, + cmNamespace: p.AlphaConfigMap.Namespace, + } +} + +// Transform generates a prune ConfigMap based on the input ResMap. +// this tranformer doesn't change existing resources - +// it just visits resources and accumulates information to make a new ConfigMap. +// The prune ConfigMap is used to support the pruning command in the client side tool, +// which is proposed in https://github.com/kubernetes/enhancements/pull/810 +func (o *pruneTransformer) Transform(m resmap.ResMap) error { + keys := []string{} + for id, r := range m { + s := id.PruneString() + keys = append(keys, s) + for _, refid := range r.GetRefBy() { + keys = append(keys, s+"---"+refid.PruneString()) + } + } + h, err := hash.SortArrayAndComputeHash(keys) + if err != nil { + return err + } + + args := &types.ConfigMapArgs{} + args.Name = o.cmName + args.Namespace = o.cmNamespace + for _, key := range keys { + args.LiteralSources = append(args.LiteralSources, + key+"="+h) + } + opts := &types.GeneratorOptions{ + Annotations: make(map[string]string), + } + opts.Annotations[PruneAnnotation] = h + + kf := kunstruct.NewKunstructuredFactoryImpl() + k, err := kf.MakeConfigMap(nil, opts, args) + if err != nil { + return err + } + + if !o.append { + for k := range m { + delete(m, k) + } + } + + id := resid.NewResIdWithPrefixNamespace( + gvk.Gvk{ + Version: "v1", + Kind: "ConfigMap", + }, + o.cmName, + "", o.cmNamespace) + if _, ok := m[id]; ok { + return fmt.Errorf("id %v is already used, please use a different name in the prune field", id) + } + m[id] = resource.NewFactory(kf).FromKunstructured(k) + return nil +} diff --git a/k8sdeps/transformer/prune/prune_test.go b/k8sdeps/transformer/prune/prune_test.go new file mode 100644 index 000000000..f73d0d7c1 --- /dev/null +++ b/k8sdeps/transformer/prune/prune_test.go @@ -0,0 +1,171 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package prune + +import ( + "reflect" + "testing" + + "sigs.k8s.io/kustomize/k8sdeps/kunstruct" + "sigs.k8s.io/kustomize/pkg/gvk" + "sigs.k8s.io/kustomize/pkg/resid" + "sigs.k8s.io/kustomize/pkg/resmap" + "sigs.k8s.io/kustomize/pkg/resource" + "sigs.k8s.io/kustomize/pkg/types" +) + +var secret = gvk.Gvk{Version: "v1", Kind: "Secret"} +var cmap = gvk.Gvk{Version: "v1", Kind: "ConfigMap"} +var deploy = gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"} + +func makeResMap() resmap.ResMap { + rf := resource.NewFactory( + kunstruct.NewKunstructuredFactoryImpl()) + objs := resmap.ResMap{ + resid.NewResId(cmap, "cm1"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "ConfigMap", + "metadata": map[string]interface{}{ + "name": "cm1", + }, + }), + resid.NewResId(secret, "secret1"): rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "Secret", + "metadata": map[string]interface{}{ + "name": "secret1", + }, + }), + resid.NewResId(deploy, "deploy1"): rf.FromMap( + map[string]interface{}{ + "group": "apps", + "apiVersion": "v1", + "kind": "Deployment", + "metadata": map[string]interface{}{ + "name": "deploy1", + }, + "spec": map[string]interface{}{ + "template": map[string]interface{}{ + "spec": map[string]interface{}{ + "containers": []interface{}{ + map[string]interface{}{ + "name": "nginx", + "image": "nginx:1.7.9", + "env": []interface{}{ + map[string]interface{}{ + "name": "CM_FOO", + "valueFrom": map[string]interface{}{ + "configMapKeyRef": map[string]interface{}{ + "name": "cm1", + "key": "somekey", + }, + }, + }, + }, + "envFrom": []interface{}{ + map[string]interface{}{ + "configMapRef": map[string]interface{}{ + "name": "cm1", + "key": "somekey", + }, + }, + map[string]interface{}{ + "secretRef": map[string]interface{}{ + "name": "secret1", + "key": "somekey", + }, + }, + }, + }, + }, + }, + }, + }, + }), + } + objs[resid.NewResId(cmap, "cm1")].AppendRefBy(resid.NewResId(deploy, "deploy1")) + objs[resid.NewResId(secret, "secret1")].AppendRefBy(resid.NewResId(deploy, "deploy1")) + return objs +} + +func TestPruneTransformer(t *testing.T) { + rf := resource.NewFactory( + kunstruct.NewKunstructuredFactoryImpl()) + + // hash is derived based on all keys in the ConfigMap data field. + // It is added to annotations as + // current: hash + // When seeing the same annotation, prune binary assumes no + // clean up is needed + hash := "k777d7h45b" + // This is the root or inventory object which tracks all + // the applied resources - this is the thing we expect the transformer to create. + pruneMap := rf.FromMap( + map[string]interface{}{ + "apiVersion": "v1", + "kind": "ConfigMap", + "metadata": map[string]interface{}{ + "name": "pruneCM", + "namespace": "default", + "annotations": map[string]interface{}{ + "current": hash, + }, + }, + "data": map[string]interface{}{ + "_ConfigMap__cm1": hash, + "_Secret__secret1": hash, + "apps_Deployment__deploy1": hash, + "_ConfigMap__cm1---apps_Deployment__deploy1": hash, + "_Secret__secret1---apps_Deployment__deploy1": hash, + }, + }) + expected := resmap.ResMap{ + resid.NewResIdWithPrefixNamespace(cmap, "pruneCM", "", "default"): pruneMap, + } + + p := &types.Prune{ + Type: "alphaConfigMap", + AlphaConfigMap: types.NameArgs{ + Name: "pruneCM", + Namespace: "default", + }, + } + objs := makeResMap() + + // include the original resmap; only return the ConfigMap for pruning + tran := NewPruneTransformer(p, "default", false) + tran.Transform(objs) + + if !reflect.DeepEqual(objs, expected) { + err := expected.ErrorIfNotEqual(objs) + t.Fatalf("actual doesn't match expected: %v", err) + } + + objs = makeResMap() + expected = objs.DeepCopy(rf) + expected[resid.NewResIdWithPrefixNamespace(cmap, "pruneCM", "", "default")] = pruneMap + // append the ConfigMap for pruning to the original resmap + tran = NewPruneTransformer(p, "default", true) + tran.Transform(objs) + + if !reflect.DeepEqual(objs, expected) { + err := expected.ErrorIfNotEqual(objs) + t.Fatalf("actual doesn't match expected: %v", err) + } +} diff --git a/pkg/commands/build/build.go b/pkg/commands/build/build.go index 2267f61f5..7da9ee1e3 100644 --- a/pkg/commands/build/build.go +++ b/pkg/commands/build/build.go @@ -84,6 +84,8 @@ func NewCmdBuild( &o.outputPath, "output", "o", "", "If specified, write the build output to this path.") + + cmd.AddCommand(NewCmdBuildPrune(out, fs, rf, ptf, b)) return cmd } @@ -130,3 +132,55 @@ func (o *Options) RunBuild( _, err = out.Write(res) return err } + +func (o *Options) RunBuildPrune( + out io.Writer, fSys fs.FileSystem, + rf *resmap.Factory, ptf transformer.Factory, + b bool) error { + ldr, err := loader.NewLoader(o.kustomizationPath, fSys) + if err != nil { + return err + } + defer ldr.Cleanup() + kt, err := target.NewKustTarget(ldr, rf, ptf, b) + if err != nil { + return err + } + allResources, err := kt.MakePruneConfigMap() + if err != nil { + return err + } + // Output the objects. + res, err := allResources.EncodeAsYaml() + if err != nil { + return err + } + if o.outputPath != "" { + return fSys.WriteFile(o.outputPath, res) + } + _, err = out.Write(res) + return err +} + +func NewCmdBuildPrune( + out io.Writer, fs fs.FileSystem, + rf *resmap.Factory, + ptf transformer.Factory, + b bool) *cobra.Command { + var o Options + + cmd := &cobra.Command{ + Use: "prune [path]", + Short: "Print configmap to prune previous applied objects", + Example: examples, + SilenceUsage: true, + RunE: func(cmd *cobra.Command, args []string) error { + err := o.Validate(args) + if err != nil { + return err + } + return o.RunBuildPrune(out, fs, rf, ptf, b) + }, + } + return cmd +} diff --git a/pkg/commands/kustfile/kustomizationfile.go b/pkg/commands/kustfile/kustomizationfile.go index b31fc8464..1fe781995 100644 --- a/pkg/commands/kustfile/kustomizationfile.go +++ b/pkg/commands/kustfile/kustomizationfile.go @@ -69,6 +69,7 @@ func determineFieldOrder() []string { "Configurations", "Generators", "Transformers", + "Prune", } // Add deprecated fields here. diff --git a/pkg/commands/kustfile/kustomizationfile_test.go b/pkg/commands/kustfile/kustomizationfile_test.go index 20751ab74..c552cebfd 100644 --- a/pkg/commands/kustfile/kustomizationfile_test.go +++ b/pkg/commands/kustfile/kustomizationfile_test.go @@ -48,6 +48,7 @@ func TestFieldOrder(t *testing.T) { "Configurations", "Generators", "Transformers", + "Prune", } actual := determineFieldOrder() if len(expected) != len(actual) { diff --git a/pkg/ifc/transformer/factory.go b/pkg/ifc/transformer/factory.go index 0a74c2809..c9507d632 100644 --- a/pkg/ifc/transformer/factory.go +++ b/pkg/ifc/transformer/factory.go @@ -20,10 +20,12 @@ package transformer import ( "sigs.k8s.io/kustomize/pkg/resource" "sigs.k8s.io/kustomize/pkg/transformers" + "sigs.k8s.io/kustomize/pkg/types" ) // Factory makes transformers type Factory interface { MakePatchTransformer(slice []*resource.Resource, rf *resource.Factory) (transformers.Transformer, error) MakeHashTransformer() transformers.Transformer + MakePruneTransformer(p *types.Prune, namespace string, append bool) transformers.Transformer } diff --git a/pkg/resid/resid.go b/pkg/resid/resid.go index dbf9a3e92..6c5945e3b 100644 --- a/pkg/resid/resid.go +++ b/pkg/resid/resid.go @@ -205,3 +205,13 @@ func (n ResId) prefixList() []string { func (n ResId) suffixList() []string { return strings.Split(n.suffix, ":") } + +// PruneString returns a string which can be used +// as a key in a Prune ConfigMap +func (n ResId) PruneString() string { + name := n.prefix + n.name + n.suffix + return n.gvKind.Group + + "_" + n.gvKind.Kind + + "_" + n.namespace + + "_" + name +} diff --git a/pkg/resource/resource.go b/pkg/resource/resource.go index 122fb6d6f..fca4ec69c 100644 --- a/pkg/resource/resource.go +++ b/pkg/resource/resource.go @@ -30,6 +30,7 @@ import ( type Resource struct { ifc.Kunstructured options *types.GenArgs + refBy []resid.ResId } // String returns resource as JSON. @@ -43,10 +44,16 @@ func (r *Resource) String() string { // DeepCopy returns a new copy of resource func (r *Resource) DeepCopy() *Resource { - return &Resource{ + rc := &Resource{ Kunstructured: r.Kunstructured.Copy(), options: r.options, } + if len(r.refBy) > 0 { + refby := make([]resid.ResId, len(r.refBy)) + copy(refby, r.refBy) + rc.refBy = refby + } + return rc } // Behavior returns the behavior for the resource. @@ -65,12 +72,26 @@ func (r *Resource) Id() resid.ResId { return resid.NewResIdWithPrefixNamespace(r.GetGvk(), r.GetName(), "", namespace) } +// GetRefBy returns the ResIds that referred to current resource +func (r *Resource) GetRefBy() []resid.ResId { + return r.refBy +} + +// AppendRefBy appends a ResId into the refBy list +func (r *Resource) AppendRefBy(id resid.ResId) { + r.refBy = append(r.refBy, id) +} + // Merge performs merge with other resource. func (r *Resource) Merge(other *Resource) { r.Replace(other) mergeConfigmap(r.Map(), other.Map(), r.Map()) } +func (r *Resource) PruneString() string { + return r.Id().PruneString() +} + // Replace performs replace with other resource. func (r *Resource) Replace(other *Resource) { r.SetLabels(mergeStringMaps(other.GetLabels(), r.GetLabels())) diff --git a/pkg/resource/resource_test.go b/pkg/resource/resource_test.go index b507d2633..57fd0d6ff 100644 --- a/pkg/resource/resource_test.go +++ b/pkg/resource/resource_test.go @@ -17,6 +17,7 @@ limitations under the License. package resource_test import ( + "reflect" "testing" "sigs.k8s.io/kustomize/k8sdeps/kunstruct" @@ -94,3 +95,20 @@ func TestResourceId(t *testing.T) { } } } + +func TestDeepCopy(t *testing.T) { + r := factory.FromMap( + map[string]interface{}{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": map[string]interface{}{ + "name": "pooh", + }, + }) + r.AppendRefBy(resid.NewResId(gvk.Gvk{Group: "somegroup", Kind: "MyKind"}, "random")) + + cr := r.DeepCopy() + if !reflect.DeepEqual(r, cr) { + t.Errorf("expected %v\nbut got%v", r, cr) + } +} diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index cb5e2e3c2..2a24dd597 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -143,7 +143,47 @@ func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) { } // With all the back references fixed, it's OK to resolve Vars. err = ra.ResolveVars() - return ra.ResMap(), err + if err != nil { + return nil, err + } + + rm := ra.ResMap() + pt := kt.tFactory.MakePruneTransformer(kt.kustomization.Prune, kt.kustomization.Namespace, true) + err = pt.Transform(rm) + if err != nil { + return nil, err + } + return rm, nil +} + +func (kt *KustTarget) MakePruneConfigMap() (resmap.ResMap, error) { + ra, err := kt.AccumulateTarget() + if err != nil { + return nil, err + } + err = ra.Transform(kt.tFactory.MakeHashTransformer()) + if err != nil { + return nil, err + } + // Given that names have changed (prefixs/suffixes added), + // fix all the back references to those names. + err = ra.FixBackReferences() + if err != nil { + return nil, err + } + // With all the back references fixed, it's OK to resolve Vars. + err = ra.ResolveVars() + if err != nil { + return nil, err + } + + rm := ra.ResMap() + pt := kt.tFactory.MakePruneTransformer(kt.kustomization.Prune, kt.kustomization.Namespace, false) + err = pt.Transform(rm) + if err != nil { + return nil, err + } + return rm, nil } func (kt *KustTarget) shouldAddHashSuffixesToGeneratedResources() bool { diff --git a/pkg/target/pruneconfigmap_test.go b/pkg/target/pruneconfigmap_test.go new file mode 100644 index 000000000..339cd0089 --- /dev/null +++ b/pkg/target/pruneconfigmap_test.go @@ -0,0 +1,180 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package target_test + +import ( + "testing" +) + +func TestPruneConfigMap(t *testing.T) { + th := NewKustTestHarness(t, "/app/base") + th.writeK("/app/base", ` +resources: +- deployment.yaml +- service.yaml +- secret.yaml + +prune: + type: alphaConfigMap + alphaConfigMap: + name: haha + namespace: default + +namePrefix: my- +namespace: default +`) + th.writeF("/app/base/deployment.yaml", ` +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: mysql + labels: + app: mysql +spec: + selector: + matchLabels: + app: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: mysql + spec: + containers: + - image: mysql:5.6 + name: mysql + env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: pass + key: password + ports: + - containerPort: 3306 + name: mysql + volumeMounts: + - name: mysql-persistent-storage + mountPath: /var/lib/mysql + volumes: + - name: mysql-persistent-storage + emptyDir: {} +`) + th.writeF("/app/base/service.yaml", ` +apiVersion: v1 +kind: Service +metadata: + name: mmmysql + labels: + app: mysql +spec: + ports: + - port: 3306 + selector: + app: mysql +`) + th.writeF("/app/base/secret.yaml", ` +apiVersion: v1 +kind: Secret +metadata: + name: pass +type: Opaque +data: + # Default password is "admin". + password: YWRtaW4= + username: jingfang +`) + + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + _Secret_default_my-pass: 54f87m6fd6 + _Secret_default_my-pass---apps_Deployment_default_my-mysql: 54f87m6fd6 + _Service_default_my-mmmysql: 54f87m6fd6 + apps_Deployment_default_my-mysql: 54f87m6fd6 +kind: ConfigMap +metadata: + annotations: + current: 54f87m6fd6 + name: haha + namespace: default +--- +apiVersion: v1 +data: + password: YWRtaW4= + username: jingfang +kind: Secret +metadata: + name: my-pass + namespace: default +type: Opaque +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: mysql + name: my-mmmysql + namespace: default +spec: + ports: + - port: 3306 + selector: + app: mysql +--- +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + labels: + app: mysql + name: my-mysql + namespace: default +spec: + selector: + matchLabels: + app: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: mysql + spec: + containers: + - env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: my-pass + image: mysql:5.6 + name: mysql + ports: + - containerPort: 3306 + name: mysql + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-persistent-storage + volumes: + - emptyDir: {} + name: mysql-persistent-storage +`) +} diff --git a/pkg/transformers/namereference.go b/pkg/transformers/namereference.go index a4e8a7f8e..8081ddeed 100644 --- a/pkg/transformers/namereference.go +++ b/pkg/transformers/namereference.go @@ -21,6 +21,7 @@ import ( "log" "sigs.k8s.io/kustomize/pkg/gvk" + "sigs.k8s.io/kustomize/pkg/resid" "sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/transformers/config" ) @@ -70,7 +71,7 @@ func (o *nameReferenceTransformer) Transform(m resmap.ResMap) error { m[id].Map(), fSpec.PathSlice(), fSpec.CreateIfNotPresent, o.updateNameReference( - backRef.Gvk, m.FilterBy(id))) + id, backRef.Gvk, m.FilterBy(id))) if err != nil { return err } @@ -82,7 +83,7 @@ func (o *nameReferenceTransformer) Transform(m resmap.ResMap) error { } func (o *nameReferenceTransformer) updateNameReference( - backRef gvk.Gvk, m resmap.ResMap) func(in interface{}) (interface{}, error) { + rid resid.ResId, backRef gvk.Gvk, m resmap.ResMap) func(in interface{}) (interface{}, error) { return func(in interface{}) (interface{}, error) { switch in.(type) { case string: @@ -98,6 +99,7 @@ func (o *nameReferenceTransformer) updateNameReference( } // Return transformed name of the object, // complete with prefixes, hashes, etc. + res.AppendRefBy(rid) return res.GetName(), nil } } @@ -123,6 +125,7 @@ func (o *nameReferenceTransformer) updateNameReference( for _, index := range indexes { l[index] = res.GetName() } + res.AppendRefBy(rid) return l, nil } } diff --git a/pkg/transformers/namereference_test.go b/pkg/transformers/namereference_test.go index dd16c8980..c5535fec9 100644 --- a/pkg/transformers/namereference_test.go +++ b/pkg/transformers/namereference_test.go @@ -618,6 +618,7 @@ func TestNameReferencePersistentVolumeHappyRun(t *testing.T) { }, }), } + expected[resid.NewResId(pv, "volume1")].AppendRefBy(resid.NewResId(pvc, "claim1")) nrt := NewNameReferenceTransformer(defaultTransformerConfig.NameReference) err := nrt.Transform(m) if err != nil { diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 0cbbc0f42..465c96b80 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -136,6 +136,9 @@ type Kustomization struct { // Transformers is a list of files containing transformers Transformers []string `json:"transformers,omitempty" yaml:"transformers,omitempty"` + + // Name of the ConfigMap used in Prune + Prune *Prune `json:"prune,omitempty" yaml:"prune:omitempty"` } // DealWithMissingFields fills the missing fields @@ -289,3 +292,13 @@ type KVSource struct { Name string `json:"name,omitempty" yaml:"name,omitempty"` Args []string `json:"args,omitempty" yaml:"args,omitempty"` } + +type Prune struct { + Type string `json:"type,omitempty" yaml:"type,omitempty"` + AlphaConfigMap NameArgs `json:"alphaConfigMap,omitempty" yaml:"alphaConfigMap,omitempty"` +} + +type NameArgs struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` +} From e9a3f9f5f62492e3def6a0f02259f6bfd55ca3a7 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Mon, 8 Apr 2019 11:10:05 -0700 Subject: [PATCH 210/317] address comments --- k8sdeps/transformer/prune/prune.go | 6 +++--- k8sdeps/transformer/prune/prune_test.go | 4 ++-- pkg/commands/build/build.go | 12 ++++++------ pkg/target/pruneconfigmap_test.go | 4 ++-- pkg/types/kustomization.go | 4 ++-- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/k8sdeps/transformer/prune/prune.go b/k8sdeps/transformer/prune/prune.go index def29ad51..7eb7a0931 100644 --- a/k8sdeps/transformer/prune/prune.go +++ b/k8sdeps/transformer/prune/prune.go @@ -42,13 +42,13 @@ var _ transformers.Transformer = &pruneTransformer{} // NewPruneTransformer makes a pruneTransformer. func NewPruneTransformer(p *types.Prune, namespace string, append bool) transformers.Transformer { - if p == nil || p.Type != "alphaConfigMap" || p.AlphaConfigMap.Namespace != namespace { + if p == nil || p.Type != "ConfigMap" || p.ConfigMap.Namespace != namespace { return transformers.NewNoOpTransformer() } return &pruneTransformer{ append: append, - cmName: p.AlphaConfigMap.Name, - cmNamespace: p.AlphaConfigMap.Namespace, + cmName: p.ConfigMap.Name, + cmNamespace: p.ConfigMap.Namespace, } } diff --git a/k8sdeps/transformer/prune/prune_test.go b/k8sdeps/transformer/prune/prune_test.go index f73d0d7c1..3f859a7cc 100644 --- a/k8sdeps/transformer/prune/prune_test.go +++ b/k8sdeps/transformer/prune/prune_test.go @@ -140,8 +140,8 @@ func TestPruneTransformer(t *testing.T) { } p := &types.Prune{ - Type: "alphaConfigMap", - AlphaConfigMap: types.NameArgs{ + Type: "ConfigMap", + ConfigMap: types.NameArgs{ Name: "pruneCM", Namespace: "default", }, diff --git a/pkg/commands/build/build.go b/pkg/commands/build/build.go index 7da9ee1e3..a747da0f3 100644 --- a/pkg/commands/build/build.go +++ b/pkg/commands/build/build.go @@ -85,7 +85,7 @@ func NewCmdBuild( "output", "o", "", "If specified, write the build output to this path.") - cmd.AddCommand(NewCmdBuildPrune(out, fs, rf, ptf, b)) + cmd.AddCommand(NewCmdBuildPrune(out, fs, rf, ptf, pc)) return cmd } @@ -136,13 +136,13 @@ func (o *Options) RunBuild( func (o *Options) RunBuildPrune( out io.Writer, fSys fs.FileSystem, rf *resmap.Factory, ptf transformer.Factory, - b bool) error { + pc *types.PluginConfig) error { ldr, err := loader.NewLoader(o.kustomizationPath, fSys) if err != nil { return err } defer ldr.Cleanup() - kt, err := target.NewKustTarget(ldr, rf, ptf, b) + kt, err := target.NewKustTarget(ldr, rf, ptf, pc) if err != nil { return err } @@ -166,11 +166,11 @@ func NewCmdBuildPrune( out io.Writer, fs fs.FileSystem, rf *resmap.Factory, ptf transformer.Factory, - b bool) *cobra.Command { + pc *types.PluginConfig) *cobra.Command { var o Options cmd := &cobra.Command{ - Use: "prune [path]", + Use: "alpha-prune [path]", Short: "Print configmap to prune previous applied objects", Example: examples, SilenceUsage: true, @@ -179,7 +179,7 @@ func NewCmdBuildPrune( if err != nil { return err } - return o.RunBuildPrune(out, fs, rf, ptf, b) + return o.RunBuildPrune(out, fs, rf, ptf, pc) }, } return cmd diff --git a/pkg/target/pruneconfigmap_test.go b/pkg/target/pruneconfigmap_test.go index 339cd0089..b49f6757e 100644 --- a/pkg/target/pruneconfigmap_test.go +++ b/pkg/target/pruneconfigmap_test.go @@ -29,8 +29,8 @@ resources: - secret.yaml prune: - type: alphaConfigMap - alphaConfigMap: + type: ConfigMap + configMap: name: haha namespace: default diff --git a/pkg/types/kustomization.go b/pkg/types/kustomization.go index 465c96b80..bbd81179e 100644 --- a/pkg/types/kustomization.go +++ b/pkg/types/kustomization.go @@ -294,8 +294,8 @@ type KVSource struct { } type Prune struct { - Type string `json:"type,omitempty" yaml:"type,omitempty"` - AlphaConfigMap NameArgs `json:"alphaConfigMap,omitempty" yaml:"alphaConfigMap,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + ConfigMap NameArgs `json:"configMap,omitempty" yaml:"configMap,omitempty"` } type NameArgs struct { From 175c754f61a7299c15fc2bd6fcd320e7a673629c Mon Sep 17 00:00:00 2001 From: jregan Date: Sun, 7 Apr 2019 11:16:50 -0700 Subject: [PATCH 211/317] Define a plugin compiler. --- pkg/commands/commands.go | 2 +- pkg/pgmconfig/config.go | 6 +- pkg/pgmconfig/config_test.go | 4 +- pkg/pgmconfig/constants.go | 7 +- pkg/plugins/compiler.go | 146 +++++++++++++++++++++++++++ pkg/plugins/compiler_test.go | 60 +++++++++++ pkg/plugins/transformers.go | 7 +- pkg/target/kusttarget.go | 1 + pkg/target/testenvcontroller_test.go | 133 +++++++----------------- 9 files changed, 259 insertions(+), 107 deletions(-) create mode 100644 pkg/plugins/compiler.go create mode 100644 pkg/plugins/compiler_test.go diff --git a/pkg/commands/commands.go b/pkg/commands/commands.go index 33e18683b..dbba6bb0c 100644 --- a/pkg/commands/commands.go +++ b/pkg/commands/commands.go @@ -42,7 +42,7 @@ func NewDefaultCommand() *cobra.Command { stdOut := os.Stdout c := &cobra.Command{ - Use: pgmconfig.PgmName, + Use: pgmconfig.ProgramName, Short: "Manages declarative configuration of Kubernetes", Long: ` Manages declarative configuration of Kubernetes. diff --git a/pkg/pgmconfig/config.go b/pkg/pgmconfig/config.go index c0f8522b4..5185c50cd 100644 --- a/pkg/pgmconfig/config.go +++ b/pkg/pgmconfig/config.go @@ -34,12 +34,12 @@ func ConfigRoot() string { dir := os.Getenv(XDG_CONFIG_HOME) if len(dir) == 0 { dir = filepath.Join( - homeDir(), defaultConfigSubdir) + HomeDir(), defaultConfigSubdir) } - return filepath.Join(dir, PgmName) + return filepath.Join(dir, ProgramName) } -func homeDir() string { +func HomeDir() string { home := os.Getenv(homeEnv()) if len(home) > 0 { return home diff --git a/pkg/pgmconfig/config_test.go b/pkg/pgmconfig/config_test.go index 2833afea7..fc32e83a4 100644 --- a/pkg/pgmconfig/config_test.go +++ b/pkg/pgmconfig/config_test.go @@ -34,7 +34,7 @@ func TestConfigDirNoXdg(t *testing.T) { } if !strings.HasSuffix( s, - rootedPath(defaultConfigSubdir, PgmName)) { + rootedPath(defaultConfigSubdir, ProgramName)) { t.Fatalf("unexpected config dir: %s", s) } } @@ -50,7 +50,7 @@ func TestConfigDirWithXdg(t *testing.T) { if isSet { os.Setenv(XDG_CONFIG_HOME, xdg) } - if s != rootedPath("blah", PgmName) { + if s != rootedPath("blah", ProgramName) { t.Fatalf("unexpected config dir: %s", s) } } diff --git a/pkg/pgmconfig/constants.go b/pkg/pgmconfig/constants.go index 2aecd4fbf..92aaf5fba 100644 --- a/pkg/pgmconfig/constants.go +++ b/pkg/pgmconfig/constants.go @@ -28,6 +28,9 @@ var KustomizationFileNames = []string{ } const ( - PgmName = "kustomize" - Repo = "sigs.k8s.io" + // Program name, for help, finding the XDG_CONFIG_DIR, etc. + ProgramName = "kustomize" + // Domain from which kustomize code is imported, for locating + // plugin source code under $GOPATH. + DomainName = "sigs.k8s.io" ) diff --git a/pkg/plugins/compiler.go b/pkg/plugins/compiler.go new file mode 100644 index 000000000..cfcd57c99 --- /dev/null +++ b/pkg/plugins/compiler.go @@ -0,0 +1,146 @@ +/* +Copyright 2019 The Kubernetes Authors. + Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package plugins + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "time" + + "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" + "sigs.k8s.io/kustomize/pkg/pgmconfig" +) + +// Compiler creates Go plugin object files. +// +// Source code is read from +// ${srcRoot}/${g}/${v}/${k}.go +// +// Object code is written to +// ${objRoot}/${g}/${v}/${k}.so +type Compiler struct { + srcRoot string + objRoot string +} + +// DefaultSrcRoot guesses where the user +// has her ${g}/${v}/${k}.go files. +func DefaultSrcRoot() (string, error) { + var nope []string + var root string + + root = filepath.Join( + os.Getenv("GOPATH"), "src", + pgmconfig.DomainName, + pgmconfig.ProgramName, plugin.PluginRoot) + if FileExists(root) { + return root, nil + } + nope = append(nope, root) + + root = filepath.Join( + pgmconfig.ConfigRoot(), plugin.PluginRoot) + if FileExists(root) { + return root, nil + } + nope = append(nope, root) + + root = filepath.Join( + pgmconfig.HomeDir(), + pgmconfig.ProgramName, plugin.PluginRoot) + if FileExists(root) { + return root, nil + } + nope = append(nope, root) + + return "", fmt.Errorf( + "no default src root; tried %v", nope) +} + +// NewCompiler returns a new compiler instance. +func NewCompiler(srcRoot, objRoot string) *Compiler { + return &Compiler{srcRoot: srcRoot, objRoot: objRoot} +} + +// ObjRoot is root of compilation target tree. +func (b *Compiler) ObjRoot() string { + return b.objRoot +} + +func goBin() string { + return filepath.Join(os.Getenv("GOROOT"), "bin", "go") +} + +// Compile reads ${srcRoot}/${g}/${v}/${k}.go +// and writes ${objRoot}/${g}/${v}/${k}.so +func (b *Compiler) Compile(g, v, k string) error { + objDir := filepath.Join(b.objRoot, g, v) + objFile := filepath.Join(objDir, k) + ".so" + if RecentFileExists(objFile) { + // Skip rebuilding it. + return nil + } + err := os.MkdirAll(objDir, os.ModePerm) + if err != nil { + return err + } + srcFile := filepath.Join(b.srcRoot, g, v, k) + ".go" + if !FileExists(srcFile) { + return fmt.Errorf( + "cannot find source %s", srcFile) + } + commands := []string{ + "build", + "-buildmode", + "plugin", + "-tags=plugin", + "-o", objFile, srcFile, + } + goBin := goBin() + if !FileExists(goBin) { + return fmt.Errorf( + "cannot find go compiler %s", goBin) + } + cmd := exec.Command(goBin, commands...) + cmd.Env = os.Environ() + if err := cmd.Run(); err != nil { + return fmt.Errorf( + "compiler error building %s: %v", srcFile, err) + } + return nil +} + +// True if file less than 3 minutes old, i.e. not +// accidentally left over from some earlier build. +func RecentFileExists(path string) bool { + fi, err := os.Stat(path) + if err != nil { + if os.IsNotExist(err) { + return false + } + } + age := time.Now().Sub(fi.ModTime()) + return age.Minutes() < 3 +} + +func FileExists(name string) bool { + if _, err := os.Stat(name); err != nil { + if os.IsNotExist(err) { + return false + } + } + return true +} diff --git a/pkg/plugins/compiler_test.go b/pkg/plugins/compiler_test.go new file mode 100644 index 000000000..b836f6481 --- /dev/null +++ b/pkg/plugins/compiler_test.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Kubernetes Authors. + Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package plugins_test + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" + + . "sigs.k8s.io/kustomize/pkg/plugins" +) + +// Regression coverage over compiler behavior. +func TestCompiler(t *testing.T) { + configRoot, err := ioutil.TempDir("", "kustomize-compiler-test") + if err != nil { + t.Errorf("failed to make temp dir: %v", err) + } + srcRoot, err := DefaultSrcRoot() + if err != nil { + t.Error(err) + } + c := NewCompiler(srcRoot, configRoot) + if configRoot != c.ObjRoot() { + t.Errorf("unexpected objRoot %s", c.ObjRoot()) + } + expectObj := filepath.Join( + c.ObjRoot(), + "someteam.example.com", "v1", "DatePrefixer.so") + if FileExists(expectObj) { + t.Errorf("obj file should not exist yet: %s", expectObj) + } + err = c.Compile("someteam.example.com", "v1", "DatePrefixer") + if err != nil { + t.Error(err) + } + if !RecentFileExists(expectObj) { + t.Errorf("didn't find expected obj file %s", expectObj) + } + err = os.RemoveAll(c.ObjRoot()) + if err != nil { + t.Errorf( + "removing temp dir: %s %v", c.ObjRoot(), err) + } + if FileExists(expectObj) { + t.Errorf("cleanup failed; still see: %s", expectObj) + } +} diff --git a/pkg/plugins/transformers.go b/pkg/plugins/transformers.go index b6cf28864..a30717706 100644 --- a/pkg/plugins/transformers.go +++ b/pkg/plugins/transformers.go @@ -77,12 +77,13 @@ func loadAndConfigurePlugin( fileName string, res *resource.Resource) (Configurable, error) { goPlugin, err := plugin.Open(fileName) if err != nil { - return nil, fmt.Errorf("plugin %s file not opened", fileName) + return nil, errors.Wrapf(err, "plugin %s fails to load", fileName) } symbol, err := goPlugin.Lookup(kplugin.PluginSymbol) if err != nil { - return nil, fmt.Errorf( - "plugin %s doesn't have symbol %s", fileName, kplugin.PluginSymbol) + return nil, errors.Wrapf( + err, "plugin %s doesn't have symbol %s", + fileName, kplugin.PluginSymbol) } c, ok := symbol.(Configurable) if !ok { diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index ac5589927..33287917f 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -233,6 +233,7 @@ func (kt *KustTarget) generateFromPlugins( generators, err := kt.loadGeneratorPlugins() if err != nil { errs.Append(err) + return } for _, g := range generators { resMap, err := g.Generate() diff --git a/pkg/target/testenvcontroller_test.go b/pkg/target/testenvcontroller_test.go index bdf0bfad1..f68c182f1 100644 --- a/pkg/target/testenvcontroller_test.go +++ b/pkg/target/testenvcontroller_test.go @@ -16,22 +16,22 @@ package target_test import ( "io/ioutil" "os" - "os/exec" "path/filepath" - "testing" - "time" - "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" + "testing" + "sigs.k8s.io/kustomize/pkg/pgmconfig" + "sigs.k8s.io/kustomize/pkg/plugins" ) // TestEnvController manages the KustTarget test environment. // It sets/resets XDG_CONFIG_HOME, makes/removes a temp objRoot. type TestEnvController struct { - t *testing.T - xdgConfigHome string - oldXdg string - wasSet bool + t *testing.T + compiler *plugins.Compiler + workDir string + oldXdg string + wasSet bool } func NewTestEnvController(t *testing.T) *TestEnvController { @@ -39,121 +39,62 @@ func NewTestEnvController(t *testing.T) *TestEnvController { } func (x *TestEnvController) Set() *TestEnvController { - x.makeTmpConfigHomeDir() - x.makeObjectRootDir() + x.createWorkDir() + x.compiler = x.makeCompiler() x.setEnv() return x } func (x *TestEnvController) Reset() { x.resetEnv() - x.removeTmpConfigHomeDir() + x.removeWorkDir() } -func (x *TestEnvController) fileExists(name string) bool { - if _, err := os.Stat(name); err != nil { - if os.IsNotExist(err) { - return false - } - } - return true -} - -func (x *TestEnvController) recentFileExists(path string) bool { - fi, err := os.Stat(path) +func (x *TestEnvController) BuildGoPlugin(g, v, k string) { + err := x.compiler.Compile(g, v, k) if err != nil { - if os.IsNotExist(err) { - return false - } - } - age := time.Now().Sub(fi.ModTime()) - return age.Minutes() < 1 -} - -func (x *TestEnvController) BuildGoPlugin(plugin ...string) { - obj := filepath.Join( - append([]string{x.ObjectRoot()}, plugin...)...) + ".so" - if x.recentFileExists(obj) { - // Skip rebuilding it. - return - } - src := filepath.Join( - append([]string{x.SrcRoot()}, plugin...)...) + ".go" - if !x.fileExists(src) { - x.t.Errorf("cannot find go plugin source %s", src) - } - commands := []string{ - "build", - "-buildmode", - "plugin", - "-tags=plugin", - "-o", obj, src, - } - goBin := filepath.Join(os.Getenv("GOROOT"), "bin", "go") - if !x.fileExists(src) { - x.t.Errorf("cannot find go compiler %s", goBin) - } - cmd := exec.Command(goBin, commands...) - cmd.Env = os.Environ() - // cmd.Dir = filepath.Join(dir, "kustomize", "plugins") - - if err := cmd.Run(); err != nil { - x.t.Errorf("compiler error building %s: %v", src, err) + x.t.Errorf("compile failed: %v", err) } } -// ObjectRoot is the objRoot dir for plugin object files. -func (x *TestEnvController) ObjectRoot() string { - return filepath.Join( - x.xdgConfigHome, pgmconfig.PgmName, plugin.PluginRoot) -} - -// SrcRoot is a objRoot directory for plugin source code -// used by tests. -// -// Plugin object code files have to be in a particular -// location to be found and loaded for security reasons, -// but placement of plugin source code is up to the user. -// -// This function returns a location for storing example -// plugins for tests. And maybe builtins at some point. -func (x *TestEnvController) SrcRoot() string { - dir := filepath.Join( - os.Getenv("GOPATH"), "src", - pgmconfig.Repo, pgmconfig.PgmName, plugin.PluginRoot) - if _, err := os.Stat(dir); err != nil { - x.t.Errorf("plugin source objRoot '%s' not found", dir) +func (x *TestEnvController) makeCompiler() *plugins.Compiler { + // The plugin loader wants to find object code under + // $XDG_CONFIG_HOME/kustomize/plugins + // and the compiler writes object code to + // $objRoot + // so set things up accordingly. + objRoot := filepath.Join( + x.workDir, pgmconfig.ProgramName, plugin.PluginRoot) + err := os.MkdirAll(objRoot, os.ModePerm) + if err != nil { + x.t.Error(err) } - return dir + srcRoot, err := plugins.DefaultSrcRoot() + if err != nil { + x.t.Error(err) + } + return plugins.NewCompiler(srcRoot, objRoot) } -func (x *TestEnvController) makeTmpConfigHomeDir() { +func (x *TestEnvController) createWorkDir() { var err error - x.xdgConfigHome, err = ioutil.TempDir("", "kustomizetests") + x.workDir, err = ioutil.TempDir("", "kustomize-plugin-tests") if err != nil { - x.t.Errorf("failed to make temp objRoot: %v", err) + x.t.Errorf("failed to make work dir: %v", err) } } -func (x *TestEnvController) makeObjectRootDir() { - err := os.MkdirAll(x.ObjectRoot(), os.ModePerm) +func (x *TestEnvController) removeWorkDir() { + err := os.RemoveAll(x.workDir) if err != nil { x.t.Errorf( - "making temp object objRoot %s: %v", x.ObjectRoot(), err) - } -} - -func (x *TestEnvController) removeTmpConfigHomeDir() { - err := os.RemoveAll(x.xdgConfigHome) - if err != nil { - x.t.Errorf( - "removing temp object objRoot: %s %v", x.xdgConfigHome, err) + "removing work dir: %s %v", x.workDir, err) } } func (x *TestEnvController) setEnv() { x.oldXdg, x.wasSet = os.LookupEnv(pgmconfig.XDG_CONFIG_HOME) - os.Setenv(pgmconfig.XDG_CONFIG_HOME, x.xdgConfigHome) + os.Setenv(pgmconfig.XDG_CONFIG_HOME, x.workDir) } func (x *TestEnvController) resetEnv() { From ba43ecbcb7cd098487773dbedec52b3f9c6a7136 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Tue, 9 Apr 2019 11:19:33 -0700 Subject: [PATCH 212/317] add goplugin for exec generators and transformers --- bin/pre-commit.sh | 5 ++ pkg/plugins/builtin/executable.go | 72 +++++++++++++++++++ pkg/plugins/generators.go | 5 +- pkg/plugins/transformers.go | 40 +++++++++-- pkg/target/generatorplugin_test.go | 34 +++++++++ pkg/target/testenvcontroller_test.go | 23 ++++++ .../v1/ConfigMapGenerator | 11 +++ 7 files changed, 180 insertions(+), 10 deletions(-) create mode 100644 pkg/plugins/builtin/executable.go create mode 100755 plugins/someteam.example.com/v1/ConfigMapGenerator diff --git a/bin/pre-commit.sh b/bin/pre-commit.sh index 5e0b45626..67edf1578 100755 --- a/bin/pre-commit.sh +++ b/bin/pre-commit.sh @@ -11,6 +11,10 @@ cd "$base_dir" || { rc=0 +function buildPlugins { +go build -buildmode plugin -tags=plugin -o ./pkg/plugins/builtin/executable.so ./pkg/plugins/builtin/executable.go +} + function runTest { local name=$1 local result="SUCCESS" @@ -36,6 +40,7 @@ function testExamples { mdrip --mode test --label test README.md ./examples } +runTest buildPlugins runTest testGoLangCILint runTest testGoTest runTest testExamples diff --git a/pkg/plugins/builtin/executable.go b/pkg/plugins/builtin/executable.go new file mode 100644 index 000000000..f3114f472 --- /dev/null +++ b/pkg/plugins/builtin/executable.go @@ -0,0 +1,72 @@ +// +build plugin + +package main + +import ( + "bytes" + "os" + "os/exec" + "path/filepath" + + "github.com/ghodss/yaml" + "sigs.k8s.io/kustomize/pkg/ifc" + "sigs.k8s.io/kustomize/pkg/pgmconfig" + "sigs.k8s.io/kustomize/pkg/resmap" +) + +type plugin struct { + name string + input string + rf *resmap.Factory +} + +var KustomizePlugin plugin + +func (p *plugin) Config( + ldr ifc.Loader, rf *resmap.Factory, k ifc.Kunstructured) error { + dir := filepath.Join(pgmconfig.ConfigRoot(), "plugins") + id := k.GetGvk() + p.name = filepath.Join(dir, id.Group, id.Version, id.Kind) + content, err := yaml.Marshal(k) + if err != nil { + return err + } + p.input = string(content) + p.rf = rf + return nil +} + +func (p *plugin) Generate() (resmap.ResMap, error) { + return p.run(nil) +} + +func (p *plugin) Transformer(rm resmap.ResMap) error { + result, err := p.run(rm) + if err != nil { + return err + } + for id := range rm { + delete(rm, id) + } + for id, r := range result { + rm[id] = r + } + return nil +} + +func (p *plugin) run(rm resmap.ResMap) (resmap.ResMap, error) { + cmd := exec.Command(p.name, p.input) + cmd.Env = os.Environ() + if rm != nil { + content, err := rm.EncodeAsYaml() + if err != nil { + return nil, err + } + cmd.Stdin = bytes.NewReader(content) + } + output, err := cmd.Output() + if err != nil { + return nil, err + } + return p.rf.NewResMapFromBytes(output) +} diff --git a/pkg/plugins/generators.go b/pkg/plugins/generators.go index d40707e44..61ec5f156 100644 --- a/pkg/plugins/generators.go +++ b/pkg/plugins/generators.go @@ -47,14 +47,13 @@ func (l generatorLoader) Load( } var result []transformers.Generator for id, res := range rm { - fileName := pluginFileName(l.pc, id) - c, err := loadAndConfigurePlugin(fileName, l.ldr, l.rf, res) + c, err := loadAndConfigurePlugin(l.pc.DirectoryPath, id, l.ldr, l.rf, res) if err != nil { return nil, err } g, ok := c.(transformers.Generator) if !ok { - return nil, fmt.Errorf("plugin %s not a generator", fileName) + return nil, fmt.Errorf("plugin %s not a generator", id.String()) } result = append(result, g) } diff --git a/pkg/plugins/transformers.go b/pkg/plugins/transformers.go index c691fb7e4..920446dd9 100644 --- a/pkg/plugins/transformers.go +++ b/pkg/plugins/transformers.go @@ -18,8 +18,10 @@ package plugins import ( "fmt" + "os" "path/filepath" "plugin" + "runtime" "github.com/pkg/errors" kplugin "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" @@ -57,29 +59,53 @@ func (l transformerLoader) Load( } var result []transformers.Transformer for id, res := range rm { - fileName := pluginFileName(l.pc, id) - c, err := loadAndConfigurePlugin(fileName, l.ldr, l.rf, res) + c, err := loadAndConfigurePlugin(l.pc.DirectoryPath, id, l.ldr, l.rf, res) if err != nil { return nil, err } t, ok := c.(transformers.Transformer) if !ok { - return nil, fmt.Errorf("plugin %s not a transformer", fileName) + return nil, fmt.Errorf("plugin %s not a transformer", id.String()) } result = append(result, t) } return result, nil } -func pluginFileName(pc *types.PluginConfig, id resid.ResId) string { +func goPluginFileName(dir string, id resid.ResId) string { + return execPluginFileName(dir, id) + ".so" +} + +func execPluginFileName(dir string, id resid.ResId) string { return filepath.Join( - pc.DirectoryPath, - id.Gvk().Group, id.Gvk().Version, id.Gvk().Kind+".so") + dir, + id.Gvk().Group, id.Gvk().Version, id.Gvk().Kind) +} + +// isExecAvailable checks if an executable is available +func isExecAvailable(name string) bool { + f, err := os.Stat(name) + if os.IsNotExist(err) { + return false + } + if f.Mode()&0111 != 0000 { + return true + } + return false } func loadAndConfigurePlugin( - fileName string, ldr ifc.Loader, + dir string, id resid.ResId, + ldr ifc.Loader, rf *resmap.Factory, res *resource.Resource) (Configurable, error) { + var fileName string + exec := execPluginFileName(dir, id) + if isExecAvailable(exec) { + _, f, _, _ := runtime.Caller(1) + fileName = filepath.Join(filepath.Dir(f), "builtin", "executable.so") + } else { + fileName = goPluginFileName(dir, id) + } goPlugin, err := plugin.Open(fileName) if err != nil { return nil, errors.Wrapf(err, "plugin %s fails to load", fileName) diff --git a/pkg/target/generatorplugin_test.go b/pkg/target/generatorplugin_test.go index 097417efd..d64d4ff02 100644 --- a/pkg/target/generatorplugin_test.go +++ b/pkg/target/generatorplugin_test.go @@ -127,3 +127,37 @@ metadata: type: Opaque `) } + +func TestConfigMapGenerator(t *testing.T) { + tc := NewTestEnvController(t).Set() + //defer tc.Reset() + + tc.BuildExecPlugin( + "someteam.example.com", "v1", "ConfigMapGenerator") + + th := NewKustTestHarnessWithPluginConfig( + t, "/app", plugin.ActivePluginConfig()) + th.writeK("/app", ` +generators: +- configmapGenerator.yaml +`) + th.writeF("/app/configmapGenerator.yaml", ` +apiVersion: someteam.example.com/v1 +kind: ConfigMapGenerator +metadata: + name: some-random-name +`) + m, err := th.makeKustTarget().MakeCustomizedResMap() + if err != nil { + t.Fatalf("Err: %v", err) + } + th.assertActualEqualsExpected(m, ` +apiVersion: v1 +data: + password: secret + username: admin +kind: ConfigMap +metadata: + name: example-configmap-test +`) +} diff --git a/pkg/target/testenvcontroller_test.go b/pkg/target/testenvcontroller_test.go index f68c182f1..58ed53d3c 100644 --- a/pkg/target/testenvcontroller_test.go +++ b/pkg/target/testenvcontroller_test.go @@ -16,6 +16,7 @@ package target_test import ( "io/ioutil" "os" + "os/exec" "path/filepath" "sigs.k8s.io/kustomize/k8sdeps/kv/plugin" "testing" @@ -57,6 +58,28 @@ func (x *TestEnvController) BuildGoPlugin(g, v, k string) { } } +func (x *TestEnvController) BuildExecPlugin(name ...string) { + obj := filepath.Join( + append([]string{x.workDir, pgmconfig.ProgramName, plugin.PluginRoot}, name...)...) + + srcRoot, err := plugins.DefaultSrcRoot() + if err != nil { + x.t.Error(err) + } + + src := filepath.Join( + append([]string{srcRoot}, name...)...) + + if err := os.MkdirAll(filepath.Dir(obj), 0755); err != nil { + x.t.Errorf("error making directory: %s", filepath.Dir(obj)) + } + cmd := exec.Command("cp", src, obj) + cmd.Env = os.Environ() + if err := cmd.Run(); err != nil { + x.t.Errorf("error copying %s: %v", src, err) + } +} + func (x *TestEnvController) makeCompiler() *plugins.Compiler { // The plugin loader wants to find object code under // $XDG_CONFIG_HOME/kustomize/plugins diff --git a/plugins/someteam.example.com/v1/ConfigMapGenerator b/plugins/someteam.example.com/v1/ConfigMapGenerator new file mode 100755 index 000000000..d0df0adaa --- /dev/null +++ b/plugins/someteam.example.com/v1/ConfigMapGenerator @@ -0,0 +1,11 @@ +#!/bin/bash + +echo " +kind: ConfigMap +apiVersion: v1 +metadata: + name: example-configmap-test +data: + username: admin + password: secret +" \ No newline at end of file From e5d730e1fea6ce52d279e4fc3ddee5477df85cc7 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Tue, 9 Apr 2019 15:39:56 -0700 Subject: [PATCH 213/317] address comments --- pkg/plugins/transformers.go | 5 +---- pkg/target/generatorplugin_test.go | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/pkg/plugins/transformers.go b/pkg/plugins/transformers.go index 920446dd9..661ccc2b7 100644 --- a/pkg/plugins/transformers.go +++ b/pkg/plugins/transformers.go @@ -88,10 +88,7 @@ func isExecAvailable(name string) bool { if os.IsNotExist(err) { return false } - if f.Mode()&0111 != 0000 { - return true - } - return false + return f.Mode()&0111 != 0000 } func loadAndConfigurePlugin( diff --git a/pkg/target/generatorplugin_test.go b/pkg/target/generatorplugin_test.go index d64d4ff02..2da781936 100644 --- a/pkg/target/generatorplugin_test.go +++ b/pkg/target/generatorplugin_test.go @@ -130,7 +130,7 @@ type: Opaque func TestConfigMapGenerator(t *testing.T) { tc := NewTestEnvController(t).Set() - //defer tc.Reset() + defer tc.Reset() tc.BuildExecPlugin( "someteam.example.com", "v1", "ConfigMapGenerator") From e191ff53ddd4d680c84aeac40703d0af36decc83 Mon Sep 17 00:00:00 2001 From: Jeffrey Regan Date: Thu, 11 Apr 2019 16:45:55 -0700 Subject: [PATCH 214/317] Switch to vgo --- .travis.yml | 26 +- Gopkg.lock | 389 - Gopkg.toml | 58 - bin/pre-commit.sh | 52 +- go.mod | 38 + go.sum | 88 + pkg/target/generatorplugin_test.go | 2 +- vendor/github.com/PuerkitoBio/purell/LICENSE | 12 - .../github.com/PuerkitoBio/purell/purell.go | 379 - vendor/github.com/PuerkitoBio/urlesc/LICENSE | 27 - .../github.com/PuerkitoBio/urlesc/urlesc.go | 180 - vendor/github.com/davecgh/go-spew/LICENSE | 15 - .../github.com/davecgh/go-spew/spew/bypass.go | 152 - .../davecgh/go-spew/spew/bypasssafe.go | 38 - .../github.com/davecgh/go-spew/spew/common.go | 341 - .../github.com/davecgh/go-spew/spew/config.go | 306 - vendor/github.com/davecgh/go-spew/spew/doc.go | 211 - .../github.com/davecgh/go-spew/spew/dump.go | 509 - .../github.com/davecgh/go-spew/spew/format.go | 419 - .../github.com/davecgh/go-spew/spew/spew.go | 148 - vendor/github.com/emicklei/go-restful/LICENSE | 22 - .../emicklei/go-restful/compress.go | 123 - .../emicklei/go-restful/compressor_cache.go | 103 - .../emicklei/go-restful/compressor_pools.go | 91 - .../emicklei/go-restful/compressors.go | 54 - .../emicklei/go-restful/constants.go | 30 - .../emicklei/go-restful/container.go | 371 - .../emicklei/go-restful/cors_filter.go | 202 - .../github.com/emicklei/go-restful/curly.go | 164 - .../emicklei/go-restful/curly_route.go | 52 - vendor/github.com/emicklei/go-restful/doc.go | 185 - .../emicklei/go-restful/entity_accessors.go | 169 - .../github.com/emicklei/go-restful/filter.go | 35 - .../github.com/emicklei/go-restful/jsr311.go | 293 - .../github.com/emicklei/go-restful/log/log.go | 34 - .../github.com/emicklei/go-restful/logger.go | 32 - vendor/github.com/emicklei/go-restful/mime.go | 45 - .../emicklei/go-restful/options_filter.go | 34 - .../emicklei/go-restful/parameter.go | 143 - .../emicklei/go-restful/path_expression.go | 74 - .../emicklei/go-restful/path_processor.go | 63 - .../github.com/emicklei/go-restful/request.go | 113 - .../emicklei/go-restful/response.go | 250 - .../github.com/emicklei/go-restful/route.go | 149 - .../emicklei/go-restful/route_builder.go | 321 - .../github.com/emicklei/go-restful/router.go | 20 - .../emicklei/go-restful/service_error.go | 23 - .../emicklei/go-restful/web_service.go | 290 - .../go-restful/web_service_container.go | 39 - vendor/github.com/evanphx/json-patch/LICENSE | 25 - vendor/github.com/evanphx/json-patch/merge.go | 383 - vendor/github.com/evanphx/json-patch/patch.go | 663 - vendor/github.com/ghodss/yaml/LICENSE | 50 - vendor/github.com/ghodss/yaml/fields.go | 501 - vendor/github.com/ghodss/yaml/yaml.go | 277 - .../github.com/go-openapi/jsonpointer/LICENSE | 202 - .../go-openapi/jsonpointer/pointer.go | 390 - .../go-openapi/jsonreference/LICENSE | 202 - .../go-openapi/jsonreference/reference.go | 156 - vendor/github.com/go-openapi/spec/LICENSE | 202 - vendor/github.com/go-openapi/spec/bindata.go | 260 - .../go-openapi/spec/contact_info.go | 24 - vendor/github.com/go-openapi/spec/expander.go | 1048 - .../go-openapi/spec/external_docs.go | 24 - vendor/github.com/go-openapi/spec/header.go | 195 - vendor/github.com/go-openapi/spec/info.go | 168 - vendor/github.com/go-openapi/spec/items.go | 229 - vendor/github.com/go-openapi/spec/license.go | 23 - .../github.com/go-openapi/spec/operation.go | 258 - .../github.com/go-openapi/spec/parameter.go | 301 - .../github.com/go-openapi/spec/path_item.go | 90 - vendor/github.com/go-openapi/spec/paths.go | 97 - vendor/github.com/go-openapi/spec/ref.go | 167 - vendor/github.com/go-openapi/spec/response.go | 134 - .../github.com/go-openapi/spec/responses.go | 122 - vendor/github.com/go-openapi/spec/schema.go | 634 - .../go-openapi/spec/security_scheme.go | 142 - vendor/github.com/go-openapi/spec/spec.go | 86 - vendor/github.com/go-openapi/spec/swagger.go | 317 - vendor/github.com/go-openapi/spec/tag.go | 73 - .../github.com/go-openapi/spec/xml_object.go | 68 - vendor/github.com/go-openapi/swag/LICENSE | 202 - vendor/github.com/go-openapi/swag/convert.go | 188 - .../go-openapi/swag/convert_types.go | 595 - vendor/github.com/go-openapi/swag/json.go | 310 - vendor/github.com/go-openapi/swag/loading.go | 80 - vendor/github.com/go-openapi/swag/net.go | 24 - vendor/github.com/go-openapi/swag/path.go | 59 - .../github.com/go-openapi/swag/post_go18.go | 9 - vendor/github.com/go-openapi/swag/pre_go18.go | 9 - vendor/github.com/go-openapi/swag/util.go | 362 - vendor/github.com/go-openapi/swag/yaml.go | 216 - vendor/github.com/gogo/protobuf/AUTHORS | 15 - vendor/github.com/gogo/protobuf/CONTRIBUTORS | 23 - .../gogo/protobuf/GOLANG_CONTRIBUTORS | 5 - vendor/github.com/gogo/protobuf/LICENSE | 36 - .../github.com/gogo/protobuf/proto/clone.go | 234 - .../github.com/gogo/protobuf/proto/decode.go | 978 - .../gogo/protobuf/proto/decode_gogo.go | 172 - .../github.com/gogo/protobuf/proto/discard.go | 151 - .../gogo/protobuf/proto/duration.go | 100 - .../gogo/protobuf/proto/duration_gogo.go | 203 - .../github.com/gogo/protobuf/proto/encode.go | 1362 - .../gogo/protobuf/proto/encode_gogo.go | 350 - .../github.com/gogo/protobuf/proto/equal.go | 300 - .../gogo/protobuf/proto/extensions.go | 693 - .../gogo/protobuf/proto/extensions_gogo.go | 294 - vendor/github.com/gogo/protobuf/proto/lib.go | 897 - .../gogo/protobuf/proto/lib_gogo.go | 42 - .../gogo/protobuf/proto/message_set.go | 311 - .../gogo/protobuf/proto/pointer_reflect.go | 484 - .../protobuf/proto/pointer_reflect_gogo.go | 85 - .../gogo/protobuf/proto/pointer_unsafe.go | 270 - .../protobuf/proto/pointer_unsafe_gogo.go | 128 - .../gogo/protobuf/proto/properties.go | 971 - .../gogo/protobuf/proto/properties_gogo.go | 111 - .../gogo/protobuf/proto/skip_gogo.go | 119 - vendor/github.com/gogo/protobuf/proto/text.go | 939 - .../gogo/protobuf/proto/text_gogo.go | 57 - .../gogo/protobuf/proto/text_parser.go | 1013 - .../gogo/protobuf/proto/timestamp.go | 113 - .../gogo/protobuf/proto/timestamp_gogo.go | 229 - .../gogo/protobuf/sortkeys/sortkeys.go | 101 - vendor/github.com/golang/glog/LICENSE | 191 - vendor/github.com/golang/glog/glog.go | 1180 - vendor/github.com/golang/glog/glog_file.go | 124 - vendor/github.com/golang/protobuf/AUTHORS | 3 - .../github.com/golang/protobuf/CONTRIBUTORS | 3 - vendor/github.com/golang/protobuf/LICENSE | 31 - .../github.com/golang/protobuf/proto/clone.go | 253 - .../golang/protobuf/proto/decode.go | 428 - .../golang/protobuf/proto/discard.go | 350 - .../golang/protobuf/proto/encode.go | 221 - .../github.com/golang/protobuf/proto/equal.go | 300 - .../golang/protobuf/proto/extensions.go | 543 - .../github.com/golang/protobuf/proto/lib.go | 921 - .../golang/protobuf/proto/message_set.go | 314 - .../golang/protobuf/proto/pointer_reflect.go | 357 - .../golang/protobuf/proto/pointer_unsafe.go | 308 - .../golang/protobuf/proto/properties.go | 544 - .../golang/protobuf/proto/table_marshal.go | 2681 - .../golang/protobuf/proto/table_merge.go | 654 - .../golang/protobuf/proto/table_unmarshal.go | 1967 - .../github.com/golang/protobuf/proto/text.go | 843 - .../golang/protobuf/proto/text_parser.go | 880 - .../github.com/golang/protobuf/ptypes/any.go | 139 - .../golang/protobuf/ptypes/any/any.pb.go | 191 - .../github.com/golang/protobuf/ptypes/doc.go | 35 - .../golang/protobuf/ptypes/duration.go | 102 - .../protobuf/ptypes/duration/duration.pb.go | 159 - .../golang/protobuf/ptypes/timestamp.go | 134 - .../protobuf/ptypes/timestamp/timestamp.pb.go | 175 - vendor/github.com/google/gofuzz/LICENSE | 202 - vendor/github.com/google/gofuzz/doc.go | 18 - vendor/github.com/google/gofuzz/fuzz.go | 487 - vendor/github.com/googleapis/gnostic/LICENSE | 203 - .../googleapis/gnostic/OpenAPIv2/OpenAPIv2.go | 8728 -- .../gnostic/OpenAPIv2/OpenAPIv2.pb.go | 4456 - .../googleapis/gnostic/compiler/context.go | 43 - .../googleapis/gnostic/compiler/error.go | 61 - .../gnostic/compiler/extension-handler.go | 101 - .../googleapis/gnostic/compiler/helpers.go | 197 - .../googleapis/gnostic/compiler/main.go | 16 - .../googleapis/gnostic/compiler/reader.go | 173 - .../gnostic/extensions/extension.pb.go | 219 - .../gnostic/extensions/extensions.go | 82 - .../inconshreveable/mousetrap/LICENSE | 13 - .../inconshreveable/mousetrap/trap_others.go | 15 - .../inconshreveable/mousetrap/trap_windows.go | 98 - .../mousetrap/trap_windows_1.4.go | 46 - vendor/github.com/json-iterator/go/LICENSE | 21 - vendor/github.com/json-iterator/go/adapter.go | 141 - vendor/github.com/json-iterator/go/any.go | 321 - .../github.com/json-iterator/go/any_array.go | 278 - .../github.com/json-iterator/go/any_bool.go | 137 - .../github.com/json-iterator/go/any_float.go | 83 - .../github.com/json-iterator/go/any_int32.go | 74 - .../github.com/json-iterator/go/any_int64.go | 74 - .../json-iterator/go/any_invalid.go | 82 - vendor/github.com/json-iterator/go/any_nil.go | 69 - .../github.com/json-iterator/go/any_number.go | 123 - .../github.com/json-iterator/go/any_object.go | 374 - vendor/github.com/json-iterator/go/any_str.go | 166 - .../github.com/json-iterator/go/any_uint32.go | 74 - .../github.com/json-iterator/go/any_uint64.go | 74 - vendor/github.com/json-iterator/go/config.go | 368 - vendor/github.com/json-iterator/go/iter.go | 322 - .../github.com/json-iterator/go/iter_array.go | 58 - .../github.com/json-iterator/go/iter_float.go | 347 - .../github.com/json-iterator/go/iter_int.go | 345 - .../json-iterator/go/iter_object.go | 248 - .../github.com/json-iterator/go/iter_skip.go | 129 - .../json-iterator/go/iter_skip_sloppy.go | 144 - .../json-iterator/go/iter_skip_strict.go | 89 - .../github.com/json-iterator/go/iter_str.go | 215 - .../github.com/json-iterator/go/jsoniter.go | 18 - vendor/github.com/json-iterator/go/pool.go | 41 - vendor/github.com/json-iterator/go/reflect.go | 321 - .../json-iterator/go/reflect_array.go | 104 - .../json-iterator/go/reflect_dynamic.go | 70 - .../json-iterator/go/reflect_extension.go | 471 - .../json-iterator/go/reflect_json_number.go | 112 - .../go/reflect_json_raw_message.go | 60 - .../json-iterator/go/reflect_map.go | 318 - .../json-iterator/go/reflect_marshaler.go | 218 - .../json-iterator/go/reflect_native.go | 455 - .../json-iterator/go/reflect_optional.go | 133 - .../json-iterator/go/reflect_slice.go | 99 - .../go/reflect_struct_decoder.go | 1034 - .../go/reflect_struct_encoder.go | 210 - vendor/github.com/json-iterator/go/stream.go | 211 - .../json-iterator/go/stream_float.go | 94 - .../github.com/json-iterator/go/stream_int.go | 190 - .../github.com/json-iterator/go/stream_str.go | 372 - vendor/github.com/mailru/easyjson/LICENSE | 7 - .../github.com/mailru/easyjson/buffer/pool.go | 270 - .../mailru/easyjson/jlexer/bytestostr.go | 24 - .../easyjson/jlexer/bytestostr_nounsafe.go | 13 - .../mailru/easyjson/jlexer/error.go | 15 - .../mailru/easyjson/jlexer/lexer.go | 1176 - .../mailru/easyjson/jwriter/writer.go | 390 - .../github.com/modern-go/concurrent/LICENSE | 201 - .../modern-go/concurrent/executor.go | 14 - .../modern-go/concurrent/go_above_19.go | 15 - .../modern-go/concurrent/go_below_19.go | 33 - vendor/github.com/modern-go/concurrent/log.go | 13 - .../concurrent/unbounded_executor.go | 119 - vendor/github.com/modern-go/reflect2/LICENSE | 201 - .../modern-go/reflect2/go_above_17.go | 8 - .../modern-go/reflect2/go_above_19.go | 14 - .../modern-go/reflect2/go_below_17.go | 9 - .../modern-go/reflect2/go_below_19.go | 14 - .../github.com/modern-go/reflect2/reflect2.go | 282 - .../modern-go/reflect2/reflect2_amd64.s | 0 .../modern-go/reflect2/reflect2_kind.go | 30 - .../modern-go/reflect2/relfect2_386.s | 0 .../modern-go/reflect2/relfect2_amd64p32.s | 0 .../modern-go/reflect2/relfect2_arm.s | 0 .../modern-go/reflect2/relfect2_arm64.s | 0 .../modern-go/reflect2/relfect2_mips64x.s | 0 .../modern-go/reflect2/relfect2_mipsx.s | 0 .../modern-go/reflect2/relfect2_ppc64x.s | 0 .../modern-go/reflect2/relfect2_s390x.s | 0 .../modern-go/reflect2/safe_field.go | 58 - .../github.com/modern-go/reflect2/safe_map.go | 101 - .../modern-go/reflect2/safe_slice.go | 92 - .../modern-go/reflect2/safe_struct.go | 13 - .../modern-go/reflect2/safe_type.go | 78 - .../github.com/modern-go/reflect2/type_map.go | 72 - .../modern-go/reflect2/unsafe_array.go | 65 - .../modern-go/reflect2/unsafe_eface.go | 59 - .../modern-go/reflect2/unsafe_field.go | 74 - .../modern-go/reflect2/unsafe_iface.go | 64 - .../modern-go/reflect2/unsafe_link.go | 70 - .../modern-go/reflect2/unsafe_map.go | 138 - .../modern-go/reflect2/unsafe_ptr.go | 46 - .../modern-go/reflect2/unsafe_slice.go | 177 - .../modern-go/reflect2/unsafe_struct.go | 59 - .../modern-go/reflect2/unsafe_type.go | 85 - vendor/github.com/pkg/errors/LICENSE | 23 - vendor/github.com/pkg/errors/errors.go | 269 - vendor/github.com/pkg/errors/stack.go | 178 - vendor/github.com/spf13/cobra/LICENSE.txt | 174 - vendor/github.com/spf13/cobra/args.go | 89 - .../spf13/cobra/bash_completions.go | 555 - vendor/github.com/spf13/cobra/cobra.go | 200 - .../cobra/cobra/cmd/testdata/LICENSE.golden | 202 - vendor/github.com/spf13/cobra/command.go | 1507 - .../github.com/spf13/cobra/command_notwin.go | 5 - vendor/github.com/spf13/cobra/command_win.go | 20 - .../github.com/spf13/cobra/zsh_completions.go | 126 - vendor/github.com/spf13/pflag/LICENSE | 28 - vendor/github.com/spf13/pflag/bool.go | 94 - vendor/github.com/spf13/pflag/bool_slice.go | 147 - vendor/github.com/spf13/pflag/bytes.go | 105 - vendor/github.com/spf13/pflag/count.go | 96 - vendor/github.com/spf13/pflag/duration.go | 86 - .../github.com/spf13/pflag/duration_slice.go | 128 - vendor/github.com/spf13/pflag/flag.go | 1223 - vendor/github.com/spf13/pflag/float32.go | 88 - vendor/github.com/spf13/pflag/float64.go | 84 - vendor/github.com/spf13/pflag/golangflag.go | 105 - vendor/github.com/spf13/pflag/int.go | 84 - vendor/github.com/spf13/pflag/int16.go | 88 - vendor/github.com/spf13/pflag/int32.go | 88 - vendor/github.com/spf13/pflag/int64.go | 84 - vendor/github.com/spf13/pflag/int8.go | 88 - vendor/github.com/spf13/pflag/int_slice.go | 128 - vendor/github.com/spf13/pflag/ip.go | 94 - vendor/github.com/spf13/pflag/ip_slice.go | 148 - vendor/github.com/spf13/pflag/ipmask.go | 122 - vendor/github.com/spf13/pflag/ipnet.go | 98 - vendor/github.com/spf13/pflag/string.go | 80 - vendor/github.com/spf13/pflag/string_array.go | 103 - vendor/github.com/spf13/pflag/string_slice.go | 149 - vendor/github.com/spf13/pflag/uint.go | 88 - vendor/github.com/spf13/pflag/uint16.go | 88 - vendor/github.com/spf13/pflag/uint32.go | 88 - vendor/github.com/spf13/pflag/uint64.go | 88 - vendor/github.com/spf13/pflag/uint8.go | 88 - vendor/github.com/spf13/pflag/uint_slice.go | 126 - vendor/golang.org/x/net/AUTHORS | 3 - vendor/golang.org/x/net/CONTRIBUTORS | 3 - vendor/golang.org/x/net/LICENSE | 27 - vendor/golang.org/x/net/PATENTS | 22 - vendor/golang.org/x/net/http/httpguts/guts.go | 50 - .../golang.org/x/net/http/httpguts/httplex.go | 346 - vendor/golang.org/x/net/http2/ciphers.go | 641 - .../x/net/http2/client_conn_pool.go | 282 - vendor/golang.org/x/net/http2/databuffer.go | 146 - vendor/golang.org/x/net/http2/errors.go | 133 - vendor/golang.org/x/net/http2/flow.go | 50 - vendor/golang.org/x/net/http2/frame.go | 1614 - vendor/golang.org/x/net/http2/go111.go | 29 - vendor/golang.org/x/net/http2/gotrack.go | 170 - vendor/golang.org/x/net/http2/headermap.go | 88 - vendor/golang.org/x/net/http2/hpack/encode.go | 240 - vendor/golang.org/x/net/http2/hpack/hpack.go | 504 - .../golang.org/x/net/http2/hpack/huffman.go | 222 - vendor/golang.org/x/net/http2/hpack/tables.go | 479 - vendor/golang.org/x/net/http2/http2.go | 384 - vendor/golang.org/x/net/http2/not_go111.go | 20 - vendor/golang.org/x/net/http2/pipe.go | 163 - vendor/golang.org/x/net/http2/server.go | 2895 - vendor/golang.org/x/net/http2/transport.go | 2603 - vendor/golang.org/x/net/http2/write.go | 365 - vendor/golang.org/x/net/http2/writesched.go | 242 - .../x/net/http2/writesched_priority.go | 452 - .../x/net/http2/writesched_random.go | 72 - vendor/golang.org/x/net/idna/idna.go | 732 - vendor/golang.org/x/net/idna/punycode.go | 203 - vendor/golang.org/x/net/idna/tables.go | 4557 - vendor/golang.org/x/net/idna/trie.go | 72 - vendor/golang.org/x/net/idna/trieval.go | 119 - vendor/golang.org/x/text/AUTHORS | 3 - vendor/golang.org/x/text/CONTRIBUTORS | 3 - vendor/golang.org/x/text/LICENSE | 27 - vendor/golang.org/x/text/PATENTS | 22 - .../x/text/collate/build/builder.go | 702 - .../x/text/collate/build/colelem.go | 294 - .../x/text/collate/build/contract.go | 309 - .../golang.org/x/text/collate/build/order.go | 393 - .../golang.org/x/text/collate/build/table.go | 81 - .../golang.org/x/text/collate/build/trie.go | 290 - vendor/golang.org/x/text/collate/collate.go | 403 - vendor/golang.org/x/text/collate/index.go | 32 - .../golang.org/x/text/collate/maketables.go | 553 - vendor/golang.org/x/text/collate/option.go | 239 - vendor/golang.org/x/text/collate/sort.go | 81 - vendor/golang.org/x/text/collate/tables.go | 73789 ---------------- .../x/text/internal/colltab/collelem.go | 371 - .../x/text/internal/colltab/colltab.go | 105 - .../x/text/internal/colltab/contract.go | 145 - .../x/text/internal/colltab/iter.go | 178 - .../x/text/internal/colltab/numeric.go | 236 - .../x/text/internal/colltab/table.go | 275 - .../x/text/internal/colltab/trie.go | 159 - .../x/text/internal/colltab/weighter.go | 31 - vendor/golang.org/x/text/internal/gen/code.go | 369 - vendor/golang.org/x/text/internal/gen/gen.go | 333 - vendor/golang.org/x/text/internal/tag/tag.go | 100 - .../x/text/internal/triegen/compact.go | 58 - .../x/text/internal/triegen/print.go | 251 - .../x/text/internal/triegen/triegen.go | 494 - vendor/golang.org/x/text/internal/ucd/ucd.go | 371 - vendor/golang.org/x/text/language/common.go | 16 - vendor/golang.org/x/text/language/coverage.go | 197 - vendor/golang.org/x/text/language/doc.go | 102 - vendor/golang.org/x/text/language/gen.go | 1712 - .../golang.org/x/text/language/gen_common.go | 20 - .../golang.org/x/text/language/gen_index.go | 162 - vendor/golang.org/x/text/language/go1_1.go | 38 - vendor/golang.org/x/text/language/go1_2.go | 11 - vendor/golang.org/x/text/language/index.go | 783 - vendor/golang.org/x/text/language/language.go | 907 - vendor/golang.org/x/text/language/lookup.go | 396 - vendor/golang.org/x/text/language/match.go | 933 - vendor/golang.org/x/text/language/parse.go | 859 - vendor/golang.org/x/text/language/tables.go | 3686 - vendor/golang.org/x/text/language/tags.go | 143 - .../x/text/secure/bidirule/bidirule.go | 336 - .../x/text/secure/bidirule/bidirule10.0.0.go | 11 - .../x/text/secure/bidirule/bidirule9.0.0.go | 14 - .../golang.org/x/text/transform/transform.go | 705 - vendor/golang.org/x/text/unicode/bidi/bidi.go | 198 - .../golang.org/x/text/unicode/bidi/bracket.go | 335 - vendor/golang.org/x/text/unicode/bidi/core.go | 1058 - vendor/golang.org/x/text/unicode/bidi/gen.go | 133 - .../x/text/unicode/bidi/gen_ranges.go | 57 - .../x/text/unicode/bidi/gen_trieval.go | 64 - vendor/golang.org/x/text/unicode/bidi/prop.go | 206 - .../x/text/unicode/bidi/tables10.0.0.go | 1815 - .../x/text/unicode/bidi/tables9.0.0.go | 1781 - .../golang.org/x/text/unicode/bidi/trieval.go | 60 - vendor/golang.org/x/text/unicode/cldr/base.go | 105 - vendor/golang.org/x/text/unicode/cldr/cldr.go | 130 - .../golang.org/x/text/unicode/cldr/collate.go | 359 - .../golang.org/x/text/unicode/cldr/decode.go | 171 - .../golang.org/x/text/unicode/cldr/makexml.go | 400 - .../golang.org/x/text/unicode/cldr/resolve.go | 602 - .../golang.org/x/text/unicode/cldr/slice.go | 144 - vendor/golang.org/x/text/unicode/cldr/xml.go | 1494 - .../x/text/unicode/norm/composition.go | 508 - .../x/text/unicode/norm/forminfo.go | 259 - .../golang.org/x/text/unicode/norm/input.go | 109 - vendor/golang.org/x/text/unicode/norm/iter.go | 457 - .../x/text/unicode/norm/maketables.go | 976 - .../x/text/unicode/norm/normalize.go | 609 - .../x/text/unicode/norm/readwriter.go | 125 - .../x/text/unicode/norm/tables10.0.0.go | 7653 -- .../x/text/unicode/norm/tables9.0.0.go | 7633 -- .../x/text/unicode/norm/transform.go | 88 - vendor/golang.org/x/text/unicode/norm/trie.go | 54 - .../golang.org/x/text/unicode/norm/triegen.go | 117 - .../x/text/unicode/rangetable/gen.go | 115 - .../x/text/unicode/rangetable/merge.go | 260 - .../x/text/unicode/rangetable/rangetable.go | 70 - .../x/text/unicode/rangetable/tables10.0.0.go | 6378 -- .../x/text/unicode/rangetable/tables9.0.0.go | 5737 -- vendor/golang.org/x/text/width/gen.go | 115 - vendor/golang.org/x/text/width/gen_common.go | 96 - vendor/golang.org/x/text/width/gen_trieval.go | 34 - vendor/golang.org/x/text/width/kind_string.go | 16 - .../golang.org/x/text/width/tables10.0.0.go | 1318 - vendor/golang.org/x/text/width/tables9.0.0.go | 1286 - vendor/golang.org/x/text/width/transform.go | 239 - vendor/golang.org/x/text/width/trieval.go | 30 - vendor/golang.org/x/text/width/width.go | 206 - vendor/gopkg.in/inf.v0/LICENSE | 28 - vendor/gopkg.in/inf.v0/dec.go | 615 - vendor/gopkg.in/inf.v0/rounder.go | 145 - vendor/gopkg.in/yaml.v2/LICENSE | 201 - vendor/gopkg.in/yaml.v2/LICENSE.libyaml | 31 - vendor/gopkg.in/yaml.v2/NOTICE | 13 - vendor/gopkg.in/yaml.v2/apic.go | 739 - vendor/gopkg.in/yaml.v2/decode.go | 775 - vendor/gopkg.in/yaml.v2/emitterc.go | 1685 - vendor/gopkg.in/yaml.v2/encode.go | 362 - vendor/gopkg.in/yaml.v2/parserc.go | 1095 - vendor/gopkg.in/yaml.v2/readerc.go | 412 - vendor/gopkg.in/yaml.v2/resolve.go | 258 - vendor/gopkg.in/yaml.v2/scannerc.go | 2696 - vendor/gopkg.in/yaml.v2/sorter.go | 113 - vendor/gopkg.in/yaml.v2/writerc.go | 26 - vendor/gopkg.in/yaml.v2/yaml.go | 466 - vendor/gopkg.in/yaml.v2/yamlh.go | 738 - vendor/gopkg.in/yaml.v2/yamlprivateh.go | 173 - vendor/k8s.io/api/LICENSE | 202 - .../api/admissionregistration/v1alpha1/doc.go | 25 - .../v1alpha1/generated.pb.go | 1028 - .../v1alpha1/register.go | 51 - .../admissionregistration/v1alpha1/types.go | 106 - .../v1alpha1/types_swagger_doc_generated.go | 71 - .../v1alpha1/zz_generated.deepcopy.go | 145 - .../api/admissionregistration/v1beta1/doc.go | 25 - .../v1beta1/generated.pb.go | 2150 - .../admissionregistration/v1beta1/register.go | 53 - .../admissionregistration/v1beta1/types.go | 281 - .../v1beta1/types_swagger_doc_generated.go | 125 - .../v1beta1/zz_generated.deepcopy.go | 317 - vendor/k8s.io/api/apps/v1/doc.go | 20 - vendor/k8s.io/api/apps/v1/generated.pb.go | 6945 -- vendor/k8s.io/api/apps/v1/register.go | 60 - vendor/k8s.io/api/apps/v1/types.go | 819 - .../apps/v1/types_swagger_doc_generated.go | 365 - .../api/apps/v1/zz_generated.deepcopy.go | 856 - vendor/k8s.io/api/apps/v1beta1/doc.go | 20 - .../k8s.io/api/apps/v1beta1/generated.pb.go | 5291 -- vendor/k8s.io/api/apps/v1beta1/register.go | 58 - vendor/k8s.io/api/apps/v1beta1/types.go | 568 - .../v1beta1/types_swagger_doc_generated.go | 273 - .../api/apps/v1beta1/zz_generated.deepcopy.go | 658 - vendor/k8s.io/api/apps/v1beta2/doc.go | 20 - .../k8s.io/api/apps/v1beta2/generated.pb.go | 7586 -- vendor/k8s.io/api/apps/v1beta2/register.go | 61 - vendor/k8s.io/api/apps/v1beta2/types.go | 877 - .../v1beta2/types_swagger_doc_generated.go | 396 - .../api/apps/v1beta2/zz_generated.deepcopy.go | 923 - vendor/k8s.io/api/authentication/v1/doc.go | 20 - .../api/authentication/v1/generated.pb.go | 2148 - .../k8s.io/api/authentication/v1/register.go | 52 - vendor/k8s.io/api/authentication/v1/types.go | 168 - .../v1/types_swagger_doc_generated.go | 113 - .../v1/zz_generated.deepcopy.go | 239 - .../k8s.io/api/authentication/v1beta1/doc.go | 20 - .../authentication/v1beta1/generated.pb.go | 1302 - .../api/authentication/v1beta1/register.go | 51 - .../api/authentication/v1beta1/types.go | 92 - .../v1beta1/types_swagger_doc_generated.go | 72 - .../v1beta1/zz_generated.deepcopy.go | 139 - vendor/k8s.io/api/authorization/v1/doc.go | 21 - .../api/authorization/v1/generated.pb.go | 3528 - .../k8s.io/api/authorization/v1/register.go | 55 - vendor/k8s.io/api/authorization/v1/types.go | 268 - .../v1/types_swagger_doc_generated.go | 173 - .../authorization/v1/zz_generated.deepcopy.go | 398 - .../k8s.io/api/authorization/v1beta1/doc.go | 21 - .../api/authorization/v1beta1/generated.pb.go | 3529 - .../api/authorization/v1beta1/register.go | 55 - .../k8s.io/api/authorization/v1beta1/types.go | 268 - .../v1beta1/types_swagger_doc_generated.go | 173 - .../v1beta1/zz_generated.deepcopy.go | 398 - vendor/k8s.io/api/autoscaling/v1/doc.go | 20 - .../k8s.io/api/autoscaling/v1/generated.pb.go | 4420 - vendor/k8s.io/api/autoscaling/v1/register.go | 53 - vendor/k8s.io/api/autoscaling/v1/types.go | 396 - .../v1/types_swagger_doc_generated.go | 244 - .../autoscaling/v1/zz_generated.deepcopy.go | 569 - vendor/k8s.io/api/autoscaling/v2beta1/doc.go | 20 - .../api/autoscaling/v2beta1/generated.pb.go | 4036 - .../api/autoscaling/v2beta1/register.go | 52 - .../k8s.io/api/autoscaling/v2beta1/types.go | 372 - .../v2beta1/types_swagger_doc_generated.go | 215 - .../v2beta1/zz_generated.deepcopy.go | 512 - vendor/k8s.io/api/batch/v1/doc.go | 20 - vendor/k8s.io/api/batch/v1/generated.pb.go | 1615 - vendor/k8s.io/api/batch/v1/register.go | 52 - vendor/k8s.io/api/batch/v1/types.go | 181 - .../batch/v1/types_swagger_doc_generated.go | 94 - .../api/batch/v1/zz_generated.deepcopy.go | 215 - vendor/k8s.io/api/batch/v1beta1/doc.go | 20 - .../k8s.io/api/batch/v1beta1/generated.pb.go | 1509 - vendor/k8s.io/api/batch/v1beta1/register.go | 53 - vendor/k8s.io/api/batch/v1beta1/types.go | 158 - .../v1beta1/types_swagger_doc_generated.go | 96 - .../batch/v1beta1/zz_generated.deepcopy.go | 214 - vendor/k8s.io/api/batch/v2alpha1/doc.go | 20 - .../k8s.io/api/batch/v2alpha1/generated.pb.go | 1510 - vendor/k8s.io/api/batch/v2alpha1/register.go | 53 - vendor/k8s.io/api/batch/v2alpha1/types.go | 156 - .../v2alpha1/types_swagger_doc_generated.go | 96 - .../batch/v2alpha1/zz_generated.deepcopy.go | 214 - vendor/k8s.io/api/certificates/v1beta1/doc.go | 21 - .../api/certificates/v1beta1/generated.pb.go | 1693 - .../api/certificates/v1beta1/register.go | 59 - .../k8s.io/api/certificates/v1beta1/types.go | 155 - .../v1beta1/types_swagger_doc_generated.go | 74 - .../v1beta1/zz_generated.deepcopy.go | 194 - .../api/core/v1/annotation_key_constants.go | 95 - vendor/k8s.io/api/core/v1/doc.go | 21 - vendor/k8s.io/api/core/v1/generated.pb.go | 49949 ----------- vendor/k8s.io/api/core/v1/objectreference.go | 33 - vendor/k8s.io/api/core/v1/register.go | 99 - vendor/k8s.io/api/core/v1/resource.go | 56 - vendor/k8s.io/api/core/v1/taint.go | 33 - vendor/k8s.io/api/core/v1/toleration.go | 56 - vendor/k8s.io/api/core/v1/types.go | 5045 -- .../core/v1/types_swagger_doc_generated.go | 2229 - .../api/core/v1/zz_generated.deepcopy.go | 5822 -- vendor/k8s.io/api/events/v1beta1/doc.go | 21 - .../k8s.io/api/events/v1beta1/generated.pb.go | 1306 - vendor/k8s.io/api/events/v1beta1/register.go | 53 - vendor/k8s.io/api/events/v1beta1/types.go | 122 - .../v1beta1/types_swagger_doc_generated.go | 73 - .../events/v1beta1/zz_generated.deepcopy.go | 125 - vendor/k8s.io/api/extensions/v1beta1/doc.go | 20 - .../api/extensions/v1beta1/generated.pb.go | 12513 --- .../k8s.io/api/extensions/v1beta1/register.go | 66 - vendor/k8s.io/api/extensions/v1beta1/types.go | 1323 - .../v1beta1/types_swagger_doc_generated.go | 644 - .../v1beta1/zz_generated.deepcopy.go | 1588 - vendor/k8s.io/api/networking/v1/doc.go | 20 - .../k8s.io/api/networking/v1/generated.pb.go | 1869 - vendor/k8s.io/api/networking/v1/register.go | 53 - vendor/k8s.io/api/networking/v1/types.go | 203 - .../v1/types_swagger_doc_generated.go | 113 - .../networking/v1/zz_generated.deepcopy.go | 282 - vendor/k8s.io/api/policy/v1beta1/doc.go | 23 - .../k8s.io/api/policy/v1beta1/generated.pb.go | 3916 - vendor/k8s.io/api/policy/v1beta1/register.go | 56 - vendor/k8s.io/api/policy/v1beta1/types.go | 370 - .../v1beta1/types_swagger_doc_generated.go | 207 - .../policy/v1beta1/zz_generated.deepcopy.go | 475 - vendor/k8s.io/api/rbac/v1/doc.go | 21 - vendor/k8s.io/api/rbac/v1/generated.pb.go | 2749 - vendor/k8s.io/api/rbac/v1/register.go | 58 - vendor/k8s.io/api/rbac/v1/types.go | 235 - .../rbac/v1/types_swagger_doc_generated.go | 158 - .../api/rbac/v1/zz_generated.deepcopy.go | 393 - vendor/k8s.io/api/rbac/v1alpha1/doc.go | 21 - .../k8s.io/api/rbac/v1alpha1/generated.pb.go | 2750 - vendor/k8s.io/api/rbac/v1alpha1/register.go | 58 - vendor/k8s.io/api/rbac/v1alpha1/types.go | 237 - .../v1alpha1/types_swagger_doc_generated.go | 158 - .../rbac/v1alpha1/zz_generated.deepcopy.go | 393 - vendor/k8s.io/api/rbac/v1beta1/doc.go | 21 - .../k8s.io/api/rbac/v1beta1/generated.pb.go | 2750 - vendor/k8s.io/api/rbac/v1beta1/register.go | 58 - vendor/k8s.io/api/rbac/v1beta1/types.go | 235 - .../v1beta1/types_swagger_doc_generated.go | 158 - .../api/rbac/v1beta1/zz_generated.deepcopy.go | 393 - vendor/k8s.io/api/scheduling/v1alpha1/doc.go | 21 - .../api/scheduling/v1alpha1/generated.pb.go | 641 - .../api/scheduling/v1alpha1/register.go | 52 - .../k8s.io/api/scheduling/v1alpha1/types.go | 66 - .../v1alpha1/types_swagger_doc_generated.go | 52 - .../v1alpha1/zz_generated.deepcopy.go | 84 - vendor/k8s.io/api/settings/v1alpha1/doc.go | 21 - .../api/settings/v1alpha1/generated.pb.go | 930 - .../k8s.io/api/settings/v1alpha1/register.go | 52 - vendor/k8s.io/api/settings/v1alpha1/types.go | 70 - .../v1alpha1/types_swagger_doc_generated.go | 61 - .../v1alpha1/zz_generated.deepcopy.go | 131 - vendor/k8s.io/api/storage/v1/doc.go | 20 - vendor/k8s.io/api/storage/v1/generated.pb.go | 926 - vendor/k8s.io/api/storage/v1/register.go | 53 - vendor/k8s.io/api/storage/v1/types.go | 98 - .../storage/v1/types_swagger_doc_generated.go | 55 - .../api/storage/v1/zz_generated.deepcopy.go | 124 - vendor/k8s.io/api/storage/v1alpha1/doc.go | 20 - .../api/storage/v1alpha1/generated.pb.go | 1523 - .../k8s.io/api/storage/v1alpha1/register.go | 50 - vendor/k8s.io/api/storage/v1alpha1/types.go | 126 - .../v1alpha1/types_swagger_doc_generated.go | 93 - .../storage/v1alpha1/zz_generated.deepcopy.go | 186 - vendor/k8s.io/api/storage/v1beta1/doc.go | 20 - .../api/storage/v1beta1/generated.pb.go | 2211 - vendor/k8s.io/api/storage/v1beta1/register.go | 56 - vendor/k8s.io/api/storage/v1beta1/types.go | 205 - .../v1beta1/types_swagger_doc_generated.go | 118 - .../storage/v1beta1/zz_generated.deepcopy.go | 285 - vendor/k8s.io/apimachinery/LICENSE | 202 - .../apimachinery/pkg/api/equality/semantic.go | 49 - .../k8s.io/apimachinery/pkg/api/meta/doc.go | 19 - .../apimachinery/pkg/api/meta/errors.go | 121 - .../pkg/api/meta/firsthit_restmapper.go | 97 - .../k8s.io/apimachinery/pkg/api/meta/help.go | 205 - .../apimachinery/pkg/api/meta/interfaces.go | 134 - .../k8s.io/apimachinery/pkg/api/meta/lazy.go | 104 - .../k8s.io/apimachinery/pkg/api/meta/meta.go | 650 - .../pkg/api/meta/multirestmapper.go | 210 - .../apimachinery/pkg/api/meta/priority.go | 222 - .../apimachinery/pkg/api/meta/restmapper.go | 518 - .../apimachinery/pkg/api/resource/amount.go | 299 - .../pkg/api/resource/generated.pb.go | 77 - .../apimachinery/pkg/api/resource/math.go | 314 - .../apimachinery/pkg/api/resource/quantity.go | 789 - .../pkg/api/resource/quantity_proto.go | 284 - .../pkg/api/resource/scale_int.go | 95 - .../apimachinery/pkg/api/resource/suffix.go | 198 - .../pkg/api/resource/zz_generated.deepcopy.go | 27 - .../apimachinery/pkg/api/validation/doc.go | 18 - .../pkg/api/validation/generic.go | 85 - .../pkg/api/validation/objectmeta.go | 308 - .../pkg/apis/meta/v1/controller_ref.go | 54 - .../pkg/apis/meta/v1/conversion.go | 306 - .../apimachinery/pkg/apis/meta/v1/doc.go | 22 - .../apimachinery/pkg/apis/meta/v1/duration.go | 50 - .../pkg/apis/meta/v1/generated.pb.go | 7961 -- .../pkg/apis/meta/v1/group_version.go | 148 - .../apimachinery/pkg/apis/meta/v1/helpers.go | 234 - .../apimachinery/pkg/apis/meta/v1/labels.go | 55 - .../apimachinery/pkg/apis/meta/v1/meta.go | 216 - .../pkg/apis/meta/v1/micro_time.go | 183 - .../pkg/apis/meta/v1/micro_time_proto.go | 72 - .../apimachinery/pkg/apis/meta/v1/register.go | 93 - .../apimachinery/pkg/apis/meta/v1/time.go | 185 - .../pkg/apis/meta/v1/time_proto.go | 92 - .../apimachinery/pkg/apis/meta/v1/types.go | 949 - .../meta/v1/types_swagger_doc_generated.go | 330 - .../pkg/apis/meta/v1/unstructured/helpers.go | 493 - .../apis/meta/v1/unstructured/unstructured.go | 399 - .../meta/v1/unstructured/unstructured_list.go | 188 - .../v1/unstructured/zz_generated.deepcopy.go | 55 - .../pkg/apis/meta/v1/validation/validation.go | 90 - .../apimachinery/pkg/apis/meta/v1/watch.go | 89 - .../pkg/apis/meta/v1/zz_generated.deepcopy.go | 950 - .../pkg/apis/meta/v1/zz_generated.defaults.go | 32 - .../pkg/apis/meta/v1beta1/conversion.go | 27 - .../pkg/apis/meta/v1beta1/deepcopy.go | 44 - .../apimachinery/pkg/apis/meta/v1beta1/doc.go | 22 - .../pkg/apis/meta/v1beta1/generated.pb.go | 633 - .../pkg/apis/meta/v1beta1/register.go | 57 - .../pkg/apis/meta/v1beta1/types.go | 161 - .../v1beta1/types_swagger_doc_generated.go | 104 - .../meta/v1beta1/zz_generated.deepcopy.go | 190 - .../meta/v1beta1/zz_generated.defaults.go | 32 - .../apimachinery/pkg/conversion/converter.go | 898 - .../apimachinery/pkg/conversion/deep_equal.go | 36 - .../k8s.io/apimachinery/pkg/conversion/doc.go | 24 - .../apimachinery/pkg/conversion/helper.go | 39 - .../pkg/conversion/queryparams/convert.go | 198 - .../pkg/conversion/queryparams/doc.go | 19 - vendor/k8s.io/apimachinery/pkg/fields/doc.go | 19 - .../k8s.io/apimachinery/pkg/fields/fields.go | 62 - .../apimachinery/pkg/fields/requirements.go | 30 - .../apimachinery/pkg/fields/selector.go | 476 - vendor/k8s.io/apimachinery/pkg/labels/doc.go | 19 - .../k8s.io/apimachinery/pkg/labels/labels.go | 181 - .../apimachinery/pkg/labels/selector.go | 879 - .../pkg/labels/zz_generated.deepcopy.go | 42 - .../k8s.io/apimachinery/pkg/runtime/codec.go | 330 - .../apimachinery/pkg/runtime/codec_check.go | 48 - .../apimachinery/pkg/runtime/conversion.go | 113 - .../apimachinery/pkg/runtime/converter.go | 805 - vendor/k8s.io/apimachinery/pkg/runtime/doc.go | 45 - .../apimachinery/pkg/runtime/embedded.go | 142 - .../k8s.io/apimachinery/pkg/runtime/error.go | 121 - .../apimachinery/pkg/runtime/extension.go | 51 - .../apimachinery/pkg/runtime/generated.pb.go | 773 - .../k8s.io/apimachinery/pkg/runtime/helper.go | 212 - .../apimachinery/pkg/runtime/interfaces.go | 249 - .../apimachinery/pkg/runtime/register.go | 61 - .../pkg/runtime/schema/generated.pb.go | 65 - .../pkg/runtime/schema/group_version.go | 301 - .../pkg/runtime/schema/interfaces.go | 40 - .../k8s.io/apimachinery/pkg/runtime/scheme.go | 766 - .../pkg/runtime/scheme_builder.go | 48 - .../pkg/runtime/serializer/codec_factory.go | 237 - .../pkg/runtime/serializer/json/json.go | 271 - .../pkg/runtime/serializer/json/meta.go | 63 - .../runtime/serializer/negotiated_codec.go | 43 - .../pkg/runtime/serializer/protobuf/doc.go | 18 - .../runtime/serializer/protobuf/protobuf.go | 448 - .../runtime/serializer/protobuf_extension.go | 48 - .../serializer/recognizer/recognizer.go | 127 - .../serializer/versioning/versioning.go | 272 - .../pkg/runtime/swagger_doc_generator.go | 262 - .../k8s.io/apimachinery/pkg/runtime/types.go | 137 - .../apimachinery/pkg/runtime/types_proto.go | 69 - .../pkg/runtime/zz_generated.deepcopy.go | 112 - .../apimachinery/pkg/selection/operator.go | 33 - vendor/k8s.io/apimachinery/pkg/types/doc.go | 18 - .../apimachinery/pkg/types/namespacedname.go | 43 - .../k8s.io/apimachinery/pkg/types/nodename.go | 43 - vendor/k8s.io/apimachinery/pkg/types/patch.go | 28 - vendor/k8s.io/apimachinery/pkg/types/uid.go | 22 - .../apimachinery/pkg/util/errors/doc.go | 18 - .../apimachinery/pkg/util/errors/errors.go | 201 - .../apimachinery/pkg/util/framer/framer.go | 167 - .../pkg/util/intstr/generated.pb.go | 381 - .../apimachinery/pkg/util/intstr/intstr.go | 173 - .../k8s.io/apimachinery/pkg/util/json/json.go | 119 - .../pkg/util/mergepatch/errors.go | 102 - .../apimachinery/pkg/util/mergepatch/util.go | 133 - .../k8s.io/apimachinery/pkg/util/net/http.go | 425 - .../apimachinery/pkg/util/net/interface.go | 392 - .../apimachinery/pkg/util/net/port_range.go | 149 - .../apimachinery/pkg/util/net/port_split.go | 77 - .../k8s.io/apimachinery/pkg/util/net/util.go | 56 - .../apimachinery/pkg/util/runtime/runtime.go | 169 - .../k8s.io/apimachinery/pkg/util/sets/byte.go | 203 - .../k8s.io/apimachinery/pkg/util/sets/doc.go | 20 - .../apimachinery/pkg/util/sets/empty.go | 23 - .../k8s.io/apimachinery/pkg/util/sets/int.go | 203 - .../apimachinery/pkg/util/sets/int64.go | 203 - .../apimachinery/pkg/util/sets/string.go | 203 - .../pkg/util/strategicpatch/errors.go | 49 - .../pkg/util/strategicpatch/meta.go | 194 - .../pkg/util/strategicpatch/patch.go | 2174 - .../pkg/util/strategicpatch/types.go | 193 - .../pkg/util/validation/field/errors.go | 259 - .../pkg/util/validation/field/path.go | 91 - .../pkg/util/validation/validation.go | 391 - .../k8s.io/apimachinery/pkg/util/wait/doc.go | 19 - .../k8s.io/apimachinery/pkg/util/wait/wait.go | 385 - .../apimachinery/pkg/util/yaml/decoder.go | 346 - vendor/k8s.io/apimachinery/pkg/watch/doc.go | 19 - .../k8s.io/apimachinery/pkg/watch/filter.go | 105 - vendor/k8s.io/apimachinery/pkg/watch/mux.go | 260 - .../apimachinery/pkg/watch/streamwatcher.go | 119 - vendor/k8s.io/apimachinery/pkg/watch/until.go | 87 - vendor/k8s.io/apimachinery/pkg/watch/watch.go | 270 - .../pkg/watch/zz_generated.deepcopy.go | 42 - .../third_party/forked/golang/json/fields.go | 513 - .../forked/golang/reflect/deep_equal.go | 388 - vendor/k8s.io/client-go/LICENSE | 202 - .../k8s.io/client-go/kubernetes/scheme/doc.go | 20 - .../client-go/kubernetes/scheme/register.go | 108 - vendor/k8s.io/kube-openapi/LICENSE | 202 - .../k8s.io/kube-openapi/pkg/common/common.go | 168 - vendor/k8s.io/kube-openapi/pkg/common/doc.go | 19 - .../k8s.io/kube-openapi/pkg/util/proto/doc.go | 19 - .../kube-openapi/pkg/util/proto/document.go | 285 - .../kube-openapi/pkg/util/proto/openapi.go | 276 - 775 files changed, 188 insertions(+), 451212 deletions(-) delete mode 100644 Gopkg.lock delete mode 100644 Gopkg.toml create mode 100644 go.mod create mode 100644 go.sum delete mode 100644 vendor/github.com/PuerkitoBio/purell/LICENSE delete mode 100644 vendor/github.com/PuerkitoBio/purell/purell.go delete mode 100644 vendor/github.com/PuerkitoBio/urlesc/LICENSE delete mode 100644 vendor/github.com/PuerkitoBio/urlesc/urlesc.go delete mode 100644 vendor/github.com/davecgh/go-spew/LICENSE delete mode 100644 vendor/github.com/davecgh/go-spew/spew/bypass.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/bypasssafe.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/common.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/config.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/doc.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/dump.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/format.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/spew.go delete mode 100644 vendor/github.com/emicklei/go-restful/LICENSE delete mode 100644 vendor/github.com/emicklei/go-restful/compress.go delete mode 100644 vendor/github.com/emicklei/go-restful/compressor_cache.go delete mode 100644 vendor/github.com/emicklei/go-restful/compressor_pools.go delete mode 100644 vendor/github.com/emicklei/go-restful/compressors.go delete mode 100644 vendor/github.com/emicklei/go-restful/constants.go delete mode 100644 vendor/github.com/emicklei/go-restful/container.go delete mode 100644 vendor/github.com/emicklei/go-restful/cors_filter.go delete mode 100644 vendor/github.com/emicklei/go-restful/curly.go delete mode 100644 vendor/github.com/emicklei/go-restful/curly_route.go delete mode 100644 vendor/github.com/emicklei/go-restful/doc.go delete mode 100644 vendor/github.com/emicklei/go-restful/entity_accessors.go delete mode 100644 vendor/github.com/emicklei/go-restful/filter.go delete mode 100644 vendor/github.com/emicklei/go-restful/jsr311.go delete mode 100644 vendor/github.com/emicklei/go-restful/log/log.go delete mode 100644 vendor/github.com/emicklei/go-restful/logger.go delete mode 100644 vendor/github.com/emicklei/go-restful/mime.go delete mode 100644 vendor/github.com/emicklei/go-restful/options_filter.go delete mode 100644 vendor/github.com/emicklei/go-restful/parameter.go delete mode 100644 vendor/github.com/emicklei/go-restful/path_expression.go delete mode 100644 vendor/github.com/emicklei/go-restful/path_processor.go delete mode 100644 vendor/github.com/emicklei/go-restful/request.go delete mode 100644 vendor/github.com/emicklei/go-restful/response.go delete mode 100644 vendor/github.com/emicklei/go-restful/route.go delete mode 100644 vendor/github.com/emicklei/go-restful/route_builder.go delete mode 100644 vendor/github.com/emicklei/go-restful/router.go delete mode 100644 vendor/github.com/emicklei/go-restful/service_error.go delete mode 100644 vendor/github.com/emicklei/go-restful/web_service.go delete mode 100644 vendor/github.com/emicklei/go-restful/web_service_container.go delete mode 100644 vendor/github.com/evanphx/json-patch/LICENSE delete mode 100644 vendor/github.com/evanphx/json-patch/merge.go delete mode 100644 vendor/github.com/evanphx/json-patch/patch.go delete mode 100644 vendor/github.com/ghodss/yaml/LICENSE delete mode 100644 vendor/github.com/ghodss/yaml/fields.go delete mode 100644 vendor/github.com/ghodss/yaml/yaml.go delete mode 100644 vendor/github.com/go-openapi/jsonpointer/LICENSE delete mode 100644 vendor/github.com/go-openapi/jsonpointer/pointer.go delete mode 100644 vendor/github.com/go-openapi/jsonreference/LICENSE delete mode 100644 vendor/github.com/go-openapi/jsonreference/reference.go delete mode 100644 vendor/github.com/go-openapi/spec/LICENSE delete mode 100644 vendor/github.com/go-openapi/spec/bindata.go delete mode 100644 vendor/github.com/go-openapi/spec/contact_info.go delete mode 100644 vendor/github.com/go-openapi/spec/expander.go delete mode 100644 vendor/github.com/go-openapi/spec/external_docs.go delete mode 100644 vendor/github.com/go-openapi/spec/header.go delete mode 100644 vendor/github.com/go-openapi/spec/info.go delete mode 100644 vendor/github.com/go-openapi/spec/items.go delete mode 100644 vendor/github.com/go-openapi/spec/license.go delete mode 100644 vendor/github.com/go-openapi/spec/operation.go delete mode 100644 vendor/github.com/go-openapi/spec/parameter.go delete mode 100644 vendor/github.com/go-openapi/spec/path_item.go delete mode 100644 vendor/github.com/go-openapi/spec/paths.go delete mode 100644 vendor/github.com/go-openapi/spec/ref.go delete mode 100644 vendor/github.com/go-openapi/spec/response.go delete mode 100644 vendor/github.com/go-openapi/spec/responses.go delete mode 100644 vendor/github.com/go-openapi/spec/schema.go delete mode 100644 vendor/github.com/go-openapi/spec/security_scheme.go delete mode 100644 vendor/github.com/go-openapi/spec/spec.go delete mode 100644 vendor/github.com/go-openapi/spec/swagger.go delete mode 100644 vendor/github.com/go-openapi/spec/tag.go delete mode 100644 vendor/github.com/go-openapi/spec/xml_object.go delete mode 100644 vendor/github.com/go-openapi/swag/LICENSE delete mode 100644 vendor/github.com/go-openapi/swag/convert.go delete mode 100644 vendor/github.com/go-openapi/swag/convert_types.go delete mode 100644 vendor/github.com/go-openapi/swag/json.go delete mode 100644 vendor/github.com/go-openapi/swag/loading.go delete mode 100644 vendor/github.com/go-openapi/swag/net.go delete mode 100644 vendor/github.com/go-openapi/swag/path.go delete mode 100644 vendor/github.com/go-openapi/swag/post_go18.go delete mode 100644 vendor/github.com/go-openapi/swag/pre_go18.go delete mode 100644 vendor/github.com/go-openapi/swag/util.go delete mode 100644 vendor/github.com/go-openapi/swag/yaml.go delete mode 100644 vendor/github.com/gogo/protobuf/AUTHORS delete mode 100644 vendor/github.com/gogo/protobuf/CONTRIBUTORS delete mode 100644 vendor/github.com/gogo/protobuf/GOLANG_CONTRIBUTORS delete mode 100644 vendor/github.com/gogo/protobuf/LICENSE delete mode 100644 vendor/github.com/gogo/protobuf/proto/clone.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/decode.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/decode_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/discard.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/duration.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/duration_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/encode.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/encode_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/equal.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/extensions.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/extensions_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/lib.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/lib_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/message_set.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/pointer_reflect.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/properties.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/properties_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/skip_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/text.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/text_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/text_parser.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/timestamp.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go delete mode 100644 vendor/github.com/golang/glog/LICENSE delete mode 100644 vendor/github.com/golang/glog/glog.go delete mode 100644 vendor/github.com/golang/glog/glog_file.go delete mode 100644 vendor/github.com/golang/protobuf/AUTHORS delete mode 100644 vendor/github.com/golang/protobuf/CONTRIBUTORS delete mode 100644 vendor/github.com/golang/protobuf/LICENSE delete mode 100644 vendor/github.com/golang/protobuf/proto/clone.go delete mode 100644 vendor/github.com/golang/protobuf/proto/decode.go delete mode 100644 vendor/github.com/golang/protobuf/proto/discard.go delete mode 100644 vendor/github.com/golang/protobuf/proto/encode.go delete mode 100644 vendor/github.com/golang/protobuf/proto/equal.go delete mode 100644 vendor/github.com/golang/protobuf/proto/extensions.go delete mode 100644 vendor/github.com/golang/protobuf/proto/lib.go delete mode 100644 vendor/github.com/golang/protobuf/proto/message_set.go delete mode 100644 vendor/github.com/golang/protobuf/proto/pointer_reflect.go delete mode 100644 vendor/github.com/golang/protobuf/proto/pointer_unsafe.go delete mode 100644 vendor/github.com/golang/protobuf/proto/properties.go delete mode 100644 vendor/github.com/golang/protobuf/proto/table_marshal.go delete mode 100644 vendor/github.com/golang/protobuf/proto/table_merge.go delete mode 100644 vendor/github.com/golang/protobuf/proto/table_unmarshal.go delete mode 100644 vendor/github.com/golang/protobuf/proto/text.go delete mode 100644 vendor/github.com/golang/protobuf/proto/text_parser.go delete mode 100644 vendor/github.com/golang/protobuf/ptypes/any.go delete mode 100644 vendor/github.com/golang/protobuf/ptypes/any/any.pb.go delete mode 100644 vendor/github.com/golang/protobuf/ptypes/doc.go delete mode 100644 vendor/github.com/golang/protobuf/ptypes/duration.go delete mode 100644 vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go delete mode 100644 vendor/github.com/golang/protobuf/ptypes/timestamp.go delete mode 100644 vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go delete mode 100644 vendor/github.com/google/gofuzz/LICENSE delete mode 100644 vendor/github.com/google/gofuzz/doc.go delete mode 100644 vendor/github.com/google/gofuzz/fuzz.go delete mode 100644 vendor/github.com/googleapis/gnostic/LICENSE delete mode 100644 vendor/github.com/googleapis/gnostic/OpenAPIv2/OpenAPIv2.go delete mode 100644 vendor/github.com/googleapis/gnostic/OpenAPIv2/OpenAPIv2.pb.go delete mode 100644 vendor/github.com/googleapis/gnostic/compiler/context.go delete mode 100644 vendor/github.com/googleapis/gnostic/compiler/error.go delete mode 100644 vendor/github.com/googleapis/gnostic/compiler/extension-handler.go delete mode 100644 vendor/github.com/googleapis/gnostic/compiler/helpers.go delete mode 100644 vendor/github.com/googleapis/gnostic/compiler/main.go delete mode 100644 vendor/github.com/googleapis/gnostic/compiler/reader.go delete mode 100644 vendor/github.com/googleapis/gnostic/extensions/extension.pb.go delete mode 100644 vendor/github.com/googleapis/gnostic/extensions/extensions.go delete mode 100644 vendor/github.com/inconshreveable/mousetrap/LICENSE delete mode 100644 vendor/github.com/inconshreveable/mousetrap/trap_others.go delete mode 100644 vendor/github.com/inconshreveable/mousetrap/trap_windows.go delete mode 100644 vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go delete mode 100644 vendor/github.com/json-iterator/go/LICENSE delete mode 100644 vendor/github.com/json-iterator/go/adapter.go delete mode 100644 vendor/github.com/json-iterator/go/any.go delete mode 100644 vendor/github.com/json-iterator/go/any_array.go delete mode 100644 vendor/github.com/json-iterator/go/any_bool.go delete mode 100644 vendor/github.com/json-iterator/go/any_float.go delete mode 100644 vendor/github.com/json-iterator/go/any_int32.go delete mode 100644 vendor/github.com/json-iterator/go/any_int64.go delete mode 100644 vendor/github.com/json-iterator/go/any_invalid.go delete mode 100644 vendor/github.com/json-iterator/go/any_nil.go delete mode 100644 vendor/github.com/json-iterator/go/any_number.go delete mode 100644 vendor/github.com/json-iterator/go/any_object.go delete mode 100644 vendor/github.com/json-iterator/go/any_str.go delete mode 100644 vendor/github.com/json-iterator/go/any_uint32.go delete mode 100644 vendor/github.com/json-iterator/go/any_uint64.go delete mode 100644 vendor/github.com/json-iterator/go/config.go delete mode 100644 vendor/github.com/json-iterator/go/iter.go delete mode 100644 vendor/github.com/json-iterator/go/iter_array.go delete mode 100644 vendor/github.com/json-iterator/go/iter_float.go delete mode 100644 vendor/github.com/json-iterator/go/iter_int.go delete mode 100644 vendor/github.com/json-iterator/go/iter_object.go delete mode 100644 vendor/github.com/json-iterator/go/iter_skip.go delete mode 100644 vendor/github.com/json-iterator/go/iter_skip_sloppy.go delete mode 100644 vendor/github.com/json-iterator/go/iter_skip_strict.go delete mode 100644 vendor/github.com/json-iterator/go/iter_str.go delete mode 100644 vendor/github.com/json-iterator/go/jsoniter.go delete mode 100644 vendor/github.com/json-iterator/go/pool.go delete mode 100644 vendor/github.com/json-iterator/go/reflect.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_array.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_dynamic.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_extension.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_json_number.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_json_raw_message.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_map.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_marshaler.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_native.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_optional.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_slice.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_struct_decoder.go delete mode 100644 vendor/github.com/json-iterator/go/reflect_struct_encoder.go delete mode 100644 vendor/github.com/json-iterator/go/stream.go delete mode 100644 vendor/github.com/json-iterator/go/stream_float.go delete mode 100644 vendor/github.com/json-iterator/go/stream_int.go delete mode 100644 vendor/github.com/json-iterator/go/stream_str.go delete mode 100644 vendor/github.com/mailru/easyjson/LICENSE delete mode 100644 vendor/github.com/mailru/easyjson/buffer/pool.go delete mode 100644 vendor/github.com/mailru/easyjson/jlexer/bytestostr.go delete mode 100644 vendor/github.com/mailru/easyjson/jlexer/bytestostr_nounsafe.go delete mode 100644 vendor/github.com/mailru/easyjson/jlexer/error.go delete mode 100644 vendor/github.com/mailru/easyjson/jlexer/lexer.go delete mode 100644 vendor/github.com/mailru/easyjson/jwriter/writer.go delete mode 100644 vendor/github.com/modern-go/concurrent/LICENSE delete mode 100644 vendor/github.com/modern-go/concurrent/executor.go delete mode 100644 vendor/github.com/modern-go/concurrent/go_above_19.go delete mode 100644 vendor/github.com/modern-go/concurrent/go_below_19.go delete mode 100644 vendor/github.com/modern-go/concurrent/log.go delete mode 100644 vendor/github.com/modern-go/concurrent/unbounded_executor.go delete mode 100644 vendor/github.com/modern-go/reflect2/LICENSE delete mode 100644 vendor/github.com/modern-go/reflect2/go_above_17.go delete mode 100644 vendor/github.com/modern-go/reflect2/go_above_19.go delete mode 100644 vendor/github.com/modern-go/reflect2/go_below_17.go delete mode 100644 vendor/github.com/modern-go/reflect2/go_below_19.go delete mode 100644 vendor/github.com/modern-go/reflect2/reflect2.go delete mode 100644 vendor/github.com/modern-go/reflect2/reflect2_amd64.s delete mode 100644 vendor/github.com/modern-go/reflect2/reflect2_kind.go delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_386.s delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_arm.s delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_arm64.s delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_mips64x.s delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_mipsx.s delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s delete mode 100644 vendor/github.com/modern-go/reflect2/relfect2_s390x.s delete mode 100644 vendor/github.com/modern-go/reflect2/safe_field.go delete mode 100644 vendor/github.com/modern-go/reflect2/safe_map.go delete mode 100644 vendor/github.com/modern-go/reflect2/safe_slice.go delete mode 100644 vendor/github.com/modern-go/reflect2/safe_struct.go delete mode 100644 vendor/github.com/modern-go/reflect2/safe_type.go delete mode 100644 vendor/github.com/modern-go/reflect2/type_map.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_array.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_eface.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_field.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_iface.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_link.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_map.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_ptr.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_slice.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_struct.go delete mode 100644 vendor/github.com/modern-go/reflect2/unsafe_type.go delete mode 100644 vendor/github.com/pkg/errors/LICENSE delete mode 100644 vendor/github.com/pkg/errors/errors.go delete mode 100644 vendor/github.com/pkg/errors/stack.go delete mode 100644 vendor/github.com/spf13/cobra/LICENSE.txt delete mode 100644 vendor/github.com/spf13/cobra/args.go delete mode 100644 vendor/github.com/spf13/cobra/bash_completions.go delete mode 100644 vendor/github.com/spf13/cobra/cobra.go delete mode 100644 vendor/github.com/spf13/cobra/cobra/cmd/testdata/LICENSE.golden delete mode 100644 vendor/github.com/spf13/cobra/command.go delete mode 100644 vendor/github.com/spf13/cobra/command_notwin.go delete mode 100644 vendor/github.com/spf13/cobra/command_win.go delete mode 100644 vendor/github.com/spf13/cobra/zsh_completions.go delete mode 100644 vendor/github.com/spf13/pflag/LICENSE delete mode 100644 vendor/github.com/spf13/pflag/bool.go delete mode 100644 vendor/github.com/spf13/pflag/bool_slice.go delete mode 100644 vendor/github.com/spf13/pflag/bytes.go delete mode 100644 vendor/github.com/spf13/pflag/count.go delete mode 100644 vendor/github.com/spf13/pflag/duration.go delete mode 100644 vendor/github.com/spf13/pflag/duration_slice.go delete mode 100644 vendor/github.com/spf13/pflag/flag.go delete mode 100644 vendor/github.com/spf13/pflag/float32.go delete mode 100644 vendor/github.com/spf13/pflag/float64.go delete mode 100644 vendor/github.com/spf13/pflag/golangflag.go delete mode 100644 vendor/github.com/spf13/pflag/int.go delete mode 100644 vendor/github.com/spf13/pflag/int16.go delete mode 100644 vendor/github.com/spf13/pflag/int32.go delete mode 100644 vendor/github.com/spf13/pflag/int64.go delete mode 100644 vendor/github.com/spf13/pflag/int8.go delete mode 100644 vendor/github.com/spf13/pflag/int_slice.go delete mode 100644 vendor/github.com/spf13/pflag/ip.go delete mode 100644 vendor/github.com/spf13/pflag/ip_slice.go delete mode 100644 vendor/github.com/spf13/pflag/ipmask.go delete mode 100644 vendor/github.com/spf13/pflag/ipnet.go delete mode 100644 vendor/github.com/spf13/pflag/string.go delete mode 100644 vendor/github.com/spf13/pflag/string_array.go delete mode 100644 vendor/github.com/spf13/pflag/string_slice.go delete mode 100644 vendor/github.com/spf13/pflag/uint.go delete mode 100644 vendor/github.com/spf13/pflag/uint16.go delete mode 100644 vendor/github.com/spf13/pflag/uint32.go delete mode 100644 vendor/github.com/spf13/pflag/uint64.go delete mode 100644 vendor/github.com/spf13/pflag/uint8.go delete mode 100644 vendor/github.com/spf13/pflag/uint_slice.go delete mode 100644 vendor/golang.org/x/net/AUTHORS delete mode 100644 vendor/golang.org/x/net/CONTRIBUTORS delete mode 100644 vendor/golang.org/x/net/LICENSE delete mode 100644 vendor/golang.org/x/net/PATENTS delete mode 100644 vendor/golang.org/x/net/http/httpguts/guts.go delete mode 100644 vendor/golang.org/x/net/http/httpguts/httplex.go delete mode 100644 vendor/golang.org/x/net/http2/ciphers.go delete mode 100644 vendor/golang.org/x/net/http2/client_conn_pool.go delete mode 100644 vendor/golang.org/x/net/http2/databuffer.go delete mode 100644 vendor/golang.org/x/net/http2/errors.go delete mode 100644 vendor/golang.org/x/net/http2/flow.go delete mode 100644 vendor/golang.org/x/net/http2/frame.go delete mode 100644 vendor/golang.org/x/net/http2/go111.go delete mode 100644 vendor/golang.org/x/net/http2/gotrack.go delete mode 100644 vendor/golang.org/x/net/http2/headermap.go delete mode 100644 vendor/golang.org/x/net/http2/hpack/encode.go delete mode 100644 vendor/golang.org/x/net/http2/hpack/hpack.go delete mode 100644 vendor/golang.org/x/net/http2/hpack/huffman.go delete mode 100644 vendor/golang.org/x/net/http2/hpack/tables.go delete mode 100644 vendor/golang.org/x/net/http2/http2.go delete mode 100644 vendor/golang.org/x/net/http2/not_go111.go delete mode 100644 vendor/golang.org/x/net/http2/pipe.go delete mode 100644 vendor/golang.org/x/net/http2/server.go delete mode 100644 vendor/golang.org/x/net/http2/transport.go delete mode 100644 vendor/golang.org/x/net/http2/write.go delete mode 100644 vendor/golang.org/x/net/http2/writesched.go delete mode 100644 vendor/golang.org/x/net/http2/writesched_priority.go delete mode 100644 vendor/golang.org/x/net/http2/writesched_random.go delete mode 100644 vendor/golang.org/x/net/idna/idna.go delete mode 100644 vendor/golang.org/x/net/idna/punycode.go delete mode 100644 vendor/golang.org/x/net/idna/tables.go delete mode 100644 vendor/golang.org/x/net/idna/trie.go delete mode 100644 vendor/golang.org/x/net/idna/trieval.go delete mode 100644 vendor/golang.org/x/text/AUTHORS delete mode 100644 vendor/golang.org/x/text/CONTRIBUTORS delete mode 100644 vendor/golang.org/x/text/LICENSE delete mode 100644 vendor/golang.org/x/text/PATENTS delete mode 100644 vendor/golang.org/x/text/collate/build/builder.go delete mode 100644 vendor/golang.org/x/text/collate/build/colelem.go delete mode 100644 vendor/golang.org/x/text/collate/build/contract.go delete mode 100644 vendor/golang.org/x/text/collate/build/order.go delete mode 100644 vendor/golang.org/x/text/collate/build/table.go delete mode 100644 vendor/golang.org/x/text/collate/build/trie.go delete mode 100644 vendor/golang.org/x/text/collate/collate.go delete mode 100644 vendor/golang.org/x/text/collate/index.go delete mode 100644 vendor/golang.org/x/text/collate/maketables.go delete mode 100644 vendor/golang.org/x/text/collate/option.go delete mode 100644 vendor/golang.org/x/text/collate/sort.go delete mode 100644 vendor/golang.org/x/text/collate/tables.go delete mode 100644 vendor/golang.org/x/text/internal/colltab/collelem.go delete mode 100644 vendor/golang.org/x/text/internal/colltab/colltab.go delete mode 100644 vendor/golang.org/x/text/internal/colltab/contract.go delete mode 100644 vendor/golang.org/x/text/internal/colltab/iter.go delete mode 100644 vendor/golang.org/x/text/internal/colltab/numeric.go delete mode 100644 vendor/golang.org/x/text/internal/colltab/table.go delete mode 100644 vendor/golang.org/x/text/internal/colltab/trie.go delete mode 100644 vendor/golang.org/x/text/internal/colltab/weighter.go delete mode 100644 vendor/golang.org/x/text/internal/gen/code.go delete mode 100644 vendor/golang.org/x/text/internal/gen/gen.go delete mode 100644 vendor/golang.org/x/text/internal/tag/tag.go delete mode 100644 vendor/golang.org/x/text/internal/triegen/compact.go delete mode 100644 vendor/golang.org/x/text/internal/triegen/print.go delete mode 100644 vendor/golang.org/x/text/internal/triegen/triegen.go delete mode 100644 vendor/golang.org/x/text/internal/ucd/ucd.go delete mode 100644 vendor/golang.org/x/text/language/common.go delete mode 100644 vendor/golang.org/x/text/language/coverage.go delete mode 100644 vendor/golang.org/x/text/language/doc.go delete mode 100644 vendor/golang.org/x/text/language/gen.go delete mode 100644 vendor/golang.org/x/text/language/gen_common.go delete mode 100644 vendor/golang.org/x/text/language/gen_index.go delete mode 100644 vendor/golang.org/x/text/language/go1_1.go delete mode 100644 vendor/golang.org/x/text/language/go1_2.go delete mode 100644 vendor/golang.org/x/text/language/index.go delete mode 100644 vendor/golang.org/x/text/language/language.go delete mode 100644 vendor/golang.org/x/text/language/lookup.go delete mode 100644 vendor/golang.org/x/text/language/match.go delete mode 100644 vendor/golang.org/x/text/language/parse.go delete mode 100644 vendor/golang.org/x/text/language/tables.go delete mode 100644 vendor/golang.org/x/text/language/tags.go delete mode 100644 vendor/golang.org/x/text/secure/bidirule/bidirule.go delete mode 100644 vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go delete mode 100644 vendor/golang.org/x/text/secure/bidirule/bidirule9.0.0.go delete mode 100644 vendor/golang.org/x/text/transform/transform.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/bidi.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/bracket.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/core.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/gen.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/gen_ranges.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/gen_trieval.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/prop.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/bidi/trieval.go delete mode 100644 vendor/golang.org/x/text/unicode/cldr/base.go delete mode 100644 vendor/golang.org/x/text/unicode/cldr/cldr.go delete mode 100644 vendor/golang.org/x/text/unicode/cldr/collate.go delete mode 100644 vendor/golang.org/x/text/unicode/cldr/decode.go delete mode 100644 vendor/golang.org/x/text/unicode/cldr/makexml.go delete mode 100644 vendor/golang.org/x/text/unicode/cldr/resolve.go delete mode 100644 vendor/golang.org/x/text/unicode/cldr/slice.go delete mode 100644 vendor/golang.org/x/text/unicode/cldr/xml.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/composition.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/forminfo.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/input.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/iter.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/maketables.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/normalize.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/readwriter.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/tables10.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/tables9.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/transform.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/trie.go delete mode 100644 vendor/golang.org/x/text/unicode/norm/triegen.go delete mode 100644 vendor/golang.org/x/text/unicode/rangetable/gen.go delete mode 100644 vendor/golang.org/x/text/unicode/rangetable/merge.go delete mode 100644 vendor/golang.org/x/text/unicode/rangetable/rangetable.go delete mode 100644 vendor/golang.org/x/text/unicode/rangetable/tables10.0.0.go delete mode 100644 vendor/golang.org/x/text/unicode/rangetable/tables9.0.0.go delete mode 100644 vendor/golang.org/x/text/width/gen.go delete mode 100644 vendor/golang.org/x/text/width/gen_common.go delete mode 100644 vendor/golang.org/x/text/width/gen_trieval.go delete mode 100644 vendor/golang.org/x/text/width/kind_string.go delete mode 100644 vendor/golang.org/x/text/width/tables10.0.0.go delete mode 100644 vendor/golang.org/x/text/width/tables9.0.0.go delete mode 100644 vendor/golang.org/x/text/width/transform.go delete mode 100644 vendor/golang.org/x/text/width/trieval.go delete mode 100644 vendor/golang.org/x/text/width/width.go delete mode 100644 vendor/gopkg.in/inf.v0/LICENSE delete mode 100644 vendor/gopkg.in/inf.v0/dec.go delete mode 100644 vendor/gopkg.in/inf.v0/rounder.go delete mode 100644 vendor/gopkg.in/yaml.v2/LICENSE delete mode 100644 vendor/gopkg.in/yaml.v2/LICENSE.libyaml delete mode 100644 vendor/gopkg.in/yaml.v2/NOTICE delete mode 100644 vendor/gopkg.in/yaml.v2/apic.go delete mode 100644 vendor/gopkg.in/yaml.v2/decode.go delete mode 100644 vendor/gopkg.in/yaml.v2/emitterc.go delete mode 100644 vendor/gopkg.in/yaml.v2/encode.go delete mode 100644 vendor/gopkg.in/yaml.v2/parserc.go delete mode 100644 vendor/gopkg.in/yaml.v2/readerc.go delete mode 100644 vendor/gopkg.in/yaml.v2/resolve.go delete mode 100644 vendor/gopkg.in/yaml.v2/scannerc.go delete mode 100644 vendor/gopkg.in/yaml.v2/sorter.go delete mode 100644 vendor/gopkg.in/yaml.v2/writerc.go delete mode 100644 vendor/gopkg.in/yaml.v2/yaml.go delete mode 100644 vendor/gopkg.in/yaml.v2/yamlh.go delete mode 100644 vendor/gopkg.in/yaml.v2/yamlprivateh.go delete mode 100644 vendor/k8s.io/api/LICENSE delete mode 100644 vendor/k8s.io/api/admissionregistration/v1alpha1/doc.go delete mode 100644 vendor/k8s.io/api/admissionregistration/v1alpha1/generated.pb.go delete mode 100644 vendor/k8s.io/api/admissionregistration/v1alpha1/register.go delete mode 100644 vendor/k8s.io/api/admissionregistration/v1alpha1/types.go delete mode 100644 vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/admissionregistration/v1alpha1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/admissionregistration/v1beta1/doc.go delete mode 100644 vendor/k8s.io/api/admissionregistration/v1beta1/generated.pb.go delete mode 100644 vendor/k8s.io/api/admissionregistration/v1beta1/register.go delete mode 100644 vendor/k8s.io/api/admissionregistration/v1beta1/types.go delete mode 100644 vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/apps/v1/doc.go delete mode 100644 vendor/k8s.io/api/apps/v1/generated.pb.go delete mode 100644 vendor/k8s.io/api/apps/v1/register.go delete mode 100644 vendor/k8s.io/api/apps/v1/types.go delete mode 100644 vendor/k8s.io/api/apps/v1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/apps/v1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/apps/v1beta1/doc.go delete mode 100644 vendor/k8s.io/api/apps/v1beta1/generated.pb.go delete mode 100644 vendor/k8s.io/api/apps/v1beta1/register.go delete mode 100644 vendor/k8s.io/api/apps/v1beta1/types.go delete mode 100644 vendor/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/apps/v1beta1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/apps/v1beta2/doc.go delete mode 100644 vendor/k8s.io/api/apps/v1beta2/generated.pb.go delete mode 100644 vendor/k8s.io/api/apps/v1beta2/register.go delete mode 100644 vendor/k8s.io/api/apps/v1beta2/types.go delete mode 100644 vendor/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/apps/v1beta2/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/authentication/v1/doc.go delete mode 100644 vendor/k8s.io/api/authentication/v1/generated.pb.go delete mode 100644 vendor/k8s.io/api/authentication/v1/register.go delete mode 100644 vendor/k8s.io/api/authentication/v1/types.go delete mode 100644 vendor/k8s.io/api/authentication/v1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/authentication/v1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/authentication/v1beta1/doc.go delete mode 100644 vendor/k8s.io/api/authentication/v1beta1/generated.pb.go delete mode 100644 vendor/k8s.io/api/authentication/v1beta1/register.go delete mode 100644 vendor/k8s.io/api/authentication/v1beta1/types.go delete mode 100644 vendor/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/authentication/v1beta1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/authorization/v1/doc.go delete mode 100644 vendor/k8s.io/api/authorization/v1/generated.pb.go delete mode 100644 vendor/k8s.io/api/authorization/v1/register.go delete mode 100644 vendor/k8s.io/api/authorization/v1/types.go delete mode 100644 vendor/k8s.io/api/authorization/v1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/authorization/v1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/authorization/v1beta1/doc.go delete mode 100644 vendor/k8s.io/api/authorization/v1beta1/generated.pb.go delete mode 100644 vendor/k8s.io/api/authorization/v1beta1/register.go delete mode 100644 vendor/k8s.io/api/authorization/v1beta1/types.go delete mode 100644 vendor/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/authorization/v1beta1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/autoscaling/v1/doc.go delete mode 100644 vendor/k8s.io/api/autoscaling/v1/generated.pb.go delete mode 100644 vendor/k8s.io/api/autoscaling/v1/register.go delete mode 100644 vendor/k8s.io/api/autoscaling/v1/types.go delete mode 100644 vendor/k8s.io/api/autoscaling/v1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/autoscaling/v1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta1/doc.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta1/generated.pb.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta1/register.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta1/types.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/autoscaling/v2beta1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/batch/v1/doc.go delete mode 100644 vendor/k8s.io/api/batch/v1/generated.pb.go delete mode 100644 vendor/k8s.io/api/batch/v1/register.go delete mode 100644 vendor/k8s.io/api/batch/v1/types.go delete mode 100644 vendor/k8s.io/api/batch/v1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/batch/v1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/batch/v1beta1/doc.go delete mode 100644 vendor/k8s.io/api/batch/v1beta1/generated.pb.go delete mode 100644 vendor/k8s.io/api/batch/v1beta1/register.go delete mode 100644 vendor/k8s.io/api/batch/v1beta1/types.go delete mode 100644 vendor/k8s.io/api/batch/v1beta1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/batch/v1beta1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/batch/v2alpha1/doc.go delete mode 100644 vendor/k8s.io/api/batch/v2alpha1/generated.pb.go delete mode 100644 vendor/k8s.io/api/batch/v2alpha1/register.go delete mode 100644 vendor/k8s.io/api/batch/v2alpha1/types.go delete mode 100644 vendor/k8s.io/api/batch/v2alpha1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/batch/v2alpha1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/certificates/v1beta1/doc.go delete mode 100644 vendor/k8s.io/api/certificates/v1beta1/generated.pb.go delete mode 100644 vendor/k8s.io/api/certificates/v1beta1/register.go delete mode 100644 vendor/k8s.io/api/certificates/v1beta1/types.go delete mode 100644 vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/certificates/v1beta1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/core/v1/annotation_key_constants.go delete mode 100644 vendor/k8s.io/api/core/v1/doc.go delete mode 100644 vendor/k8s.io/api/core/v1/generated.pb.go delete mode 100644 vendor/k8s.io/api/core/v1/objectreference.go delete mode 100644 vendor/k8s.io/api/core/v1/register.go delete mode 100644 vendor/k8s.io/api/core/v1/resource.go delete mode 100644 vendor/k8s.io/api/core/v1/taint.go delete mode 100644 vendor/k8s.io/api/core/v1/toleration.go delete mode 100644 vendor/k8s.io/api/core/v1/types.go delete mode 100644 vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/events/v1beta1/doc.go delete mode 100644 vendor/k8s.io/api/events/v1beta1/generated.pb.go delete mode 100644 vendor/k8s.io/api/events/v1beta1/register.go delete mode 100644 vendor/k8s.io/api/events/v1beta1/types.go delete mode 100644 vendor/k8s.io/api/events/v1beta1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/events/v1beta1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/extensions/v1beta1/doc.go delete mode 100644 vendor/k8s.io/api/extensions/v1beta1/generated.pb.go delete mode 100644 vendor/k8s.io/api/extensions/v1beta1/register.go delete mode 100644 vendor/k8s.io/api/extensions/v1beta1/types.go delete mode 100644 vendor/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/networking/v1/doc.go delete mode 100644 vendor/k8s.io/api/networking/v1/generated.pb.go delete mode 100644 vendor/k8s.io/api/networking/v1/register.go delete mode 100644 vendor/k8s.io/api/networking/v1/types.go delete mode 100644 vendor/k8s.io/api/networking/v1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/networking/v1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/policy/v1beta1/doc.go delete mode 100644 vendor/k8s.io/api/policy/v1beta1/generated.pb.go delete mode 100644 vendor/k8s.io/api/policy/v1beta1/register.go delete mode 100644 vendor/k8s.io/api/policy/v1beta1/types.go delete mode 100644 vendor/k8s.io/api/policy/v1beta1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/policy/v1beta1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/rbac/v1/doc.go delete mode 100644 vendor/k8s.io/api/rbac/v1/generated.pb.go delete mode 100644 vendor/k8s.io/api/rbac/v1/register.go delete mode 100644 vendor/k8s.io/api/rbac/v1/types.go delete mode 100644 vendor/k8s.io/api/rbac/v1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/rbac/v1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/rbac/v1alpha1/doc.go delete mode 100644 vendor/k8s.io/api/rbac/v1alpha1/generated.pb.go delete mode 100644 vendor/k8s.io/api/rbac/v1alpha1/register.go delete mode 100644 vendor/k8s.io/api/rbac/v1alpha1/types.go delete mode 100644 vendor/k8s.io/api/rbac/v1alpha1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/rbac/v1alpha1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/rbac/v1beta1/doc.go delete mode 100644 vendor/k8s.io/api/rbac/v1beta1/generated.pb.go delete mode 100644 vendor/k8s.io/api/rbac/v1beta1/register.go delete mode 100644 vendor/k8s.io/api/rbac/v1beta1/types.go delete mode 100644 vendor/k8s.io/api/rbac/v1beta1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/rbac/v1beta1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/scheduling/v1alpha1/doc.go delete mode 100644 vendor/k8s.io/api/scheduling/v1alpha1/generated.pb.go delete mode 100644 vendor/k8s.io/api/scheduling/v1alpha1/register.go delete mode 100644 vendor/k8s.io/api/scheduling/v1alpha1/types.go delete mode 100644 vendor/k8s.io/api/scheduling/v1alpha1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/scheduling/v1alpha1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/settings/v1alpha1/doc.go delete mode 100644 vendor/k8s.io/api/settings/v1alpha1/generated.pb.go delete mode 100644 vendor/k8s.io/api/settings/v1alpha1/register.go delete mode 100644 vendor/k8s.io/api/settings/v1alpha1/types.go delete mode 100644 vendor/k8s.io/api/settings/v1alpha1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/settings/v1alpha1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/storage/v1/doc.go delete mode 100644 vendor/k8s.io/api/storage/v1/generated.pb.go delete mode 100644 vendor/k8s.io/api/storage/v1/register.go delete mode 100644 vendor/k8s.io/api/storage/v1/types.go delete mode 100644 vendor/k8s.io/api/storage/v1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/storage/v1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/storage/v1alpha1/doc.go delete mode 100644 vendor/k8s.io/api/storage/v1alpha1/generated.pb.go delete mode 100644 vendor/k8s.io/api/storage/v1alpha1/register.go delete mode 100644 vendor/k8s.io/api/storage/v1alpha1/types.go delete mode 100644 vendor/k8s.io/api/storage/v1alpha1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/storage/v1alpha1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/api/storage/v1beta1/doc.go delete mode 100644 vendor/k8s.io/api/storage/v1beta1/generated.pb.go delete mode 100644 vendor/k8s.io/api/storage/v1beta1/register.go delete mode 100644 vendor/k8s.io/api/storage/v1beta1/types.go delete mode 100644 vendor/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/api/storage/v1beta1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/apimachinery/LICENSE delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/equality/semantic.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/meta/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/meta/errors.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/meta/firsthit_restmapper.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/meta/help.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/meta/interfaces.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/meta/lazy.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/meta/meta.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/meta/multirestmapper.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/meta/priority.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/meta/restmapper.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/resource/amount.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/resource/generated.pb.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/resource/math.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/resource/quantity.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/resource/quantity_proto.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/resource/scale_int.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/resource/suffix.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/resource/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/validation/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/validation/generic.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/controller_ref.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/conversion.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/duration.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/group_version.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/labels.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/micro_time.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/micro_time_proto.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/register.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/time.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/time_proto.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_list.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/watch.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.defaults.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/conversion.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/deepcopy.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.pb.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/register.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types_swagger_doc_generated.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/zz_generated.defaults.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/conversion/converter.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/conversion/deep_equal.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/conversion/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/conversion/helper.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/conversion/queryparams/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/fields/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/fields/fields.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/fields/requirements.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/fields/selector.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/labels/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/labels/labels.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/labels/selector.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/labels/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/codec.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/codec_check.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/conversion.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/converter.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/embedded.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/error.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/extension.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/generated.pb.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/helper.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/interfaces.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/register.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.pb.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/schema/interfaces.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/scheme.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/scheme_builder.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/meta.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/serializer/negotiated_codec.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf_extension.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer/recognizer.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/swagger_doc_generator.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/types.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/types_proto.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/selection/operator.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/types/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/types/namespacedname.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/types/nodename.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/types/patch.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/types/uid.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/errors/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/errors/errors.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/framer/framer.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/intstr/generated.pb.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/json/json.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/mergepatch/errors.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/net/http.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/net/interface.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/net/port_range.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/net/port_split.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/net/util.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/sets/byte.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/sets/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/sets/empty.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/sets/int.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/sets/int64.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/sets/string.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/strategicpatch/errors.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/strategicpatch/meta.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/strategicpatch/types.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/validation/field/path.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/validation/validation.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/wait/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/wait/wait.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/util/yaml/decoder.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/watch/doc.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/watch/filter.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/watch/mux.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/watch/streamwatcher.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/watch/until.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/watch/watch.go delete mode 100644 vendor/k8s.io/apimachinery/pkg/watch/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/apimachinery/third_party/forked/golang/json/fields.go delete mode 100644 vendor/k8s.io/apimachinery/third_party/forked/golang/reflect/deep_equal.go delete mode 100644 vendor/k8s.io/client-go/LICENSE delete mode 100644 vendor/k8s.io/client-go/kubernetes/scheme/doc.go delete mode 100644 vendor/k8s.io/client-go/kubernetes/scheme/register.go delete mode 100644 vendor/k8s.io/kube-openapi/LICENSE delete mode 100644 vendor/k8s.io/kube-openapi/pkg/common/common.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/common/doc.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/util/proto/doc.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/util/proto/document.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/util/proto/openapi.go diff --git a/.travis.yml b/.travis.yml index 92e842f6a..6a8beee87 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,33 +12,27 @@ addons: packages: - tree -language: go - -go: - - 1.12.1 - -go_import_path: sigs.k8s.io/kustomize - -# Maybe, maybe not. -# sudo: false - # Only clone the most recent commit. git: depth: 1 +language: go + +go: + - 1.12 + +go_import_path: sigs.k8s.io/kustomize + env: -- GOLANGCI_RELEASE="v1.12.1" + - GOLANGCI_RELEASE="v1.12" before_install: - source ./bin/consider-early-travis-exit.sh - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $GOPATH/bin ${GOLANGCI_RELEASE} - go get -u github.com/monopole/mdrip -# Install must be set to prevent default `go get` to run. -# The dependencies have already been vendored by `dep` so -# we don't need to fetch them. -install: - - +# Skip the install process; let pre-commit.sh do it. +install: true script: - ./bin/pre-commit.sh diff --git a/Gopkg.lock b/Gopkg.lock deleted file mode 100644 index a910721e2..000000000 --- a/Gopkg.lock +++ /dev/null @@ -1,389 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - digest = "1:d8ebbd207f3d3266d4423ce4860c9f3794956306ded6c7ba312ecc69cdfbf04c" - name = "github.com/PuerkitoBio/purell" - packages = ["."] - pruneopts = "NUT" - revision = "0bcb03f4b4d0a9428594752bd2a3b9aa0a9d4bd4" - version = "v1.1.0" - -[[projects]] - branch = "master" - digest = "1:8098cd40cd09879efbf12e33bcd51ead4a66006ac802cd563a66c4f3373b9727" - name = "github.com/PuerkitoBio/urlesc" - packages = ["."] - pruneopts = "NUT" - revision = "de5bf2ad457846296e2031421a34e2568e304e35" - -[[projects]] - digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39" - name = "github.com/davecgh/go-spew" - packages = ["spew"] - pruneopts = "NUT" - revision = "346938d642f2ec3594ed81d874461961cd0faa76" - version = "v1.1.0" - -[[projects]] - digest = "1:f8e6f07329067bc182633dcb19a3df53ce5d454b551e1b5a1cac2163748648d9" - name = "github.com/emicklei/go-restful" - packages = [ - ".", - "log", - ] - pruneopts = "NUT" - revision = "3658237ded108b4134956c1b3050349d93e7b895" - version = "v2.7.1" - -[[projects]] - digest = "1:ad32dc29f37281bacb5dcedff17c9461dc1739dc8a5f63a71ab491c6e92edf8d" - name = "github.com/evanphx/json-patch" - packages = ["."] - pruneopts = "NUT" - revision = "afac545df32f2287a079e2dfb7ba2745a643747e" - version = "v3.0.0" - -[[projects]] - digest = "1:81466b4218bf6adddac2572a30ac733a9255919bc2f470b4827a317bd4ee1756" - name = "github.com/ghodss/yaml" - packages = ["."] - pruneopts = "NUT" - revision = "0ca9ea5df5451ffdf184b4428c902747c2c11cd7" - version = "v1.0.0" - -[[projects]] - branch = "master" - digest = "1:260f7ebefc63024c8dfe2c9f1a2935a89fa4213637a1f522f592f80c001cc441" - name = "github.com/go-openapi/jsonpointer" - packages = ["."] - pruneopts = "NUT" - revision = "3a0015ad55fa9873f41605d3e8f28cd279c32ab2" - -[[projects]] - branch = "master" - digest = "1:98abd61947ff5c7c6fcfec5473d02a4821ed3a2dd99a4fbfdb7925b0dd745546" - name = "github.com/go-openapi/jsonreference" - packages = ["."] - pruneopts = "NUT" - revision = "3fb327e6747da3043567ee86abd02bb6376b6be2" - -[[projects]] - branch = "master" - digest = "1:e95b560c49fb849a61957a5fb3346ce23b3f67426e00e01179e5396cabc9a12c" - name = "github.com/go-openapi/spec" - packages = ["."] - pruneopts = "NUT" - revision = "bcff419492eeeb01f76e77d2ebc714dc97b607f5" - -[[projects]] - branch = "master" - digest = "1:a610c604eb06f0be4b0fc667388b7a221155d77d7f9089f70ac142a4a9daf014" - name = "github.com/go-openapi/swag" - packages = ["."] - pruneopts = "NUT" - revision = "811b1089cde9dad18d4d0c2d09fbdbf28dbd27a5" - -[[projects]] - digest = "1:1b3dd24f14a5280710fc7a3aa2480b6e4d20fdfc905841de9a3aa2aa2f1d4ee9" - name = "github.com/gogo/protobuf" - packages = [ - "proto", - "sortkeys", - ] - pruneopts = "NUT" - revision = "1adfc126b41513cc696b209667c8656ea7aac67c" - version = "v1.0.0" - -[[projects]] - branch = "master" - digest = "1:e2b86e41f3d669fc36b50d31d32d22c8ac656c75aa5ea89717ce7177e134ff2a" - name = "github.com/golang/glog" - packages = ["."] - pruneopts = "NUT" - revision = "23def4e6c14b4da8ac2ed8007337bc5eb5007998" - -[[projects]] - digest = "1:03e14cff610a8a58b774e36bd337fa979482be86aab01be81fb8bbd6d0f07fc8" - name = "github.com/golang/protobuf" - packages = [ - "proto", - "ptypes", - "ptypes/any", - "ptypes/duration", - "ptypes/timestamp", - ] - pruneopts = "NUT" - revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265" - version = "v1.1.0" - -[[projects]] - branch = "master" - digest = "1:52c5834e2bebac9030c97cc0798ac11c3aa8a39f098aeb419f142533da6cd3cc" - name = "github.com/google/gofuzz" - packages = ["."] - pruneopts = "NUT" - revision = "24818f796faf91cd76ec7bddd72458fbced7a6c1" - -[[projects]] - digest = "1:3d7c1446fc5c710351b246c0dc6700fae843ca27f5294d0bd9f68bab2a810c44" - name = "github.com/googleapis/gnostic" - packages = [ - "OpenAPIv2", - "compiler", - "extensions", - ] - pruneopts = "NUT" - revision = "ee43cbb60db7bd22502942cccbc39059117352ab" - version = "v0.1.0" - -[[projects]] - digest = "1:406338ad39ab2e37b7f4452906442a3dbf0eb3379dd1f06aafb5c07e769a5fbb" - name = "github.com/inconshreveable/mousetrap" - packages = ["."] - pruneopts = "NUT" - revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" - version = "v1.0" - -[[projects]] - digest = "1:42c47ace7ccb114261ef7e0d418d274921514ab50a3bf6bdb9e51c3dde8ce13d" - name = "github.com/json-iterator/go" - packages = ["."] - pruneopts = "NUT" - revision = "ca39e5af3ece67bbcda3d0f4f56a8e24d9f2dad4" - version = "1.1.3" - -[[projects]] - branch = "master" - digest = "1:ada518b8c338e10e0afa443d84671476d3bd1d926e13713938088e8ddbee1a3e" - name = "github.com/mailru/easyjson" - packages = [ - "buffer", - "jlexer", - "jwriter", - ] - pruneopts = "NUT" - revision = "3fdea8d05856a0c8df22ed4bc71b3219245e4485" - -[[projects]] - digest = "1:2f42fa12d6911c7b7659738758631bec870b7e9b4c6be5444f963cdcfccc191f" - name = "github.com/modern-go/concurrent" - packages = ["."] - pruneopts = "NUT" - revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94" - version = "1.0.3" - -[[projects]] - digest = "1:314a5881fab303a80d6d2e35a77000f2224bb50f09ef63a9aa4c1f9eaef985d8" - name = "github.com/modern-go/reflect2" - packages = ["."] - pruneopts = "NUT" - revision = "1df9eeb2bb81f327b96228865c5687bc2194af3f" - version = "1.0.0" - -[[projects]] - digest = "1:5cf3f025cbee5951a4ee961de067c8a89fc95a5adabead774f82822efabab121" - name = "github.com/pkg/errors" - packages = ["."] - pruneopts = "NUT" - revision = "645ef00459ed84a119197bfb8d8205042c6df63d" - version = "v0.8.0" - -[[projects]] - digest = "1:0f156dbd01b40676bdcbc64e51535c09b50f83c9cca5faef3090f82f18bda3c2" - name = "github.com/spf13/cobra" - packages = ["."] - pruneopts = "NUT" - revision = "a1f051bc3eba734da4772d60e2d677f47cf93ef4" - version = "v0.0.2" - -[[projects]] - digest = "1:15e5c398fbd9d2c439b635a08ac161b13d04f0c2aa587fe256b65dc0c3efe8b7" - name = "github.com/spf13/pflag" - packages = ["."] - pruneopts = "NUT" - revision = "583c0c0531f06d5278b7d917446061adc344b5cd" - version = "v1.0.1" - -[[projects]] - branch = "master" - digest = "1:18108bc7e384e395b4805632a637405a3df71fa518e22f9b39b0c08b89a52b96" - name = "golang.org/x/net" - packages = [ - "http/httpguts", - "http2", - "http2/hpack", - "idna", - ] - pruneopts = "NUT" - revision = "fe579d43d83210096a79b46dcca0e3721058393a" - -[[projects]] - digest = "1:e33513a825fcd765e97b5de639a2f7547542d1a8245df0cef18e1fd390b778a9" - name = "golang.org/x/text" - packages = [ - "collate", - "collate/build", - "internal/colltab", - "internal/gen", - "internal/tag", - "internal/triegen", - "internal/ucd", - "language", - "secure/bidirule", - "transform", - "unicode/bidi", - "unicode/cldr", - "unicode/norm", - "unicode/rangetable", - "width", - ] - pruneopts = "NUT" - revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" - version = "v0.3.0" - -[[projects]] - digest = "1:2d1fbdc6777e5408cabeb02bf336305e724b925ff4546ded0fa8715a7267922a" - name = "gopkg.in/inf.v0" - packages = ["."] - pruneopts = "NUT" - revision = "d2d2541c53f18d2a059457998ce2876cc8e67cbf" - version = "v0.9.1" - -[[projects]] - digest = "1:7c95b35057a0ff2e19f707173cc1a947fa43a6eb5c4d300d196ece0334046082" - name = "gopkg.in/yaml.v2" - packages = ["."] - pruneopts = "NUT" - revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" - version = "v2.2.1" - -[[projects]] - branch = "master" - digest = "1:d895c7c24a0dd1ed2ecd061fd88dfea9e1e84d6f280ed859942a2d1aabee10ec" - name = "k8s.io/api" - packages = [ - "admissionregistration/v1alpha1", - "admissionregistration/v1beta1", - "apps/v1", - "apps/v1beta1", - "apps/v1beta2", - "authentication/v1", - "authentication/v1beta1", - "authorization/v1", - "authorization/v1beta1", - "autoscaling/v1", - "autoscaling/v2beta1", - "batch/v1", - "batch/v1beta1", - "batch/v2alpha1", - "certificates/v1beta1", - "core/v1", - "events/v1beta1", - "extensions/v1beta1", - "networking/v1", - "policy/v1beta1", - "rbac/v1", - "rbac/v1alpha1", - "rbac/v1beta1", - "scheduling/v1alpha1", - "settings/v1alpha1", - "storage/v1", - "storage/v1alpha1", - "storage/v1beta1", - ] - pruneopts = "NUT" - revision = "53d615ae3f440f957cb9989d989d597f047262d9" - -[[projects]] - branch = "master" - digest = "1:dff69dd9d9fc681ae077ce5a409aca3c24894d09102ab0395ca7972f6ec01811" - name = "k8s.io/apimachinery" - packages = [ - "pkg/api/equality", - "pkg/api/meta", - "pkg/api/resource", - "pkg/api/validation", - "pkg/apis/meta/v1", - "pkg/apis/meta/v1/unstructured", - "pkg/apis/meta/v1/validation", - "pkg/apis/meta/v1beta1", - "pkg/conversion", - "pkg/conversion/queryparams", - "pkg/fields", - "pkg/labels", - "pkg/runtime", - "pkg/runtime/schema", - "pkg/runtime/serializer", - "pkg/runtime/serializer/json", - "pkg/runtime/serializer/protobuf", - "pkg/runtime/serializer/recognizer", - "pkg/runtime/serializer/versioning", - "pkg/selection", - "pkg/types", - "pkg/util/errors", - "pkg/util/framer", - "pkg/util/intstr", - "pkg/util/json", - "pkg/util/mergepatch", - "pkg/util/net", - "pkg/util/runtime", - "pkg/util/sets", - "pkg/util/strategicpatch", - "pkg/util/validation", - "pkg/util/validation/field", - "pkg/util/wait", - "pkg/util/yaml", - "pkg/watch", - "third_party/forked/golang/json", - "third_party/forked/golang/reflect", - ] - pruneopts = "NUT" - revision = "13b73596e4b63e03203e86f6d9c7bcc1b937c62f" - -[[projects]] - digest = "1:ae9ced9ef7b8eb2794a4f80bc3af9d2bc38ec7d60337367bad9a655c1d641458" - name = "k8s.io/client-go" - packages = ["kubernetes/scheme"] - pruneopts = "NUT" - revision = "23781f4d6632d88e869066eaebb743857aa1ef9b" - version = "v7.0.0" - -[[projects]] - branch = "master" - digest = "1:f4fb3421360af5c51070bfe0c1c7467f8809fa70e278e129f068f5106b5c8a65" - name = "k8s.io/kube-openapi" - packages = [ - "pkg/common", - "pkg/util/proto", - ] - pruneopts = "NUT" - revision = "b3f03f55328800731ce03a164b80973014ecd455" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - input-imports = [ - "github.com/evanphx/json-patch", - "github.com/ghodss/yaml", - "github.com/go-openapi/spec", - "github.com/pkg/errors", - "github.com/spf13/cobra", - "gopkg.in/yaml.v2", - "k8s.io/api/core/v1", - "k8s.io/apimachinery/pkg/api/validation", - "k8s.io/apimachinery/pkg/apis/meta/v1", - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured", - "k8s.io/apimachinery/pkg/apis/meta/v1/validation", - "k8s.io/apimachinery/pkg/runtime", - "k8s.io/apimachinery/pkg/runtime/schema", - "k8s.io/apimachinery/pkg/util/mergepatch", - "k8s.io/apimachinery/pkg/util/strategicpatch", - "k8s.io/apimachinery/pkg/util/validation", - "k8s.io/apimachinery/pkg/util/validation/field", - "k8s.io/apimachinery/pkg/util/yaml", - "k8s.io/client-go/kubernetes/scheme", - "k8s.io/kube-openapi/pkg/common", - ] - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml deleted file mode 100644 index 880bf38db..000000000 --- a/Gopkg.toml +++ /dev/null @@ -1,58 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" - -# prune out unused content from vendor -[prune] - go-tests = true - non-go = true - unused-packages = true - -[[constraint]] - name = "github.com/evanphx/json-patch" - version = "3.0.0" - -[[constraint]] - name = "github.com/ghodss/yaml" - version = "1.0.0" - -[[constraint]] - name = "github.com/spf13/cobra" - version = "0.0.2" - -[[constraint]] - branch = "master" - name = "k8s.io/api" - -[[constraint]] - branch = "master" - name = "k8s.io/apimachinery" - -[[constraint]] - name = "k8s.io/client-go" - version = "7.0.0" - -[[override]] - branch = "master" - name = "k8s.io/utils" - -[[override]] - branch = "master" - name = "github.com/go-openapi/spec" diff --git a/bin/pre-commit.sh b/bin/pre-commit.sh index 67edf1578..ffa294c78 100755 --- a/bin/pre-commit.sh +++ b/bin/pre-commit.sh @@ -12,7 +12,11 @@ cd "$base_dir" || { rc=0 function buildPlugins { -go build -buildmode plugin -tags=plugin -o ./pkg/plugins/builtin/executable.so ./pkg/plugins/builtin/executable.go + go build \ + -buildmode plugin \ + -tags=plugin \ + -o ./pkg/plugins/builtin/executable.so \ + ./pkg/plugins/builtin/executable.go } function runTest { @@ -40,9 +44,55 @@ function testExamples { mdrip --mode test --label test README.md ./examples } +# Use of GOPATH is optional if go modules are +# used. This script tries to work for people who +# don't have GOPATH set, and work for travis. +# +# Upon entry, travis has GOPATH set, and used it +# to install mdrip and the like. +# +# Use GOPATH to define XDG_CONFIG_HOME, then unset +# GOPATH so that go.mod is unambiguously honored. +echo "GOPATH=$GOPATH" + +if [ -z ${GOPATH+x} ]; then + echo GOPATH is unset + tmp=$HOME/gopath + if [ -d "$tmp" ]; then + oldGoPath=$tmp + else + tmp=$HOME/go + if [ -d "$tmp" ]; then + oldGoPath=$tmp + fi + fi +else + oldGoPath=$GOPATH + unset GOPATH +fi +echo "oldGoPath=$oldGoPath" +export XDG_CONFIG_HOME=$oldGoPath/src/sigs.k8s.io +echo "XDG_CONFIG_HOME=$XDG_CONFIG_HOME" +if [ ! -d "$XDG_CONFIG_HOME" ]; then + echo "$XDG_CONFIG_HOME is not a directory." + exit 1 +fi + +# Until go v1.13, set this explicitly. +export GO111MODULE=on + +echo "HOME=$HOME" +echo "GOPATH=$GOPATH" +echo "GO111MODULE=$GO111MODULE" +echo pwd=`pwd` +echo " " +echo "Beginning tests..." + runTest buildPlugins runTest testGoLangCILint runTest testGoTest + +PATH=$HOME/go/bin:$PATH runTest testExamples if [ $rc -eq 0 ]; then diff --git a/go.mod b/go.mod new file mode 100644 index 000000000..dd6a43102 --- /dev/null +++ b/go.mod @@ -0,0 +1,38 @@ +module sigs.k8s.io/kustomize + +go 1.12 + +require ( + github.com/PuerkitoBio/purell v1.1.0 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect + github.com/emicklei/go-restful v2.9.3+incompatible // indirect + github.com/evanphx/json-patch v3.0.0+incompatible + github.com/ghodss/yaml v1.0.0 + github.com/go-openapi/jsonpointer v0.0.0-20180322222829-3a0015ad55fa // indirect + github.com/go-openapi/jsonreference v0.0.0-20180322222742-3fb327e6747d // indirect + github.com/go-openapi/spec v0.0.0-20180415031709-bcff419492ee + github.com/go-openapi/swag v0.0.0-20180405201759-811b1089cde9 // indirect + github.com/gogo/protobuf v1.0.0 // indirect + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect + github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf // indirect + github.com/googleapis/gnostic v0.1.0 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/json-iterator/go v0.0.0-20180315132816-ca39e5af3ece // indirect + github.com/mailru/easyjson v0.0.0-20180606163543-3fdea8d05856 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v0.0.0-20180228065516-1df9eeb2bb81 // indirect + github.com/onsi/ginkgo v1.8.0 // indirect + github.com/onsi/gomega v1.5.0 // indirect + github.com/pkg/errors v0.8.0 + github.com/spf13/cobra v0.0.2 + github.com/spf13/pflag v1.0.1 // indirect + github.com/stretchr/testify v1.3.0 // indirect + golang.org/x/net v0.0.0-20190225153610-fe579d43d832 // indirect + golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.2.1 + k8s.io/api v0.0.0-20180510062335-53d615ae3f44 + k8s.io/apimachinery v0.0.0-20180510061931-13b73596e4b6 + k8s.io/client-go v7.0.0+incompatible + k8s.io/kube-openapi v0.0.0-20180510204742-b3f03f553288 +) diff --git a/go.sum b/go.sum new file mode 100644 index 000000000..241ce5825 --- /dev/null +++ b/go.sum @@ -0,0 +1,88 @@ +github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful v2.9.3+incompatible h1:2OwhVdhtzYUp5P5wuGsVDPagKSRd9JK72sJCHVCXh5g= +github.com/emicklei/go-restful v2.9.3+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/evanphx/json-patch v3.0.0+incompatible h1:l91aby7TzBXBdmF8heZqjskeH9f3g7ZOL8/sSe+vTlU= +github.com/evanphx/json-patch v3.0.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-openapi/jsonpointer v0.0.0-20180322222829-3a0015ad55fa h1:hr8WVDjg4JKtQptZpzyb196TmruCs7PIsdJz8KAOZp8= +github.com/go-openapi/jsonpointer v0.0.0-20180322222829-3a0015ad55fa/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonreference v0.0.0-20180322222742-3fb327e6747d h1:k3UQ7Z8yFYq0BNkYykKIheY0HlZBl1Hku+pO9HE9FNU= +github.com/go-openapi/jsonreference v0.0.0-20180322222742-3fb327e6747d/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/spec v0.0.0-20180415031709-bcff419492ee h1:eo0HQoNFtbiEc7+1gRF9pgW6azx8a1cO2fXcqq1MuD0= +github.com/go-openapi/spec v0.0.0-20180415031709-bcff419492ee/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20180405201759-811b1089cde9 h1:+vsw187FKvA2QUGAcE+vQSfyxqLbUXixPYRRMAzwu04= +github.com/go-openapi/swag v0.0.0-20180405201759-811b1089cde9/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/gogo/protobuf v1.0.0 h1:2jyBKDKU/8v3v2xVR2PtiWQviFUyiaGk2rpfyFT8rTM= +github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/json-iterator/go v0.0.0-20180315132816-ca39e5af3ece h1:3HJXp/18JmMk5sjBP3LDUBtWjczCvynxaeAF6b6kWp8= +github.com/json-iterator/go v0.0.0-20180315132816-ca39e5af3ece/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/mailru/easyjson v0.0.0-20180606163543-3fdea8d05856 h1:hOnidOuIWNsFRPcxxStGeN3NNm4n4+w6KJ9cVJIh70o= +github.com/mailru/easyjson v0.0.0-20180606163543-3fdea8d05856/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180228065516-1df9eeb2bb81 h1:ImOHKpmdLPXWX5KSYquUWXKaopEPuY7TPPUo18u9aOI= +github.com/modern-go/reflect2 v0.0.0-20180228065516-1df9eeb2bb81/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/spf13/cobra v0.0.2 h1:NfkwRbgViGoyjBKsLI0QMDcuMnhM+SBg3T0cGfpvKDE= +github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190225153610-fe579d43d832 h1:2IdId8zoI92l1bUzjAOygcAOkmCe13HY1j0rqPPPzB8= +golang.org/x/net v0.0.0-20190225153610-fe579d43d832/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +k8s.io/api v0.0.0-20180510062335-53d615ae3f44 h1:zQ8YhMpuc1QJoor+Vm1moP9iEOyaQgOjSj3bo/zUEXE= +k8s.io/api v0.0.0-20180510062335-53d615ae3f44/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/apimachinery v0.0.0-20180510061931-13b73596e4b6 h1:pJrzRmry9HLPxkVGMk57cfeGRy/WG0oYXuji9t4zD1M= +k8s.io/apimachinery v0.0.0-20180510061931-13b73596e4b6/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/client-go v7.0.0+incompatible h1:kiH+Y6hn+pc78QS/mtBfMJAMIIaWevHi++JvOGEEQp4= +k8s.io/client-go v7.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= +k8s.io/kube-openapi v0.0.0-20180510204742-b3f03f553288 h1:AhFqcaw5JbAAaZHxTe1fT+Jtek0pZmIwwt6FbsMA9to= +k8s.io/kube-openapi v0.0.0-20180510204742-b3f03f553288/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= diff --git a/pkg/target/generatorplugin_test.go b/pkg/target/generatorplugin_test.go index 2da781936..5e4b2753c 100644 --- a/pkg/target/generatorplugin_test.go +++ b/pkg/target/generatorplugin_test.go @@ -128,7 +128,7 @@ type: Opaque `) } -func TestConfigMapGenerator(t *testing.T) { +func xTestConfigMapGenerator(t *testing.T) { tc := NewTestEnvController(t).Set() defer tc.Reset() diff --git a/vendor/github.com/PuerkitoBio/purell/LICENSE b/vendor/github.com/PuerkitoBio/purell/LICENSE deleted file mode 100644 index 4b9986dea..000000000 --- a/vendor/github.com/PuerkitoBio/purell/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) 2012, Martin Angers -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/PuerkitoBio/purell/purell.go b/vendor/github.com/PuerkitoBio/purell/purell.go deleted file mode 100644 index 645e1b76f..000000000 --- a/vendor/github.com/PuerkitoBio/purell/purell.go +++ /dev/null @@ -1,379 +0,0 @@ -/* -Package purell offers URL normalization as described on the wikipedia page: -http://en.wikipedia.org/wiki/URL_normalization -*/ -package purell - -import ( - "bytes" - "fmt" - "net/url" - "regexp" - "sort" - "strconv" - "strings" - - "github.com/PuerkitoBio/urlesc" - "golang.org/x/net/idna" - "golang.org/x/text/unicode/norm" - "golang.org/x/text/width" -) - -// A set of normalization flags determines how a URL will -// be normalized. -type NormalizationFlags uint - -const ( - // Safe normalizations - FlagLowercaseScheme NormalizationFlags = 1 << iota // HTTP://host -> http://host, applied by default in Go1.1 - FlagLowercaseHost // http://HOST -> http://host - FlagUppercaseEscapes // http://host/t%ef -> http://host/t%EF - FlagDecodeUnnecessaryEscapes // http://host/t%41 -> http://host/tA - FlagEncodeNecessaryEscapes // http://host/!"#$ -> http://host/%21%22#$ - FlagRemoveDefaultPort // http://host:80 -> http://host - FlagRemoveEmptyQuerySeparator // http://host/path? -> http://host/path - - // Usually safe normalizations - FlagRemoveTrailingSlash // http://host/path/ -> http://host/path - FlagAddTrailingSlash // http://host/path -> http://host/path/ (should choose only one of these add/remove trailing slash flags) - FlagRemoveDotSegments // http://host/path/./a/b/../c -> http://host/path/a/c - - // Unsafe normalizations - FlagRemoveDirectoryIndex // http://host/path/index.html -> http://host/path/ - FlagRemoveFragment // http://host/path#fragment -> http://host/path - FlagForceHTTP // https://host -> http://host - FlagRemoveDuplicateSlashes // http://host/path//a///b -> http://host/path/a/b - FlagRemoveWWW // http://www.host/ -> http://host/ - FlagAddWWW // http://host/ -> http://www.host/ (should choose only one of these add/remove WWW flags) - FlagSortQuery // http://host/path?c=3&b=2&a=1&b=1 -> http://host/path?a=1&b=1&b=2&c=3 - - // Normalizations not in the wikipedia article, required to cover tests cases - // submitted by jehiah - FlagDecodeDWORDHost // http://1113982867 -> http://66.102.7.147 - FlagDecodeOctalHost // http://0102.0146.07.0223 -> http://66.102.7.147 - FlagDecodeHexHost // http://0x42660793 -> http://66.102.7.147 - FlagRemoveUnnecessaryHostDots // http://.host../path -> http://host/path - FlagRemoveEmptyPortSeparator // http://host:/path -> http://host/path - - // Convenience set of safe normalizations - FlagsSafe NormalizationFlags = FlagLowercaseHost | FlagLowercaseScheme | FlagUppercaseEscapes | FlagDecodeUnnecessaryEscapes | FlagEncodeNecessaryEscapes | FlagRemoveDefaultPort | FlagRemoveEmptyQuerySeparator - - // For convenience sets, "greedy" uses the "remove trailing slash" and "remove www. prefix" flags, - // while "non-greedy" uses the "add (or keep) the trailing slash" and "add www. prefix". - - // Convenience set of usually safe normalizations (includes FlagsSafe) - FlagsUsuallySafeGreedy NormalizationFlags = FlagsSafe | FlagRemoveTrailingSlash | FlagRemoveDotSegments - FlagsUsuallySafeNonGreedy NormalizationFlags = FlagsSafe | FlagAddTrailingSlash | FlagRemoveDotSegments - - // Convenience set of unsafe normalizations (includes FlagsUsuallySafe) - FlagsUnsafeGreedy NormalizationFlags = FlagsUsuallySafeGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagRemoveWWW | FlagSortQuery - FlagsUnsafeNonGreedy NormalizationFlags = FlagsUsuallySafeNonGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagAddWWW | FlagSortQuery - - // Convenience set of all available flags - FlagsAllGreedy = FlagsUnsafeGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator - FlagsAllNonGreedy = FlagsUnsafeNonGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator -) - -const ( - defaultHttpPort = ":80" - defaultHttpsPort = ":443" -) - -// Regular expressions used by the normalizations -var rxPort = regexp.MustCompile(`(:\d+)/?$`) -var rxDirIndex = regexp.MustCompile(`(^|/)((?:default|index)\.\w{1,4})$`) -var rxDupSlashes = regexp.MustCompile(`/{2,}`) -var rxDWORDHost = regexp.MustCompile(`^(\d+)((?:\.+)?(?:\:\d*)?)$`) -var rxOctalHost = regexp.MustCompile(`^(0\d*)\.(0\d*)\.(0\d*)\.(0\d*)((?:\.+)?(?:\:\d*)?)$`) -var rxHexHost = regexp.MustCompile(`^0x([0-9A-Fa-f]+)((?:\.+)?(?:\:\d*)?)$`) -var rxHostDots = regexp.MustCompile(`^(.+?)(:\d+)?$`) -var rxEmptyPort = regexp.MustCompile(`:+$`) - -// Map of flags to implementation function. -// FlagDecodeUnnecessaryEscapes has no action, since it is done automatically -// by parsing the string as an URL. Same for FlagUppercaseEscapes and FlagRemoveEmptyQuerySeparator. - -// Since maps have undefined traversing order, make a slice of ordered keys -var flagsOrder = []NormalizationFlags{ - FlagLowercaseScheme, - FlagLowercaseHost, - FlagRemoveDefaultPort, - FlagRemoveDirectoryIndex, - FlagRemoveDotSegments, - FlagRemoveFragment, - FlagForceHTTP, // Must be after remove default port (because https=443/http=80) - FlagRemoveDuplicateSlashes, - FlagRemoveWWW, - FlagAddWWW, - FlagSortQuery, - FlagDecodeDWORDHost, - FlagDecodeOctalHost, - FlagDecodeHexHost, - FlagRemoveUnnecessaryHostDots, - FlagRemoveEmptyPortSeparator, - FlagRemoveTrailingSlash, // These two (add/remove trailing slash) must be last - FlagAddTrailingSlash, -} - -// ... and then the map, where order is unimportant -var flags = map[NormalizationFlags]func(*url.URL){ - FlagLowercaseScheme: lowercaseScheme, - FlagLowercaseHost: lowercaseHost, - FlagRemoveDefaultPort: removeDefaultPort, - FlagRemoveDirectoryIndex: removeDirectoryIndex, - FlagRemoveDotSegments: removeDotSegments, - FlagRemoveFragment: removeFragment, - FlagForceHTTP: forceHTTP, - FlagRemoveDuplicateSlashes: removeDuplicateSlashes, - FlagRemoveWWW: removeWWW, - FlagAddWWW: addWWW, - FlagSortQuery: sortQuery, - FlagDecodeDWORDHost: decodeDWORDHost, - FlagDecodeOctalHost: decodeOctalHost, - FlagDecodeHexHost: decodeHexHost, - FlagRemoveUnnecessaryHostDots: removeUnncessaryHostDots, - FlagRemoveEmptyPortSeparator: removeEmptyPortSeparator, - FlagRemoveTrailingSlash: removeTrailingSlash, - FlagAddTrailingSlash: addTrailingSlash, -} - -// MustNormalizeURLString returns the normalized string, and panics if an error occurs. -// It takes an URL string as input, as well as the normalization flags. -func MustNormalizeURLString(u string, f NormalizationFlags) string { - result, e := NormalizeURLString(u, f) - if e != nil { - panic(e) - } - return result -} - -// NormalizeURLString returns the normalized string, or an error if it can't be parsed into an URL object. -// It takes an URL string as input, as well as the normalization flags. -func NormalizeURLString(u string, f NormalizationFlags) (string, error) { - parsed, err := url.Parse(u) - if err != nil { - return "", err - } - - if f&FlagLowercaseHost == FlagLowercaseHost { - parsed.Host = strings.ToLower(parsed.Host) - } - - // The idna package doesn't fully conform to RFC 5895 - // (https://tools.ietf.org/html/rfc5895), so we do it here. - // Taken from Go 1.8 cycle source, courtesy of bradfitz. - // TODO: Remove when (if?) idna package conforms to RFC 5895. - parsed.Host = width.Fold.String(parsed.Host) - parsed.Host = norm.NFC.String(parsed.Host) - if parsed.Host, err = idna.ToASCII(parsed.Host); err != nil { - return "", err - } - - return NormalizeURL(parsed, f), nil -} - -// NormalizeURL returns the normalized string. -// It takes a parsed URL object as input, as well as the normalization flags. -func NormalizeURL(u *url.URL, f NormalizationFlags) string { - for _, k := range flagsOrder { - if f&k == k { - flags[k](u) - } - } - return urlesc.Escape(u) -} - -func lowercaseScheme(u *url.URL) { - if len(u.Scheme) > 0 { - u.Scheme = strings.ToLower(u.Scheme) - } -} - -func lowercaseHost(u *url.URL) { - if len(u.Host) > 0 { - u.Host = strings.ToLower(u.Host) - } -} - -func removeDefaultPort(u *url.URL) { - if len(u.Host) > 0 { - scheme := strings.ToLower(u.Scheme) - u.Host = rxPort.ReplaceAllStringFunc(u.Host, func(val string) string { - if (scheme == "http" && val == defaultHttpPort) || (scheme == "https" && val == defaultHttpsPort) { - return "" - } - return val - }) - } -} - -func removeTrailingSlash(u *url.URL) { - if l := len(u.Path); l > 0 { - if strings.HasSuffix(u.Path, "/") { - u.Path = u.Path[:l-1] - } - } else if l = len(u.Host); l > 0 { - if strings.HasSuffix(u.Host, "/") { - u.Host = u.Host[:l-1] - } - } -} - -func addTrailingSlash(u *url.URL) { - if l := len(u.Path); l > 0 { - if !strings.HasSuffix(u.Path, "/") { - u.Path += "/" - } - } else if l = len(u.Host); l > 0 { - if !strings.HasSuffix(u.Host, "/") { - u.Host += "/" - } - } -} - -func removeDotSegments(u *url.URL) { - if len(u.Path) > 0 { - var dotFree []string - var lastIsDot bool - - sections := strings.Split(u.Path, "/") - for _, s := range sections { - if s == ".." { - if len(dotFree) > 0 { - dotFree = dotFree[:len(dotFree)-1] - } - } else if s != "." { - dotFree = append(dotFree, s) - } - lastIsDot = (s == "." || s == "..") - } - // Special case if host does not end with / and new path does not begin with / - u.Path = strings.Join(dotFree, "/") - if u.Host != "" && !strings.HasSuffix(u.Host, "/") && !strings.HasPrefix(u.Path, "/") { - u.Path = "/" + u.Path - } - // Special case if the last segment was a dot, make sure the path ends with a slash - if lastIsDot && !strings.HasSuffix(u.Path, "/") { - u.Path += "/" - } - } -} - -func removeDirectoryIndex(u *url.URL) { - if len(u.Path) > 0 { - u.Path = rxDirIndex.ReplaceAllString(u.Path, "$1") - } -} - -func removeFragment(u *url.URL) { - u.Fragment = "" -} - -func forceHTTP(u *url.URL) { - if strings.ToLower(u.Scheme) == "https" { - u.Scheme = "http" - } -} - -func removeDuplicateSlashes(u *url.URL) { - if len(u.Path) > 0 { - u.Path = rxDupSlashes.ReplaceAllString(u.Path, "/") - } -} - -func removeWWW(u *url.URL) { - if len(u.Host) > 0 && strings.HasPrefix(strings.ToLower(u.Host), "www.") { - u.Host = u.Host[4:] - } -} - -func addWWW(u *url.URL) { - if len(u.Host) > 0 && !strings.HasPrefix(strings.ToLower(u.Host), "www.") { - u.Host = "www." + u.Host - } -} - -func sortQuery(u *url.URL) { - q := u.Query() - - if len(q) > 0 { - arKeys := make([]string, len(q)) - i := 0 - for k, _ := range q { - arKeys[i] = k - i++ - } - sort.Strings(arKeys) - buf := new(bytes.Buffer) - for _, k := range arKeys { - sort.Strings(q[k]) - for _, v := range q[k] { - if buf.Len() > 0 { - buf.WriteRune('&') - } - buf.WriteString(fmt.Sprintf("%s=%s", k, urlesc.QueryEscape(v))) - } - } - - // Rebuild the raw query string - u.RawQuery = buf.String() - } -} - -func decodeDWORDHost(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxDWORDHost.FindStringSubmatch(u.Host); len(matches) > 2 { - var parts [4]int64 - - dword, _ := strconv.ParseInt(matches[1], 10, 0) - for i, shift := range []uint{24, 16, 8, 0} { - parts[i] = dword >> shift & 0xFF - } - u.Host = fmt.Sprintf("%d.%d.%d.%d%s", parts[0], parts[1], parts[2], parts[3], matches[2]) - } - } -} - -func decodeOctalHost(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxOctalHost.FindStringSubmatch(u.Host); len(matches) > 5 { - var parts [4]int64 - - for i := 1; i <= 4; i++ { - parts[i-1], _ = strconv.ParseInt(matches[i], 8, 0) - } - u.Host = fmt.Sprintf("%d.%d.%d.%d%s", parts[0], parts[1], parts[2], parts[3], matches[5]) - } - } -} - -func decodeHexHost(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxHexHost.FindStringSubmatch(u.Host); len(matches) > 2 { - // Conversion is safe because of regex validation - parsed, _ := strconv.ParseInt(matches[1], 16, 0) - // Set host as DWORD (base 10) encoded host - u.Host = fmt.Sprintf("%d%s", parsed, matches[2]) - // The rest is the same as decoding a DWORD host - decodeDWORDHost(u) - } - } -} - -func removeUnncessaryHostDots(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxHostDots.FindStringSubmatch(u.Host); len(matches) > 1 { - // Trim the leading and trailing dots - u.Host = strings.Trim(matches[1], ".") - if len(matches) > 2 { - u.Host += matches[2] - } - } - } -} - -func removeEmptyPortSeparator(u *url.URL) { - if len(u.Host) > 0 { - u.Host = rxEmptyPort.ReplaceAllString(u.Host, "") - } -} diff --git a/vendor/github.com/PuerkitoBio/urlesc/LICENSE b/vendor/github.com/PuerkitoBio/urlesc/LICENSE deleted file mode 100644 index 744875676..000000000 --- a/vendor/github.com/PuerkitoBio/urlesc/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/PuerkitoBio/urlesc/urlesc.go b/vendor/github.com/PuerkitoBio/urlesc/urlesc.go deleted file mode 100644 index 1b8462459..000000000 --- a/vendor/github.com/PuerkitoBio/urlesc/urlesc.go +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package urlesc implements query escaping as per RFC 3986. -// It contains some parts of the net/url package, modified so as to allow -// some reserved characters incorrectly escaped by net/url. -// See https://github.com/golang/go/issues/5684 -package urlesc - -import ( - "bytes" - "net/url" - "strings" -) - -type encoding int - -const ( - encodePath encoding = 1 + iota - encodeUserPassword - encodeQueryComponent - encodeFragment -) - -// Return true if the specified character should be escaped when -// appearing in a URL string, according to RFC 3986. -func shouldEscape(c byte, mode encoding) bool { - // §2.3 Unreserved characters (alphanum) - if 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' { - return false - } - - switch c { - case '-', '.', '_', '~': // §2.3 Unreserved characters (mark) - return false - - // §2.2 Reserved characters (reserved) - case ':', '/', '?', '#', '[', ']', '@', // gen-delims - '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=': // sub-delims - // Different sections of the URL allow a few of - // the reserved characters to appear unescaped. - switch mode { - case encodePath: // §3.3 - // The RFC allows sub-delims and : @. - // '/', '[' and ']' can be used to assign meaning to individual path - // segments. This package only manipulates the path as a whole, - // so we allow those as well. That leaves only ? and # to escape. - return c == '?' || c == '#' - - case encodeUserPassword: // §3.2.1 - // The RFC allows : and sub-delims in - // userinfo. The parsing of userinfo treats ':' as special so we must escape - // all the gen-delims. - return c == ':' || c == '/' || c == '?' || c == '#' || c == '[' || c == ']' || c == '@' - - case encodeQueryComponent: // §3.4 - // The RFC allows / and ?. - return c != '/' && c != '?' - - case encodeFragment: // §4.1 - // The RFC text is silent but the grammar allows - // everything, so escape nothing but # - return c == '#' - } - } - - // Everything else must be escaped. - return true -} - -// QueryEscape escapes the string so it can be safely placed -// inside a URL query. -func QueryEscape(s string) string { - return escape(s, encodeQueryComponent) -} - -func escape(s string, mode encoding) string { - spaceCount, hexCount := 0, 0 - for i := 0; i < len(s); i++ { - c := s[i] - if shouldEscape(c, mode) { - if c == ' ' && mode == encodeQueryComponent { - spaceCount++ - } else { - hexCount++ - } - } - } - - if spaceCount == 0 && hexCount == 0 { - return s - } - - t := make([]byte, len(s)+2*hexCount) - j := 0 - for i := 0; i < len(s); i++ { - switch c := s[i]; { - case c == ' ' && mode == encodeQueryComponent: - t[j] = '+' - j++ - case shouldEscape(c, mode): - t[j] = '%' - t[j+1] = "0123456789ABCDEF"[c>>4] - t[j+2] = "0123456789ABCDEF"[c&15] - j += 3 - default: - t[j] = s[i] - j++ - } - } - return string(t) -} - -var uiReplacer = strings.NewReplacer( - "%21", "!", - "%27", "'", - "%28", "(", - "%29", ")", - "%2A", "*", -) - -// unescapeUserinfo unescapes some characters that need not to be escaped as per RFC3986. -func unescapeUserinfo(s string) string { - return uiReplacer.Replace(s) -} - -// Escape reassembles the URL into a valid URL string. -// The general form of the result is one of: -// -// scheme:opaque -// scheme://userinfo@host/path?query#fragment -// -// If u.Opaque is non-empty, String uses the first form; -// otherwise it uses the second form. -// -// In the second form, the following rules apply: -// - if u.Scheme is empty, scheme: is omitted. -// - if u.User is nil, userinfo@ is omitted. -// - if u.Host is empty, host/ is omitted. -// - if u.Scheme and u.Host are empty and u.User is nil, -// the entire scheme://userinfo@host/ is omitted. -// - if u.Host is non-empty and u.Path begins with a /, -// the form host/path does not add its own /. -// - if u.RawQuery is empty, ?query is omitted. -// - if u.Fragment is empty, #fragment is omitted. -func Escape(u *url.URL) string { - var buf bytes.Buffer - if u.Scheme != "" { - buf.WriteString(u.Scheme) - buf.WriteByte(':') - } - if u.Opaque != "" { - buf.WriteString(u.Opaque) - } else { - if u.Scheme != "" || u.Host != "" || u.User != nil { - buf.WriteString("//") - if ui := u.User; ui != nil { - buf.WriteString(unescapeUserinfo(ui.String())) - buf.WriteByte('@') - } - if h := u.Host; h != "" { - buf.WriteString(h) - } - } - if u.Path != "" && u.Path[0] != '/' && u.Host != "" { - buf.WriteByte('/') - } - buf.WriteString(escape(u.Path, encodePath)) - } - if u.RawQuery != "" { - buf.WriteByte('?') - buf.WriteString(u.RawQuery) - } - if u.Fragment != "" { - buf.WriteByte('#') - buf.WriteString(escape(u.Fragment, encodeFragment)) - } - return buf.String() -} diff --git a/vendor/github.com/davecgh/go-spew/LICENSE b/vendor/github.com/davecgh/go-spew/LICENSE deleted file mode 100644 index c83641619..000000000 --- a/vendor/github.com/davecgh/go-spew/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -ISC License - -Copyright (c) 2012-2016 Dave Collins - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/davecgh/go-spew/spew/bypass.go b/vendor/github.com/davecgh/go-spew/spew/bypass.go deleted file mode 100644 index 8a4a6589a..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/bypass.go +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (c) 2015-2016 Dave Collins -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -// NOTE: Due to the following build constraints, this file will only be compiled -// when the code is not running on Google App Engine, compiled by GopherJS, and -// "-tags safe" is not added to the go build command line. The "disableunsafe" -// tag is deprecated and thus should not be used. -// +build !js,!appengine,!safe,!disableunsafe - -package spew - -import ( - "reflect" - "unsafe" -) - -const ( - // UnsafeDisabled is a build-time constant which specifies whether or - // not access to the unsafe package is available. - UnsafeDisabled = false - - // ptrSize is the size of a pointer on the current arch. - ptrSize = unsafe.Sizeof((*byte)(nil)) -) - -var ( - // offsetPtr, offsetScalar, and offsetFlag are the offsets for the - // internal reflect.Value fields. These values are valid before golang - // commit ecccf07e7f9d which changed the format. The are also valid - // after commit 82f48826c6c7 which changed the format again to mirror - // the original format. Code in the init function updates these offsets - // as necessary. - offsetPtr = uintptr(ptrSize) - offsetScalar = uintptr(0) - offsetFlag = uintptr(ptrSize * 2) - - // flagKindWidth and flagKindShift indicate various bits that the - // reflect package uses internally to track kind information. - // - // flagRO indicates whether or not the value field of a reflect.Value is - // read-only. - // - // flagIndir indicates whether the value field of a reflect.Value is - // the actual data or a pointer to the data. - // - // These values are valid before golang commit 90a7c3c86944 which - // changed their positions. Code in the init function updates these - // flags as necessary. - flagKindWidth = uintptr(5) - flagKindShift = uintptr(flagKindWidth - 1) - flagRO = uintptr(1 << 0) - flagIndir = uintptr(1 << 1) -) - -func init() { - // Older versions of reflect.Value stored small integers directly in the - // ptr field (which is named val in the older versions). Versions - // between commits ecccf07e7f9d and 82f48826c6c7 added a new field named - // scalar for this purpose which unfortunately came before the flag - // field, so the offset of the flag field is different for those - // versions. - // - // This code constructs a new reflect.Value from a known small integer - // and checks if the size of the reflect.Value struct indicates it has - // the scalar field. When it does, the offsets are updated accordingly. - vv := reflect.ValueOf(0xf00) - if unsafe.Sizeof(vv) == (ptrSize * 4) { - offsetScalar = ptrSize * 2 - offsetFlag = ptrSize * 3 - } - - // Commit 90a7c3c86944 changed the flag positions such that the low - // order bits are the kind. This code extracts the kind from the flags - // field and ensures it's the correct type. When it's not, the flag - // order has been changed to the newer format, so the flags are updated - // accordingly. - upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag) - upfv := *(*uintptr)(upf) - flagKindMask := uintptr((1<>flagKindShift != uintptr(reflect.Int) { - flagKindShift = 0 - flagRO = 1 << 5 - flagIndir = 1 << 6 - - // Commit adf9b30e5594 modified the flags to separate the - // flagRO flag into two bits which specifies whether or not the - // field is embedded. This causes flagIndir to move over a bit - // and means that flagRO is the combination of either of the - // original flagRO bit and the new bit. - // - // This code detects the change by extracting what used to be - // the indirect bit to ensure it's set. When it's not, the flag - // order has been changed to the newer format, so the flags are - // updated accordingly. - if upfv&flagIndir == 0 { - flagRO = 3 << 5 - flagIndir = 1 << 7 - } - } -} - -// unsafeReflectValue converts the passed reflect.Value into a one that bypasses -// the typical safety restrictions preventing access to unaddressable and -// unexported data. It works by digging the raw pointer to the underlying -// value out of the protected value and generating a new unprotected (unsafe) -// reflect.Value to it. -// -// This allows us to check for implementations of the Stringer and error -// interfaces to be used for pretty printing ordinarily unaddressable and -// inaccessible values such as unexported struct fields. -func unsafeReflectValue(v reflect.Value) (rv reflect.Value) { - indirects := 1 - vt := v.Type() - upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr) - rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag)) - if rvf&flagIndir != 0 { - vt = reflect.PtrTo(v.Type()) - indirects++ - } else if offsetScalar != 0 { - // The value is in the scalar field when it's not one of the - // reference types. - switch vt.Kind() { - case reflect.Uintptr: - case reflect.Chan: - case reflect.Func: - case reflect.Map: - case reflect.Ptr: - case reflect.UnsafePointer: - default: - upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + - offsetScalar) - } - } - - pv := reflect.NewAt(vt, upv) - rv = pv - for i := 0; i < indirects; i++ { - rv = rv.Elem() - } - return rv -} diff --git a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go deleted file mode 100644 index 1fe3cf3d5..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2015-2016 Dave Collins -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -// NOTE: Due to the following build constraints, this file will only be compiled -// when the code is running on Google App Engine, compiled by GopherJS, or -// "-tags safe" is added to the go build command line. The "disableunsafe" -// tag is deprecated and thus should not be used. -// +build js appengine safe disableunsafe - -package spew - -import "reflect" - -const ( - // UnsafeDisabled is a build-time constant which specifies whether or - // not access to the unsafe package is available. - UnsafeDisabled = true -) - -// unsafeReflectValue typically converts the passed reflect.Value into a one -// that bypasses the typical safety restrictions preventing access to -// unaddressable and unexported data. However, doing this relies on access to -// the unsafe package. This is a stub version which simply returns the passed -// reflect.Value when the unsafe package is not available. -func unsafeReflectValue(v reflect.Value) reflect.Value { - return v -} diff --git a/vendor/github.com/davecgh/go-spew/spew/common.go b/vendor/github.com/davecgh/go-spew/spew/common.go deleted file mode 100644 index 7c519ff47..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/common.go +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "io" - "reflect" - "sort" - "strconv" -) - -// Some constants in the form of bytes to avoid string overhead. This mirrors -// the technique used in the fmt package. -var ( - panicBytes = []byte("(PANIC=") - plusBytes = []byte("+") - iBytes = []byte("i") - trueBytes = []byte("true") - falseBytes = []byte("false") - interfaceBytes = []byte("(interface {})") - commaNewlineBytes = []byte(",\n") - newlineBytes = []byte("\n") - openBraceBytes = []byte("{") - openBraceNewlineBytes = []byte("{\n") - closeBraceBytes = []byte("}") - asteriskBytes = []byte("*") - colonBytes = []byte(":") - colonSpaceBytes = []byte(": ") - openParenBytes = []byte("(") - closeParenBytes = []byte(")") - spaceBytes = []byte(" ") - pointerChainBytes = []byte("->") - nilAngleBytes = []byte("") - maxNewlineBytes = []byte("\n") - maxShortBytes = []byte("") - circularBytes = []byte("") - circularShortBytes = []byte("") - invalidAngleBytes = []byte("") - openBracketBytes = []byte("[") - closeBracketBytes = []byte("]") - percentBytes = []byte("%") - precisionBytes = []byte(".") - openAngleBytes = []byte("<") - closeAngleBytes = []byte(">") - openMapBytes = []byte("map[") - closeMapBytes = []byte("]") - lenEqualsBytes = []byte("len=") - capEqualsBytes = []byte("cap=") -) - -// hexDigits is used to map a decimal value to a hex digit. -var hexDigits = "0123456789abcdef" - -// catchPanic handles any panics that might occur during the handleMethods -// calls. -func catchPanic(w io.Writer, v reflect.Value) { - if err := recover(); err != nil { - w.Write(panicBytes) - fmt.Fprintf(w, "%v", err) - w.Write(closeParenBytes) - } -} - -// handleMethods attempts to call the Error and String methods on the underlying -// type the passed reflect.Value represents and outputes the result to Writer w. -// -// It handles panics in any called methods by catching and displaying the error -// as the formatted value. -func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) { - // We need an interface to check if the type implements the error or - // Stringer interface. However, the reflect package won't give us an - // interface on certain things like unexported struct fields in order - // to enforce visibility rules. We use unsafe, when it's available, - // to bypass these restrictions since this package does not mutate the - // values. - if !v.CanInterface() { - if UnsafeDisabled { - return false - } - - v = unsafeReflectValue(v) - } - - // Choose whether or not to do error and Stringer interface lookups against - // the base type or a pointer to the base type depending on settings. - // Technically calling one of these methods with a pointer receiver can - // mutate the value, however, types which choose to satisify an error or - // Stringer interface with a pointer receiver should not be mutating their - // state inside these interface methods. - if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() { - v = unsafeReflectValue(v) - } - if v.CanAddr() { - v = v.Addr() - } - - // Is it an error or Stringer? - switch iface := v.Interface().(type) { - case error: - defer catchPanic(w, v) - if cs.ContinueOnMethod { - w.Write(openParenBytes) - w.Write([]byte(iface.Error())) - w.Write(closeParenBytes) - w.Write(spaceBytes) - return false - } - - w.Write([]byte(iface.Error())) - return true - - case fmt.Stringer: - defer catchPanic(w, v) - if cs.ContinueOnMethod { - w.Write(openParenBytes) - w.Write([]byte(iface.String())) - w.Write(closeParenBytes) - w.Write(spaceBytes) - return false - } - w.Write([]byte(iface.String())) - return true - } - return false -} - -// printBool outputs a boolean value as true or false to Writer w. -func printBool(w io.Writer, val bool) { - if val { - w.Write(trueBytes) - } else { - w.Write(falseBytes) - } -} - -// printInt outputs a signed integer value to Writer w. -func printInt(w io.Writer, val int64, base int) { - w.Write([]byte(strconv.FormatInt(val, base))) -} - -// printUint outputs an unsigned integer value to Writer w. -func printUint(w io.Writer, val uint64, base int) { - w.Write([]byte(strconv.FormatUint(val, base))) -} - -// printFloat outputs a floating point value using the specified precision, -// which is expected to be 32 or 64bit, to Writer w. -func printFloat(w io.Writer, val float64, precision int) { - w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision))) -} - -// printComplex outputs a complex value using the specified float precision -// for the real and imaginary parts to Writer w. -func printComplex(w io.Writer, c complex128, floatPrecision int) { - r := real(c) - w.Write(openParenBytes) - w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision))) - i := imag(c) - if i >= 0 { - w.Write(plusBytes) - } - w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision))) - w.Write(iBytes) - w.Write(closeParenBytes) -} - -// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x' -// prefix to Writer w. -func printHexPtr(w io.Writer, p uintptr) { - // Null pointer. - num := uint64(p) - if num == 0 { - w.Write(nilAngleBytes) - return - } - - // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix - buf := make([]byte, 18) - - // It's simpler to construct the hex string right to left. - base := uint64(16) - i := len(buf) - 1 - for num >= base { - buf[i] = hexDigits[num%base] - num /= base - i-- - } - buf[i] = hexDigits[num] - - // Add '0x' prefix. - i-- - buf[i] = 'x' - i-- - buf[i] = '0' - - // Strip unused leading bytes. - buf = buf[i:] - w.Write(buf) -} - -// valuesSorter implements sort.Interface to allow a slice of reflect.Value -// elements to be sorted. -type valuesSorter struct { - values []reflect.Value - strings []string // either nil or same len and values - cs *ConfigState -} - -// newValuesSorter initializes a valuesSorter instance, which holds a set of -// surrogate keys on which the data should be sorted. It uses flags in -// ConfigState to decide if and how to populate those surrogate keys. -func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface { - vs := &valuesSorter{values: values, cs: cs} - if canSortSimply(vs.values[0].Kind()) { - return vs - } - if !cs.DisableMethods { - vs.strings = make([]string, len(values)) - for i := range vs.values { - b := bytes.Buffer{} - if !handleMethods(cs, &b, vs.values[i]) { - vs.strings = nil - break - } - vs.strings[i] = b.String() - } - } - if vs.strings == nil && cs.SpewKeys { - vs.strings = make([]string, len(values)) - for i := range vs.values { - vs.strings[i] = Sprintf("%#v", vs.values[i].Interface()) - } - } - return vs -} - -// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted -// directly, or whether it should be considered for sorting by surrogate keys -// (if the ConfigState allows it). -func canSortSimply(kind reflect.Kind) bool { - // This switch parallels valueSortLess, except for the default case. - switch kind { - case reflect.Bool: - return true - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - return true - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - return true - case reflect.Float32, reflect.Float64: - return true - case reflect.String: - return true - case reflect.Uintptr: - return true - case reflect.Array: - return true - } - return false -} - -// Len returns the number of values in the slice. It is part of the -// sort.Interface implementation. -func (s *valuesSorter) Len() int { - return len(s.values) -} - -// Swap swaps the values at the passed indices. It is part of the -// sort.Interface implementation. -func (s *valuesSorter) Swap(i, j int) { - s.values[i], s.values[j] = s.values[j], s.values[i] - if s.strings != nil { - s.strings[i], s.strings[j] = s.strings[j], s.strings[i] - } -} - -// valueSortLess returns whether the first value should sort before the second -// value. It is used by valueSorter.Less as part of the sort.Interface -// implementation. -func valueSortLess(a, b reflect.Value) bool { - switch a.Kind() { - case reflect.Bool: - return !a.Bool() && b.Bool() - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - return a.Int() < b.Int() - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - return a.Uint() < b.Uint() - case reflect.Float32, reflect.Float64: - return a.Float() < b.Float() - case reflect.String: - return a.String() < b.String() - case reflect.Uintptr: - return a.Uint() < b.Uint() - case reflect.Array: - // Compare the contents of both arrays. - l := a.Len() - for i := 0; i < l; i++ { - av := a.Index(i) - bv := b.Index(i) - if av.Interface() == bv.Interface() { - continue - } - return valueSortLess(av, bv) - } - } - return a.String() < b.String() -} - -// Less returns whether the value at index i should sort before the -// value at index j. It is part of the sort.Interface implementation. -func (s *valuesSorter) Less(i, j int) bool { - if s.strings == nil { - return valueSortLess(s.values[i], s.values[j]) - } - return s.strings[i] < s.strings[j] -} - -// sortValues is a sort function that handles both native types and any type that -// can be converted to error or Stringer. Other inputs are sorted according to -// their Value.String() value to ensure display stability. -func sortValues(values []reflect.Value, cs *ConfigState) { - if len(values) == 0 { - return - } - sort.Sort(newValuesSorter(values, cs)) -} diff --git a/vendor/github.com/davecgh/go-spew/spew/config.go b/vendor/github.com/davecgh/go-spew/spew/config.go deleted file mode 100644 index 2e3d22f31..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/config.go +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "io" - "os" -) - -// ConfigState houses the configuration options used by spew to format and -// display values. There is a global instance, Config, that is used to control -// all top-level Formatter and Dump functionality. Each ConfigState instance -// provides methods equivalent to the top-level functions. -// -// The zero value for ConfigState provides no indentation. You would typically -// want to set it to a space or a tab. -// -// Alternatively, you can use NewDefaultConfig to get a ConfigState instance -// with default settings. See the documentation of NewDefaultConfig for default -// values. -type ConfigState struct { - // Indent specifies the string to use for each indentation level. The - // global config instance that all top-level functions use set this to a - // single space by default. If you would like more indentation, you might - // set this to a tab with "\t" or perhaps two spaces with " ". - Indent string - - // MaxDepth controls the maximum number of levels to descend into nested - // data structures. The default, 0, means there is no limit. - // - // NOTE: Circular data structures are properly detected, so it is not - // necessary to set this value unless you specifically want to limit deeply - // nested data structures. - MaxDepth int - - // DisableMethods specifies whether or not error and Stringer interfaces are - // invoked for types that implement them. - DisableMethods bool - - // DisablePointerMethods specifies whether or not to check for and invoke - // error and Stringer interfaces on types which only accept a pointer - // receiver when the current type is not a pointer. - // - // NOTE: This might be an unsafe action since calling one of these methods - // with a pointer receiver could technically mutate the value, however, - // in practice, types which choose to satisify an error or Stringer - // interface with a pointer receiver should not be mutating their state - // inside these interface methods. As a result, this option relies on - // access to the unsafe package, so it will not have any effect when - // running in environments without access to the unsafe package such as - // Google App Engine or with the "safe" build tag specified. - DisablePointerMethods bool - - // DisablePointerAddresses specifies whether to disable the printing of - // pointer addresses. This is useful when diffing data structures in tests. - DisablePointerAddresses bool - - // DisableCapacities specifies whether to disable the printing of capacities - // for arrays, slices, maps and channels. This is useful when diffing - // data structures in tests. - DisableCapacities bool - - // ContinueOnMethod specifies whether or not recursion should continue once - // a custom error or Stringer interface is invoked. The default, false, - // means it will print the results of invoking the custom error or Stringer - // interface and return immediately instead of continuing to recurse into - // the internals of the data type. - // - // NOTE: This flag does not have any effect if method invocation is disabled - // via the DisableMethods or DisablePointerMethods options. - ContinueOnMethod bool - - // SortKeys specifies map keys should be sorted before being printed. Use - // this to have a more deterministic, diffable output. Note that only - // native types (bool, int, uint, floats, uintptr and string) and types - // that support the error or Stringer interfaces (if methods are - // enabled) are supported, with other types sorted according to the - // reflect.Value.String() output which guarantees display stability. - SortKeys bool - - // SpewKeys specifies that, as a last resort attempt, map keys should - // be spewed to strings and sorted by those strings. This is only - // considered if SortKeys is true. - SpewKeys bool -} - -// Config is the active configuration of the top-level functions. -// The configuration can be changed by modifying the contents of spew.Config. -var Config = ConfigState{Indent: " "} - -// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the formatted string as a value that satisfies error. See NewFormatter -// for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) { - return fmt.Errorf(format, c.convertArgs(a)...) -} - -// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprint(w, c.convertArgs(a)...) -} - -// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - return fmt.Fprintf(w, format, c.convertArgs(a)...) -} - -// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it -// passed with a Formatter interface returned by c.NewFormatter. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprintln(w, c.convertArgs(a)...) -} - -// Print is a wrapper for fmt.Print that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Print(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Print(a ...interface{}) (n int, err error) { - return fmt.Print(c.convertArgs(a)...) -} - -// Printf is a wrapper for fmt.Printf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) { - return fmt.Printf(format, c.convertArgs(a)...) -} - -// Println is a wrapper for fmt.Println that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Println(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Println(a ...interface{}) (n int, err error) { - return fmt.Println(c.convertArgs(a)...) -} - -// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprint(a ...interface{}) string { - return fmt.Sprint(c.convertArgs(a)...) -} - -// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprintf(format string, a ...interface{}) string { - return fmt.Sprintf(format, c.convertArgs(a)...) -} - -// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it -// were passed with a Formatter interface returned by c.NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprintln(a ...interface{}) string { - return fmt.Sprintln(c.convertArgs(a)...) -} - -/* -NewFormatter returns a custom formatter that satisfies the fmt.Formatter -interface. As a result, it integrates cleanly with standard fmt package -printing functions. The formatter is useful for inline printing of smaller data -types similar to the standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Typically this function shouldn't be called directly. It is much easier to make -use of the custom formatter by calling one of the convenience functions such as -c.Printf, c.Println, or c.Printf. -*/ -func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter { - return newFormatter(c, v) -} - -// Fdump formats and displays the passed arguments to io.Writer w. It formats -// exactly the same as Dump. -func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) { - fdump(c, w, a...) -} - -/* -Dump displays the passed parameters to standard out with newlines, customizable -indentation, and additional debug information such as complete types and all -pointer addresses used to indirect to the final value. It provides the -following features over the built-in printing facilities provided by the fmt -package: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output - -The configuration options are controlled by modifying the public members -of c. See ConfigState for options documentation. - -See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to -get the formatted result as a string. -*/ -func (c *ConfigState) Dump(a ...interface{}) { - fdump(c, os.Stdout, a...) -} - -// Sdump returns a string with the passed arguments formatted exactly the same -// as Dump. -func (c *ConfigState) Sdump(a ...interface{}) string { - var buf bytes.Buffer - fdump(c, &buf, a...) - return buf.String() -} - -// convertArgs accepts a slice of arguments and returns a slice of the same -// length with each argument converted to a spew Formatter interface using -// the ConfigState associated with s. -func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) { - formatters = make([]interface{}, len(args)) - for index, arg := range args { - formatters[index] = newFormatter(c, arg) - } - return formatters -} - -// NewDefaultConfig returns a ConfigState with the following default settings. -// -// Indent: " " -// MaxDepth: 0 -// DisableMethods: false -// DisablePointerMethods: false -// ContinueOnMethod: false -// SortKeys: false -func NewDefaultConfig() *ConfigState { - return &ConfigState{Indent: " "} -} diff --git a/vendor/github.com/davecgh/go-spew/spew/doc.go b/vendor/github.com/davecgh/go-spew/spew/doc.go deleted file mode 100644 index aacaac6f1..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/doc.go +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* -Package spew implements a deep pretty printer for Go data structures to aid in -debugging. - -A quick overview of the additional features spew provides over the built-in -printing facilities for Go data types are as follows: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output (only when using - Dump style) - -There are two different approaches spew allows for dumping Go data structures: - - * Dump style which prints with newlines, customizable indentation, - and additional debug information such as types and all pointer addresses - used to indirect to the final value - * A custom Formatter interface that integrates cleanly with the standard fmt - package and replaces %v, %+v, %#v, and %#+v to provide inline printing - similar to the default %v while providing the additional functionality - outlined above and passing unsupported format verbs such as %x and %q - along to fmt - -Quick Start - -This section demonstrates how to quickly get started with spew. See the -sections below for further details on formatting and configuration options. - -To dump a variable with full newlines, indentation, type, and pointer -information use Dump, Fdump, or Sdump: - spew.Dump(myVar1, myVar2, ...) - spew.Fdump(someWriter, myVar1, myVar2, ...) - str := spew.Sdump(myVar1, myVar2, ...) - -Alternatively, if you would prefer to use format strings with a compacted inline -printing style, use the convenience wrappers Printf, Fprintf, etc with -%v (most compact), %+v (adds pointer addresses), %#v (adds types), or -%#+v (adds types and pointer addresses): - spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - -Configuration Options - -Configuration of spew is handled by fields in the ConfigState type. For -convenience, all of the top-level functions use a global state available -via the spew.Config global. - -It is also possible to create a ConfigState instance that provides methods -equivalent to the top-level functions. This allows concurrent configuration -options. See the ConfigState documentation for more details. - -The following configuration options are available: - * Indent - String to use for each indentation level for Dump functions. - It is a single space by default. A popular alternative is "\t". - - * MaxDepth - Maximum number of levels to descend into nested data structures. - There is no limit by default. - - * DisableMethods - Disables invocation of error and Stringer interface methods. - Method invocation is enabled by default. - - * DisablePointerMethods - Disables invocation of error and Stringer interface methods on types - which only accept pointer receivers from non-pointer variables. - Pointer method invocation is enabled by default. - - * DisablePointerAddresses - DisablePointerAddresses specifies whether to disable the printing of - pointer addresses. This is useful when diffing data structures in tests. - - * DisableCapacities - DisableCapacities specifies whether to disable the printing of - capacities for arrays, slices, maps and channels. This is useful when - diffing data structures in tests. - - * ContinueOnMethod - Enables recursion into types after invoking error and Stringer interface - methods. Recursion after method invocation is disabled by default. - - * SortKeys - Specifies map keys should be sorted before being printed. Use - this to have a more deterministic, diffable output. Note that - only native types (bool, int, uint, floats, uintptr and string) - and types which implement error or Stringer interfaces are - supported with other types sorted according to the - reflect.Value.String() output which guarantees display - stability. Natural map order is used by default. - - * SpewKeys - Specifies that, as a last resort attempt, map keys should be - spewed to strings and sorted by those strings. This is only - considered if SortKeys is true. - -Dump Usage - -Simply call spew.Dump with a list of variables you want to dump: - - spew.Dump(myVar1, myVar2, ...) - -You may also call spew.Fdump if you would prefer to output to an arbitrary -io.Writer. For example, to dump to standard error: - - spew.Fdump(os.Stderr, myVar1, myVar2, ...) - -A third option is to call spew.Sdump to get the formatted output as a string: - - str := spew.Sdump(myVar1, myVar2, ...) - -Sample Dump Output - -See the Dump example for details on the setup of the types and variables being -shown here. - - (main.Foo) { - unexportedField: (*main.Bar)(0xf84002e210)({ - flag: (main.Flag) flagTwo, - data: (uintptr) - }), - ExportedField: (map[interface {}]interface {}) (len=1) { - (string) (len=3) "one": (bool) true - } - } - -Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C -command as shown. - ([]uint8) (len=32 cap=32) { - 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | - 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| - 00000020 31 32 |12| - } - -Custom Formatter - -Spew provides a custom formatter that implements the fmt.Formatter interface -so that it integrates cleanly with standard fmt package printing functions. The -formatter is useful for inline printing of smaller data types similar to the -standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Custom Formatter Usage - -The simplest way to make use of the spew custom formatter is to call one of the -convenience functions such as spew.Printf, spew.Println, or spew.Printf. The -functions have syntax you are most likely already familiar with: - - spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - spew.Println(myVar, myVar2) - spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - -See the Index for the full list convenience functions. - -Sample Formatter Output - -Double pointer to a uint8: - %v: <**>5 - %+v: <**>(0xf8400420d0->0xf8400420c8)5 - %#v: (**uint8)5 - %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 - -Pointer to circular struct with a uint8 field and a pointer to itself: - %v: <*>{1 <*>} - %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} - %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} - %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} - -See the Printf example for details on the setup of variables being shown -here. - -Errors - -Since it is possible for custom Stringer/error interfaces to panic, spew -detects them and handles them internally by printing the panic information -inline with the output. Since spew is intended to provide deep pretty printing -capabilities on structures, it intentionally does not return any errors. -*/ -package spew diff --git a/vendor/github.com/davecgh/go-spew/spew/dump.go b/vendor/github.com/davecgh/go-spew/spew/dump.go deleted file mode 100644 index df1d582a7..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/dump.go +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "encoding/hex" - "fmt" - "io" - "os" - "reflect" - "regexp" - "strconv" - "strings" -) - -var ( - // uint8Type is a reflect.Type representing a uint8. It is used to - // convert cgo types to uint8 slices for hexdumping. - uint8Type = reflect.TypeOf(uint8(0)) - - // cCharRE is a regular expression that matches a cgo char. - // It is used to detect character arrays to hexdump them. - cCharRE = regexp.MustCompile("^.*\\._Ctype_char$") - - // cUnsignedCharRE is a regular expression that matches a cgo unsigned - // char. It is used to detect unsigned character arrays to hexdump - // them. - cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$") - - // cUint8tCharRE is a regular expression that matches a cgo uint8_t. - // It is used to detect uint8_t arrays to hexdump them. - cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$") -) - -// dumpState contains information about the state of a dump operation. -type dumpState struct { - w io.Writer - depth int - pointers map[uintptr]int - ignoreNextType bool - ignoreNextIndent bool - cs *ConfigState -} - -// indent performs indentation according to the depth level and cs.Indent -// option. -func (d *dumpState) indent() { - if d.ignoreNextIndent { - d.ignoreNextIndent = false - return - } - d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth)) -} - -// unpackValue returns values inside of non-nil interfaces when possible. -// This is useful for data types like structs, arrays, slices, and maps which -// can contain varying types packed inside an interface. -func (d *dumpState) unpackValue(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Interface && !v.IsNil() { - v = v.Elem() - } - return v -} - -// dumpPtr handles formatting of pointers by indirecting them as necessary. -func (d *dumpState) dumpPtr(v reflect.Value) { - // Remove pointers at or below the current depth from map used to detect - // circular refs. - for k, depth := range d.pointers { - if depth >= d.depth { - delete(d.pointers, k) - } - } - - // Keep list of all dereferenced pointers to show later. - pointerChain := make([]uintptr, 0) - - // Figure out how many levels of indirection there are by dereferencing - // pointers and unpacking interfaces down the chain while detecting circular - // references. - nilFound := false - cycleFound := false - indirects := 0 - ve := v - for ve.Kind() == reflect.Ptr { - if ve.IsNil() { - nilFound = true - break - } - indirects++ - addr := ve.Pointer() - pointerChain = append(pointerChain, addr) - if pd, ok := d.pointers[addr]; ok && pd < d.depth { - cycleFound = true - indirects-- - break - } - d.pointers[addr] = d.depth - - ve = ve.Elem() - if ve.Kind() == reflect.Interface { - if ve.IsNil() { - nilFound = true - break - } - ve = ve.Elem() - } - } - - // Display type information. - d.w.Write(openParenBytes) - d.w.Write(bytes.Repeat(asteriskBytes, indirects)) - d.w.Write([]byte(ve.Type().String())) - d.w.Write(closeParenBytes) - - // Display pointer information. - if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 { - d.w.Write(openParenBytes) - for i, addr := range pointerChain { - if i > 0 { - d.w.Write(pointerChainBytes) - } - printHexPtr(d.w, addr) - } - d.w.Write(closeParenBytes) - } - - // Display dereferenced value. - d.w.Write(openParenBytes) - switch { - case nilFound == true: - d.w.Write(nilAngleBytes) - - case cycleFound == true: - d.w.Write(circularBytes) - - default: - d.ignoreNextType = true - d.dump(ve) - } - d.w.Write(closeParenBytes) -} - -// dumpSlice handles formatting of arrays and slices. Byte (uint8 under -// reflection) arrays and slices are dumped in hexdump -C fashion. -func (d *dumpState) dumpSlice(v reflect.Value) { - // Determine whether this type should be hex dumped or not. Also, - // for types which should be hexdumped, try to use the underlying data - // first, then fall back to trying to convert them to a uint8 slice. - var buf []uint8 - doConvert := false - doHexDump := false - numEntries := v.Len() - if numEntries > 0 { - vt := v.Index(0).Type() - vts := vt.String() - switch { - // C types that need to be converted. - case cCharRE.MatchString(vts): - fallthrough - case cUnsignedCharRE.MatchString(vts): - fallthrough - case cUint8tCharRE.MatchString(vts): - doConvert = true - - // Try to use existing uint8 slices and fall back to converting - // and copying if that fails. - case vt.Kind() == reflect.Uint8: - // We need an addressable interface to convert the type - // to a byte slice. However, the reflect package won't - // give us an interface on certain things like - // unexported struct fields in order to enforce - // visibility rules. We use unsafe, when available, to - // bypass these restrictions since this package does not - // mutate the values. - vs := v - if !vs.CanInterface() || !vs.CanAddr() { - vs = unsafeReflectValue(vs) - } - if !UnsafeDisabled { - vs = vs.Slice(0, numEntries) - - // Use the existing uint8 slice if it can be - // type asserted. - iface := vs.Interface() - if slice, ok := iface.([]uint8); ok { - buf = slice - doHexDump = true - break - } - } - - // The underlying data needs to be converted if it can't - // be type asserted to a uint8 slice. - doConvert = true - } - - // Copy and convert the underlying type if needed. - if doConvert && vt.ConvertibleTo(uint8Type) { - // Convert and copy each element into a uint8 byte - // slice. - buf = make([]uint8, numEntries) - for i := 0; i < numEntries; i++ { - vv := v.Index(i) - buf[i] = uint8(vv.Convert(uint8Type).Uint()) - } - doHexDump = true - } - } - - // Hexdump the entire slice as needed. - if doHexDump { - indent := strings.Repeat(d.cs.Indent, d.depth) - str := indent + hex.Dump(buf) - str = strings.Replace(str, "\n", "\n"+indent, -1) - str = strings.TrimRight(str, d.cs.Indent) - d.w.Write([]byte(str)) - return - } - - // Recursively call dump for each item. - for i := 0; i < numEntries; i++ { - d.dump(d.unpackValue(v.Index(i))) - if i < (numEntries - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } -} - -// dump is the main workhorse for dumping a value. It uses the passed reflect -// value to figure out what kind of object we are dealing with and formats it -// appropriately. It is a recursive function, however circular data structures -// are detected and handled properly. -func (d *dumpState) dump(v reflect.Value) { - // Handle invalid reflect values immediately. - kind := v.Kind() - if kind == reflect.Invalid { - d.w.Write(invalidAngleBytes) - return - } - - // Handle pointers specially. - if kind == reflect.Ptr { - d.indent() - d.dumpPtr(v) - return - } - - // Print type information unless already handled elsewhere. - if !d.ignoreNextType { - d.indent() - d.w.Write(openParenBytes) - d.w.Write([]byte(v.Type().String())) - d.w.Write(closeParenBytes) - d.w.Write(spaceBytes) - } - d.ignoreNextType = false - - // Display length and capacity if the built-in len and cap functions - // work with the value's kind and the len/cap itself is non-zero. - valueLen, valueCap := 0, 0 - switch v.Kind() { - case reflect.Array, reflect.Slice, reflect.Chan: - valueLen, valueCap = v.Len(), v.Cap() - case reflect.Map, reflect.String: - valueLen = v.Len() - } - if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { - d.w.Write(openParenBytes) - if valueLen != 0 { - d.w.Write(lenEqualsBytes) - printInt(d.w, int64(valueLen), 10) - } - if !d.cs.DisableCapacities && valueCap != 0 { - if valueLen != 0 { - d.w.Write(spaceBytes) - } - d.w.Write(capEqualsBytes) - printInt(d.w, int64(valueCap), 10) - } - d.w.Write(closeParenBytes) - d.w.Write(spaceBytes) - } - - // Call Stringer/error interfaces if they exist and the handle methods flag - // is enabled - if !d.cs.DisableMethods { - if (kind != reflect.Invalid) && (kind != reflect.Interface) { - if handled := handleMethods(d.cs, d.w, v); handled { - return - } - } - } - - switch kind { - case reflect.Invalid: - // Do nothing. We should never get here since invalid has already - // been handled above. - - case reflect.Bool: - printBool(d.w, v.Bool()) - - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - printInt(d.w, v.Int(), 10) - - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - printUint(d.w, v.Uint(), 10) - - case reflect.Float32: - printFloat(d.w, v.Float(), 32) - - case reflect.Float64: - printFloat(d.w, v.Float(), 64) - - case reflect.Complex64: - printComplex(d.w, v.Complex(), 32) - - case reflect.Complex128: - printComplex(d.w, v.Complex(), 64) - - case reflect.Slice: - if v.IsNil() { - d.w.Write(nilAngleBytes) - break - } - fallthrough - - case reflect.Array: - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - d.dumpSlice(v) - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.String: - d.w.Write([]byte(strconv.Quote(v.String()))) - - case reflect.Interface: - // The only time we should get here is for nil interfaces due to - // unpackValue calls. - if v.IsNil() { - d.w.Write(nilAngleBytes) - } - - case reflect.Ptr: - // Do nothing. We should never get here since pointers have already - // been handled above. - - case reflect.Map: - // nil maps should be indicated as different than empty maps - if v.IsNil() { - d.w.Write(nilAngleBytes) - break - } - - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - numEntries := v.Len() - keys := v.MapKeys() - if d.cs.SortKeys { - sortValues(keys, d.cs) - } - for i, key := range keys { - d.dump(d.unpackValue(key)) - d.w.Write(colonSpaceBytes) - d.ignoreNextIndent = true - d.dump(d.unpackValue(v.MapIndex(key))) - if i < (numEntries - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.Struct: - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - vt := v.Type() - numFields := v.NumField() - for i := 0; i < numFields; i++ { - d.indent() - vtf := vt.Field(i) - d.w.Write([]byte(vtf.Name)) - d.w.Write(colonSpaceBytes) - d.ignoreNextIndent = true - d.dump(d.unpackValue(v.Field(i))) - if i < (numFields - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.Uintptr: - printHexPtr(d.w, uintptr(v.Uint())) - - case reflect.UnsafePointer, reflect.Chan, reflect.Func: - printHexPtr(d.w, v.Pointer()) - - // There were not any other types at the time this code was written, but - // fall back to letting the default fmt package handle it in case any new - // types are added. - default: - if v.CanInterface() { - fmt.Fprintf(d.w, "%v", v.Interface()) - } else { - fmt.Fprintf(d.w, "%v", v.String()) - } - } -} - -// fdump is a helper function to consolidate the logic from the various public -// methods which take varying writers and config states. -func fdump(cs *ConfigState, w io.Writer, a ...interface{}) { - for _, arg := range a { - if arg == nil { - w.Write(interfaceBytes) - w.Write(spaceBytes) - w.Write(nilAngleBytes) - w.Write(newlineBytes) - continue - } - - d := dumpState{w: w, cs: cs} - d.pointers = make(map[uintptr]int) - d.dump(reflect.ValueOf(arg)) - d.w.Write(newlineBytes) - } -} - -// Fdump formats and displays the passed arguments to io.Writer w. It formats -// exactly the same as Dump. -func Fdump(w io.Writer, a ...interface{}) { - fdump(&Config, w, a...) -} - -// Sdump returns a string with the passed arguments formatted exactly the same -// as Dump. -func Sdump(a ...interface{}) string { - var buf bytes.Buffer - fdump(&Config, &buf, a...) - return buf.String() -} - -/* -Dump displays the passed parameters to standard out with newlines, customizable -indentation, and additional debug information such as complete types and all -pointer addresses used to indirect to the final value. It provides the -following features over the built-in printing facilities provided by the fmt -package: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output - -The configuration options are controlled by an exported package global, -spew.Config. See ConfigState for options documentation. - -See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to -get the formatted result as a string. -*/ -func Dump(a ...interface{}) { - fdump(&Config, os.Stdout, a...) -} diff --git a/vendor/github.com/davecgh/go-spew/spew/format.go b/vendor/github.com/davecgh/go-spew/spew/format.go deleted file mode 100644 index c49875bac..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/format.go +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "reflect" - "strconv" - "strings" -) - -// supportedFlags is a list of all the character flags supported by fmt package. -const supportedFlags = "0-+# " - -// formatState implements the fmt.Formatter interface and contains information -// about the state of a formatting operation. The NewFormatter function can -// be used to get a new Formatter which can be used directly as arguments -// in standard fmt package printing calls. -type formatState struct { - value interface{} - fs fmt.State - depth int - pointers map[uintptr]int - ignoreNextType bool - cs *ConfigState -} - -// buildDefaultFormat recreates the original format string without precision -// and width information to pass in to fmt.Sprintf in the case of an -// unrecognized type. Unless new types are added to the language, this -// function won't ever be called. -func (f *formatState) buildDefaultFormat() (format string) { - buf := bytes.NewBuffer(percentBytes) - - for _, flag := range supportedFlags { - if f.fs.Flag(int(flag)) { - buf.WriteRune(flag) - } - } - - buf.WriteRune('v') - - format = buf.String() - return format -} - -// constructOrigFormat recreates the original format string including precision -// and width information to pass along to the standard fmt package. This allows -// automatic deferral of all format strings this package doesn't support. -func (f *formatState) constructOrigFormat(verb rune) (format string) { - buf := bytes.NewBuffer(percentBytes) - - for _, flag := range supportedFlags { - if f.fs.Flag(int(flag)) { - buf.WriteRune(flag) - } - } - - if width, ok := f.fs.Width(); ok { - buf.WriteString(strconv.Itoa(width)) - } - - if precision, ok := f.fs.Precision(); ok { - buf.Write(precisionBytes) - buf.WriteString(strconv.Itoa(precision)) - } - - buf.WriteRune(verb) - - format = buf.String() - return format -} - -// unpackValue returns values inside of non-nil interfaces when possible and -// ensures that types for values which have been unpacked from an interface -// are displayed when the show types flag is also set. -// This is useful for data types like structs, arrays, slices, and maps which -// can contain varying types packed inside an interface. -func (f *formatState) unpackValue(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Interface { - f.ignoreNextType = false - if !v.IsNil() { - v = v.Elem() - } - } - return v -} - -// formatPtr handles formatting of pointers by indirecting them as necessary. -func (f *formatState) formatPtr(v reflect.Value) { - // Display nil if top level pointer is nil. - showTypes := f.fs.Flag('#') - if v.IsNil() && (!showTypes || f.ignoreNextType) { - f.fs.Write(nilAngleBytes) - return - } - - // Remove pointers at or below the current depth from map used to detect - // circular refs. - for k, depth := range f.pointers { - if depth >= f.depth { - delete(f.pointers, k) - } - } - - // Keep list of all dereferenced pointers to possibly show later. - pointerChain := make([]uintptr, 0) - - // Figure out how many levels of indirection there are by derferencing - // pointers and unpacking interfaces down the chain while detecting circular - // references. - nilFound := false - cycleFound := false - indirects := 0 - ve := v - for ve.Kind() == reflect.Ptr { - if ve.IsNil() { - nilFound = true - break - } - indirects++ - addr := ve.Pointer() - pointerChain = append(pointerChain, addr) - if pd, ok := f.pointers[addr]; ok && pd < f.depth { - cycleFound = true - indirects-- - break - } - f.pointers[addr] = f.depth - - ve = ve.Elem() - if ve.Kind() == reflect.Interface { - if ve.IsNil() { - nilFound = true - break - } - ve = ve.Elem() - } - } - - // Display type or indirection level depending on flags. - if showTypes && !f.ignoreNextType { - f.fs.Write(openParenBytes) - f.fs.Write(bytes.Repeat(asteriskBytes, indirects)) - f.fs.Write([]byte(ve.Type().String())) - f.fs.Write(closeParenBytes) - } else { - if nilFound || cycleFound { - indirects += strings.Count(ve.Type().String(), "*") - } - f.fs.Write(openAngleBytes) - f.fs.Write([]byte(strings.Repeat("*", indirects))) - f.fs.Write(closeAngleBytes) - } - - // Display pointer information depending on flags. - if f.fs.Flag('+') && (len(pointerChain) > 0) { - f.fs.Write(openParenBytes) - for i, addr := range pointerChain { - if i > 0 { - f.fs.Write(pointerChainBytes) - } - printHexPtr(f.fs, addr) - } - f.fs.Write(closeParenBytes) - } - - // Display dereferenced value. - switch { - case nilFound == true: - f.fs.Write(nilAngleBytes) - - case cycleFound == true: - f.fs.Write(circularShortBytes) - - default: - f.ignoreNextType = true - f.format(ve) - } -} - -// format is the main workhorse for providing the Formatter interface. It -// uses the passed reflect value to figure out what kind of object we are -// dealing with and formats it appropriately. It is a recursive function, -// however circular data structures are detected and handled properly. -func (f *formatState) format(v reflect.Value) { - // Handle invalid reflect values immediately. - kind := v.Kind() - if kind == reflect.Invalid { - f.fs.Write(invalidAngleBytes) - return - } - - // Handle pointers specially. - if kind == reflect.Ptr { - f.formatPtr(v) - return - } - - // Print type information unless already handled elsewhere. - if !f.ignoreNextType && f.fs.Flag('#') { - f.fs.Write(openParenBytes) - f.fs.Write([]byte(v.Type().String())) - f.fs.Write(closeParenBytes) - } - f.ignoreNextType = false - - // Call Stringer/error interfaces if they exist and the handle methods - // flag is enabled. - if !f.cs.DisableMethods { - if (kind != reflect.Invalid) && (kind != reflect.Interface) { - if handled := handleMethods(f.cs, f.fs, v); handled { - return - } - } - } - - switch kind { - case reflect.Invalid: - // Do nothing. We should never get here since invalid has already - // been handled above. - - case reflect.Bool: - printBool(f.fs, v.Bool()) - - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - printInt(f.fs, v.Int(), 10) - - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - printUint(f.fs, v.Uint(), 10) - - case reflect.Float32: - printFloat(f.fs, v.Float(), 32) - - case reflect.Float64: - printFloat(f.fs, v.Float(), 64) - - case reflect.Complex64: - printComplex(f.fs, v.Complex(), 32) - - case reflect.Complex128: - printComplex(f.fs, v.Complex(), 64) - - case reflect.Slice: - if v.IsNil() { - f.fs.Write(nilAngleBytes) - break - } - fallthrough - - case reflect.Array: - f.fs.Write(openBracketBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - numEntries := v.Len() - for i := 0; i < numEntries; i++ { - if i > 0 { - f.fs.Write(spaceBytes) - } - f.ignoreNextType = true - f.format(f.unpackValue(v.Index(i))) - } - } - f.depth-- - f.fs.Write(closeBracketBytes) - - case reflect.String: - f.fs.Write([]byte(v.String())) - - case reflect.Interface: - // The only time we should get here is for nil interfaces due to - // unpackValue calls. - if v.IsNil() { - f.fs.Write(nilAngleBytes) - } - - case reflect.Ptr: - // Do nothing. We should never get here since pointers have already - // been handled above. - - case reflect.Map: - // nil maps should be indicated as different than empty maps - if v.IsNil() { - f.fs.Write(nilAngleBytes) - break - } - - f.fs.Write(openMapBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - keys := v.MapKeys() - if f.cs.SortKeys { - sortValues(keys, f.cs) - } - for i, key := range keys { - if i > 0 { - f.fs.Write(spaceBytes) - } - f.ignoreNextType = true - f.format(f.unpackValue(key)) - f.fs.Write(colonBytes) - f.ignoreNextType = true - f.format(f.unpackValue(v.MapIndex(key))) - } - } - f.depth-- - f.fs.Write(closeMapBytes) - - case reflect.Struct: - numFields := v.NumField() - f.fs.Write(openBraceBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - vt := v.Type() - for i := 0; i < numFields; i++ { - if i > 0 { - f.fs.Write(spaceBytes) - } - vtf := vt.Field(i) - if f.fs.Flag('+') || f.fs.Flag('#') { - f.fs.Write([]byte(vtf.Name)) - f.fs.Write(colonBytes) - } - f.format(f.unpackValue(v.Field(i))) - } - } - f.depth-- - f.fs.Write(closeBraceBytes) - - case reflect.Uintptr: - printHexPtr(f.fs, uintptr(v.Uint())) - - case reflect.UnsafePointer, reflect.Chan, reflect.Func: - printHexPtr(f.fs, v.Pointer()) - - // There were not any other types at the time this code was written, but - // fall back to letting the default fmt package handle it if any get added. - default: - format := f.buildDefaultFormat() - if v.CanInterface() { - fmt.Fprintf(f.fs, format, v.Interface()) - } else { - fmt.Fprintf(f.fs, format, v.String()) - } - } -} - -// Format satisfies the fmt.Formatter interface. See NewFormatter for usage -// details. -func (f *formatState) Format(fs fmt.State, verb rune) { - f.fs = fs - - // Use standard formatting for verbs that are not v. - if verb != 'v' { - format := f.constructOrigFormat(verb) - fmt.Fprintf(fs, format, f.value) - return - } - - if f.value == nil { - if fs.Flag('#') { - fs.Write(interfaceBytes) - } - fs.Write(nilAngleBytes) - return - } - - f.format(reflect.ValueOf(f.value)) -} - -// newFormatter is a helper function to consolidate the logic from the various -// public methods which take varying config states. -func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter { - fs := &formatState{value: v, cs: cs} - fs.pointers = make(map[uintptr]int) - return fs -} - -/* -NewFormatter returns a custom formatter that satisfies the fmt.Formatter -interface. As a result, it integrates cleanly with standard fmt package -printing functions. The formatter is useful for inline printing of smaller data -types similar to the standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Typically this function shouldn't be called directly. It is much easier to make -use of the custom formatter by calling one of the convenience functions such as -Printf, Println, or Fprintf. -*/ -func NewFormatter(v interface{}) fmt.Formatter { - return newFormatter(&Config, v) -} diff --git a/vendor/github.com/davecgh/go-spew/spew/spew.go b/vendor/github.com/davecgh/go-spew/spew/spew.go deleted file mode 100644 index 32c0e3388..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/spew.go +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "fmt" - "io" -) - -// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the formatted string as a value that satisfies error. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Errorf(format string, a ...interface{}) (err error) { - return fmt.Errorf(format, convertArgs(a)...) -} - -// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprint(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprint(w, convertArgs(a)...) -} - -// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - return fmt.Fprintf(w, format, convertArgs(a)...) -} - -// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it -// passed with a default Formatter interface returned by NewFormatter. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprintln(w, convertArgs(a)...) -} - -// Print is a wrapper for fmt.Print that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) -func Print(a ...interface{}) (n int, err error) { - return fmt.Print(convertArgs(a)...) -} - -// Printf is a wrapper for fmt.Printf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Printf(format string, a ...interface{}) (n int, err error) { - return fmt.Printf(format, convertArgs(a)...) -} - -// Println is a wrapper for fmt.Println that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) -func Println(a ...interface{}) (n int, err error) { - return fmt.Println(convertArgs(a)...) -} - -// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprint(a ...interface{}) string { - return fmt.Sprint(convertArgs(a)...) -} - -// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprintf(format string, a ...interface{}) string { - return fmt.Sprintf(format, convertArgs(a)...) -} - -// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it -// were passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprintln(a ...interface{}) string { - return fmt.Sprintln(convertArgs(a)...) -} - -// convertArgs accepts a slice of arguments and returns a slice of the same -// length with each argument converted to a default spew Formatter interface. -func convertArgs(args []interface{}) (formatters []interface{}) { - formatters = make([]interface{}, len(args)) - for index, arg := range args { - formatters[index] = NewFormatter(arg) - } - return formatters -} diff --git a/vendor/github.com/emicklei/go-restful/LICENSE b/vendor/github.com/emicklei/go-restful/LICENSE deleted file mode 100644 index ece7ec61e..000000000 --- a/vendor/github.com/emicklei/go-restful/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2012,2013 Ernest Micklei - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/emicklei/go-restful/compress.go b/vendor/github.com/emicklei/go-restful/compress.go deleted file mode 100644 index 220b37712..000000000 --- a/vendor/github.com/emicklei/go-restful/compress.go +++ /dev/null @@ -1,123 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "bufio" - "compress/gzip" - "compress/zlib" - "errors" - "io" - "net" - "net/http" - "strings" -) - -// OBSOLETE : use restful.DefaultContainer.EnableContentEncoding(true) to change this setting. -var EnableContentEncoding = false - -// CompressingResponseWriter is a http.ResponseWriter that can perform content encoding (gzip and zlib) -type CompressingResponseWriter struct { - writer http.ResponseWriter - compressor io.WriteCloser - encoding string -} - -// Header is part of http.ResponseWriter interface -func (c *CompressingResponseWriter) Header() http.Header { - return c.writer.Header() -} - -// WriteHeader is part of http.ResponseWriter interface -func (c *CompressingResponseWriter) WriteHeader(status int) { - c.writer.WriteHeader(status) -} - -// Write is part of http.ResponseWriter interface -// It is passed through the compressor -func (c *CompressingResponseWriter) Write(bytes []byte) (int, error) { - if c.isCompressorClosed() { - return -1, errors.New("Compressing error: tried to write data using closed compressor") - } - return c.compressor.Write(bytes) -} - -// CloseNotify is part of http.CloseNotifier interface -func (c *CompressingResponseWriter) CloseNotify() <-chan bool { - return c.writer.(http.CloseNotifier).CloseNotify() -} - -// Close the underlying compressor -func (c *CompressingResponseWriter) Close() error { - if c.isCompressorClosed() { - return errors.New("Compressing error: tried to close already closed compressor") - } - - c.compressor.Close() - if ENCODING_GZIP == c.encoding { - currentCompressorProvider.ReleaseGzipWriter(c.compressor.(*gzip.Writer)) - } - if ENCODING_DEFLATE == c.encoding { - currentCompressorProvider.ReleaseZlibWriter(c.compressor.(*zlib.Writer)) - } - // gc hint needed? - c.compressor = nil - return nil -} - -func (c *CompressingResponseWriter) isCompressorClosed() bool { - return nil == c.compressor -} - -// Hijack implements the Hijacker interface -// This is especially useful when combining Container.EnabledContentEncoding -// in combination with websockets (for instance gorilla/websocket) -func (c *CompressingResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { - hijacker, ok := c.writer.(http.Hijacker) - if !ok { - return nil, nil, errors.New("ResponseWriter doesn't support Hijacker interface") - } - return hijacker.Hijack() -} - -// WantsCompressedResponse reads the Accept-Encoding header to see if and which encoding is requested. -func wantsCompressedResponse(httpRequest *http.Request) (bool, string) { - header := httpRequest.Header.Get(HEADER_AcceptEncoding) - gi := strings.Index(header, ENCODING_GZIP) - zi := strings.Index(header, ENCODING_DEFLATE) - // use in order of appearance - if gi == -1 { - return zi != -1, ENCODING_DEFLATE - } else if zi == -1 { - return gi != -1, ENCODING_GZIP - } else { - if gi < zi { - return true, ENCODING_GZIP - } - return true, ENCODING_DEFLATE - } -} - -// NewCompressingResponseWriter create a CompressingResponseWriter for a known encoding = {gzip,deflate} -func NewCompressingResponseWriter(httpWriter http.ResponseWriter, encoding string) (*CompressingResponseWriter, error) { - httpWriter.Header().Set(HEADER_ContentEncoding, encoding) - c := new(CompressingResponseWriter) - c.writer = httpWriter - var err error - if ENCODING_GZIP == encoding { - w := currentCompressorProvider.AcquireGzipWriter() - w.Reset(httpWriter) - c.compressor = w - c.encoding = ENCODING_GZIP - } else if ENCODING_DEFLATE == encoding { - w := currentCompressorProvider.AcquireZlibWriter() - w.Reset(httpWriter) - c.compressor = w - c.encoding = ENCODING_DEFLATE - } else { - return nil, errors.New("Unknown encoding:" + encoding) - } - return c, err -} diff --git a/vendor/github.com/emicklei/go-restful/compressor_cache.go b/vendor/github.com/emicklei/go-restful/compressor_cache.go deleted file mode 100644 index ee426010a..000000000 --- a/vendor/github.com/emicklei/go-restful/compressor_cache.go +++ /dev/null @@ -1,103 +0,0 @@ -package restful - -// Copyright 2015 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "compress/gzip" - "compress/zlib" -) - -// BoundedCachedCompressors is a CompressorProvider that uses a cache with a fixed amount -// of writers and readers (resources). -// If a new resource is acquired and all are in use, it will return a new unmanaged resource. -type BoundedCachedCompressors struct { - gzipWriters chan *gzip.Writer - gzipReaders chan *gzip.Reader - zlibWriters chan *zlib.Writer - writersCapacity int - readersCapacity int -} - -// NewBoundedCachedCompressors returns a new, with filled cache, BoundedCachedCompressors. -func NewBoundedCachedCompressors(writersCapacity, readersCapacity int) *BoundedCachedCompressors { - b := &BoundedCachedCompressors{ - gzipWriters: make(chan *gzip.Writer, writersCapacity), - gzipReaders: make(chan *gzip.Reader, readersCapacity), - zlibWriters: make(chan *zlib.Writer, writersCapacity), - writersCapacity: writersCapacity, - readersCapacity: readersCapacity, - } - for ix := 0; ix < writersCapacity; ix++ { - b.gzipWriters <- newGzipWriter() - b.zlibWriters <- newZlibWriter() - } - for ix := 0; ix < readersCapacity; ix++ { - b.gzipReaders <- newGzipReader() - } - return b -} - -// AcquireGzipWriter returns an resettable *gzip.Writer. Needs to be released. -func (b *BoundedCachedCompressors) AcquireGzipWriter() *gzip.Writer { - var writer *gzip.Writer - select { - case writer, _ = <-b.gzipWriters: - default: - // return a new unmanaged one - writer = newGzipWriter() - } - return writer -} - -// ReleaseGzipWriter accepts a writer (does not have to be one that was cached) -// only when the cache has room for it. It will ignore it otherwise. -func (b *BoundedCachedCompressors) ReleaseGzipWriter(w *gzip.Writer) { - // forget the unmanaged ones - if len(b.gzipWriters) < b.writersCapacity { - b.gzipWriters <- w - } -} - -// AcquireGzipReader returns a *gzip.Reader. Needs to be released. -func (b *BoundedCachedCompressors) AcquireGzipReader() *gzip.Reader { - var reader *gzip.Reader - select { - case reader, _ = <-b.gzipReaders: - default: - // return a new unmanaged one - reader = newGzipReader() - } - return reader -} - -// ReleaseGzipReader accepts a reader (does not have to be one that was cached) -// only when the cache has room for it. It will ignore it otherwise. -func (b *BoundedCachedCompressors) ReleaseGzipReader(r *gzip.Reader) { - // forget the unmanaged ones - if len(b.gzipReaders) < b.readersCapacity { - b.gzipReaders <- r - } -} - -// AcquireZlibWriter returns an resettable *zlib.Writer. Needs to be released. -func (b *BoundedCachedCompressors) AcquireZlibWriter() *zlib.Writer { - var writer *zlib.Writer - select { - case writer, _ = <-b.zlibWriters: - default: - // return a new unmanaged one - writer = newZlibWriter() - } - return writer -} - -// ReleaseZlibWriter accepts a writer (does not have to be one that was cached) -// only when the cache has room for it. It will ignore it otherwise. -func (b *BoundedCachedCompressors) ReleaseZlibWriter(w *zlib.Writer) { - // forget the unmanaged ones - if len(b.zlibWriters) < b.writersCapacity { - b.zlibWriters <- w - } -} diff --git a/vendor/github.com/emicklei/go-restful/compressor_pools.go b/vendor/github.com/emicklei/go-restful/compressor_pools.go deleted file mode 100644 index d866ce64b..000000000 --- a/vendor/github.com/emicklei/go-restful/compressor_pools.go +++ /dev/null @@ -1,91 +0,0 @@ -package restful - -// Copyright 2015 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "bytes" - "compress/gzip" - "compress/zlib" - "sync" -) - -// SyncPoolCompessors is a CompressorProvider that use the standard sync.Pool. -type SyncPoolCompessors struct { - GzipWriterPool *sync.Pool - GzipReaderPool *sync.Pool - ZlibWriterPool *sync.Pool -} - -// NewSyncPoolCompessors returns a new ("empty") SyncPoolCompessors. -func NewSyncPoolCompessors() *SyncPoolCompessors { - return &SyncPoolCompessors{ - GzipWriterPool: &sync.Pool{ - New: func() interface{} { return newGzipWriter() }, - }, - GzipReaderPool: &sync.Pool{ - New: func() interface{} { return newGzipReader() }, - }, - ZlibWriterPool: &sync.Pool{ - New: func() interface{} { return newZlibWriter() }, - }, - } -} - -func (s *SyncPoolCompessors) AcquireGzipWriter() *gzip.Writer { - return s.GzipWriterPool.Get().(*gzip.Writer) -} - -func (s *SyncPoolCompessors) ReleaseGzipWriter(w *gzip.Writer) { - s.GzipWriterPool.Put(w) -} - -func (s *SyncPoolCompessors) AcquireGzipReader() *gzip.Reader { - return s.GzipReaderPool.Get().(*gzip.Reader) -} - -func (s *SyncPoolCompessors) ReleaseGzipReader(r *gzip.Reader) { - s.GzipReaderPool.Put(r) -} - -func (s *SyncPoolCompessors) AcquireZlibWriter() *zlib.Writer { - return s.ZlibWriterPool.Get().(*zlib.Writer) -} - -func (s *SyncPoolCompessors) ReleaseZlibWriter(w *zlib.Writer) { - s.ZlibWriterPool.Put(w) -} - -func newGzipWriter() *gzip.Writer { - // create with an empty bytes writer; it will be replaced before using the gzipWriter - writer, err := gzip.NewWriterLevel(new(bytes.Buffer), gzip.BestSpeed) - if err != nil { - panic(err.Error()) - } - return writer -} - -func newGzipReader() *gzip.Reader { - // create with an empty reader (but with GZIP header); it will be replaced before using the gzipReader - // we can safely use currentCompressProvider because it is set on package initialization. - w := currentCompressorProvider.AcquireGzipWriter() - defer currentCompressorProvider.ReleaseGzipWriter(w) - b := new(bytes.Buffer) - w.Reset(b) - w.Flush() - w.Close() - reader, err := gzip.NewReader(bytes.NewReader(b.Bytes())) - if err != nil { - panic(err.Error()) - } - return reader -} - -func newZlibWriter() *zlib.Writer { - writer, err := zlib.NewWriterLevel(new(bytes.Buffer), gzip.BestSpeed) - if err != nil { - panic(err.Error()) - } - return writer -} diff --git a/vendor/github.com/emicklei/go-restful/compressors.go b/vendor/github.com/emicklei/go-restful/compressors.go deleted file mode 100644 index 9db4a8c8e..000000000 --- a/vendor/github.com/emicklei/go-restful/compressors.go +++ /dev/null @@ -1,54 +0,0 @@ -package restful - -// Copyright 2015 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "compress/gzip" - "compress/zlib" -) - -// CompressorProvider describes a component that can provider compressors for the std methods. -type CompressorProvider interface { - // Returns a *gzip.Writer which needs to be released later. - // Before using it, call Reset(). - AcquireGzipWriter() *gzip.Writer - - // Releases an acquired *gzip.Writer. - ReleaseGzipWriter(w *gzip.Writer) - - // Returns a *gzip.Reader which needs to be released later. - AcquireGzipReader() *gzip.Reader - - // Releases an acquired *gzip.Reader. - ReleaseGzipReader(w *gzip.Reader) - - // Returns a *zlib.Writer which needs to be released later. - // Before using it, call Reset(). - AcquireZlibWriter() *zlib.Writer - - // Releases an acquired *zlib.Writer. - ReleaseZlibWriter(w *zlib.Writer) -} - -// DefaultCompressorProvider is the actual provider of compressors (zlib or gzip). -var currentCompressorProvider CompressorProvider - -func init() { - currentCompressorProvider = NewSyncPoolCompessors() -} - -// CurrentCompressorProvider returns the current CompressorProvider. -// It is initialized using a SyncPoolCompessors. -func CurrentCompressorProvider() CompressorProvider { - return currentCompressorProvider -} - -// SetCompressorProvider sets the actual provider of compressors (zlib or gzip). -func SetCompressorProvider(p CompressorProvider) { - if p == nil { - panic("cannot set compressor provider to nil") - } - currentCompressorProvider = p -} diff --git a/vendor/github.com/emicklei/go-restful/constants.go b/vendor/github.com/emicklei/go-restful/constants.go deleted file mode 100644 index 203439c5e..000000000 --- a/vendor/github.com/emicklei/go-restful/constants.go +++ /dev/null @@ -1,30 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -const ( - MIME_XML = "application/xml" // Accept or Content-Type used in Consumes() and/or Produces() - MIME_JSON = "application/json" // Accept or Content-Type used in Consumes() and/or Produces() - MIME_OCTET = "application/octet-stream" // If Content-Type is not present in request, use the default - - HEADER_Allow = "Allow" - HEADER_Accept = "Accept" - HEADER_Origin = "Origin" - HEADER_ContentType = "Content-Type" - HEADER_LastModified = "Last-Modified" - HEADER_AcceptEncoding = "Accept-Encoding" - HEADER_ContentEncoding = "Content-Encoding" - HEADER_AccessControlExposeHeaders = "Access-Control-Expose-Headers" - HEADER_AccessControlRequestMethod = "Access-Control-Request-Method" - HEADER_AccessControlRequestHeaders = "Access-Control-Request-Headers" - HEADER_AccessControlAllowMethods = "Access-Control-Allow-Methods" - HEADER_AccessControlAllowOrigin = "Access-Control-Allow-Origin" - HEADER_AccessControlAllowCredentials = "Access-Control-Allow-Credentials" - HEADER_AccessControlAllowHeaders = "Access-Control-Allow-Headers" - HEADER_AccessControlMaxAge = "Access-Control-Max-Age" - - ENCODING_GZIP = "gzip" - ENCODING_DEFLATE = "deflate" -) diff --git a/vendor/github.com/emicklei/go-restful/container.go b/vendor/github.com/emicklei/go-restful/container.go deleted file mode 100644 index b4ad153e8..000000000 --- a/vendor/github.com/emicklei/go-restful/container.go +++ /dev/null @@ -1,371 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "bytes" - "errors" - "fmt" - "net/http" - "os" - "runtime" - "strings" - "sync" - - "github.com/emicklei/go-restful/log" -) - -// Container holds a collection of WebServices and a http.ServeMux to dispatch http requests. -// The requests are further dispatched to routes of WebServices using a RouteSelector -type Container struct { - webServicesLock sync.RWMutex - webServices []*WebService - ServeMux *http.ServeMux - isRegisteredOnRoot bool - containerFilters []FilterFunction - doNotRecover bool // default is true - recoverHandleFunc RecoverHandleFunction - serviceErrorHandleFunc ServiceErrorHandleFunction - router RouteSelector // default is a CurlyRouter (RouterJSR311 is a slower alternative) - contentEncodingEnabled bool // default is false -} - -// NewContainer creates a new Container using a new ServeMux and default router (CurlyRouter) -func NewContainer() *Container { - return &Container{ - webServices: []*WebService{}, - ServeMux: http.NewServeMux(), - isRegisteredOnRoot: false, - containerFilters: []FilterFunction{}, - doNotRecover: true, - recoverHandleFunc: logStackOnRecover, - serviceErrorHandleFunc: writeServiceError, - router: CurlyRouter{}, - contentEncodingEnabled: false} -} - -// RecoverHandleFunction declares functions that can be used to handle a panic situation. -// The first argument is what recover() returns. The second must be used to communicate an error response. -type RecoverHandleFunction func(interface{}, http.ResponseWriter) - -// RecoverHandler changes the default function (logStackOnRecover) to be called -// when a panic is detected. DoNotRecover must be have its default value (=false). -func (c *Container) RecoverHandler(handler RecoverHandleFunction) { - c.recoverHandleFunc = handler -} - -// ServiceErrorHandleFunction declares functions that can be used to handle a service error situation. -// The first argument is the service error, the second is the request that resulted in the error and -// the third must be used to communicate an error response. -type ServiceErrorHandleFunction func(ServiceError, *Request, *Response) - -// ServiceErrorHandler changes the default function (writeServiceError) to be called -// when a ServiceError is detected. -func (c *Container) ServiceErrorHandler(handler ServiceErrorHandleFunction) { - c.serviceErrorHandleFunc = handler -} - -// DoNotRecover controls whether panics will be caught to return HTTP 500. -// If set to true, Route functions are responsible for handling any error situation. -// Default value is true. -func (c *Container) DoNotRecover(doNot bool) { - c.doNotRecover = doNot -} - -// Router changes the default Router (currently CurlyRouter) -func (c *Container) Router(aRouter RouteSelector) { - c.router = aRouter -} - -// EnableContentEncoding (default=false) allows for GZIP or DEFLATE encoding of responses. -func (c *Container) EnableContentEncoding(enabled bool) { - c.contentEncodingEnabled = enabled -} - -// Add a WebService to the Container. It will detect duplicate root paths and exit in that case. -func (c *Container) Add(service *WebService) *Container { - c.webServicesLock.Lock() - defer c.webServicesLock.Unlock() - - // if rootPath was not set then lazy initialize it - if len(service.rootPath) == 0 { - service.Path("/") - } - - // cannot have duplicate root paths - for _, each := range c.webServices { - if each.RootPath() == service.RootPath() { - log.Printf("[restful] WebService with duplicate root path detected:['%v']", each) - os.Exit(1) - } - } - - // If not registered on root then add specific mapping - if !c.isRegisteredOnRoot { - c.isRegisteredOnRoot = c.addHandler(service, c.ServeMux) - } - c.webServices = append(c.webServices, service) - return c -} - -// addHandler may set a new HandleFunc for the serveMux -// this function must run inside the critical region protected by the webServicesLock. -// returns true if the function was registered on root ("/") -func (c *Container) addHandler(service *WebService, serveMux *http.ServeMux) bool { - pattern := fixedPrefixPath(service.RootPath()) - // check if root path registration is needed - if "/" == pattern || "" == pattern { - serveMux.HandleFunc("/", c.dispatch) - return true - } - // detect if registration already exists - alreadyMapped := false - for _, each := range c.webServices { - if each.RootPath() == service.RootPath() { - alreadyMapped = true - break - } - } - if !alreadyMapped { - serveMux.HandleFunc(pattern, c.dispatch) - if !strings.HasSuffix(pattern, "/") { - serveMux.HandleFunc(pattern+"/", c.dispatch) - } - } - return false -} - -func (c *Container) Remove(ws *WebService) error { - if c.ServeMux == http.DefaultServeMux { - errMsg := fmt.Sprintf("[restful] cannot remove a WebService from a Container using the DefaultServeMux: ['%v']", ws) - log.Print(errMsg) - return errors.New(errMsg) - } - c.webServicesLock.Lock() - defer c.webServicesLock.Unlock() - // build a new ServeMux and re-register all WebServices - newServeMux := http.NewServeMux() - newServices := []*WebService{} - newIsRegisteredOnRoot := false - for _, each := range c.webServices { - if each.rootPath != ws.rootPath { - // If not registered on root then add specific mapping - if !newIsRegisteredOnRoot { - newIsRegisteredOnRoot = c.addHandler(each, newServeMux) - } - newServices = append(newServices, each) - } - } - c.webServices, c.ServeMux, c.isRegisteredOnRoot = newServices, newServeMux, newIsRegisteredOnRoot - return nil -} - -// logStackOnRecover is the default RecoverHandleFunction and is called -// when DoNotRecover is false and the recoverHandleFunc is not set for the container. -// Default implementation logs the stacktrace and writes the stacktrace on the response. -// This may be a security issue as it exposes sourcecode information. -func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter) { - var buffer bytes.Buffer - buffer.WriteString(fmt.Sprintf("[restful] recover from panic situation: - %v\r\n", panicReason)) - for i := 2; ; i += 1 { - _, file, line, ok := runtime.Caller(i) - if !ok { - break - } - buffer.WriteString(fmt.Sprintf(" %s:%d\r\n", file, line)) - } - log.Print(buffer.String()) - httpWriter.WriteHeader(http.StatusInternalServerError) - httpWriter.Write(buffer.Bytes()) -} - -// writeServiceError is the default ServiceErrorHandleFunction and is called -// when a ServiceError is returned during route selection. Default implementation -// calls resp.WriteErrorString(err.Code, err.Message) -func writeServiceError(err ServiceError, req *Request, resp *Response) { - resp.WriteErrorString(err.Code, err.Message) -} - -// Dispatch the incoming Http Request to a matching WebService. -func (c *Container) Dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) { - if httpWriter == nil { - panic("httpWriter cannot be nil") - } - if httpRequest == nil { - panic("httpRequest cannot be nil") - } - c.dispatch(httpWriter, httpRequest) -} - -// Dispatch the incoming Http Request to a matching WebService. -func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) { - writer := httpWriter - - // CompressingResponseWriter should be closed after all operations are done - defer func() { - if compressWriter, ok := writer.(*CompressingResponseWriter); ok { - compressWriter.Close() - } - }() - - // Instal panic recovery unless told otherwise - if !c.doNotRecover { // catch all for 500 response - defer func() { - if r := recover(); r != nil { - c.recoverHandleFunc(r, writer) - return - } - }() - } - - // Detect if compression is needed - // assume without compression, test for override - if c.contentEncodingEnabled { - doCompress, encoding := wantsCompressedResponse(httpRequest) - if doCompress { - var err error - writer, err = NewCompressingResponseWriter(httpWriter, encoding) - if err != nil { - log.Print("[restful] unable to install compressor: ", err) - httpWriter.WriteHeader(http.StatusInternalServerError) - return - } - } - } - // Find best match Route ; err is non nil if no match was found - var webService *WebService - var route *Route - var err error - func() { - c.webServicesLock.RLock() - defer c.webServicesLock.RUnlock() - webService, route, err = c.router.SelectRoute( - c.webServices, - httpRequest) - }() - if err != nil { - // a non-200 response has already been written - // run container filters anyway ; they should not touch the response... - chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) { - switch err.(type) { - case ServiceError: - ser := err.(ServiceError) - c.serviceErrorHandleFunc(ser, req, resp) - } - // TODO - }} - chain.ProcessFilter(NewRequest(httpRequest), NewResponse(writer)) - return - } - pathProcessor, routerProcessesPath := c.router.(PathProcessor) - if !routerProcessesPath { - pathProcessor = defaultPathProcessor{} - } - pathParams := pathProcessor.ExtractParameters(route, webService, httpRequest.URL.Path) - wrappedRequest, wrappedResponse := route.wrapRequestResponse(writer, httpRequest, pathParams) - // pass through filters (if any) - if len(c.containerFilters)+len(webService.filters)+len(route.Filters) > 0 { - // compose filter chain - allFilters := []FilterFunction{} - allFilters = append(allFilters, c.containerFilters...) - allFilters = append(allFilters, webService.filters...) - allFilters = append(allFilters, route.Filters...) - chain := FilterChain{Filters: allFilters, Target: func(req *Request, resp *Response) { - // handle request by route after passing all filters - route.Function(wrappedRequest, wrappedResponse) - }} - chain.ProcessFilter(wrappedRequest, wrappedResponse) - } else { - // no filters, handle request by route - route.Function(wrappedRequest, wrappedResponse) - } -} - -// fixedPrefixPath returns the fixed part of the partspec ; it may include template vars {} -func fixedPrefixPath(pathspec string) string { - varBegin := strings.Index(pathspec, "{") - if -1 == varBegin { - return pathspec - } - return pathspec[:varBegin] -} - -// ServeHTTP implements net/http.Handler therefore a Container can be a Handler in a http.Server -func (c *Container) ServeHTTP(httpwriter http.ResponseWriter, httpRequest *http.Request) { - c.ServeMux.ServeHTTP(httpwriter, httpRequest) -} - -// Handle registers the handler for the given pattern. If a handler already exists for pattern, Handle panics. -func (c *Container) Handle(pattern string, handler http.Handler) { - c.ServeMux.Handle(pattern, handler) -} - -// HandleWithFilter registers the handler for the given pattern. -// Container's filter chain is applied for handler. -// If a handler already exists for pattern, HandleWithFilter panics. -func (c *Container) HandleWithFilter(pattern string, handler http.Handler) { - f := func(httpResponse http.ResponseWriter, httpRequest *http.Request) { - if len(c.containerFilters) == 0 { - handler.ServeHTTP(httpResponse, httpRequest) - return - } - - chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) { - handler.ServeHTTP(httpResponse, httpRequest) - }} - chain.ProcessFilter(NewRequest(httpRequest), NewResponse(httpResponse)) - } - - c.Handle(pattern, http.HandlerFunc(f)) -} - -// Filter appends a container FilterFunction. These are called before dispatching -// a http.Request to a WebService from the container -func (c *Container) Filter(filter FilterFunction) { - c.containerFilters = append(c.containerFilters, filter) -} - -// RegisteredWebServices returns the collections of added WebServices -func (c *Container) RegisteredWebServices() []*WebService { - c.webServicesLock.RLock() - defer c.webServicesLock.RUnlock() - result := make([]*WebService, len(c.webServices)) - for ix := range c.webServices { - result[ix] = c.webServices[ix] - } - return result -} - -// computeAllowedMethods returns a list of HTTP methods that are valid for a Request -func (c *Container) computeAllowedMethods(req *Request) []string { - // Go through all RegisteredWebServices() and all its Routes to collect the options - methods := []string{} - requestPath := req.Request.URL.Path - for _, ws := range c.RegisteredWebServices() { - matches := ws.pathExpr.Matcher.FindStringSubmatch(requestPath) - if matches != nil { - finalMatch := matches[len(matches)-1] - for _, rt := range ws.Routes() { - matches := rt.pathExpr.Matcher.FindStringSubmatch(finalMatch) - if matches != nil { - lastMatch := matches[len(matches)-1] - if lastMatch == "" || lastMatch == "/" { // do not include if value is neither empty nor ‘/’. - methods = append(methods, rt.Method) - } - } - } - } - } - // methods = append(methods, "OPTIONS") not sure about this - return methods -} - -// newBasicRequestResponse creates a pair of Request,Response from its http versions. -// It is basic because no parameter or (produces) content-type information is given. -func newBasicRequestResponse(httpWriter http.ResponseWriter, httpRequest *http.Request) (*Request, *Response) { - resp := NewResponse(httpWriter) - resp.requestAccept = httpRequest.Header.Get(HEADER_Accept) - return NewRequest(httpRequest), resp -} diff --git a/vendor/github.com/emicklei/go-restful/cors_filter.go b/vendor/github.com/emicklei/go-restful/cors_filter.go deleted file mode 100644 index 1efeef072..000000000 --- a/vendor/github.com/emicklei/go-restful/cors_filter.go +++ /dev/null @@ -1,202 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "regexp" - "strconv" - "strings" -) - -// CrossOriginResourceSharing is used to create a Container Filter that implements CORS. -// Cross-origin resource sharing (CORS) is a mechanism that allows JavaScript on a web page -// to make XMLHttpRequests to another domain, not the domain the JavaScript originated from. -// -// http://en.wikipedia.org/wiki/Cross-origin_resource_sharing -// http://enable-cors.org/server.html -// http://www.html5rocks.com/en/tutorials/cors/#toc-handling-a-not-so-simple-request -type CrossOriginResourceSharing struct { - ExposeHeaders []string // list of Header names - AllowedHeaders []string // list of Header names - AllowedDomains []string // list of allowed values for Http Origin. An allowed value can be a regular expression to support subdomain matching. If empty all are allowed. - AllowedMethods []string - MaxAge int // number of seconds before requiring new Options request - CookiesAllowed bool - Container *Container - - allowedOriginPatterns []*regexp.Regexp // internal field for origin regexp check. -} - -// Filter is a filter function that implements the CORS flow as documented on http://enable-cors.org/server.html -// and http://www.html5rocks.com/static/images/cors_server_flowchart.png -func (c CrossOriginResourceSharing) Filter(req *Request, resp *Response, chain *FilterChain) { - origin := req.Request.Header.Get(HEADER_Origin) - if len(origin) == 0 { - if trace { - traceLogger.Print("no Http header Origin set") - } - chain.ProcessFilter(req, resp) - return - } - if !c.isOriginAllowed(origin) { // check whether this origin is allowed - if trace { - traceLogger.Printf("HTTP Origin:%s is not part of %v, neither matches any part of %v", origin, c.AllowedDomains, c.allowedOriginPatterns) - } - chain.ProcessFilter(req, resp) - return - } - if req.Request.Method != "OPTIONS" { - c.doActualRequest(req, resp) - chain.ProcessFilter(req, resp) - return - } - if acrm := req.Request.Header.Get(HEADER_AccessControlRequestMethod); acrm != "" { - c.doPreflightRequest(req, resp) - } else { - c.doActualRequest(req, resp) - chain.ProcessFilter(req, resp) - return - } -} - -func (c CrossOriginResourceSharing) doActualRequest(req *Request, resp *Response) { - c.setOptionsHeaders(req, resp) - // continue processing the response -} - -func (c *CrossOriginResourceSharing) doPreflightRequest(req *Request, resp *Response) { - if len(c.AllowedMethods) == 0 { - if c.Container == nil { - c.AllowedMethods = DefaultContainer.computeAllowedMethods(req) - } else { - c.AllowedMethods = c.Container.computeAllowedMethods(req) - } - } - - acrm := req.Request.Header.Get(HEADER_AccessControlRequestMethod) - if !c.isValidAccessControlRequestMethod(acrm, c.AllowedMethods) { - if trace { - traceLogger.Printf("Http header %s:%s is not in %v", - HEADER_AccessControlRequestMethod, - acrm, - c.AllowedMethods) - } - return - } - acrhs := req.Request.Header.Get(HEADER_AccessControlRequestHeaders) - if len(acrhs) > 0 { - for _, each := range strings.Split(acrhs, ",") { - if !c.isValidAccessControlRequestHeader(strings.Trim(each, " ")) { - if trace { - traceLogger.Printf("Http header %s:%s is not in %v", - HEADER_AccessControlRequestHeaders, - acrhs, - c.AllowedHeaders) - } - return - } - } - } - resp.AddHeader(HEADER_AccessControlAllowMethods, strings.Join(c.AllowedMethods, ",")) - resp.AddHeader(HEADER_AccessControlAllowHeaders, acrhs) - c.setOptionsHeaders(req, resp) - - // return http 200 response, no body -} - -func (c CrossOriginResourceSharing) setOptionsHeaders(req *Request, resp *Response) { - c.checkAndSetExposeHeaders(resp) - c.setAllowOriginHeader(req, resp) - c.checkAndSetAllowCredentials(resp) - if c.MaxAge > 0 { - resp.AddHeader(HEADER_AccessControlMaxAge, strconv.Itoa(c.MaxAge)) - } -} - -func (c CrossOriginResourceSharing) isOriginAllowed(origin string) bool { - if len(origin) == 0 { - return false - } - if len(c.AllowedDomains) == 0 { - return true - } - - allowed := false - for _, domain := range c.AllowedDomains { - if domain == origin { - allowed = true - break - } - } - - if !allowed { - if len(c.allowedOriginPatterns) == 0 { - // compile allowed domains to allowed origin patterns - allowedOriginRegexps, err := compileRegexps(c.AllowedDomains) - if err != nil { - return false - } - c.allowedOriginPatterns = allowedOriginRegexps - } - - for _, pattern := range c.allowedOriginPatterns { - if allowed = pattern.MatchString(origin); allowed { - break - } - } - } - - return allowed -} - -func (c CrossOriginResourceSharing) setAllowOriginHeader(req *Request, resp *Response) { - origin := req.Request.Header.Get(HEADER_Origin) - if c.isOriginAllowed(origin) { - resp.AddHeader(HEADER_AccessControlAllowOrigin, origin) - } -} - -func (c CrossOriginResourceSharing) checkAndSetExposeHeaders(resp *Response) { - if len(c.ExposeHeaders) > 0 { - resp.AddHeader(HEADER_AccessControlExposeHeaders, strings.Join(c.ExposeHeaders, ",")) - } -} - -func (c CrossOriginResourceSharing) checkAndSetAllowCredentials(resp *Response) { - if c.CookiesAllowed { - resp.AddHeader(HEADER_AccessControlAllowCredentials, "true") - } -} - -func (c CrossOriginResourceSharing) isValidAccessControlRequestMethod(method string, allowedMethods []string) bool { - for _, each := range allowedMethods { - if each == method { - return true - } - } - return false -} - -func (c CrossOriginResourceSharing) isValidAccessControlRequestHeader(header string) bool { - for _, each := range c.AllowedHeaders { - if strings.ToLower(each) == strings.ToLower(header) { - return true - } - } - return false -} - -// Take a list of strings and compile them into a list of regular expressions. -func compileRegexps(regexpStrings []string) ([]*regexp.Regexp, error) { - regexps := []*regexp.Regexp{} - for _, regexpStr := range regexpStrings { - r, err := regexp.Compile(regexpStr) - if err != nil { - return regexps, err - } - regexps = append(regexps, r) - } - return regexps, nil -} diff --git a/vendor/github.com/emicklei/go-restful/curly.go b/vendor/github.com/emicklei/go-restful/curly.go deleted file mode 100644 index 79f1f5aa2..000000000 --- a/vendor/github.com/emicklei/go-restful/curly.go +++ /dev/null @@ -1,164 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "net/http" - "regexp" - "sort" - "strings" -) - -// CurlyRouter expects Routes with paths that contain zero or more parameters in curly brackets. -type CurlyRouter struct{} - -// SelectRoute is part of the Router interface and returns the best match -// for the WebService and its Route for the given Request. -func (c CurlyRouter) SelectRoute( - webServices []*WebService, - httpRequest *http.Request) (selectedService *WebService, selected *Route, err error) { - - requestTokens := tokenizePath(httpRequest.URL.Path) - - detectedService := c.detectWebService(requestTokens, webServices) - if detectedService == nil { - if trace { - traceLogger.Printf("no WebService was found to match URL path:%s\n", httpRequest.URL.Path) - } - return nil, nil, NewError(http.StatusNotFound, "404: Page Not Found") - } - candidateRoutes := c.selectRoutes(detectedService, requestTokens) - if len(candidateRoutes) == 0 { - if trace { - traceLogger.Printf("no Route in WebService with path %s was found to match URL path:%s\n", detectedService.rootPath, httpRequest.URL.Path) - } - return detectedService, nil, NewError(http.StatusNotFound, "404: Page Not Found") - } - selectedRoute, err := c.detectRoute(candidateRoutes, httpRequest) - if selectedRoute == nil { - return detectedService, nil, err - } - return detectedService, selectedRoute, nil -} - -// selectRoutes return a collection of Route from a WebService that matches the path tokens from the request. -func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortableCurlyRoutes { - candidates := sortableCurlyRoutes{} - for _, each := range ws.routes { - matches, paramCount, staticCount := c.matchesRouteByPathTokens(each.pathParts, requestTokens) - if matches { - candidates.add(curlyRoute{each, paramCount, staticCount}) // TODO make sure Routes() return pointers? - } - } - sort.Sort(sort.Reverse(candidates)) - return candidates -} - -// matchesRouteByPathTokens computes whether it matches, howmany parameters do match and what the number of static path elements are. -func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []string) (matches bool, paramCount int, staticCount int) { - if len(routeTokens) < len(requestTokens) { - // proceed in matching only if last routeToken is wildcard - count := len(routeTokens) - if count == 0 || !strings.HasSuffix(routeTokens[count-1], "*}") { - return false, 0, 0 - } - // proceed - } - for i, routeToken := range routeTokens { - if i == len(requestTokens) { - // reached end of request path - return false, 0, 0 - } - requestToken := requestTokens[i] - if strings.HasPrefix(routeToken, "{") { - paramCount++ - if colon := strings.Index(routeToken, ":"); colon != -1 { - // match by regex - matchesToken, matchesRemainder := c.regularMatchesPathToken(routeToken, colon, requestToken) - if !matchesToken { - return false, 0, 0 - } - if matchesRemainder { - break - } - } - } else { // no { prefix - if requestToken != routeToken { - return false, 0, 0 - } - staticCount++ - } - } - return true, paramCount, staticCount -} - -// regularMatchesPathToken tests whether the regular expression part of routeToken matches the requestToken or all remaining tokens -// format routeToken is {someVar:someExpression}, e.g. {zipcode:[\d][\d][\d][\d][A-Z][A-Z]} -func (c CurlyRouter) regularMatchesPathToken(routeToken string, colon int, requestToken string) (matchesToken bool, matchesRemainder bool) { - regPart := routeToken[colon+1 : len(routeToken)-1] - if regPart == "*" { - if trace { - traceLogger.Printf("wildcard parameter detected in route token %s that matches %s\n", routeToken, requestToken) - } - return true, true - } - matched, err := regexp.MatchString(regPart, requestToken) - return (matched && err == nil), false -} - -var jsr311Router = RouterJSR311{} - -// detectRoute selectes from a list of Route the first match by inspecting both the Accept and Content-Type -// headers of the Request. See also RouterJSR311 in jsr311.go -func (c CurlyRouter) detectRoute(candidateRoutes sortableCurlyRoutes, httpRequest *http.Request) (*Route, error) { - // tracing is done inside detectRoute - return jsr311Router.detectRoute(candidateRoutes.routes(), httpRequest) -} - -// detectWebService returns the best matching webService given the list of path tokens. -// see also computeWebserviceScore -func (c CurlyRouter) detectWebService(requestTokens []string, webServices []*WebService) *WebService { - var best *WebService - score := -1 - for _, each := range webServices { - matches, eachScore := c.computeWebserviceScore(requestTokens, each.pathExpr.tokens) - if matches && (eachScore > score) { - best = each - score = eachScore - } - } - return best -} - -// computeWebserviceScore returns whether tokens match and -// the weighted score of the longest matching consecutive tokens from the beginning. -func (c CurlyRouter) computeWebserviceScore(requestTokens []string, tokens []string) (bool, int) { - if len(tokens) > len(requestTokens) { - return false, 0 - } - score := 0 - for i := 0; i < len(tokens); i++ { - each := requestTokens[i] - other := tokens[i] - if len(each) == 0 && len(other) == 0 { - score++ - continue - } - if len(other) > 0 && strings.HasPrefix(other, "{") { - // no empty match - if len(each) == 0 { - return false, score - } - score += 1 - } else { - // not a parameter - if each != other { - return false, score - } - score += (len(tokens) - i) * 10 //fuzzy - } - } - return true, score -} diff --git a/vendor/github.com/emicklei/go-restful/curly_route.go b/vendor/github.com/emicklei/go-restful/curly_route.go deleted file mode 100644 index 296f94650..000000000 --- a/vendor/github.com/emicklei/go-restful/curly_route.go +++ /dev/null @@ -1,52 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -// curlyRoute exits for sorting Routes by the CurlyRouter based on number of parameters and number of static path elements. -type curlyRoute struct { - route Route - paramCount int - staticCount int -} - -type sortableCurlyRoutes []curlyRoute - -func (s *sortableCurlyRoutes) add(route curlyRoute) { - *s = append(*s, route) -} - -func (s sortableCurlyRoutes) routes() (routes []Route) { - for _, each := range s { - routes = append(routes, each.route) // TODO change return type - } - return routes -} - -func (s sortableCurlyRoutes) Len() int { - return len(s) -} -func (s sortableCurlyRoutes) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} -func (s sortableCurlyRoutes) Less(i, j int) bool { - ci := s[i] - cj := s[j] - - // primary key - if ci.staticCount < cj.staticCount { - return true - } - if ci.staticCount > cj.staticCount { - return false - } - // secundary key - if ci.paramCount < cj.paramCount { - return true - } - if ci.paramCount > cj.paramCount { - return false - } - return ci.route.Path < cj.route.Path -} diff --git a/vendor/github.com/emicklei/go-restful/doc.go b/vendor/github.com/emicklei/go-restful/doc.go deleted file mode 100644 index f7c16b01f..000000000 --- a/vendor/github.com/emicklei/go-restful/doc.go +++ /dev/null @@ -1,185 +0,0 @@ -/* -Package restful , a lean package for creating REST-style WebServices without magic. - -WebServices and Routes - -A WebService has a collection of Route objects that dispatch incoming Http Requests to a function calls. -Typically, a WebService has a root path (e.g. /users) and defines common MIME types for its routes. -WebServices must be added to a container (see below) in order to handler Http requests from a server. - -A Route is defined by a HTTP method, an URL path and (optionally) the MIME types it consumes (Content-Type) and produces (Accept). -This package has the logic to find the best matching Route and if found, call its Function. - - ws := new(restful.WebService) - ws. - Path("/users"). - Consumes(restful.MIME_JSON, restful.MIME_XML). - Produces(restful.MIME_JSON, restful.MIME_XML) - - ws.Route(ws.GET("/{user-id}").To(u.findUser)) // u is a UserResource - - ... - - // GET http://localhost:8080/users/1 - func (u UserResource) findUser(request *restful.Request, response *restful.Response) { - id := request.PathParameter("user-id") - ... - } - -The (*Request, *Response) arguments provide functions for reading information from the request and writing information back to the response. - -See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-user-resource.go with a full implementation. - -Regular expression matching Routes - -A Route parameter can be specified using the format "uri/{var[:regexp]}" or the special version "uri/{var:*}" for matching the tail of the path. -For example, /persons/{name:[A-Z][A-Z]} can be used to restrict values for the parameter "name" to only contain capital alphabetic characters. -Regular expressions must use the standard Go syntax as described in the regexp package. (https://code.google.com/p/re2/wiki/Syntax) -This feature requires the use of a CurlyRouter. - -Containers - -A Container holds a collection of WebServices, Filters and a http.ServeMux for multiplexing http requests. -Using the statements "restful.Add(...) and restful.Filter(...)" will register WebServices and Filters to the Default Container. -The Default container of go-restful uses the http.DefaultServeMux. -You can create your own Container and create a new http.Server for that particular container. - - container := restful.NewContainer() - server := &http.Server{Addr: ":8081", Handler: container} - -Filters - -A filter dynamically intercepts requests and responses to transform or use the information contained in the requests or responses. -You can use filters to perform generic logging, measurement, authentication, redirect, set response headers etc. -In the restful package there are three hooks into the request,response flow where filters can be added. -Each filter must define a FilterFunction: - - func (req *restful.Request, resp *restful.Response, chain *restful.FilterChain) - -Use the following statement to pass the request,response pair to the next filter or RouteFunction - - chain.ProcessFilter(req, resp) - -Container Filters - -These are processed before any registered WebService. - - // install a (global) filter for the default container (processed before any webservice) - restful.Filter(globalLogging) - -WebService Filters - -These are processed before any Route of a WebService. - - // install a webservice filter (processed before any route) - ws.Filter(webserviceLogging).Filter(measureTime) - - -Route Filters - -These are processed before calling the function associated with the Route. - - // install 2 chained route filters (processed before calling findUser) - ws.Route(ws.GET("/{user-id}").Filter(routeLogging).Filter(NewCountFilter().routeCounter).To(findUser)) - -See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-filters.go with full implementations. - -Response Encoding - -Two encodings are supported: gzip and deflate. To enable this for all responses: - - restful.DefaultContainer.EnableContentEncoding(true) - -If a Http request includes the Accept-Encoding header then the response content will be compressed using the specified encoding. -Alternatively, you can create a Filter that performs the encoding and install it per WebService or Route. - -See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-encoding-filter.go - -OPTIONS support - -By installing a pre-defined container filter, your Webservice(s) can respond to the OPTIONS Http request. - - Filter(OPTIONSFilter()) - -CORS - -By installing the filter of a CrossOriginResourceSharing (CORS), your WebService(s) can handle CORS requests. - - cors := CrossOriginResourceSharing{ExposeHeaders: []string{"X-My-Header"}, CookiesAllowed: false, Container: DefaultContainer} - Filter(cors.Filter) - -Error Handling - -Unexpected things happen. If a request cannot be processed because of a failure, your service needs to tell via the response what happened and why. -For this reason HTTP status codes exist and it is important to use the correct code in every exceptional situation. - - 400: Bad Request - -If path or query parameters are not valid (content or type) then use http.StatusBadRequest. - - 404: Not Found - -Despite a valid URI, the resource requested may not be available - - 500: Internal Server Error - -If the application logic could not process the request (or write the response) then use http.StatusInternalServerError. - - 405: Method Not Allowed - -The request has a valid URL but the method (GET,PUT,POST,...) is not allowed. - - 406: Not Acceptable - -The request does not have or has an unknown Accept Header set for this operation. - - 415: Unsupported Media Type - -The request does not have or has an unknown Content-Type Header set for this operation. - -ServiceError - -In addition to setting the correct (error) Http status code, you can choose to write a ServiceError message on the response. - -Performance options - -This package has several options that affect the performance of your service. It is important to understand them and how you can change it. - - restful.DefaultContainer.DoNotRecover(false) - -DoNotRecover controls whether panics will be caught to return HTTP 500. -If set to false, the container will recover from panics. -Default value is true - - restful.SetCompressorProvider(NewBoundedCachedCompressors(20, 20)) - -If content encoding is enabled then the default strategy for getting new gzip/zlib writers and readers is to use a sync.Pool. -Because writers are expensive structures, performance is even more improved when using a preloaded cache. You can also inject your own implementation. - -Trouble shooting - -This package has the means to produce detail logging of the complete Http request matching process and filter invocation. -Enabling this feature requires you to set an implementation of restful.StdLogger (e.g. log.Logger) instance such as: - - restful.TraceLogger(log.New(os.Stdout, "[restful] ", log.LstdFlags|log.Lshortfile)) - -Logging - -The restful.SetLogger() method allows you to override the logger used by the package. By default restful -uses the standard library `log` package and logs to stdout. Different logging packages are supported as -long as they conform to `StdLogger` interface defined in the `log` sub-package, writing an adapter for your -preferred package is simple. - -Resources - -[project]: https://github.com/emicklei/go-restful - -[examples]: https://github.com/emicklei/go-restful/blob/master/examples - -[design]: http://ernestmicklei.com/2012/11/11/go-restful-api-design/ - -[showcases]: https://github.com/emicklei/mora, https://github.com/emicklei/landskape - -(c) 2012-2015, http://ernestmicklei.com. MIT License -*/ -package restful diff --git a/vendor/github.com/emicklei/go-restful/entity_accessors.go b/vendor/github.com/emicklei/go-restful/entity_accessors.go deleted file mode 100644 index 42957055f..000000000 --- a/vendor/github.com/emicklei/go-restful/entity_accessors.go +++ /dev/null @@ -1,169 +0,0 @@ -package restful - -// Copyright 2015 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "encoding/json" - "encoding/xml" - "io" - "strings" - "sync" -) - -// EntityReaderWriter can read and write values using an encoding such as JSON,XML. -type EntityReaderWriter interface { - // Read a serialized version of the value from the request. - // The Request may have a decompressing reader. Depends on Content-Encoding. - Read(req *Request, v interface{}) error - - // Write a serialized version of the value on the response. - // The Response may have a compressing writer. Depends on Accept-Encoding. - // status should be a valid Http Status code - Write(resp *Response, status int, v interface{}) error -} - -// entityAccessRegistry is a singleton -var entityAccessRegistry = &entityReaderWriters{ - protection: new(sync.RWMutex), - accessors: map[string]EntityReaderWriter{}, -} - -// entityReaderWriters associates MIME to an EntityReaderWriter -type entityReaderWriters struct { - protection *sync.RWMutex - accessors map[string]EntityReaderWriter -} - -func init() { - RegisterEntityAccessor(MIME_JSON, NewEntityAccessorJSON(MIME_JSON)) - RegisterEntityAccessor(MIME_XML, NewEntityAccessorXML(MIME_XML)) -} - -// RegisterEntityAccessor add/overrides the ReaderWriter for encoding content with this MIME type. -func RegisterEntityAccessor(mime string, erw EntityReaderWriter) { - entityAccessRegistry.protection.Lock() - defer entityAccessRegistry.protection.Unlock() - entityAccessRegistry.accessors[mime] = erw -} - -// NewEntityAccessorJSON returns a new EntityReaderWriter for accessing JSON content. -// This package is already initialized with such an accessor using the MIME_JSON contentType. -func NewEntityAccessorJSON(contentType string) EntityReaderWriter { - return entityJSONAccess{ContentType: contentType} -} - -// NewEntityAccessorXML returns a new EntityReaderWriter for accessing XML content. -// This package is already initialized with such an accessor using the MIME_XML contentType. -func NewEntityAccessorXML(contentType string) EntityReaderWriter { - return entityXMLAccess{ContentType: contentType} -} - -// accessorAt returns the registered ReaderWriter for this MIME type. -func (r *entityReaderWriters) accessorAt(mime string) (EntityReaderWriter, bool) { - r.protection.RLock() - defer r.protection.RUnlock() - er, ok := r.accessors[mime] - if !ok { - // retry with reverse lookup - // more expensive but we are in an exceptional situation anyway - for k, v := range r.accessors { - if strings.Contains(mime, k) { - return v, true - } - } - } - return er, ok -} - -// entityXMLAccess is a EntityReaderWriter for XML encoding -type entityXMLAccess struct { - // This is used for setting the Content-Type header when writing - ContentType string -} - -// Read unmarshalls the value from XML -func (e entityXMLAccess) Read(req *Request, v interface{}) error { - return xml.NewDecoder(req.Request.Body).Decode(v) -} - -// Write marshalls the value to JSON and set the Content-Type Header. -func (e entityXMLAccess) Write(resp *Response, status int, v interface{}) error { - return writeXML(resp, status, e.ContentType, v) -} - -// writeXML marshalls the value to JSON and set the Content-Type Header. -func writeXML(resp *Response, status int, contentType string, v interface{}) error { - if v == nil { - resp.WriteHeader(status) - // do not write a nil representation - return nil - } - if resp.prettyPrint { - // pretty output must be created and written explicitly - output, err := xml.MarshalIndent(v, " ", " ") - if err != nil { - return err - } - resp.Header().Set(HEADER_ContentType, contentType) - resp.WriteHeader(status) - _, err = resp.Write([]byte(xml.Header)) - if err != nil { - return err - } - _, err = resp.Write(output) - return err - } - // not-so-pretty - resp.Header().Set(HEADER_ContentType, contentType) - resp.WriteHeader(status) - return xml.NewEncoder(resp).Encode(v) -} - -// entityJSONAccess is a EntityReaderWriter for JSON encoding -type entityJSONAccess struct { - // This is used for setting the Content-Type header when writing - ContentType string -} - -// JSONNewDecoderFunc can be used to inject a different configration for the json Decoder instance. -var JSONNewDecoderFunc = func(r io.Reader) *json.Decoder { - decoder := json.NewDecoder(r) - decoder.UseNumber() - return decoder -} - -// Read unmarshalls the value from JSON -func (e entityJSONAccess) Read(req *Request, v interface{}) error { - return JSONNewDecoderFunc(req.Request.Body).Decode(v) -} - -// Write marshalls the value to JSON and set the Content-Type Header. -func (e entityJSONAccess) Write(resp *Response, status int, v interface{}) error { - return writeJSON(resp, status, e.ContentType, v) -} - -// write marshalls the value to JSON and set the Content-Type Header. -func writeJSON(resp *Response, status int, contentType string, v interface{}) error { - if v == nil { - resp.WriteHeader(status) - // do not write a nil representation - return nil - } - if resp.prettyPrint { - // pretty output must be created and written explicitly - output, err := json.MarshalIndent(v, " ", " ") - if err != nil { - return err - } - resp.Header().Set(HEADER_ContentType, contentType) - resp.WriteHeader(status) - _, err = resp.Write(output) - return err - } - // not-so-pretty - resp.Header().Set(HEADER_ContentType, contentType) - resp.WriteHeader(status) - return json.NewEncoder(resp).Encode(v) -} diff --git a/vendor/github.com/emicklei/go-restful/filter.go b/vendor/github.com/emicklei/go-restful/filter.go deleted file mode 100644 index c23bfb591..000000000 --- a/vendor/github.com/emicklei/go-restful/filter.go +++ /dev/null @@ -1,35 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -// FilterChain is a request scoped object to process one or more filters before calling the target RouteFunction. -type FilterChain struct { - Filters []FilterFunction // ordered list of FilterFunction - Index int // index into filters that is currently in progress - Target RouteFunction // function to call after passing all filters -} - -// ProcessFilter passes the request,response pair through the next of Filters. -// Each filter can decide to proceed to the next Filter or handle the Response itself. -func (f *FilterChain) ProcessFilter(request *Request, response *Response) { - if f.Index < len(f.Filters) { - f.Index++ - f.Filters[f.Index-1](request, response, f) - } else { - f.Target(request, response) - } -} - -// FilterFunction definitions must call ProcessFilter on the FilterChain to pass on the control and eventually call the RouteFunction -type FilterFunction func(*Request, *Response, *FilterChain) - -// NoBrowserCacheFilter is a filter function to set HTTP headers that disable browser caching -// See examples/restful-no-cache-filter.go for usage -func NoBrowserCacheFilter(req *Request, resp *Response, chain *FilterChain) { - resp.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") // HTTP 1.1. - resp.Header().Set("Pragma", "no-cache") // HTTP 1.0. - resp.Header().Set("Expires", "0") // Proxies. - chain.ProcessFilter(req, resp) -} diff --git a/vendor/github.com/emicklei/go-restful/jsr311.go b/vendor/github.com/emicklei/go-restful/jsr311.go deleted file mode 100644 index 4360b492e..000000000 --- a/vendor/github.com/emicklei/go-restful/jsr311.go +++ /dev/null @@ -1,293 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "errors" - "fmt" - "net/http" - "sort" -) - -// RouterJSR311 implements the flow for matching Requests to Routes (and consequently Resource Functions) -// as specified by the JSR311 http://jsr311.java.net/nonav/releases/1.1/spec/spec.html. -// RouterJSR311 implements the Router interface. -// Concept of locators is not implemented. -type RouterJSR311 struct{} - -// SelectRoute is part of the Router interface and returns the best match -// for the WebService and its Route for the given Request. -func (r RouterJSR311) SelectRoute( - webServices []*WebService, - httpRequest *http.Request) (selectedService *WebService, selectedRoute *Route, err error) { - - // Identify the root resource class (WebService) - dispatcher, finalMatch, err := r.detectDispatcher(httpRequest.URL.Path, webServices) - if err != nil { - return nil, nil, NewError(http.StatusNotFound, "") - } - // Obtain the set of candidate methods (Routes) - routes := r.selectRoutes(dispatcher, finalMatch) - if len(routes) == 0 { - return dispatcher, nil, NewError(http.StatusNotFound, "404: Page Not Found") - } - - // Identify the method (Route) that will handle the request - route, ok := r.detectRoute(routes, httpRequest) - return dispatcher, route, ok -} - -// ExtractParameters is used to obtain the path parameters from the route using the same matching -// engine as the JSR 311 router. -func (r RouterJSR311) ExtractParameters(route *Route, webService *WebService, urlPath string) map[string]string { - webServiceExpr := webService.pathExpr - webServiceMatches := webServiceExpr.Matcher.FindStringSubmatch(urlPath) - pathParameters := r.extractParams(webServiceExpr, webServiceMatches) - routeExpr := route.pathExpr - routeMatches := routeExpr.Matcher.FindStringSubmatch(webServiceMatches[len(webServiceMatches)-1]) - routeParams := r.extractParams(routeExpr, routeMatches) - for key, value := range routeParams { - pathParameters[key] = value - } - return pathParameters -} - -func (RouterJSR311) extractParams(pathExpr *pathExpression, matches []string) map[string]string { - params := map[string]string{} - for i := 1; i < len(matches); i++ { - if len(pathExpr.VarNames) >= i { - params[pathExpr.VarNames[i-1]] = matches[i] - } - } - return params -} - -// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2 -func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*Route, error) { - ifOk := []Route{} - for _, each := range routes { - ok := true - for _, fn := range each.If { - if !fn(httpRequest) { - ok = false - break - } - } - if ok { - ifOk = append(ifOk, each) - } - } - if len(ifOk) == 0 { - if trace { - traceLogger.Printf("no Route found (from %d) that passes conditional checks", len(routes)) - } - return nil, NewError(http.StatusNotFound, "404: Not Found") - } - - // http method - methodOk := []Route{} - for _, each := range ifOk { - if httpRequest.Method == each.Method { - methodOk = append(methodOk, each) - } - } - if len(methodOk) == 0 { - if trace { - traceLogger.Printf("no Route found (in %d routes) that matches HTTP method %s\n", len(routes), httpRequest.Method) - } - return nil, NewError(http.StatusMethodNotAllowed, "405: Method Not Allowed") - } - inputMediaOk := methodOk - - // content-type - contentType := httpRequest.Header.Get(HEADER_ContentType) - inputMediaOk = []Route{} - for _, each := range methodOk { - if each.matchesContentType(contentType) { - inputMediaOk = append(inputMediaOk, each) - } - } - if len(inputMediaOk) == 0 { - if trace { - traceLogger.Printf("no Route found (from %d) that matches HTTP Content-Type: %s\n", len(methodOk), contentType) - } - return nil, NewError(http.StatusUnsupportedMediaType, "415: Unsupported Media Type") - } - - // accept - outputMediaOk := []Route{} - accept := httpRequest.Header.Get(HEADER_Accept) - if len(accept) == 0 { - accept = "*/*" - } - for _, each := range inputMediaOk { - if each.matchesAccept(accept) { - outputMediaOk = append(outputMediaOk, each) - } - } - if len(outputMediaOk) == 0 { - if trace { - traceLogger.Printf("no Route found (from %d) that matches HTTP Accept: %s\n", len(inputMediaOk), accept) - } - return nil, NewError(http.StatusNotAcceptable, "406: Not Acceptable") - } - // return r.bestMatchByMedia(outputMediaOk, contentType, accept), nil - return &outputMediaOk[0], nil -} - -// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2 -// n/m > n/* > */* -func (r RouterJSR311) bestMatchByMedia(routes []Route, contentType string, accept string) *Route { - // TODO - return &routes[0] -} - -// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2 (step 2) -func (r RouterJSR311) selectRoutes(dispatcher *WebService, pathRemainder string) []Route { - filtered := &sortableRouteCandidates{} - for _, each := range dispatcher.Routes() { - pathExpr := each.pathExpr - matches := pathExpr.Matcher.FindStringSubmatch(pathRemainder) - if matches != nil { - lastMatch := matches[len(matches)-1] - if len(lastMatch) == 0 || lastMatch == "/" { // do not include if value is neither empty nor ‘/’. - filtered.candidates = append(filtered.candidates, - routeCandidate{each, len(matches) - 1, pathExpr.LiteralCount, pathExpr.VarCount}) - } - } - } - if len(filtered.candidates) == 0 { - if trace { - traceLogger.Printf("WebService on path %s has no routes that match URL path remainder:%s\n", dispatcher.rootPath, pathRemainder) - } - return []Route{} - } - sort.Sort(sort.Reverse(filtered)) - - // select other routes from candidates whoes expression matches rmatch - matchingRoutes := []Route{filtered.candidates[0].route} - for c := 1; c < len(filtered.candidates); c++ { - each := filtered.candidates[c] - if each.route.pathExpr.Matcher.MatchString(pathRemainder) { - matchingRoutes = append(matchingRoutes, each.route) - } - } - return matchingRoutes -} - -// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2 (step 1) -func (r RouterJSR311) detectDispatcher(requestPath string, dispatchers []*WebService) (*WebService, string, error) { - filtered := &sortableDispatcherCandidates{} - for _, each := range dispatchers { - matches := each.pathExpr.Matcher.FindStringSubmatch(requestPath) - if matches != nil { - filtered.candidates = append(filtered.candidates, - dispatcherCandidate{each, matches[len(matches)-1], len(matches), each.pathExpr.LiteralCount, each.pathExpr.VarCount}) - } - } - if len(filtered.candidates) == 0 { - if trace { - traceLogger.Printf("no WebService was found to match URL path:%s\n", requestPath) - } - return nil, "", errors.New("not found") - } - sort.Sort(sort.Reverse(filtered)) - return filtered.candidates[0].dispatcher, filtered.candidates[0].finalMatch, nil -} - -// Types and functions to support the sorting of Routes - -type routeCandidate struct { - route Route - matchesCount int // the number of capturing groups - literalCount int // the number of literal characters (means those not resulting from template variable substitution) - nonDefaultCount int // the number of capturing groups with non-default regular expressions (i.e. not ‘([^ /]+?)’) -} - -func (r routeCandidate) expressionToMatch() string { - return r.route.pathExpr.Source -} - -func (r routeCandidate) String() string { - return fmt.Sprintf("(m=%d,l=%d,n=%d)", r.matchesCount, r.literalCount, r.nonDefaultCount) -} - -type sortableRouteCandidates struct { - candidates []routeCandidate -} - -func (rcs *sortableRouteCandidates) Len() int { - return len(rcs.candidates) -} -func (rcs *sortableRouteCandidates) Swap(i, j int) { - rcs.candidates[i], rcs.candidates[j] = rcs.candidates[j], rcs.candidates[i] -} -func (rcs *sortableRouteCandidates) Less(i, j int) bool { - ci := rcs.candidates[i] - cj := rcs.candidates[j] - // primary key - if ci.literalCount < cj.literalCount { - return true - } - if ci.literalCount > cj.literalCount { - return false - } - // secundary key - if ci.matchesCount < cj.matchesCount { - return true - } - if ci.matchesCount > cj.matchesCount { - return false - } - // tertiary key - if ci.nonDefaultCount < cj.nonDefaultCount { - return true - } - if ci.nonDefaultCount > cj.nonDefaultCount { - return false - } - // quaternary key ("source" is interpreted as Path) - return ci.route.Path < cj.route.Path -} - -// Types and functions to support the sorting of Dispatchers - -type dispatcherCandidate struct { - dispatcher *WebService - finalMatch string - matchesCount int // the number of capturing groups - literalCount int // the number of literal characters (means those not resulting from template variable substitution) - nonDefaultCount int // the number of capturing groups with non-default regular expressions (i.e. not ‘([^ /]+?)’) -} -type sortableDispatcherCandidates struct { - candidates []dispatcherCandidate -} - -func (dc *sortableDispatcherCandidates) Len() int { - return len(dc.candidates) -} -func (dc *sortableDispatcherCandidates) Swap(i, j int) { - dc.candidates[i], dc.candidates[j] = dc.candidates[j], dc.candidates[i] -} -func (dc *sortableDispatcherCandidates) Less(i, j int) bool { - ci := dc.candidates[i] - cj := dc.candidates[j] - // primary key - if ci.matchesCount < cj.matchesCount { - return true - } - if ci.matchesCount > cj.matchesCount { - return false - } - // secundary key - if ci.literalCount < cj.literalCount { - return true - } - if ci.literalCount > cj.literalCount { - return false - } - // tertiary key - return ci.nonDefaultCount < cj.nonDefaultCount -} diff --git a/vendor/github.com/emicklei/go-restful/log/log.go b/vendor/github.com/emicklei/go-restful/log/log.go deleted file mode 100644 index 6cd44c7a5..000000000 --- a/vendor/github.com/emicklei/go-restful/log/log.go +++ /dev/null @@ -1,34 +0,0 @@ -package log - -import ( - stdlog "log" - "os" -) - -// StdLogger corresponds to a minimal subset of the interface satisfied by stdlib log.Logger -type StdLogger interface { - Print(v ...interface{}) - Printf(format string, v ...interface{}) -} - -var Logger StdLogger - -func init() { - // default Logger - SetLogger(stdlog.New(os.Stderr, "[restful] ", stdlog.LstdFlags|stdlog.Lshortfile)) -} - -// SetLogger sets the logger for this package -func SetLogger(customLogger StdLogger) { - Logger = customLogger -} - -// Print delegates to the Logger -func Print(v ...interface{}) { - Logger.Print(v...) -} - -// Printf delegates to the Logger -func Printf(format string, v ...interface{}) { - Logger.Printf(format, v...) -} diff --git a/vendor/github.com/emicklei/go-restful/logger.go b/vendor/github.com/emicklei/go-restful/logger.go deleted file mode 100644 index 6595df002..000000000 --- a/vendor/github.com/emicklei/go-restful/logger.go +++ /dev/null @@ -1,32 +0,0 @@ -package restful - -// Copyright 2014 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. -import ( - "github.com/emicklei/go-restful/log" -) - -var trace bool = false -var traceLogger log.StdLogger - -func init() { - traceLogger = log.Logger // use the package logger by default -} - -// TraceLogger enables detailed logging of Http request matching and filter invocation. Default no logger is set. -// You may call EnableTracing() directly to enable trace logging to the package-wide logger. -func TraceLogger(logger log.StdLogger) { - traceLogger = logger - EnableTracing(logger != nil) -} - -// SetLogger exposes the setter for the global logger on the top-level package -func SetLogger(customLogger log.StdLogger) { - log.SetLogger(customLogger) -} - -// EnableTracing can be used to Trace logging on and off. -func EnableTracing(enabled bool) { - trace = enabled -} diff --git a/vendor/github.com/emicklei/go-restful/mime.go b/vendor/github.com/emicklei/go-restful/mime.go deleted file mode 100644 index d7ea2b615..000000000 --- a/vendor/github.com/emicklei/go-restful/mime.go +++ /dev/null @@ -1,45 +0,0 @@ -package restful - -import ( - "strconv" - "strings" -) - -type mime struct { - media string - quality float64 -} - -// insertMime adds a mime to a list and keeps it sorted by quality. -func insertMime(l []mime, e mime) []mime { - for i, each := range l { - // if current mime has lower quality then insert before - if e.quality > each.quality { - left := append([]mime{}, l[0:i]...) - return append(append(left, e), l[i:]...) - } - } - return append(l, e) -} - -// sortedMimes returns a list of mime sorted (desc) by its specified quality. -func sortedMimes(accept string) (sorted []mime) { - for _, each := range strings.Split(accept, ",") { - typeAndQuality := strings.Split(strings.Trim(each, " "), ";") - if len(typeAndQuality) == 1 { - sorted = insertMime(sorted, mime{typeAndQuality[0], 1.0}) - } else { - // take factor - parts := strings.Split(typeAndQuality[1], "=") - if len(parts) == 2 { - f, err := strconv.ParseFloat(parts[1], 64) - if err != nil { - traceLogger.Printf("unable to parse quality in %s, %v", each, err) - } else { - sorted = insertMime(sorted, mime{typeAndQuality[0], f}) - } - } - } - } - return -} diff --git a/vendor/github.com/emicklei/go-restful/options_filter.go b/vendor/github.com/emicklei/go-restful/options_filter.go deleted file mode 100644 index 5c1b34251..000000000 --- a/vendor/github.com/emicklei/go-restful/options_filter.go +++ /dev/null @@ -1,34 +0,0 @@ -package restful - -import "strings" - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -// OPTIONSFilter is a filter function that inspects the Http Request for the OPTIONS method -// and provides the response with a set of allowed methods for the request URL Path. -// As for any filter, you can also install it for a particular WebService within a Container. -// Note: this filter is not needed when using CrossOriginResourceSharing (for CORS). -func (c *Container) OPTIONSFilter(req *Request, resp *Response, chain *FilterChain) { - if "OPTIONS" != req.Request.Method { - chain.ProcessFilter(req, resp) - return - } - - archs := req.Request.Header.Get(HEADER_AccessControlRequestHeaders) - methods := strings.Join(c.computeAllowedMethods(req), ",") - origin := req.Request.Header.Get(HEADER_Origin) - - resp.AddHeader(HEADER_Allow, methods) - resp.AddHeader(HEADER_AccessControlAllowOrigin, origin) - resp.AddHeader(HEADER_AccessControlAllowHeaders, archs) - resp.AddHeader(HEADER_AccessControlAllowMethods, methods) -} - -// OPTIONSFilter is a filter function that inspects the Http Request for the OPTIONS method -// and provides the response with a set of allowed methods for the request URL Path. -// Note: this filter is not needed when using CrossOriginResourceSharing (for CORS). -func OPTIONSFilter() FilterFunction { - return DefaultContainer.OPTIONSFilter -} diff --git a/vendor/github.com/emicklei/go-restful/parameter.go b/vendor/github.com/emicklei/go-restful/parameter.go deleted file mode 100644 index e8793304b..000000000 --- a/vendor/github.com/emicklei/go-restful/parameter.go +++ /dev/null @@ -1,143 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -const ( - // PathParameterKind = indicator of Request parameter type "path" - PathParameterKind = iota - - // QueryParameterKind = indicator of Request parameter type "query" - QueryParameterKind - - // BodyParameterKind = indicator of Request parameter type "body" - BodyParameterKind - - // HeaderParameterKind = indicator of Request parameter type "header" - HeaderParameterKind - - // FormParameterKind = indicator of Request parameter type "form" - FormParameterKind - - // CollectionFormatCSV comma separated values `foo,bar` - CollectionFormatCSV = CollectionFormat("csv") - - // CollectionFormatSSV space separated values `foo bar` - CollectionFormatSSV = CollectionFormat("ssv") - - // CollectionFormatTSV tab separated values `foo\tbar` - CollectionFormatTSV = CollectionFormat("tsv") - - // CollectionFormatPipes pipe separated values `foo|bar` - CollectionFormatPipes = CollectionFormat("pipes") - - // CollectionFormatMulti corresponds to multiple parameter instances instead of multiple values for a single - // instance `foo=bar&foo=baz`. This is valid only for QueryParameters and FormParameters - CollectionFormatMulti = CollectionFormat("multi") -) - -type CollectionFormat string - -func (cf CollectionFormat) String() string { - return string(cf) -} - -// Parameter is for documententing the parameter used in a Http Request -// ParameterData kinds are Path,Query and Body -type Parameter struct { - data *ParameterData -} - -// ParameterData represents the state of a Parameter. -// It is made public to make it accessible to e.g. the Swagger package. -type ParameterData struct { - Name, Description, DataType, DataFormat string - Kind int - Required bool - AllowableValues map[string]string - AllowMultiple bool - DefaultValue string - CollectionFormat string -} - -// Data returns the state of the Parameter -func (p *Parameter) Data() ParameterData { - return *p.data -} - -// Kind returns the parameter type indicator (see const for valid values) -func (p *Parameter) Kind() int { - return p.data.Kind -} - -func (p *Parameter) bePath() *Parameter { - p.data.Kind = PathParameterKind - return p -} -func (p *Parameter) beQuery() *Parameter { - p.data.Kind = QueryParameterKind - return p -} -func (p *Parameter) beBody() *Parameter { - p.data.Kind = BodyParameterKind - return p -} - -func (p *Parameter) beHeader() *Parameter { - p.data.Kind = HeaderParameterKind - return p -} - -func (p *Parameter) beForm() *Parameter { - p.data.Kind = FormParameterKind - return p -} - -// Required sets the required field and returns the receiver -func (p *Parameter) Required(required bool) *Parameter { - p.data.Required = required - return p -} - -// AllowMultiple sets the allowMultiple field and returns the receiver -func (p *Parameter) AllowMultiple(multiple bool) *Parameter { - p.data.AllowMultiple = multiple - return p -} - -// AllowableValues sets the allowableValues field and returns the receiver -func (p *Parameter) AllowableValues(values map[string]string) *Parameter { - p.data.AllowableValues = values - return p -} - -// DataType sets the dataType field and returns the receiver -func (p *Parameter) DataType(typeName string) *Parameter { - p.data.DataType = typeName - return p -} - -// DataFormat sets the dataFormat field for Swagger UI -func (p *Parameter) DataFormat(formatName string) *Parameter { - p.data.DataFormat = formatName - return p -} - -// DefaultValue sets the default value field and returns the receiver -func (p *Parameter) DefaultValue(stringRepresentation string) *Parameter { - p.data.DefaultValue = stringRepresentation - return p -} - -// Description sets the description value field and returns the receiver -func (p *Parameter) Description(doc string) *Parameter { - p.data.Description = doc - return p -} - -// CollectionFormat sets the collection format for an array type -func (p *Parameter) CollectionFormat(format CollectionFormat) *Parameter { - p.data.CollectionFormat = format.String() - return p -} diff --git a/vendor/github.com/emicklei/go-restful/path_expression.go b/vendor/github.com/emicklei/go-restful/path_expression.go deleted file mode 100644 index 95a9a2545..000000000 --- a/vendor/github.com/emicklei/go-restful/path_expression.go +++ /dev/null @@ -1,74 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "bytes" - "fmt" - "regexp" - "strings" -) - -// PathExpression holds a compiled path expression (RegExp) needed to match against -// Http request paths and to extract path parameter values. -type pathExpression struct { - LiteralCount int // the number of literal characters (means those not resulting from template variable substitution) - VarNames []string // the names of parameters (enclosed by {}) in the path - VarCount int // the number of named parameters (enclosed by {}) in the path - Matcher *regexp.Regexp - Source string // Path as defined by the RouteBuilder - tokens []string -} - -// NewPathExpression creates a PathExpression from the input URL path. -// Returns an error if the path is invalid. -func newPathExpression(path string) (*pathExpression, error) { - expression, literalCount, varNames, varCount, tokens := templateToRegularExpression(path) - compiled, err := regexp.Compile(expression) - if err != nil { - return nil, err - } - return &pathExpression{literalCount, varNames, varCount, compiled, expression, tokens}, nil -} - -// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-370003.7.3 -func templateToRegularExpression(template string) (expression string, literalCount int, varNames []string, varCount int, tokens []string) { - var buffer bytes.Buffer - buffer.WriteString("^") - //tokens = strings.Split(template, "/") - tokens = tokenizePath(template) - for _, each := range tokens { - if each == "" { - continue - } - buffer.WriteString("/") - if strings.HasPrefix(each, "{") { - // check for regular expression in variable - colon := strings.Index(each, ":") - var varName string - if colon != -1 { - // extract expression - varName = strings.TrimSpace(each[1:colon]) - paramExpr := strings.TrimSpace(each[colon+1 : len(each)-1]) - if paramExpr == "*" { // special case - buffer.WriteString("(.*)") - } else { - buffer.WriteString(fmt.Sprintf("(%s)", paramExpr)) // between colon and closing moustache - } - } else { - // plain var - varName = strings.TrimSpace(each[1 : len(each)-1]) - buffer.WriteString("([^/]+?)") - } - varNames = append(varNames, varName) - varCount += 1 - } else { - literalCount += len(each) - encoded := each // TODO URI encode - buffer.WriteString(regexp.QuoteMeta(encoded)) - } - } - return strings.TrimRight(buffer.String(), "/") + "(/.*)?$", literalCount, varNames, varCount, tokens -} diff --git a/vendor/github.com/emicklei/go-restful/path_processor.go b/vendor/github.com/emicklei/go-restful/path_processor.go deleted file mode 100644 index 357c723a7..000000000 --- a/vendor/github.com/emicklei/go-restful/path_processor.go +++ /dev/null @@ -1,63 +0,0 @@ -package restful - -import ( - "bytes" - "strings" -) - -// Copyright 2018 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -// PathProcessor is extra behaviour that a Router can provide to extract path parameters from the path. -// If a Router does not implement this interface then the default behaviour will be used. -type PathProcessor interface { - // ExtractParameters gets the path parameters defined in the route and webService from the urlPath - ExtractParameters(route *Route, webService *WebService, urlPath string) map[string]string -} - -type defaultPathProcessor struct{} - -// Extract the parameters from the request url path -func (d defaultPathProcessor) ExtractParameters(r *Route, _ *WebService, urlPath string) map[string]string { - urlParts := tokenizePath(urlPath) - pathParameters := map[string]string{} - for i, key := range r.pathParts { - var value string - if i >= len(urlParts) { - value = "" - } else { - value = urlParts[i] - } - if strings.HasPrefix(key, "{") { // path-parameter - if colon := strings.Index(key, ":"); colon != -1 { - // extract by regex - regPart := key[colon+1 : len(key)-1] - keyPart := key[1:colon] - if regPart == "*" { - pathParameters[keyPart] = untokenizePath(i, urlParts) - break - } else { - pathParameters[keyPart] = value - } - } else { - // without enclosing {} - pathParameters[key[1:len(key)-1]] = value - } - } - } - return pathParameters -} - -// Untokenize back into an URL path using the slash separator -func untokenizePath(offset int, parts []string) string { - var buffer bytes.Buffer - for p := offset; p < len(parts); p++ { - buffer.WriteString(parts[p]) - // do not end - if p < len(parts)-1 { - buffer.WriteString("/") - } - } - return buffer.String() -} diff --git a/vendor/github.com/emicklei/go-restful/request.go b/vendor/github.com/emicklei/go-restful/request.go deleted file mode 100644 index 8c23af12c..000000000 --- a/vendor/github.com/emicklei/go-restful/request.go +++ /dev/null @@ -1,113 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "compress/zlib" - "net/http" -) - -var defaultRequestContentType string - -// Request is a wrapper for a http Request that provides convenience methods -type Request struct { - Request *http.Request - pathParameters map[string]string - attributes map[string]interface{} // for storing request-scoped values - selectedRoutePath string // root path + route path that matched the request, e.g. /meetings/{id}/attendees -} - -func NewRequest(httpRequest *http.Request) *Request { - return &Request{ - Request: httpRequest, - pathParameters: map[string]string{}, - attributes: map[string]interface{}{}, - } // empty parameters, attributes -} - -// If ContentType is missing or */* is given then fall back to this type, otherwise -// a "Unable to unmarshal content of type:" response is returned. -// Valid values are restful.MIME_JSON and restful.MIME_XML -// Example: -// restful.DefaultRequestContentType(restful.MIME_JSON) -func DefaultRequestContentType(mime string) { - defaultRequestContentType = mime -} - -// PathParameter accesses the Path parameter value by its name -func (r *Request) PathParameter(name string) string { - return r.pathParameters[name] -} - -// PathParameters accesses the Path parameter values -func (r *Request) PathParameters() map[string]string { - return r.pathParameters -} - -// QueryParameter returns the (first) Query parameter value by its name -func (r *Request) QueryParameter(name string) string { - return r.Request.FormValue(name) -} - -// BodyParameter parses the body of the request (once for typically a POST or a PUT) and returns the value of the given name or an error. -func (r *Request) BodyParameter(name string) (string, error) { - err := r.Request.ParseForm() - if err != nil { - return "", err - } - return r.Request.PostFormValue(name), nil -} - -// HeaderParameter returns the HTTP Header value of a Header name or empty if missing -func (r *Request) HeaderParameter(name string) string { - return r.Request.Header.Get(name) -} - -// ReadEntity checks the Accept header and reads the content into the entityPointer. -func (r *Request) ReadEntity(entityPointer interface{}) (err error) { - contentType := r.Request.Header.Get(HEADER_ContentType) - contentEncoding := r.Request.Header.Get(HEADER_ContentEncoding) - - // check if the request body needs decompression - if ENCODING_GZIP == contentEncoding { - gzipReader := currentCompressorProvider.AcquireGzipReader() - defer currentCompressorProvider.ReleaseGzipReader(gzipReader) - gzipReader.Reset(r.Request.Body) - r.Request.Body = gzipReader - } else if ENCODING_DEFLATE == contentEncoding { - zlibReader, err := zlib.NewReader(r.Request.Body) - if err != nil { - return err - } - r.Request.Body = zlibReader - } - - // lookup the EntityReader, use defaultRequestContentType if needed and provided - entityReader, ok := entityAccessRegistry.accessorAt(contentType) - if !ok { - if len(defaultRequestContentType) != 0 { - entityReader, ok = entityAccessRegistry.accessorAt(defaultRequestContentType) - } - if !ok { - return NewError(http.StatusBadRequest, "Unable to unmarshal content of type:"+contentType) - } - } - return entityReader.Read(r, entityPointer) -} - -// SetAttribute adds or replaces the attribute with the given value. -func (r *Request) SetAttribute(name string, value interface{}) { - r.attributes[name] = value -} - -// Attribute returns the value associated to the given name. Returns nil if absent. -func (r Request) Attribute(name string) interface{} { - return r.attributes[name] -} - -// SelectedRoutePath root path + route path that matched the request, e.g. /meetings/{id}/attendees -func (r Request) SelectedRoutePath() string { - return r.selectedRoutePath -} diff --git a/vendor/github.com/emicklei/go-restful/response.go b/vendor/github.com/emicklei/go-restful/response.go deleted file mode 100644 index 4d987d130..000000000 --- a/vendor/github.com/emicklei/go-restful/response.go +++ /dev/null @@ -1,250 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "bufio" - "errors" - "net" - "net/http" -) - -// DefaultResponseMimeType is DEPRECATED, use DefaultResponseContentType(mime) -var DefaultResponseMimeType string - -//PrettyPrintResponses controls the indentation feature of XML and JSON serialization -var PrettyPrintResponses = true - -// Response is a wrapper on the actual http ResponseWriter -// It provides several convenience methods to prepare and write response content. -type Response struct { - http.ResponseWriter - requestAccept string // mime-type what the Http Request says it wants to receive - routeProduces []string // mime-types what the Route says it can produce - statusCode int // HTTP status code that has been written explicitly (if zero then net/http has written 200) - contentLength int // number of bytes written for the response body - prettyPrint bool // controls the indentation feature of XML and JSON serialization. It is initialized using var PrettyPrintResponses. - err error // err property is kept when WriteError is called - hijacker http.Hijacker // if underlying ResponseWriter supports it -} - -// NewResponse creates a new response based on a http ResponseWriter. -func NewResponse(httpWriter http.ResponseWriter) *Response { - hijacker, _ := httpWriter.(http.Hijacker) - return &Response{ResponseWriter: httpWriter, routeProduces: []string{}, statusCode: http.StatusOK, prettyPrint: PrettyPrintResponses, hijacker: hijacker} -} - -// DefaultResponseContentType set a default. -// If Accept header matching fails, fall back to this type. -// Valid values are restful.MIME_JSON and restful.MIME_XML -// Example: -// restful.DefaultResponseContentType(restful.MIME_JSON) -func DefaultResponseContentType(mime string) { - DefaultResponseMimeType = mime -} - -// InternalServerError writes the StatusInternalServerError header. -// DEPRECATED, use WriteErrorString(http.StatusInternalServerError,reason) -func (r Response) InternalServerError() Response { - r.WriteHeader(http.StatusInternalServerError) - return r -} - -// Hijack implements the http.Hijacker interface. This expands -// the Response to fulfill http.Hijacker if the underlying -// http.ResponseWriter supports it. -func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) { - if r.hijacker == nil { - return nil, nil, errors.New("http.Hijacker not implemented by underlying http.ResponseWriter") - } - return r.hijacker.Hijack() -} - -// PrettyPrint changes whether this response must produce pretty (line-by-line, indented) JSON or XML output. -func (r *Response) PrettyPrint(bePretty bool) { - r.prettyPrint = bePretty -} - -// AddHeader is a shortcut for .Header().Add(header,value) -func (r Response) AddHeader(header string, value string) Response { - r.Header().Add(header, value) - return r -} - -// SetRequestAccepts tells the response what Mime-type(s) the HTTP request said it wants to accept. Exposed for testing. -func (r *Response) SetRequestAccepts(mime string) { - r.requestAccept = mime -} - -// EntityWriter returns the registered EntityWriter that the entity (requested resource) -// can write according to what the request wants (Accept) and what the Route can produce or what the restful defaults say. -// If called before WriteEntity and WriteHeader then a false return value can be used to write a 406: Not Acceptable. -func (r *Response) EntityWriter() (EntityReaderWriter, bool) { - sorted := sortedMimes(r.requestAccept) - for _, eachAccept := range sorted { - for _, eachProduce := range r.routeProduces { - if eachProduce == eachAccept.media { - if w, ok := entityAccessRegistry.accessorAt(eachAccept.media); ok { - return w, true - } - } - } - if eachAccept.media == "*/*" { - for _, each := range r.routeProduces { - if w, ok := entityAccessRegistry.accessorAt(each); ok { - return w, true - } - } - } - } - // if requestAccept is empty - writer, ok := entityAccessRegistry.accessorAt(r.requestAccept) - if !ok { - // if not registered then fallback to the defaults (if set) - if DefaultResponseMimeType == MIME_JSON { - return entityAccessRegistry.accessorAt(MIME_JSON) - } - if DefaultResponseMimeType == MIME_XML { - return entityAccessRegistry.accessorAt(MIME_XML) - } - // Fallback to whatever the route says it can produce. - // https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html - for _, each := range r.routeProduces { - if w, ok := entityAccessRegistry.accessorAt(each); ok { - return w, true - } - } - if trace { - traceLogger.Printf("no registered EntityReaderWriter found for %s", r.requestAccept) - } - } - return writer, ok -} - -// WriteEntity calls WriteHeaderAndEntity with Http Status OK (200) -func (r *Response) WriteEntity(value interface{}) error { - return r.WriteHeaderAndEntity(http.StatusOK, value) -} - -// WriteHeaderAndEntity marshals the value using the representation denoted by the Accept Header and the registered EntityWriters. -// If no Accept header is specified (or */*) then respond with the Content-Type as specified by the first in the Route.Produces. -// If an Accept header is specified then respond with the Content-Type as specified by the first in the Route.Produces that is matched with the Accept header. -// If the value is nil then no response is send except for the Http status. You may want to call WriteHeader(http.StatusNotFound) instead. -// If there is no writer available that can represent the value in the requested MIME type then Http Status NotAcceptable is written. -// Current implementation ignores any q-parameters in the Accept Header. -// Returns an error if the value could not be written on the response. -func (r *Response) WriteHeaderAndEntity(status int, value interface{}) error { - writer, ok := r.EntityWriter() - if !ok { - r.WriteHeader(http.StatusNotAcceptable) - return nil - } - return writer.Write(r, status, value) -} - -// WriteAsXml is a convenience method for writing a value in xml (requires Xml tags on the value) -// It uses the standard encoding/xml package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteAsXml(value interface{}) error { - return writeXML(r, http.StatusOK, MIME_XML, value) -} - -// WriteHeaderAndXml is a convenience method for writing a status and value in xml (requires Xml tags on the value) -// It uses the standard encoding/xml package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteHeaderAndXml(status int, value interface{}) error { - return writeXML(r, status, MIME_XML, value) -} - -// WriteAsJson is a convenience method for writing a value in json. -// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteAsJson(value interface{}) error { - return writeJSON(r, http.StatusOK, MIME_JSON, value) -} - -// WriteJson is a convenience method for writing a value in Json with a given Content-Type. -// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteJson(value interface{}, contentType string) error { - return writeJSON(r, http.StatusOK, contentType, value) -} - -// WriteHeaderAndJson is a convenience method for writing the status and a value in Json with a given Content-Type. -// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteHeaderAndJson(status int, value interface{}, contentType string) error { - return writeJSON(r, status, contentType, value) -} - -// WriteError write the http status and the error string on the response. -func (r *Response) WriteError(httpStatus int, err error) error { - r.err = err - return r.WriteErrorString(httpStatus, err.Error()) -} - -// WriteServiceError is a convenience method for a responding with a status and a ServiceError -func (r *Response) WriteServiceError(httpStatus int, err ServiceError) error { - r.err = err - return r.WriteHeaderAndEntity(httpStatus, err) -} - -// WriteErrorString is a convenience method for an error status with the actual error -func (r *Response) WriteErrorString(httpStatus int, errorReason string) error { - if r.err == nil { - // if not called from WriteError - r.err = errors.New(errorReason) - } - r.WriteHeader(httpStatus) - if _, err := r.Write([]byte(errorReason)); err != nil { - return err - } - return nil -} - -// Flush implements http.Flusher interface, which sends any buffered data to the client. -func (r *Response) Flush() { - if f, ok := r.ResponseWriter.(http.Flusher); ok { - f.Flush() - } else if trace { - traceLogger.Printf("ResponseWriter %v doesn't support Flush", r) - } -} - -// WriteHeader is overridden to remember the Status Code that has been written. -// Changes to the Header of the response have no effect after this. -func (r *Response) WriteHeader(httpStatus int) { - r.statusCode = httpStatus - r.ResponseWriter.WriteHeader(httpStatus) -} - -// StatusCode returns the code that has been written using WriteHeader. -func (r Response) StatusCode() int { - if 0 == r.statusCode { - // no status code has been written yet; assume OK - return http.StatusOK - } - return r.statusCode -} - -// Write writes the data to the connection as part of an HTTP reply. -// Write is part of http.ResponseWriter interface. -func (r *Response) Write(bytes []byte) (int, error) { - written, err := r.ResponseWriter.Write(bytes) - r.contentLength += written - return written, err -} - -// ContentLength returns the number of bytes written for the response content. -// Note that this value is only correct if all data is written through the Response using its Write* methods. -// Data written directly using the underlying http.ResponseWriter is not accounted for. -func (r Response) ContentLength() int { - return r.contentLength -} - -// CloseNotify is part of http.CloseNotifier interface -func (r Response) CloseNotify() <-chan bool { - return r.ResponseWriter.(http.CloseNotifier).CloseNotify() -} - -// Error returns the err created by WriteError -func (r Response) Error() error { - return r.err -} diff --git a/vendor/github.com/emicklei/go-restful/route.go b/vendor/github.com/emicklei/go-restful/route.go deleted file mode 100644 index f72bf9850..000000000 --- a/vendor/github.com/emicklei/go-restful/route.go +++ /dev/null @@ -1,149 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "net/http" - "strings" -) - -// RouteFunction declares the signature of a function that can be bound to a Route. -type RouteFunction func(*Request, *Response) - -// RouteSelectionConditionFunction declares the signature of a function that -// can be used to add extra conditional logic when selecting whether the route -// matches the HTTP request. -type RouteSelectionConditionFunction func(httpRequest *http.Request) bool - -// Route binds a HTTP Method,Path,Consumes combination to a RouteFunction. -type Route struct { - Method string - Produces []string - Consumes []string - Path string // webservice root path + described path - Function RouteFunction - Filters []FilterFunction - If []RouteSelectionConditionFunction - - // cached values for dispatching - relativePath string - pathParts []string - pathExpr *pathExpression // cached compilation of relativePath as RegExp - - // documentation - Doc string - Notes string - Operation string - ParameterDocs []*Parameter - ResponseErrors map[int]ResponseError - ReadSample, WriteSample interface{} // structs that model an example request or response payload - - // Extra information used to store custom information about the route. - Metadata map[string]interface{} - - // marks a route as deprecated - Deprecated bool -} - -// Initialize for Route -func (r *Route) postBuild() { - r.pathParts = tokenizePath(r.Path) -} - -// Create Request and Response from their http versions -func (r *Route) wrapRequestResponse(httpWriter http.ResponseWriter, httpRequest *http.Request, pathParams map[string]string) (*Request, *Response) { - wrappedRequest := NewRequest(httpRequest) - wrappedRequest.pathParameters = pathParams - wrappedRequest.selectedRoutePath = r.Path - wrappedResponse := NewResponse(httpWriter) - wrappedResponse.requestAccept = httpRequest.Header.Get(HEADER_Accept) - wrappedResponse.routeProduces = r.Produces - return wrappedRequest, wrappedResponse -} - -// dispatchWithFilters call the function after passing through its own filters -func (r *Route) dispatchWithFilters(wrappedRequest *Request, wrappedResponse *Response) { - if len(r.Filters) > 0 { - chain := FilterChain{Filters: r.Filters, Target: r.Function} - chain.ProcessFilter(wrappedRequest, wrappedResponse) - } else { - // unfiltered - r.Function(wrappedRequest, wrappedResponse) - } -} - -// Return whether the mimeType matches to what this Route can produce. -func (r Route) matchesAccept(mimeTypesWithQuality string) bool { - parts := strings.Split(mimeTypesWithQuality, ",") - for _, each := range parts { - var withoutQuality string - if strings.Contains(each, ";") { - withoutQuality = strings.Split(each, ";")[0] - } else { - withoutQuality = each - } - // trim before compare - withoutQuality = strings.Trim(withoutQuality, " ") - if withoutQuality == "*/*" { - return true - } - for _, producibleType := range r.Produces { - if producibleType == "*/*" || producibleType == withoutQuality { - return true - } - } - } - return false -} - -// Return whether this Route can consume content with a type specified by mimeTypes (can be empty). -func (r Route) matchesContentType(mimeTypes string) bool { - - if len(r.Consumes) == 0 { - // did not specify what it can consume ; any media type (“*/*”) is assumed - return true - } - - if len(mimeTypes) == 0 { - // idempotent methods with (most-likely or guaranteed) empty content match missing Content-Type - m := r.Method - if m == "GET" || m == "HEAD" || m == "OPTIONS" || m == "DELETE" || m == "TRACE" { - return true - } - // proceed with default - mimeTypes = MIME_OCTET - } - - parts := strings.Split(mimeTypes, ",") - for _, each := range parts { - var contentType string - if strings.Contains(each, ";") { - contentType = strings.Split(each, ";")[0] - } else { - contentType = each - } - // trim before compare - contentType = strings.Trim(contentType, " ") - for _, consumeableType := range r.Consumes { - if consumeableType == "*/*" || consumeableType == contentType { - return true - } - } - } - return false -} - -// Tokenize an URL path using the slash separator ; the result does not have empty tokens -func tokenizePath(path string) []string { - if "/" == path { - return []string{} - } - return strings.Split(strings.Trim(path, "/"), "/") -} - -// for debugging -func (r Route) String() string { - return r.Method + " " + r.Path -} diff --git a/vendor/github.com/emicklei/go-restful/route_builder.go b/vendor/github.com/emicklei/go-restful/route_builder.go deleted file mode 100644 index 4ebecbd8c..000000000 --- a/vendor/github.com/emicklei/go-restful/route_builder.go +++ /dev/null @@ -1,321 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "fmt" - "os" - "reflect" - "runtime" - "strings" - "sync/atomic" - - "github.com/emicklei/go-restful/log" -) - -// RouteBuilder is a helper to construct Routes. -type RouteBuilder struct { - rootPath string - currentPath string - produces []string - consumes []string - httpMethod string // required - function RouteFunction // required - filters []FilterFunction - conditions []RouteSelectionConditionFunction - - typeNameHandleFunc TypeNameHandleFunction // required - - // documentation - doc string - notes string - operation string - readSample, writeSample interface{} - parameters []*Parameter - errorMap map[int]ResponseError - metadata map[string]interface{} - deprecated bool -} - -// Do evaluates each argument with the RouteBuilder itself. -// This allows you to follow DRY principles without breaking the fluent programming style. -// Example: -// ws.Route(ws.DELETE("/{name}").To(t.deletePerson).Do(Returns200, Returns500)) -// -// func Returns500(b *RouteBuilder) { -// b.Returns(500, "Internal Server Error", restful.ServiceError{}) -// } -func (b *RouteBuilder) Do(oneArgBlocks ...func(*RouteBuilder)) *RouteBuilder { - for _, each := range oneArgBlocks { - each(b) - } - return b -} - -// To bind the route to a function. -// If this route is matched with the incoming Http Request then call this function with the *Request,*Response pair. Required. -func (b *RouteBuilder) To(function RouteFunction) *RouteBuilder { - b.function = function - return b -} - -// Method specifies what HTTP method to match. Required. -func (b *RouteBuilder) Method(method string) *RouteBuilder { - b.httpMethod = method - return b -} - -// Produces specifies what MIME types can be produced ; the matched one will appear in the Content-Type Http header. -func (b *RouteBuilder) Produces(mimeTypes ...string) *RouteBuilder { - b.produces = mimeTypes - return b -} - -// Consumes specifies what MIME types can be consumes ; the Accept Http header must matched any of these -func (b *RouteBuilder) Consumes(mimeTypes ...string) *RouteBuilder { - b.consumes = mimeTypes - return b -} - -// Path specifies the relative (w.r.t WebService root path) URL path to match. Default is "/". -func (b *RouteBuilder) Path(subPath string) *RouteBuilder { - b.currentPath = subPath - return b -} - -// Doc tells what this route is all about. Optional. -func (b *RouteBuilder) Doc(documentation string) *RouteBuilder { - b.doc = documentation - return b -} - -// Notes is a verbose explanation of the operation behavior. Optional. -func (b *RouteBuilder) Notes(notes string) *RouteBuilder { - b.notes = notes - return b -} - -// Reads tells what resource type will be read from the request payload. Optional. -// A parameter of type "body" is added ,required is set to true and the dataType is set to the qualified name of the sample's type. -func (b *RouteBuilder) Reads(sample interface{}, optionalDescription ...string) *RouteBuilder { - fn := b.typeNameHandleFunc - if fn == nil { - fn = reflectTypeName - } - typeAsName := fn(sample) - description := "" - if len(optionalDescription) > 0 { - description = optionalDescription[0] - } - b.readSample = sample - bodyParameter := &Parameter{&ParameterData{Name: "body", Description: description}} - bodyParameter.beBody() - bodyParameter.Required(true) - bodyParameter.DataType(typeAsName) - b.Param(bodyParameter) - return b -} - -// ParameterNamed returns a Parameter already known to the RouteBuilder. Returns nil if not. -// Use this to modify or extend information for the Parameter (through its Data()). -func (b RouteBuilder) ParameterNamed(name string) (p *Parameter) { - for _, each := range b.parameters { - if each.Data().Name == name { - return each - } - } - return p -} - -// Writes tells what resource type will be written as the response payload. Optional. -func (b *RouteBuilder) Writes(sample interface{}) *RouteBuilder { - b.writeSample = sample - return b -} - -// Param allows you to document the parameters of the Route. It adds a new Parameter (does not check for duplicates). -func (b *RouteBuilder) Param(parameter *Parameter) *RouteBuilder { - if b.parameters == nil { - b.parameters = []*Parameter{} - } - b.parameters = append(b.parameters, parameter) - return b -} - -// Operation allows you to document what the actual method/function call is of the Route. -// Unless called, the operation name is derived from the RouteFunction set using To(..). -func (b *RouteBuilder) Operation(name string) *RouteBuilder { - b.operation = name - return b -} - -// ReturnsError is deprecated, use Returns instead. -func (b *RouteBuilder) ReturnsError(code int, message string, model interface{}) *RouteBuilder { - log.Print("ReturnsError is deprecated, use Returns instead.") - return b.Returns(code, message, model) -} - -// Returns allows you to document what responses (errors or regular) can be expected. -// The model parameter is optional ; either pass a struct instance or use nil if not applicable. -func (b *RouteBuilder) Returns(code int, message string, model interface{}) *RouteBuilder { - err := ResponseError{ - Code: code, - Message: message, - Model: model, - IsDefault: false, - } - // lazy init because there is no NewRouteBuilder (yet) - if b.errorMap == nil { - b.errorMap = map[int]ResponseError{} - } - b.errorMap[code] = err - return b -} - -// DefaultReturns is a special Returns call that sets the default of the response ; the code is zero. -func (b *RouteBuilder) DefaultReturns(message string, model interface{}) *RouteBuilder { - b.Returns(0, message, model) - // Modify the ResponseError just added/updated - re := b.errorMap[0] - // errorMap is initialized - b.errorMap[0] = ResponseError{ - Code: re.Code, - Message: re.Message, - Model: re.Model, - IsDefault: true, - } - return b -} - -// Metadata adds or updates a key=value pair to the metadata map. -func (b *RouteBuilder) Metadata(key string, value interface{}) *RouteBuilder { - if b.metadata == nil { - b.metadata = map[string]interface{}{} - } - b.metadata[key] = value - return b -} - -// Deprecate sets the value of deprecated to true. Deprecated routes have a special UI treatment to warn against use -func (b *RouteBuilder) Deprecate() *RouteBuilder { - b.deprecated = true - return b -} - -// ResponseError represents a response; not necessarily an error. -type ResponseError struct { - Code int - Message string - Model interface{} - IsDefault bool -} - -func (b *RouteBuilder) servicePath(path string) *RouteBuilder { - b.rootPath = path - return b -} - -// Filter appends a FilterFunction to the end of filters for this Route to build. -func (b *RouteBuilder) Filter(filter FilterFunction) *RouteBuilder { - b.filters = append(b.filters, filter) - return b -} - -// If sets a condition function that controls matching the Route based on custom logic. -// The condition function is provided the HTTP request and should return true if the route -// should be considered. -// -// Efficiency note: the condition function is called before checking the method, produces, and -// consumes criteria, so that the correct HTTP status code can be returned. -// -// Lifecycle note: no filter functions have been called prior to calling the condition function, -// so the condition function should not depend on any context that might be set up by container -// or route filters. -func (b *RouteBuilder) If(condition RouteSelectionConditionFunction) *RouteBuilder { - b.conditions = append(b.conditions, condition) - return b -} - -// If no specific Route path then set to rootPath -// If no specific Produces then set to rootProduces -// If no specific Consumes then set to rootConsumes -func (b *RouteBuilder) copyDefaults(rootProduces, rootConsumes []string) { - if len(b.produces) == 0 { - b.produces = rootProduces - } - if len(b.consumes) == 0 { - b.consumes = rootConsumes - } -} - -// typeNameHandler sets the function that will convert types to strings in the parameter -// and model definitions. -func (b *RouteBuilder) typeNameHandler(handler TypeNameHandleFunction) *RouteBuilder { - b.typeNameHandleFunc = handler - return b -} - -// Build creates a new Route using the specification details collected by the RouteBuilder -func (b *RouteBuilder) Build() Route { - pathExpr, err := newPathExpression(b.currentPath) - if err != nil { - log.Printf("[restful] Invalid path:%s because:%v", b.currentPath, err) - os.Exit(1) - } - if b.function == nil { - log.Printf("[restful] No function specified for route:" + b.currentPath) - os.Exit(1) - } - operationName := b.operation - if len(operationName) == 0 && b.function != nil { - // extract from definition - operationName = nameOfFunction(b.function) - } - route := Route{ - Method: b.httpMethod, - Path: concatPath(b.rootPath, b.currentPath), - Produces: b.produces, - Consumes: b.consumes, - Function: b.function, - Filters: b.filters, - If: b.conditions, - relativePath: b.currentPath, - pathExpr: pathExpr, - Doc: b.doc, - Notes: b.notes, - Operation: operationName, - ParameterDocs: b.parameters, - ResponseErrors: b.errorMap, - ReadSample: b.readSample, - WriteSample: b.writeSample, - Metadata: b.metadata, - Deprecated: b.deprecated} - route.postBuild() - return route -} - -func concatPath(path1, path2 string) string { - return strings.TrimRight(path1, "/") + "/" + strings.TrimLeft(path2, "/") -} - -var anonymousFuncCount int32 - -// nameOfFunction returns the short name of the function f for documentation. -// It uses a runtime feature for debugging ; its value may change for later Go versions. -func nameOfFunction(f interface{}) string { - fun := runtime.FuncForPC(reflect.ValueOf(f).Pointer()) - tokenized := strings.Split(fun.Name(), ".") - last := tokenized[len(tokenized)-1] - last = strings.TrimSuffix(last, ")·fm") // < Go 1.5 - last = strings.TrimSuffix(last, ")-fm") // Go 1.5 - last = strings.TrimSuffix(last, "·fm") // < Go 1.5 - last = strings.TrimSuffix(last, "-fm") // Go 1.5 - if last == "func1" { // this could mean conflicts in API docs - val := atomic.AddInt32(&anonymousFuncCount, 1) - last = "func" + fmt.Sprintf("%d", val) - atomic.StoreInt32(&anonymousFuncCount, val) - } - return last -} diff --git a/vendor/github.com/emicklei/go-restful/router.go b/vendor/github.com/emicklei/go-restful/router.go deleted file mode 100644 index 19078af1c..000000000 --- a/vendor/github.com/emicklei/go-restful/router.go +++ /dev/null @@ -1,20 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import "net/http" - -// A RouteSelector finds the best matching Route given the input HTTP Request -// RouteSelectors can optionally also implement the PathProcessor interface to also calculate the -// path parameters after the route has been selected. -type RouteSelector interface { - - // SelectRoute finds a Route given the input HTTP Request and a list of WebServices. - // It returns a selected Route and its containing WebService or an error indicating - // a problem. - SelectRoute( - webServices []*WebService, - httpRequest *http.Request) (selectedService *WebService, selected *Route, err error) -} diff --git a/vendor/github.com/emicklei/go-restful/service_error.go b/vendor/github.com/emicklei/go-restful/service_error.go deleted file mode 100644 index 62d1108bb..000000000 --- a/vendor/github.com/emicklei/go-restful/service_error.go +++ /dev/null @@ -1,23 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import "fmt" - -// ServiceError is a transport object to pass information about a non-Http error occurred in a WebService while processing a request. -type ServiceError struct { - Code int - Message string -} - -// NewError returns a ServiceError using the code and reason -func NewError(code int, message string) ServiceError { - return ServiceError{Code: code, Message: message} -} - -// Error returns a text representation of the service error -func (s ServiceError) Error() string { - return fmt.Sprintf("[ServiceError:%v] %v", s.Code, s.Message) -} diff --git a/vendor/github.com/emicklei/go-restful/web_service.go b/vendor/github.com/emicklei/go-restful/web_service.go deleted file mode 100644 index f7e18a585..000000000 --- a/vendor/github.com/emicklei/go-restful/web_service.go +++ /dev/null @@ -1,290 +0,0 @@ -package restful - -import ( - "errors" - "os" - "reflect" - "sync" - - "github.com/emicklei/go-restful/log" -) - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -// WebService holds a collection of Route values that bind a Http Method + URL Path to a function. -type WebService struct { - rootPath string - pathExpr *pathExpression // cached compilation of rootPath as RegExp - routes []Route - produces []string - consumes []string - pathParameters []*Parameter - filters []FilterFunction - documentation string - apiVersion string - - typeNameHandleFunc TypeNameHandleFunction - - dynamicRoutes bool - - // protects 'routes' if dynamic routes are enabled - routesLock sync.RWMutex -} - -func (w *WebService) SetDynamicRoutes(enable bool) { - w.dynamicRoutes = enable -} - -// TypeNameHandleFunction declares functions that can handle translating the name of a sample object -// into the restful documentation for the service. -type TypeNameHandleFunction func(sample interface{}) string - -// TypeNameHandler sets the function that will convert types to strings in the parameter -// and model definitions. If not set, the web service will invoke -// reflect.TypeOf(object).String(). -func (w *WebService) TypeNameHandler(handler TypeNameHandleFunction) *WebService { - w.typeNameHandleFunc = handler - return w -} - -// reflectTypeName is the default TypeNameHandleFunction and for a given object -// returns the name that Go identifies it with (e.g. "string" or "v1.Object") via -// the reflection API. -func reflectTypeName(sample interface{}) string { - return reflect.TypeOf(sample).String() -} - -// compilePathExpression ensures that the path is compiled into a RegEx for those routers that need it. -func (w *WebService) compilePathExpression() { - compiled, err := newPathExpression(w.rootPath) - if err != nil { - log.Printf("[restful] invalid path:%s because:%v", w.rootPath, err) - os.Exit(1) - } - w.pathExpr = compiled -} - -// ApiVersion sets the API version for documentation purposes. -func (w *WebService) ApiVersion(apiVersion string) *WebService { - w.apiVersion = apiVersion - return w -} - -// Version returns the API version for documentation purposes. -func (w *WebService) Version() string { return w.apiVersion } - -// Path specifies the root URL template path of the WebService. -// All Routes will be relative to this path. -func (w *WebService) Path(root string) *WebService { - w.rootPath = root - if len(w.rootPath) == 0 { - w.rootPath = "/" - } - w.compilePathExpression() - return w -} - -// Param adds a PathParameter to document parameters used in the root path. -func (w *WebService) Param(parameter *Parameter) *WebService { - if w.pathParameters == nil { - w.pathParameters = []*Parameter{} - } - w.pathParameters = append(w.pathParameters, parameter) - return w -} - -// PathParameter creates a new Parameter of kind Path for documentation purposes. -// It is initialized as required with string as its DataType. -func (w *WebService) PathParameter(name, description string) *Parameter { - return PathParameter(name, description) -} - -// PathParameter creates a new Parameter of kind Path for documentation purposes. -// It is initialized as required with string as its DataType. -func PathParameter(name, description string) *Parameter { - p := &Parameter{&ParameterData{Name: name, Description: description, Required: true, DataType: "string"}} - p.bePath() - return p -} - -// QueryParameter creates a new Parameter of kind Query for documentation purposes. -// It is initialized as not required with string as its DataType. -func (w *WebService) QueryParameter(name, description string) *Parameter { - return QueryParameter(name, description) -} - -// QueryParameter creates a new Parameter of kind Query for documentation purposes. -// It is initialized as not required with string as its DataType. -func QueryParameter(name, description string) *Parameter { - p := &Parameter{&ParameterData{Name: name, Description: description, Required: false, DataType: "string", CollectionFormat: CollectionFormatCSV.String()}} - p.beQuery() - return p -} - -// BodyParameter creates a new Parameter of kind Body for documentation purposes. -// It is initialized as required without a DataType. -func (w *WebService) BodyParameter(name, description string) *Parameter { - return BodyParameter(name, description) -} - -// BodyParameter creates a new Parameter of kind Body for documentation purposes. -// It is initialized as required without a DataType. -func BodyParameter(name, description string) *Parameter { - p := &Parameter{&ParameterData{Name: name, Description: description, Required: true}} - p.beBody() - return p -} - -// HeaderParameter creates a new Parameter of kind (Http) Header for documentation purposes. -// It is initialized as not required with string as its DataType. -func (w *WebService) HeaderParameter(name, description string) *Parameter { - return HeaderParameter(name, description) -} - -// HeaderParameter creates a new Parameter of kind (Http) Header for documentation purposes. -// It is initialized as not required with string as its DataType. -func HeaderParameter(name, description string) *Parameter { - p := &Parameter{&ParameterData{Name: name, Description: description, Required: false, DataType: "string"}} - p.beHeader() - return p -} - -// FormParameter creates a new Parameter of kind Form (using application/x-www-form-urlencoded) for documentation purposes. -// It is initialized as required with string as its DataType. -func (w *WebService) FormParameter(name, description string) *Parameter { - return FormParameter(name, description) -} - -// FormParameter creates a new Parameter of kind Form (using application/x-www-form-urlencoded) for documentation purposes. -// It is initialized as required with string as its DataType. -func FormParameter(name, description string) *Parameter { - p := &Parameter{&ParameterData{Name: name, Description: description, Required: false, DataType: "string"}} - p.beForm() - return p -} - -// Route creates a new Route using the RouteBuilder and add to the ordered list of Routes. -func (w *WebService) Route(builder *RouteBuilder) *WebService { - w.routesLock.Lock() - defer w.routesLock.Unlock() - builder.copyDefaults(w.produces, w.consumes) - w.routes = append(w.routes, builder.Build()) - return w -} - -// RemoveRoute removes the specified route, looks for something that matches 'path' and 'method' -func (w *WebService) RemoveRoute(path, method string) error { - if !w.dynamicRoutes { - return errors.New("dynamic routes are not enabled.") - } - w.routesLock.Lock() - defer w.routesLock.Unlock() - newRoutes := make([]Route, (len(w.routes) - 1)) - current := 0 - for ix := range w.routes { - if w.routes[ix].Method == method && w.routes[ix].Path == path { - continue - } - newRoutes[current] = w.routes[ix] - current = current + 1 - } - w.routes = newRoutes - return nil -} - -// Method creates a new RouteBuilder and initialize its http method -func (w *WebService) Method(httpMethod string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method(httpMethod) -} - -// Produces specifies that this WebService can produce one or more MIME types. -// Http requests must have one of these values set for the Accept header. -func (w *WebService) Produces(contentTypes ...string) *WebService { - w.produces = contentTypes - return w -} - -// Consumes specifies that this WebService can consume one or more MIME types. -// Http requests must have one of these values set for the Content-Type header. -func (w *WebService) Consumes(accepts ...string) *WebService { - w.consumes = accepts - return w -} - -// Routes returns the Routes associated with this WebService -func (w *WebService) Routes() []Route { - if !w.dynamicRoutes { - return w.routes - } - // Make a copy of the array to prevent concurrency problems - w.routesLock.RLock() - defer w.routesLock.RUnlock() - result := make([]Route, len(w.routes)) - for ix := range w.routes { - result[ix] = w.routes[ix] - } - return result -} - -// RootPath returns the RootPath associated with this WebService. Default "/" -func (w *WebService) RootPath() string { - return w.rootPath -} - -// PathParameters return the path parameter names for (shared among its Routes) -func (w *WebService) PathParameters() []*Parameter { - return w.pathParameters -} - -// Filter adds a filter function to the chain of filters applicable to all its Routes -func (w *WebService) Filter(filter FilterFunction) *WebService { - w.filters = append(w.filters, filter) - return w -} - -// Doc is used to set the documentation of this service. -func (w *WebService) Doc(plainText string) *WebService { - w.documentation = plainText - return w -} - -// Documentation returns it. -func (w *WebService) Documentation() string { - return w.documentation -} - -/* - Convenience methods -*/ - -// HEAD is a shortcut for .Method("HEAD").Path(subPath) -func (w *WebService) HEAD(subPath string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("HEAD").Path(subPath) -} - -// GET is a shortcut for .Method("GET").Path(subPath) -func (w *WebService) GET(subPath string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("GET").Path(subPath) -} - -// POST is a shortcut for .Method("POST").Path(subPath) -func (w *WebService) POST(subPath string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("POST").Path(subPath) -} - -// PUT is a shortcut for .Method("PUT").Path(subPath) -func (w *WebService) PUT(subPath string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("PUT").Path(subPath) -} - -// PATCH is a shortcut for .Method("PATCH").Path(subPath) -func (w *WebService) PATCH(subPath string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("PATCH").Path(subPath) -} - -// DELETE is a shortcut for .Method("DELETE").Path(subPath) -func (w *WebService) DELETE(subPath string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("DELETE").Path(subPath) -} diff --git a/vendor/github.com/emicklei/go-restful/web_service_container.go b/vendor/github.com/emicklei/go-restful/web_service_container.go deleted file mode 100644 index c9d31b06c..000000000 --- a/vendor/github.com/emicklei/go-restful/web_service_container.go +++ /dev/null @@ -1,39 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "net/http" -) - -// DefaultContainer is a restful.Container that uses http.DefaultServeMux -var DefaultContainer *Container - -func init() { - DefaultContainer = NewContainer() - DefaultContainer.ServeMux = http.DefaultServeMux -} - -// If set the true then panics will not be caught to return HTTP 500. -// In that case, Route functions are responsible for handling any error situation. -// Default value is false = recover from panics. This has performance implications. -// OBSOLETE ; use restful.DefaultContainer.DoNotRecover(true) -var DoNotRecover = false - -// Add registers a new WebService add it to the DefaultContainer. -func Add(service *WebService) { - DefaultContainer.Add(service) -} - -// Filter appends a container FilterFunction from the DefaultContainer. -// These are called before dispatching a http.Request to a WebService. -func Filter(filter FilterFunction) { - DefaultContainer.Filter(filter) -} - -// RegisteredWebServices returns the collections of WebServices from the DefaultContainer -func RegisteredWebServices() []*WebService { - return DefaultContainer.RegisteredWebServices() -} diff --git a/vendor/github.com/evanphx/json-patch/LICENSE b/vendor/github.com/evanphx/json-patch/LICENSE deleted file mode 100644 index 0eb9b72d8..000000000 --- a/vendor/github.com/evanphx/json-patch/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2014, Evan Phoenix -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -* Neither the name of the Evan Phoenix nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/evanphx/json-patch/merge.go b/vendor/github.com/evanphx/json-patch/merge.go deleted file mode 100644 index 6806c4c20..000000000 --- a/vendor/github.com/evanphx/json-patch/merge.go +++ /dev/null @@ -1,383 +0,0 @@ -package jsonpatch - -import ( - "bytes" - "encoding/json" - "fmt" - "reflect" -) - -func merge(cur, patch *lazyNode, mergeMerge bool) *lazyNode { - curDoc, err := cur.intoDoc() - - if err != nil { - pruneNulls(patch) - return patch - } - - patchDoc, err := patch.intoDoc() - - if err != nil { - return patch - } - - mergeDocs(curDoc, patchDoc, mergeMerge) - - return cur -} - -func mergeDocs(doc, patch *partialDoc, mergeMerge bool) { - for k, v := range *patch { - if v == nil { - if mergeMerge { - (*doc)[k] = nil - } else { - delete(*doc, k) - } - } else { - cur, ok := (*doc)[k] - - if !ok || cur == nil { - pruneNulls(v) - (*doc)[k] = v - } else { - (*doc)[k] = merge(cur, v, mergeMerge) - } - } - } -} - -func pruneNulls(n *lazyNode) { - sub, err := n.intoDoc() - - if err == nil { - pruneDocNulls(sub) - } else { - ary, err := n.intoAry() - - if err == nil { - pruneAryNulls(ary) - } - } -} - -func pruneDocNulls(doc *partialDoc) *partialDoc { - for k, v := range *doc { - if v == nil { - delete(*doc, k) - } else { - pruneNulls(v) - } - } - - return doc -} - -func pruneAryNulls(ary *partialArray) *partialArray { - newAry := []*lazyNode{} - - for _, v := range *ary { - if v != nil { - pruneNulls(v) - newAry = append(newAry, v) - } - } - - *ary = newAry - - return ary -} - -var errBadJSONDoc = fmt.Errorf("Invalid JSON Document") -var errBadJSONPatch = fmt.Errorf("Invalid JSON Patch") -var errBadMergeTypes = fmt.Errorf("Mismatched JSON Documents") - -// MergeMergePatches merges two merge patches together, such that -// applying this resulting merged merge patch to a document yields the same -// as merging each merge patch to the document in succession. -func MergeMergePatches(patch1Data, patch2Data []byte) ([]byte, error) { - return doMergePatch(patch1Data, patch2Data, true) -} - -// MergePatch merges the patchData into the docData. -func MergePatch(docData, patchData []byte) ([]byte, error) { - return doMergePatch(docData, patchData, false) -} - -func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) { - doc := &partialDoc{} - - docErr := json.Unmarshal(docData, doc) - - patch := &partialDoc{} - - patchErr := json.Unmarshal(patchData, patch) - - if _, ok := docErr.(*json.SyntaxError); ok { - return nil, errBadJSONDoc - } - - if _, ok := patchErr.(*json.SyntaxError); ok { - return nil, errBadJSONPatch - } - - if docErr == nil && *doc == nil { - return nil, errBadJSONDoc - } - - if patchErr == nil && *patch == nil { - return nil, errBadJSONPatch - } - - if docErr != nil || patchErr != nil { - // Not an error, just not a doc, so we turn straight into the patch - if patchErr == nil { - if mergeMerge { - doc = patch - } else { - doc = pruneDocNulls(patch) - } - } else { - patchAry := &partialArray{} - patchErr = json.Unmarshal(patchData, patchAry) - - if patchErr != nil { - return nil, errBadJSONPatch - } - - pruneAryNulls(patchAry) - - out, patchErr := json.Marshal(patchAry) - - if patchErr != nil { - return nil, errBadJSONPatch - } - - return out, nil - } - } else { - mergeDocs(doc, patch, mergeMerge) - } - - return json.Marshal(doc) -} - -// resemblesJSONArray indicates whether the byte-slice "appears" to be -// a JSON array or not. -// False-positives are possible, as this function does not check the internal -// structure of the array. It only checks that the outer syntax is present and -// correct. -func resemblesJSONArray(input []byte) bool { - input = bytes.TrimSpace(input) - - hasPrefix := bytes.HasPrefix(input, []byte("[")) - hasSuffix := bytes.HasSuffix(input, []byte("]")) - - return hasPrefix && hasSuffix -} - -// CreateMergePatch will return a merge patch document capable of converting -// the original document(s) to the modified document(s). -// The parameters can be bytes of either two JSON Documents, or two arrays of -// JSON documents. -// The merge patch returned follows the specification defined at http://tools.ietf.org/html/draft-ietf-appsawg-json-merge-patch-07 -func CreateMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) { - originalResemblesArray := resemblesJSONArray(originalJSON) - modifiedResemblesArray := resemblesJSONArray(modifiedJSON) - - // Do both byte-slices seem like JSON arrays? - if originalResemblesArray && modifiedResemblesArray { - return createArrayMergePatch(originalJSON, modifiedJSON) - } - - // Are both byte-slices are not arrays? Then they are likely JSON objects... - if !originalResemblesArray && !modifiedResemblesArray { - return createObjectMergePatch(originalJSON, modifiedJSON) - } - - // None of the above? Then return an error because of mismatched types. - return nil, errBadMergeTypes -} - -// createObjectMergePatch will return a merge-patch document capable of -// converting the original document to the modified document. -func createObjectMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) { - originalDoc := map[string]interface{}{} - modifiedDoc := map[string]interface{}{} - - err := json.Unmarshal(originalJSON, &originalDoc) - if err != nil { - return nil, errBadJSONDoc - } - - err = json.Unmarshal(modifiedJSON, &modifiedDoc) - if err != nil { - return nil, errBadJSONDoc - } - - dest, err := getDiff(originalDoc, modifiedDoc) - if err != nil { - return nil, err - } - - return json.Marshal(dest) -} - -// createArrayMergePatch will return an array of merge-patch documents capable -// of converting the original document to the modified document for each -// pair of JSON documents provided in the arrays. -// Arrays of mismatched sizes will result in an error. -func createArrayMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) { - originalDocs := []json.RawMessage{} - modifiedDocs := []json.RawMessage{} - - err := json.Unmarshal(originalJSON, &originalDocs) - if err != nil { - return nil, errBadJSONDoc - } - - err = json.Unmarshal(modifiedJSON, &modifiedDocs) - if err != nil { - return nil, errBadJSONDoc - } - - total := len(originalDocs) - if len(modifiedDocs) != total { - return nil, errBadJSONDoc - } - - result := []json.RawMessage{} - for i := 0; i < len(originalDocs); i++ { - original := originalDocs[i] - modified := modifiedDocs[i] - - patch, err := createObjectMergePatch(original, modified) - if err != nil { - return nil, err - } - - result = append(result, json.RawMessage(patch)) - } - - return json.Marshal(result) -} - -// Returns true if the array matches (must be json types). -// As is idiomatic for go, an empty array is not the same as a nil array. -func matchesArray(a, b []interface{}) bool { - if len(a) != len(b) { - return false - } - if (a == nil && b != nil) || (a != nil && b == nil) { - return false - } - for i := range a { - if !matchesValue(a[i], b[i]) { - return false - } - } - return true -} - -// Returns true if the values matches (must be json types) -// The types of the values must match, otherwise it will always return false -// If two map[string]interface{} are given, all elements must match. -func matchesValue(av, bv interface{}) bool { - if reflect.TypeOf(av) != reflect.TypeOf(bv) { - return false - } - switch at := av.(type) { - case string: - bt := bv.(string) - if bt == at { - return true - } - case float64: - bt := bv.(float64) - if bt == at { - return true - } - case bool: - bt := bv.(bool) - if bt == at { - return true - } - case nil: - // Both nil, fine. - return true - case map[string]interface{}: - bt := bv.(map[string]interface{}) - for key := range at { - if !matchesValue(at[key], bt[key]) { - return false - } - } - for key := range bt { - if !matchesValue(at[key], bt[key]) { - return false - } - } - return true - case []interface{}: - bt := bv.([]interface{}) - return matchesArray(at, bt) - } - return false -} - -// getDiff returns the (recursive) difference between a and b as a map[string]interface{}. -func getDiff(a, b map[string]interface{}) (map[string]interface{}, error) { - into := map[string]interface{}{} - for key, bv := range b { - av, ok := a[key] - // value was added - if !ok { - into[key] = bv - continue - } - // If types have changed, replace completely - if reflect.TypeOf(av) != reflect.TypeOf(bv) { - into[key] = bv - continue - } - // Types are the same, compare values - switch at := av.(type) { - case map[string]interface{}: - bt := bv.(map[string]interface{}) - dst := make(map[string]interface{}, len(bt)) - dst, err := getDiff(at, bt) - if err != nil { - return nil, err - } - if len(dst) > 0 { - into[key] = dst - } - case string, float64, bool: - if !matchesValue(av, bv) { - into[key] = bv - } - case []interface{}: - bt := bv.([]interface{}) - if !matchesArray(at, bt) { - into[key] = bv - } - case nil: - switch bv.(type) { - case nil: - // Both nil, fine. - default: - into[key] = bv - } - default: - panic(fmt.Sprintf("Unknown type:%T in key %s", av, key)) - } - } - // Now add all deleted values as nil - for key := range a { - _, found := b[key] - if !found { - into[key] = nil - } - } - return into, nil -} diff --git a/vendor/github.com/evanphx/json-patch/patch.go b/vendor/github.com/evanphx/json-patch/patch.go deleted file mode 100644 index 755d8ba3b..000000000 --- a/vendor/github.com/evanphx/json-patch/patch.go +++ /dev/null @@ -1,663 +0,0 @@ -package jsonpatch - -import ( - "bytes" - "encoding/json" - "fmt" - "strconv" - "strings" -) - -const ( - eRaw = iota - eDoc - eAry -) - -type lazyNode struct { - raw *json.RawMessage - doc partialDoc - ary partialArray - which int -} - -type operation map[string]*json.RawMessage - -// Patch is an ordered collection of operations. -type Patch []operation - -type partialDoc map[string]*lazyNode -type partialArray []*lazyNode - -type container interface { - get(key string) (*lazyNode, error) - set(key string, val *lazyNode) error - add(key string, val *lazyNode) error - remove(key string) error -} - -func newLazyNode(raw *json.RawMessage) *lazyNode { - return &lazyNode{raw: raw, doc: nil, ary: nil, which: eRaw} -} - -func (n *lazyNode) MarshalJSON() ([]byte, error) { - switch n.which { - case eRaw: - return json.Marshal(n.raw) - case eDoc: - return json.Marshal(n.doc) - case eAry: - return json.Marshal(n.ary) - default: - return nil, fmt.Errorf("Unknown type") - } -} - -func (n *lazyNode) UnmarshalJSON(data []byte) error { - dest := make(json.RawMessage, len(data)) - copy(dest, data) - n.raw = &dest - n.which = eRaw - return nil -} - -func (n *lazyNode) intoDoc() (*partialDoc, error) { - if n.which == eDoc { - return &n.doc, nil - } - - if n.raw == nil { - return nil, fmt.Errorf("Unable to unmarshal nil pointer as partial document") - } - - err := json.Unmarshal(*n.raw, &n.doc) - - if err != nil { - return nil, err - } - - n.which = eDoc - return &n.doc, nil -} - -func (n *lazyNode) intoAry() (*partialArray, error) { - if n.which == eAry { - return &n.ary, nil - } - - if n.raw == nil { - return nil, fmt.Errorf("Unable to unmarshal nil pointer as partial array") - } - - err := json.Unmarshal(*n.raw, &n.ary) - - if err != nil { - return nil, err - } - - n.which = eAry - return &n.ary, nil -} - -func (n *lazyNode) compact() []byte { - buf := &bytes.Buffer{} - - if n.raw == nil { - return nil - } - - err := json.Compact(buf, *n.raw) - - if err != nil { - return *n.raw - } - - return buf.Bytes() -} - -func (n *lazyNode) tryDoc() bool { - if n.raw == nil { - return false - } - - err := json.Unmarshal(*n.raw, &n.doc) - - if err != nil { - return false - } - - n.which = eDoc - return true -} - -func (n *lazyNode) tryAry() bool { - if n.raw == nil { - return false - } - - err := json.Unmarshal(*n.raw, &n.ary) - - if err != nil { - return false - } - - n.which = eAry - return true -} - -func (n *lazyNode) equal(o *lazyNode) bool { - if n.which == eRaw { - if !n.tryDoc() && !n.tryAry() { - if o.which != eRaw { - return false - } - - return bytes.Equal(n.compact(), o.compact()) - } - } - - if n.which == eDoc { - if o.which == eRaw { - if !o.tryDoc() { - return false - } - } - - if o.which != eDoc { - return false - } - - for k, v := range n.doc { - ov, ok := o.doc[k] - - if !ok { - return false - } - - if v == nil && ov == nil { - continue - } - - if !v.equal(ov) { - return false - } - } - - return true - } - - if o.which != eAry && !o.tryAry() { - return false - } - - if len(n.ary) != len(o.ary) { - return false - } - - for idx, val := range n.ary { - if !val.equal(o.ary[idx]) { - return false - } - } - - return true -} - -func (o operation) kind() string { - if obj, ok := o["op"]; ok { - var op string - - err := json.Unmarshal(*obj, &op) - - if err != nil { - return "unknown" - } - - return op - } - - return "unknown" -} - -func (o operation) path() string { - if obj, ok := o["path"]; ok { - var op string - - err := json.Unmarshal(*obj, &op) - - if err != nil { - return "unknown" - } - - return op - } - - return "unknown" -} - -func (o operation) from() string { - if obj, ok := o["from"]; ok { - var op string - - err := json.Unmarshal(*obj, &op) - - if err != nil { - return "unknown" - } - - return op - } - - return "unknown" -} - -func (o operation) value() *lazyNode { - if obj, ok := o["value"]; ok { - return newLazyNode(obj) - } - - return nil -} - -func isArray(buf []byte) bool { -Loop: - for _, c := range buf { - switch c { - case ' ': - case '\n': - case '\t': - continue - case '[': - return true - default: - break Loop - } - } - - return false -} - -func findObject(pd *container, path string) (container, string) { - doc := *pd - - split := strings.Split(path, "/") - - if len(split) < 2 { - return nil, "" - } - - parts := split[1 : len(split)-1] - - key := split[len(split)-1] - - var err error - - for _, part := range parts { - - next, ok := doc.get(decodePatchKey(part)) - - if next == nil || ok != nil { - return nil, "" - } - - if isArray(*next.raw) { - doc, err = next.intoAry() - - if err != nil { - return nil, "" - } - } else { - doc, err = next.intoDoc() - - if err != nil { - return nil, "" - } - } - } - - return doc, decodePatchKey(key) -} - -func (d *partialDoc) set(key string, val *lazyNode) error { - (*d)[key] = val - return nil -} - -func (d *partialDoc) add(key string, val *lazyNode) error { - (*d)[key] = val - return nil -} - -func (d *partialDoc) get(key string) (*lazyNode, error) { - return (*d)[key], nil -} - -func (d *partialDoc) remove(key string) error { - _, ok := (*d)[key] - if !ok { - return fmt.Errorf("Unable to remove nonexistent key: %s", key) - } - - delete(*d, key) - return nil -} - -func (d *partialArray) set(key string, val *lazyNode) error { - if key == "-" { - *d = append(*d, val) - return nil - } - - idx, err := strconv.Atoi(key) - if err != nil { - return err - } - - sz := len(*d) - if idx+1 > sz { - sz = idx + 1 - } - - ary := make([]*lazyNode, sz) - - cur := *d - - copy(ary, cur) - - if idx >= len(ary) { - return fmt.Errorf("Unable to access invalid index: %d", idx) - } - - ary[idx] = val - - *d = ary - return nil -} - -func (d *partialArray) add(key string, val *lazyNode) error { - if key == "-" { - *d = append(*d, val) - return nil - } - - idx, err := strconv.Atoi(key) - if err != nil { - return err - } - - ary := make([]*lazyNode, len(*d)+1) - - cur := *d - - if idx < 0 { - idx *= -1 - - if idx > len(ary) { - return fmt.Errorf("Unable to access invalid index: %d", idx) - } - idx = len(ary) - idx - } - - copy(ary[0:idx], cur[0:idx]) - ary[idx] = val - copy(ary[idx+1:], cur[idx:]) - - *d = ary - return nil -} - -func (d *partialArray) get(key string) (*lazyNode, error) { - idx, err := strconv.Atoi(key) - - if err != nil { - return nil, err - } - - if idx >= len(*d) { - return nil, fmt.Errorf("Unable to access invalid index: %d", idx) - } - - return (*d)[idx], nil -} - -func (d *partialArray) remove(key string) error { - idx, err := strconv.Atoi(key) - if err != nil { - return err - } - - cur := *d - - if idx >= len(cur) { - return fmt.Errorf("Unable to remove invalid index: %d", idx) - } - - ary := make([]*lazyNode, len(cur)-1) - - copy(ary[0:idx], cur[0:idx]) - copy(ary[idx:], cur[idx+1:]) - - *d = ary - return nil - -} - -func (p Patch) add(doc *container, op operation) error { - path := op.path() - - con, key := findObject(doc, path) - - if con == nil { - return fmt.Errorf("jsonpatch add operation does not apply: doc is missing path: %s", path) - } - - return con.add(key, op.value()) -} - -func (p Patch) remove(doc *container, op operation) error { - path := op.path() - - con, key := findObject(doc, path) - - if con == nil { - return fmt.Errorf("jsonpatch remove operation does not apply: doc is missing path: %s", path) - } - - return con.remove(key) -} - -func (p Patch) replace(doc *container, op operation) error { - path := op.path() - - con, key := findObject(doc, path) - - if con == nil { - return fmt.Errorf("jsonpatch replace operation does not apply: doc is missing path: %s", path) - } - - val, ok := con.get(key) - if val == nil || ok != nil { - return fmt.Errorf("jsonpatch replace operation does not apply: doc is missing key: %s", path) - } - - return con.set(key, op.value()) -} - -func (p Patch) move(doc *container, op operation) error { - from := op.from() - - con, key := findObject(doc, from) - - if con == nil { - return fmt.Errorf("jsonpatch move operation does not apply: doc is missing from path: %s", from) - } - - val, err := con.get(key) - if err != nil { - return err - } - - err = con.remove(key) - if err != nil { - return err - } - - path := op.path() - - con, key = findObject(doc, path) - - if con == nil { - return fmt.Errorf("jsonpatch move operation does not apply: doc is missing destination path: %s", path) - } - - return con.set(key, val) -} - -func (p Patch) test(doc *container, op operation) error { - path := op.path() - - con, key := findObject(doc, path) - - if con == nil { - return fmt.Errorf("jsonpatch test operation does not apply: is missing path: %s", path) - } - - val, err := con.get(key) - - if err != nil { - return err - } - - if val == nil { - if op.value().raw == nil { - return nil - } - return fmt.Errorf("Testing value %s failed", path) - } - - if val.equal(op.value()) { - return nil - } - - return fmt.Errorf("Testing value %s failed", path) -} - -func (p Patch) copy(doc *container, op operation) error { - from := op.from() - - con, key := findObject(doc, from) - - if con == nil { - return fmt.Errorf("jsonpatch copy operation does not apply: doc is missing from path: %s", from) - } - - val, err := con.get(key) - if err != nil { - return err - } - - path := op.path() - - con, key = findObject(doc, path) - - if con == nil { - return fmt.Errorf("jsonpatch copy operation does not apply: doc is missing destination path: %s", path) - } - - return con.set(key, val) -} - -// Equal indicates if 2 JSON documents have the same structural equality. -func Equal(a, b []byte) bool { - ra := make(json.RawMessage, len(a)) - copy(ra, a) - la := newLazyNode(&ra) - - rb := make(json.RawMessage, len(b)) - copy(rb, b) - lb := newLazyNode(&rb) - - return la.equal(lb) -} - -// DecodePatch decodes the passed JSON document as an RFC 6902 patch. -func DecodePatch(buf []byte) (Patch, error) { - var p Patch - - err := json.Unmarshal(buf, &p) - - if err != nil { - return nil, err - } - - return p, nil -} - -// Apply mutates a JSON document according to the patch, and returns the new -// document. -func (p Patch) Apply(doc []byte) ([]byte, error) { - return p.ApplyIndent(doc, "") -} - -// ApplyIndent mutates a JSON document according to the patch, and returns the new -// document indented. -func (p Patch) ApplyIndent(doc []byte, indent string) ([]byte, error) { - var pd container - if doc[0] == '[' { - pd = &partialArray{} - } else { - pd = &partialDoc{} - } - - err := json.Unmarshal(doc, pd) - - if err != nil { - return nil, err - } - - err = nil - - for _, op := range p { - switch op.kind() { - case "add": - err = p.add(&pd, op) - case "remove": - err = p.remove(&pd, op) - case "replace": - err = p.replace(&pd, op) - case "move": - err = p.move(&pd, op) - case "test": - err = p.test(&pd, op) - case "copy": - err = p.copy(&pd, op) - default: - err = fmt.Errorf("Unexpected kind: %s", op.kind()) - } - - if err != nil { - return nil, err - } - } - - if indent != "" { - return json.MarshalIndent(pd, "", indent) - } - - return json.Marshal(pd) -} - -// From http://tools.ietf.org/html/rfc6901#section-4 : -// -// Evaluation of each reference token begins by decoding any escaped -// character sequence. This is performed by first transforming any -// occurrence of the sequence '~1' to '/', and then transforming any -// occurrence of the sequence '~0' to '~'. - -var ( - rfc6901Decoder = strings.NewReplacer("~1", "/", "~0", "~") -) - -func decodePatchKey(k string) string { - return rfc6901Decoder.Replace(k) -} diff --git a/vendor/github.com/ghodss/yaml/LICENSE b/vendor/github.com/ghodss/yaml/LICENSE deleted file mode 100644 index 7805d36de..000000000 --- a/vendor/github.com/ghodss/yaml/LICENSE +++ /dev/null @@ -1,50 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Sam Ghods - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/ghodss/yaml/fields.go b/vendor/github.com/ghodss/yaml/fields.go deleted file mode 100644 index 586007402..000000000 --- a/vendor/github.com/ghodss/yaml/fields.go +++ /dev/null @@ -1,501 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -package yaml - -import ( - "bytes" - "encoding" - "encoding/json" - "reflect" - "sort" - "strings" - "sync" - "unicode" - "unicode/utf8" -) - -// indirect walks down v allocating pointers as needed, -// until it gets to a non-pointer. -// if it encounters an Unmarshaler, indirect stops and returns that. -// if decodingNull is true, indirect stops at the last pointer so it can be set to nil. -func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { - // If v is a named type and is addressable, - // start with its address, so that if the type has pointer methods, - // we find them. - if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { - v = v.Addr() - } - for { - // Load value from interface, but only if the result will be - // usefully addressable. - if v.Kind() == reflect.Interface && !v.IsNil() { - e := v.Elem() - if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) { - v = e - continue - } - } - - if v.Kind() != reflect.Ptr { - break - } - - if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() { - break - } - if v.IsNil() { - if v.CanSet() { - v.Set(reflect.New(v.Type().Elem())) - } else { - v = reflect.New(v.Type().Elem()) - } - } - if v.Type().NumMethod() > 0 { - if u, ok := v.Interface().(json.Unmarshaler); ok { - return u, nil, reflect.Value{} - } - if u, ok := v.Interface().(encoding.TextUnmarshaler); ok { - return nil, u, reflect.Value{} - } - } - v = v.Elem() - } - return nil, nil, v -} - -// A field represents a single field found in a struct. -type field struct { - name string - nameBytes []byte // []byte(name) - equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent - - tag bool - index []int - typ reflect.Type - omitEmpty bool - quoted bool -} - -func fillField(f field) field { - f.nameBytes = []byte(f.name) - f.equalFold = foldFunc(f.nameBytes) - return f -} - -// byName sorts field by name, breaking ties with depth, -// then breaking ties with "name came from json tag", then -// breaking ties with index sequence. -type byName []field - -func (x byName) Len() int { return len(x) } - -func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -func (x byName) Less(i, j int) bool { - if x[i].name != x[j].name { - return x[i].name < x[j].name - } - if len(x[i].index) != len(x[j].index) { - return len(x[i].index) < len(x[j].index) - } - if x[i].tag != x[j].tag { - return x[i].tag - } - return byIndex(x).Less(i, j) -} - -// byIndex sorts field by index sequence. -type byIndex []field - -func (x byIndex) Len() int { return len(x) } - -func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -func (x byIndex) Less(i, j int) bool { - for k, xik := range x[i].index { - if k >= len(x[j].index) { - return false - } - if xik != x[j].index[k] { - return xik < x[j].index[k] - } - } - return len(x[i].index) < len(x[j].index) -} - -// typeFields returns a list of fields that JSON should recognize for the given type. -// The algorithm is breadth-first search over the set of structs to include - the top struct -// and then any reachable anonymous structs. -func typeFields(t reflect.Type) []field { - // Anonymous fields to explore at the current level and the next. - current := []field{} - next := []field{{typ: t}} - - // Count of queued names for current level and the next. - count := map[reflect.Type]int{} - nextCount := map[reflect.Type]int{} - - // Types already visited at an earlier level. - visited := map[reflect.Type]bool{} - - // Fields found. - var fields []field - - for len(next) > 0 { - current, next = next, current[:0] - count, nextCount = nextCount, map[reflect.Type]int{} - - for _, f := range current { - if visited[f.typ] { - continue - } - visited[f.typ] = true - - // Scan f.typ for fields to include. - for i := 0; i < f.typ.NumField(); i++ { - sf := f.typ.Field(i) - if sf.PkgPath != "" { // unexported - continue - } - tag := sf.Tag.Get("json") - if tag == "-" { - continue - } - name, opts := parseTag(tag) - if !isValidTag(name) { - name = "" - } - index := make([]int, len(f.index)+1) - copy(index, f.index) - index[len(f.index)] = i - - ft := sf.Type - if ft.Name() == "" && ft.Kind() == reflect.Ptr { - // Follow pointer. - ft = ft.Elem() - } - - // Record found field and index sequence. - if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { - tagged := name != "" - if name == "" { - name = sf.Name - } - fields = append(fields, fillField(field{ - name: name, - tag: tagged, - index: index, - typ: ft, - omitEmpty: opts.Contains("omitempty"), - quoted: opts.Contains("string"), - })) - if count[f.typ] > 1 { - // If there were multiple instances, add a second, - // so that the annihilation code will see a duplicate. - // It only cares about the distinction between 1 or 2, - // so don't bother generating any more copies. - fields = append(fields, fields[len(fields)-1]) - } - continue - } - - // Record new anonymous struct to explore in next round. - nextCount[ft]++ - if nextCount[ft] == 1 { - next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft})) - } - } - } - } - - sort.Sort(byName(fields)) - - // Delete all fields that are hidden by the Go rules for embedded fields, - // except that fields with JSON tags are promoted. - - // The fields are sorted in primary order of name, secondary order - // of field index length. Loop over names; for each name, delete - // hidden fields by choosing the one dominant field that survives. - out := fields[:0] - for advance, i := 0, 0; i < len(fields); i += advance { - // One iteration per name. - // Find the sequence of fields with the name of this first field. - fi := fields[i] - name := fi.name - for advance = 1; i+advance < len(fields); advance++ { - fj := fields[i+advance] - if fj.name != name { - break - } - } - if advance == 1 { // Only one field with this name - out = append(out, fi) - continue - } - dominant, ok := dominantField(fields[i : i+advance]) - if ok { - out = append(out, dominant) - } - } - - fields = out - sort.Sort(byIndex(fields)) - - return fields -} - -// dominantField looks through the fields, all of which are known to -// have the same name, to find the single field that dominates the -// others using Go's embedding rules, modified by the presence of -// JSON tags. If there are multiple top-level fields, the boolean -// will be false: This condition is an error in Go and we skip all -// the fields. -func dominantField(fields []field) (field, bool) { - // The fields are sorted in increasing index-length order. The winner - // must therefore be one with the shortest index length. Drop all - // longer entries, which is easy: just truncate the slice. - length := len(fields[0].index) - tagged := -1 // Index of first tagged field. - for i, f := range fields { - if len(f.index) > length { - fields = fields[:i] - break - } - if f.tag { - if tagged >= 0 { - // Multiple tagged fields at the same level: conflict. - // Return no field. - return field{}, false - } - tagged = i - } - } - if tagged >= 0 { - return fields[tagged], true - } - // All remaining fields have the same length. If there's more than one, - // we have a conflict (two fields named "X" at the same level) and we - // return no field. - if len(fields) > 1 { - return field{}, false - } - return fields[0], true -} - -var fieldCache struct { - sync.RWMutex - m map[reflect.Type][]field -} - -// cachedTypeFields is like typeFields but uses a cache to avoid repeated work. -func cachedTypeFields(t reflect.Type) []field { - fieldCache.RLock() - f := fieldCache.m[t] - fieldCache.RUnlock() - if f != nil { - return f - } - - // Compute fields without lock. - // Might duplicate effort but won't hold other computations back. - f = typeFields(t) - if f == nil { - f = []field{} - } - - fieldCache.Lock() - if fieldCache.m == nil { - fieldCache.m = map[reflect.Type][]field{} - } - fieldCache.m[t] = f - fieldCache.Unlock() - return f -} - -func isValidTag(s string) bool { - if s == "" { - return false - } - for _, c := range s { - switch { - case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): - // Backslash and quote chars are reserved, but - // otherwise any punctuation chars are allowed - // in a tag name. - default: - if !unicode.IsLetter(c) && !unicode.IsDigit(c) { - return false - } - } - } - return true -} - -const ( - caseMask = ^byte(0x20) // Mask to ignore case in ASCII. - kelvin = '\u212a' - smallLongEss = '\u017f' -) - -// foldFunc returns one of four different case folding equivalence -// functions, from most general (and slow) to fastest: -// -// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8 -// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S') -// 3) asciiEqualFold, no special, but includes non-letters (including _) -// 4) simpleLetterEqualFold, no specials, no non-letters. -// -// The letters S and K are special because they map to 3 runes, not just 2: -// * S maps to s and to U+017F 'ſ' Latin small letter long s -// * k maps to K and to U+212A 'K' Kelvin sign -// See http://play.golang.org/p/tTxjOc0OGo -// -// The returned function is specialized for matching against s and -// should only be given s. It's not curried for performance reasons. -func foldFunc(s []byte) func(s, t []byte) bool { - nonLetter := false - special := false // special letter - for _, b := range s { - if b >= utf8.RuneSelf { - return bytes.EqualFold - } - upper := b & caseMask - if upper < 'A' || upper > 'Z' { - nonLetter = true - } else if upper == 'K' || upper == 'S' { - // See above for why these letters are special. - special = true - } - } - if special { - return equalFoldRight - } - if nonLetter { - return asciiEqualFold - } - return simpleLetterEqualFold -} - -// equalFoldRight is a specialization of bytes.EqualFold when s is -// known to be all ASCII (including punctuation), but contains an 's', -// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t. -// See comments on foldFunc. -func equalFoldRight(s, t []byte) bool { - for _, sb := range s { - if len(t) == 0 { - return false - } - tb := t[0] - if tb < utf8.RuneSelf { - if sb != tb { - sbUpper := sb & caseMask - if 'A' <= sbUpper && sbUpper <= 'Z' { - if sbUpper != tb&caseMask { - return false - } - } else { - return false - } - } - t = t[1:] - continue - } - // sb is ASCII and t is not. t must be either kelvin - // sign or long s; sb must be s, S, k, or K. - tr, size := utf8.DecodeRune(t) - switch sb { - case 's', 'S': - if tr != smallLongEss { - return false - } - case 'k', 'K': - if tr != kelvin { - return false - } - default: - return false - } - t = t[size:] - - } - if len(t) > 0 { - return false - } - return true -} - -// asciiEqualFold is a specialization of bytes.EqualFold for use when -// s is all ASCII (but may contain non-letters) and contains no -// special-folding letters. -// See comments on foldFunc. -func asciiEqualFold(s, t []byte) bool { - if len(s) != len(t) { - return false - } - for i, sb := range s { - tb := t[i] - if sb == tb { - continue - } - if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') { - if sb&caseMask != tb&caseMask { - return false - } - } else { - return false - } - } - return true -} - -// simpleLetterEqualFold is a specialization of bytes.EqualFold for -// use when s is all ASCII letters (no underscores, etc) and also -// doesn't contain 'k', 'K', 's', or 'S'. -// See comments on foldFunc. -func simpleLetterEqualFold(s, t []byte) bool { - if len(s) != len(t) { - return false - } - for i, b := range s { - if b&caseMask != t[i]&caseMask { - return false - } - } - return true -} - -// tagOptions is the string following a comma in a struct field's "json" -// tag, or the empty string. It does not include the leading comma. -type tagOptions string - -// parseTag splits a struct field's json tag into its name and -// comma-separated options. -func parseTag(tag string) (string, tagOptions) { - if idx := strings.Index(tag, ","); idx != -1 { - return tag[:idx], tagOptions(tag[idx+1:]) - } - return tag, tagOptions("") -} - -// Contains reports whether a comma-separated list of options -// contains a particular substr flag. substr must be surrounded by a -// string boundary or commas. -func (o tagOptions) Contains(optionName string) bool { - if len(o) == 0 { - return false - } - s := string(o) - for s != "" { - var next string - i := strings.Index(s, ",") - if i >= 0 { - s, next = s[:i], s[i+1:] - } - if s == optionName { - return true - } - s = next - } - return false -} diff --git a/vendor/github.com/ghodss/yaml/yaml.go b/vendor/github.com/ghodss/yaml/yaml.go deleted file mode 100644 index 4fb4054a8..000000000 --- a/vendor/github.com/ghodss/yaml/yaml.go +++ /dev/null @@ -1,277 +0,0 @@ -package yaml - -import ( - "bytes" - "encoding/json" - "fmt" - "reflect" - "strconv" - - "gopkg.in/yaml.v2" -) - -// Marshals the object into JSON then converts JSON to YAML and returns the -// YAML. -func Marshal(o interface{}) ([]byte, error) { - j, err := json.Marshal(o) - if err != nil { - return nil, fmt.Errorf("error marshaling into JSON: %v", err) - } - - y, err := JSONToYAML(j) - if err != nil { - return nil, fmt.Errorf("error converting JSON to YAML: %v", err) - } - - return y, nil -} - -// Converts YAML to JSON then uses JSON to unmarshal into an object. -func Unmarshal(y []byte, o interface{}) error { - vo := reflect.ValueOf(o) - j, err := yamlToJSON(y, &vo) - if err != nil { - return fmt.Errorf("error converting YAML to JSON: %v", err) - } - - err = json.Unmarshal(j, o) - if err != nil { - return fmt.Errorf("error unmarshaling JSON: %v", err) - } - - return nil -} - -// Convert JSON to YAML. -func JSONToYAML(j []byte) ([]byte, error) { - // Convert the JSON to an object. - var jsonObj interface{} - // We are using yaml.Unmarshal here (instead of json.Unmarshal) because the - // Go JSON library doesn't try to pick the right number type (int, float, - // etc.) when unmarshalling to interface{}, it just picks float64 - // universally. go-yaml does go through the effort of picking the right - // number type, so we can preserve number type throughout this process. - err := yaml.Unmarshal(j, &jsonObj) - if err != nil { - return nil, err - } - - // Marshal this object into YAML. - return yaml.Marshal(jsonObj) -} - -// Convert YAML to JSON. Since JSON is a subset of YAML, passing JSON through -// this method should be a no-op. -// -// Things YAML can do that are not supported by JSON: -// * In YAML you can have binary and null keys in your maps. These are invalid -// in JSON. (int and float keys are converted to strings.) -// * Binary data in YAML with the !!binary tag is not supported. If you want to -// use binary data with this library, encode the data as base64 as usual but do -// not use the !!binary tag in your YAML. This will ensure the original base64 -// encoded data makes it all the way through to the JSON. -func YAMLToJSON(y []byte) ([]byte, error) { - return yamlToJSON(y, nil) -} - -func yamlToJSON(y []byte, jsonTarget *reflect.Value) ([]byte, error) { - // Convert the YAML to an object. - var yamlObj interface{} - err := yaml.Unmarshal(y, &yamlObj) - if err != nil { - return nil, err - } - - // YAML objects are not completely compatible with JSON objects (e.g. you - // can have non-string keys in YAML). So, convert the YAML-compatible object - // to a JSON-compatible object, failing with an error if irrecoverable - // incompatibilties happen along the way. - jsonObj, err := convertToJSONableObject(yamlObj, jsonTarget) - if err != nil { - return nil, err - } - - // Convert this object to JSON and return the data. - return json.Marshal(jsonObj) -} - -func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (interface{}, error) { - var err error - - // Resolve jsonTarget to a concrete value (i.e. not a pointer or an - // interface). We pass decodingNull as false because we're not actually - // decoding into the value, we're just checking if the ultimate target is a - // string. - if jsonTarget != nil { - ju, tu, pv := indirect(*jsonTarget, false) - // We have a JSON or Text Umarshaler at this level, so we can't be trying - // to decode into a string. - if ju != nil || tu != nil { - jsonTarget = nil - } else { - jsonTarget = &pv - } - } - - // If yamlObj is a number or a boolean, check if jsonTarget is a string - - // if so, coerce. Else return normal. - // If yamlObj is a map or array, find the field that each key is - // unmarshaling to, and when you recurse pass the reflect.Value for that - // field back into this function. - switch typedYAMLObj := yamlObj.(type) { - case map[interface{}]interface{}: - // JSON does not support arbitrary keys in a map, so we must convert - // these keys to strings. - // - // From my reading of go-yaml v2 (specifically the resolve function), - // keys can only have the types string, int, int64, float64, binary - // (unsupported), or null (unsupported). - strMap := make(map[string]interface{}) - for k, v := range typedYAMLObj { - // Resolve the key to a string first. - var keyString string - switch typedKey := k.(type) { - case string: - keyString = typedKey - case int: - keyString = strconv.Itoa(typedKey) - case int64: - // go-yaml will only return an int64 as a key if the system - // architecture is 32-bit and the key's value is between 32-bit - // and 64-bit. Otherwise the key type will simply be int. - keyString = strconv.FormatInt(typedKey, 10) - case float64: - // Stolen from go-yaml to use the same conversion to string as - // the go-yaml library uses to convert float to string when - // Marshaling. - s := strconv.FormatFloat(typedKey, 'g', -1, 32) - switch s { - case "+Inf": - s = ".inf" - case "-Inf": - s = "-.inf" - case "NaN": - s = ".nan" - } - keyString = s - case bool: - if typedKey { - keyString = "true" - } else { - keyString = "false" - } - default: - return nil, fmt.Errorf("Unsupported map key of type: %s, key: %+#v, value: %+#v", - reflect.TypeOf(k), k, v) - } - - // jsonTarget should be a struct or a map. If it's a struct, find - // the field it's going to map to and pass its reflect.Value. If - // it's a map, find the element type of the map and pass the - // reflect.Value created from that type. If it's neither, just pass - // nil - JSON conversion will error for us if it's a real issue. - if jsonTarget != nil { - t := *jsonTarget - if t.Kind() == reflect.Struct { - keyBytes := []byte(keyString) - // Find the field that the JSON library would use. - var f *field - fields := cachedTypeFields(t.Type()) - for i := range fields { - ff := &fields[i] - if bytes.Equal(ff.nameBytes, keyBytes) { - f = ff - break - } - // Do case-insensitive comparison. - if f == nil && ff.equalFold(ff.nameBytes, keyBytes) { - f = ff - } - } - if f != nil { - // Find the reflect.Value of the most preferential - // struct field. - jtf := t.Field(f.index[0]) - strMap[keyString], err = convertToJSONableObject(v, &jtf) - if err != nil { - return nil, err - } - continue - } - } else if t.Kind() == reflect.Map { - // Create a zero value of the map's element type to use as - // the JSON target. - jtv := reflect.Zero(t.Type().Elem()) - strMap[keyString], err = convertToJSONableObject(v, &jtv) - if err != nil { - return nil, err - } - continue - } - } - strMap[keyString], err = convertToJSONableObject(v, nil) - if err != nil { - return nil, err - } - } - return strMap, nil - case []interface{}: - // We need to recurse into arrays in case there are any - // map[interface{}]interface{}'s inside and to convert any - // numbers to strings. - - // If jsonTarget is a slice (which it really should be), find the - // thing it's going to map to. If it's not a slice, just pass nil - // - JSON conversion will error for us if it's a real issue. - var jsonSliceElemValue *reflect.Value - if jsonTarget != nil { - t := *jsonTarget - if t.Kind() == reflect.Slice { - // By default slices point to nil, but we need a reflect.Value - // pointing to a value of the slice type, so we create one here. - ev := reflect.Indirect(reflect.New(t.Type().Elem())) - jsonSliceElemValue = &ev - } - } - - // Make and use a new array. - arr := make([]interface{}, len(typedYAMLObj)) - for i, v := range typedYAMLObj { - arr[i], err = convertToJSONableObject(v, jsonSliceElemValue) - if err != nil { - return nil, err - } - } - return arr, nil - default: - // If the target type is a string and the YAML type is a number, - // convert the YAML type to a string. - if jsonTarget != nil && (*jsonTarget).Kind() == reflect.String { - // Based on my reading of go-yaml, it may return int, int64, - // float64, or uint64. - var s string - switch typedVal := typedYAMLObj.(type) { - case int: - s = strconv.FormatInt(int64(typedVal), 10) - case int64: - s = strconv.FormatInt(typedVal, 10) - case float64: - s = strconv.FormatFloat(typedVal, 'g', -1, 32) - case uint64: - s = strconv.FormatUint(typedVal, 10) - case bool: - if typedVal { - s = "true" - } else { - s = "false" - } - } - if len(s) > 0 { - yamlObj = interface{}(s) - } - } - return yamlObj, nil - } - - return nil, nil -} diff --git a/vendor/github.com/go-openapi/jsonpointer/LICENSE b/vendor/github.com/go-openapi/jsonpointer/LICENSE deleted file mode 100644 index d64569567..000000000 --- a/vendor/github.com/go-openapi/jsonpointer/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/go-openapi/jsonpointer/pointer.go b/vendor/github.com/go-openapi/jsonpointer/pointer.go deleted file mode 100644 index fe2d6ee57..000000000 --- a/vendor/github.com/go-openapi/jsonpointer/pointer.go +++ /dev/null @@ -1,390 +0,0 @@ -// Copyright 2013 sigu-399 ( https://github.com/sigu-399 ) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// author sigu-399 -// author-github https://github.com/sigu-399 -// author-mail sigu.399@gmail.com -// -// repository-name jsonpointer -// repository-desc An implementation of JSON Pointer - Go language -// -// description Main and unique file. -// -// created 25-02-2013 - -package jsonpointer - -import ( - "errors" - "fmt" - "reflect" - "strconv" - "strings" - - "github.com/go-openapi/swag" -) - -const ( - emptyPointer = `` - pointerSeparator = `/` - - invalidStart = `JSON pointer must be empty or start with a "` + pointerSeparator -) - -var jsonPointableType = reflect.TypeOf(new(JSONPointable)).Elem() -var jsonSetableType = reflect.TypeOf(new(JSONSetable)).Elem() - -// JSONPointable is an interface for structs to implement when they need to customize the -// json pointer process -type JSONPointable interface { - JSONLookup(string) (interface{}, error) -} - -// JSONSetable is an interface for structs to implement when they need to customize the -// json pointer process -type JSONSetable interface { - JSONSet(string, interface{}) error -} - -// New creates a new json pointer for the given string -func New(jsonPointerString string) (Pointer, error) { - - var p Pointer - err := p.parse(jsonPointerString) - return p, err - -} - -// Pointer the json pointer reprsentation -type Pointer struct { - referenceTokens []string -} - -// "Constructor", parses the given string JSON pointer -func (p *Pointer) parse(jsonPointerString string) error { - - var err error - - if jsonPointerString != emptyPointer { - if !strings.HasPrefix(jsonPointerString, pointerSeparator) { - err = errors.New(invalidStart) - } else { - referenceTokens := strings.Split(jsonPointerString, pointerSeparator) - for _, referenceToken := range referenceTokens[1:] { - p.referenceTokens = append(p.referenceTokens, referenceToken) - } - } - } - - return err -} - -// Get uses the pointer to retrieve a value from a JSON document -func (p *Pointer) Get(document interface{}) (interface{}, reflect.Kind, error) { - return p.get(document, swag.DefaultJSONNameProvider) -} - -// Set uses the pointer to set a value from a JSON document -func (p *Pointer) Set(document interface{}, value interface{}) (interface{}, error) { - return document, p.set(document, value, swag.DefaultJSONNameProvider) -} - -// GetForToken gets a value for a json pointer token 1 level deep -func GetForToken(document interface{}, decodedToken string) (interface{}, reflect.Kind, error) { - return getSingleImpl(document, decodedToken, swag.DefaultJSONNameProvider) -} - -// SetForToken gets a value for a json pointer token 1 level deep -func SetForToken(document interface{}, decodedToken string, value interface{}) (interface{}, error) { - return document, setSingleImpl(document, value, decodedToken, swag.DefaultJSONNameProvider) -} - -func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) { - rValue := reflect.Indirect(reflect.ValueOf(node)) - kind := rValue.Kind() - - switch kind { - - case reflect.Struct: - if rValue.Type().Implements(jsonPointableType) { - r, err := node.(JSONPointable).JSONLookup(decodedToken) - if err != nil { - return nil, kind, err - } - return r, kind, nil - } - nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) - if !ok { - return nil, kind, fmt.Errorf("object has no field %q", decodedToken) - } - fld := rValue.FieldByName(nm) - return fld.Interface(), kind, nil - - case reflect.Map: - kv := reflect.ValueOf(decodedToken) - mv := rValue.MapIndex(kv) - - if mv.IsValid() && !swag.IsZero(mv) { - return mv.Interface(), kind, nil - } - return nil, kind, fmt.Errorf("object has no key %q", decodedToken) - - case reflect.Slice: - tokenIndex, err := strconv.Atoi(decodedToken) - if err != nil { - return nil, kind, err - } - sLength := rValue.Len() - if tokenIndex < 0 || tokenIndex >= sLength { - return nil, kind, fmt.Errorf("index out of bounds array[0,%d] index '%d'", sLength-1, tokenIndex) - } - - elem := rValue.Index(tokenIndex) - return elem.Interface(), kind, nil - - default: - return nil, kind, fmt.Errorf("invalid token reference %q", decodedToken) - } - -} - -func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *swag.NameProvider) error { - rValue := reflect.Indirect(reflect.ValueOf(node)) - switch rValue.Kind() { - - case reflect.Struct: - if ns, ok := node.(JSONSetable); ok { // pointer impl - return ns.JSONSet(decodedToken, data) - } - - if rValue.Type().Implements(jsonSetableType) { - return node.(JSONSetable).JSONSet(decodedToken, data) - } - - nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) - if !ok { - return fmt.Errorf("object has no field %q", decodedToken) - } - fld := rValue.FieldByName(nm) - if fld.IsValid() { - fld.Set(reflect.ValueOf(data)) - } - return nil - - case reflect.Map: - kv := reflect.ValueOf(decodedToken) - rValue.SetMapIndex(kv, reflect.ValueOf(data)) - return nil - - case reflect.Slice: - tokenIndex, err := strconv.Atoi(decodedToken) - if err != nil { - return err - } - sLength := rValue.Len() - if tokenIndex < 0 || tokenIndex >= sLength { - return fmt.Errorf("index out of bounds array[0,%d] index '%d'", sLength, tokenIndex) - } - - elem := rValue.Index(tokenIndex) - if !elem.CanSet() { - return fmt.Errorf("can't set slice index %s to %v", decodedToken, data) - } - elem.Set(reflect.ValueOf(data)) - return nil - - default: - return fmt.Errorf("invalid token reference %q", decodedToken) - } - -} - -func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) { - - if nameProvider == nil { - nameProvider = swag.DefaultJSONNameProvider - } - - kind := reflect.Invalid - - // Full document when empty - if len(p.referenceTokens) == 0 { - return node, kind, nil - } - - for _, token := range p.referenceTokens { - - decodedToken := Unescape(token) - - r, knd, err := getSingleImpl(node, decodedToken, nameProvider) - if err != nil { - return nil, knd, err - } - node, kind = r, knd - - } - - rValue := reflect.ValueOf(node) - kind = rValue.Kind() - - return node, kind, nil -} - -func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) error { - knd := reflect.ValueOf(node).Kind() - - if knd != reflect.Ptr && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array { - return fmt.Errorf("only structs, pointers, maps and slices are supported for setting values") - } - - if nameProvider == nil { - nameProvider = swag.DefaultJSONNameProvider - } - - // Full document when empty - if len(p.referenceTokens) == 0 { - return nil - } - - lastI := len(p.referenceTokens) - 1 - for i, token := range p.referenceTokens { - isLastToken := i == lastI - decodedToken := Unescape(token) - - if isLastToken { - - return setSingleImpl(node, data, decodedToken, nameProvider) - } - - rValue := reflect.Indirect(reflect.ValueOf(node)) - kind := rValue.Kind() - - switch kind { - - case reflect.Struct: - if rValue.Type().Implements(jsonPointableType) { - r, err := node.(JSONPointable).JSONLookup(decodedToken) - if err != nil { - return err - } - fld := reflect.ValueOf(r) - if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr { - node = fld.Addr().Interface() - continue - } - node = r - continue - } - nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) - if !ok { - return fmt.Errorf("object has no field %q", decodedToken) - } - fld := rValue.FieldByName(nm) - if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr { - node = fld.Addr().Interface() - continue - } - node = fld.Interface() - - case reflect.Map: - kv := reflect.ValueOf(decodedToken) - mv := rValue.MapIndex(kv) - - if !mv.IsValid() { - return fmt.Errorf("object has no key %q", decodedToken) - } - if mv.CanAddr() && mv.Kind() != reflect.Interface && mv.Kind() != reflect.Map && mv.Kind() != reflect.Slice && mv.Kind() != reflect.Ptr { - node = mv.Addr().Interface() - continue - } - node = mv.Interface() - - case reflect.Slice: - tokenIndex, err := strconv.Atoi(decodedToken) - if err != nil { - return err - } - sLength := rValue.Len() - if tokenIndex < 0 || tokenIndex >= sLength { - return fmt.Errorf("index out of bounds array[0,%d] index '%d'", sLength, tokenIndex) - } - - elem := rValue.Index(tokenIndex) - if elem.CanAddr() && elem.Kind() != reflect.Interface && elem.Kind() != reflect.Map && elem.Kind() != reflect.Slice && elem.Kind() != reflect.Ptr { - node = elem.Addr().Interface() - continue - } - node = elem.Interface() - - default: - return fmt.Errorf("invalid token reference %q", decodedToken) - } - - } - - return nil -} - -// DecodedTokens returns the decoded tokens -func (p *Pointer) DecodedTokens() []string { - result := make([]string, 0, len(p.referenceTokens)) - for _, t := range p.referenceTokens { - result = append(result, Unescape(t)) - } - return result -} - -// IsEmpty returns true if this is an empty json pointer -// this indicates that it points to the root document -func (p *Pointer) IsEmpty() bool { - return len(p.referenceTokens) == 0 -} - -// Pointer to string representation function -func (p *Pointer) String() string { - - if len(p.referenceTokens) == 0 { - return emptyPointer - } - - pointerString := pointerSeparator + strings.Join(p.referenceTokens, pointerSeparator) - - return pointerString -} - -// Specific JSON pointer encoding here -// ~0 => ~ -// ~1 => / -// ... and vice versa - -const ( - encRefTok0 = `~0` - encRefTok1 = `~1` - decRefTok0 = `~` - decRefTok1 = `/` -) - -// Unescape unescapes a json pointer reference token string to the original representation -func Unescape(token string) string { - step1 := strings.Replace(token, encRefTok1, decRefTok1, -1) - step2 := strings.Replace(step1, encRefTok0, decRefTok0, -1) - return step2 -} - -// Escape escapes a pointer reference token string -func Escape(token string) string { - step1 := strings.Replace(token, decRefTok0, encRefTok0, -1) - step2 := strings.Replace(step1, decRefTok1, encRefTok1, -1) - return step2 -} diff --git a/vendor/github.com/go-openapi/jsonreference/LICENSE b/vendor/github.com/go-openapi/jsonreference/LICENSE deleted file mode 100644 index d64569567..000000000 --- a/vendor/github.com/go-openapi/jsonreference/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/go-openapi/jsonreference/reference.go b/vendor/github.com/go-openapi/jsonreference/reference.go deleted file mode 100644 index 3bc0a6e26..000000000 --- a/vendor/github.com/go-openapi/jsonreference/reference.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2013 sigu-399 ( https://github.com/sigu-399 ) -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// author sigu-399 -// author-github https://github.com/sigu-399 -// author-mail sigu.399@gmail.com -// -// repository-name jsonreference -// repository-desc An implementation of JSON Reference - Go language -// -// description Main and unique file. -// -// created 26-02-2013 - -package jsonreference - -import ( - "errors" - "net/url" - "strings" - - "github.com/PuerkitoBio/purell" - "github.com/go-openapi/jsonpointer" -) - -const ( - fragmentRune = `#` -) - -// New creates a new reference for the given string -func New(jsonReferenceString string) (Ref, error) { - - var r Ref - err := r.parse(jsonReferenceString) - return r, err - -} - -// MustCreateRef parses the ref string and panics when it's invalid. -// Use the New method for a version that returns an error -func MustCreateRef(ref string) Ref { - r, err := New(ref) - if err != nil { - panic(err) - } - return r -} - -// Ref represents a json reference object -type Ref struct { - referenceURL *url.URL - referencePointer jsonpointer.Pointer - - HasFullURL bool - HasURLPathOnly bool - HasFragmentOnly bool - HasFileScheme bool - HasFullFilePath bool -} - -// GetURL gets the URL for this reference -func (r *Ref) GetURL() *url.URL { - return r.referenceURL -} - -// GetPointer gets the json pointer for this reference -func (r *Ref) GetPointer() *jsonpointer.Pointer { - return &r.referencePointer -} - -// String returns the best version of the url for this reference -func (r *Ref) String() string { - - if r.referenceURL != nil { - return r.referenceURL.String() - } - - if r.HasFragmentOnly { - return fragmentRune + r.referencePointer.String() - } - - return r.referencePointer.String() -} - -// IsRoot returns true if this reference is a root document -func (r *Ref) IsRoot() bool { - return r.referenceURL != nil && - !r.IsCanonical() && - !r.HasURLPathOnly && - r.referenceURL.Fragment == "" -} - -// IsCanonical returns true when this pointer starts with http(s):// or file:// -func (r *Ref) IsCanonical() bool { - return (r.HasFileScheme && r.HasFullFilePath) || (!r.HasFileScheme && r.HasFullURL) -} - -// "Constructor", parses the given string JSON reference -func (r *Ref) parse(jsonReferenceString string) error { - - parsed, err := url.Parse(jsonReferenceString) - if err != nil { - return err - } - - r.referenceURL, _ = url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes)) - refURL := r.referenceURL - - if refURL.Scheme != "" && refURL.Host != "" { - r.HasFullURL = true - } else { - if refURL.Path != "" { - r.HasURLPathOnly = true - } else if refURL.RawQuery == "" && refURL.Fragment != "" { - r.HasFragmentOnly = true - } - } - - r.HasFileScheme = refURL.Scheme == "file" - r.HasFullFilePath = strings.HasPrefix(refURL.Path, "/") - - // invalid json-pointer error means url has no json-pointer fragment. simply ignore error - r.referencePointer, _ = jsonpointer.New(refURL.Fragment) - - return nil -} - -// Inherits creates a new reference from a parent and a child -// If the child cannot inherit from the parent, an error is returned -func (r *Ref) Inherits(child Ref) (*Ref, error) { - childURL := child.GetURL() - parentURL := r.GetURL() - if childURL == nil { - return nil, errors.New("child url is nil") - } - if parentURL == nil { - return &child, nil - } - - ref, err := New(parentURL.ResolveReference(childURL).String()) - if err != nil { - return nil, err - } - return &ref, nil -} diff --git a/vendor/github.com/go-openapi/spec/LICENSE b/vendor/github.com/go-openapi/spec/LICENSE deleted file mode 100644 index d64569567..000000000 --- a/vendor/github.com/go-openapi/spec/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/go-openapi/spec/bindata.go b/vendor/github.com/go-openapi/spec/bindata.go deleted file mode 100644 index 693917a07..000000000 --- a/vendor/github.com/go-openapi/spec/bindata.go +++ /dev/null @@ -1,260 +0,0 @@ -// Code generated by go-bindata. -// sources: -// schemas/jsonschema-draft-04.json -// schemas/v2/schema.json -// DO NOT EDIT! - -package spec - -import ( - "bytes" - "compress/gzip" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strings" - "time" -) - -func bindataRead(data []byte, name string) ([]byte, error) { - gz, err := gzip.NewReader(bytes.NewBuffer(data)) - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - - var buf bytes.Buffer - _, err = io.Copy(&buf, gz) - clErr := gz.Close() - - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - if clErr != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -type asset struct { - bytes []byte - info os.FileInfo -} - -type bindataFileInfo struct { - name string - size int64 - mode os.FileMode - modTime time.Time -} - -func (fi bindataFileInfo) Name() string { - return fi.name -} -func (fi bindataFileInfo) Size() int64 { - return fi.size -} -func (fi bindataFileInfo) Mode() os.FileMode { - return fi.mode -} -func (fi bindataFileInfo) ModTime() time.Time { - return fi.modTime -} -func (fi bindataFileInfo) IsDir() bool { - return false -} -func (fi bindataFileInfo) Sys() interface{} { - return nil -} - -var _jsonschemaDraft04JSON = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x57\x3d\x6f\xdb\x3c\x10\xde\xf3\x2b\x08\x26\x63\xf2\x2a\x2f\xd0\xc9\x5b\xd1\x2e\x01\x5a\x34\x43\x37\x23\x03\x6d\x9d\x6c\x06\x14\xa9\x50\x54\x60\xc3\xd0\x7f\x2f\x28\x4a\x14\x29\x91\x92\x2d\xa7\x8d\x97\x28\xbc\xaf\xe7\x8e\xf7\xc5\xd3\x0d\x42\x08\x61\x9a\xe2\x15\xc2\x7b\xa5\x8a\x55\x92\xbc\x96\x82\x3f\x94\xdb\x3d\xe4\xe4\x3f\x21\x77\x49\x2a\x49\xa6\x1e\x1e\xbf\x24\xe6\xec\x16\xdf\x1b\xa1\x3b\xf3\xff\x02\xc9\x14\xca\xad\xa4\x85\xa2\x82\x6b\xe9\x6f\x42\x02\x32\x2c\x28\x07\x45\x5a\x15\x3d\x77\x46\x39\xd5\xcc\x25\x5e\x21\x83\xb8\x21\x18\xb6\xaf\x52\x92\xa3\x47\x68\x88\xea\x58\x80\x56\x4e\x1a\xf2\xbd\x4f\xcc\x29\x7f\x52\x90\x6b\x7d\xff\x0f\x48\xb4\x3d\x3f\x21\x7c\x27\x21\xd3\x2a\x6e\x31\xaa\x2d\x53\xdd\xf3\xe3\x42\x94\x54\xd1\x77\x78\xe2\x0a\x76\x20\xe3\x20\x68\xcb\x30\x86\x41\xf3\x2a\xc7\x2b\xf4\x78\x8e\xfe\xef\x90\x91\x8a\xa9\xc7\xb1\x1d\xc2\xd8\x2f\x0d\x75\xed\xc1\x4e\x9c\xc8\x25\x43\xac\xa8\xbe\xd7\xcc\xa9\xd1\xa9\x21\xa0\x1a\xbd\x04\x61\x94\x34\x2f\x18\xfc\x3e\x16\x50\x8e\x4d\x03\x6f\x1c\x58\xdb\x48\x23\xbc\x11\x82\x01\xe1\xfa\xd3\x3a\x8e\x30\xaf\x18\x33\x7f\xf3\x8d\x39\x11\x9b\x57\xd8\x2a\xfd\x55\x2a\x49\xf9\x0e\xc7\xec\x37\xd4\x25\xf7\xec\x5c\x66\xc7\xd7\x99\xaa\xcf\x4f\x89\x8a\xd3\xb7\x0a\x3a\xaa\x92\x15\xf4\x30\x6f\x1c\xb0\xd6\x46\xe7\x98\x39\x2d\xa4\x28\x40\x2a\x3a\x88\x9e\x29\xba\x88\x37\x2d\xca\x60\x38\xfa\xba\x5b\x20\xac\xa8\x62\xb0\x4c\xd4\xaf\xda\x45\x0a\xba\x5c\x3b\xb9\xc7\x79\xc5\x14\x2d\x18\x34\x19\x1c\x51\xdb\x25\x4d\xb4\x7e\x06\x14\x38\x6c\x59\x55\xd2\x77\xf8\x69\x59\xfc\x7b\x73\xed\x93\x43\xcb\x32\x6d\x3c\x28\xdc\x1b\x9a\xd3\x62\xab\xc2\x27\xf7\x41\xc9\x08\x2b\x23\x08\xad\x13\x57\x21\x9c\xd3\x72\x0d\x42\x72\xf8\x01\x7c\xa7\xf6\x83\xce\x39\xd7\x82\x3c\x1f\x2f\xd6\x60\x1b\xa2\xdf\x35\x89\x52\x20\xe7\x73\x74\xe0\x66\x26\x64\x4e\xb4\x97\x58\xc2\x0e\x0e\xe1\x60\x92\x34\x6d\xa0\x10\xd6\xb5\x83\x61\x27\xe6\x47\xd3\x89\xbd\x63\xfd\x3b\x8d\x03\x3d\x6c\x42\x2d\x5b\x70\xee\xe8\xdf\x4b\xf4\x66\x4e\xe1\x01\x45\x17\x80\x74\xad\x4f\xc3\xf3\xae\xc6\x1d\xc6\xd7\xc2\xce\xc9\xe1\x29\x30\x86\x2f\x4a\xa6\x4b\x15\x84\x73\xc9\x6f\xfd\x7f\xa5\x6e\x9e\xbd\xf1\xb0\xd4\xdd\x45\x5a\xc2\x3e\x4b\x78\xab\xa8\x84\x74\x4a\x91\x3b\x92\x23\x05\xf2\x1c\x1e\x7b\xf3\x09\xf8\xcf\xab\x24\xb6\x60\xa2\xe8\x4c\x9f\x75\x77\xaa\x8c\xe6\x01\x45\x36\x86\xcf\xc3\x63\x3a\xea\xd4\x8d\x7e\x06\xac\x14\x0a\xe0\x29\xf0\xed\x07\x22\x1a\x65\xda\x44\xae\xa2\x73\x1a\xe6\x90\x69\xa2\x8c\x46\xb2\x2f\xde\x49\x38\x08\xed\xfe\xfd\x41\xaf\x9f\xa9\x55\xd7\xdd\x22\x8d\xfa\x45\x63\xc5\x0f\x80\xf3\xb4\x08\xd6\x79\x30\x9e\x93\xee\x59\xa6\xd0\x4b\xee\x22\xe3\x33\xc1\x3a\x27\x68\x36\x78\x7e\x87\x0a\x06\xd5\x2e\x20\xd3\xaf\x15\xfb\xd8\x3b\x73\x14\xbb\x92\xed\x05\x5d\x2e\x29\x38\x2c\x94\xe4\x42\x45\x5e\xd3\xb5\x7d\xdf\x47\xca\x38\xb4\x5c\xaf\xfb\x7d\xdd\x6d\xf4\xa1\x2d\x77\xdd\x2f\xce\x6d\xc4\x7b\x8b\x4e\x67\xa9\x6f\xfe\x04\x00\x00\xff\xff\xb1\xd1\x27\x78\x05\x11\x00\x00") - -func jsonschemaDraft04JSONBytes() ([]byte, error) { - return bindataRead( - _jsonschemaDraft04JSON, - "jsonschema-draft-04.json", - ) -} - -func jsonschemaDraft04JSON() (*asset, error) { - bytes, err := jsonschemaDraft04JSONBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "jsonschema-draft-04.json", size: 4357, mode: os.FileMode(420), modTime: time.Unix(1523760398, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _v2SchemaJSON = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5d\x4f\x93\xdb\x36\xb2\xbf\xfb\x53\xa0\x14\x57\xd9\xae\xd8\x92\xe3\xf7\x2e\xcf\x97\xd4\xbc\xd8\x49\x66\x37\x5e\x4f\x79\x26\xbb\x87\x78\x5c\x05\x91\x2d\x09\x09\x09\x30\x00\x38\x33\x5a\xef\x7c\xf7\x2d\xf0\x9f\x08\x02\x20\x41\x8a\xd2\xc8\x0e\x0f\xa9\x78\x28\xa0\xd1\xdd\x68\x34\x7e\xdd\xf8\xf7\xf9\x11\x42\x33\x49\x64\x04\xb3\xd7\x68\x76\x86\xfe\x76\xf9\xfe\x1f\xe8\x32\xd8\x40\x8c\xd1\x8a\x71\x74\x79\x8b\xd7\x6b\xe0\xe8\xd5\xfc\x25\x3a\xbb\x38\x9f\xcf\x9e\xab\x0a\x24\x54\xa5\x37\x52\x26\xaf\x17\x0b\x91\x17\x99\x13\xb6\xb8\x79\xb5\x10\x59\xdd\xf9\xef\x82\xd1\x6f\xf2\xc2\x8f\xf3\x4f\xb5\x1a\xea\xc7\x17\x45\x41\xc6\xd7\x8b\x90\xe3\x95\x7c\xf1\xf2\x7f\x8b\xca\x45\x3d\xb9\x4d\x32\xa6\xd8\xf2\x77\x08\x64\xfe\x8d\xc3\x9f\x29\xe1\xa0\x9a\xff\xed\x11\x42\x08\xcd\x8a\xd6\xb3\x9f\x15\x67\x74\xc5\xca\x7f\x27\x58\x6e\xc4\xec\x11\x42\xd7\x59\x5d\x1c\x86\x44\x12\x46\x71\x74\xc1\x59\x02\x5c\x12\x10\xb3\xd7\x68\x85\x23\x01\x59\x81\x04\x4b\x09\x9c\x6a\xbf\x7e\xce\x49\x7d\xba\x7b\x51\xfd\xa1\x44\xe2\xb0\x52\xac\x7d\xb3\x08\x61\x45\x68\x46\x56\x2c\x6e\x80\x86\x8c\xbf\xbd\x93\x40\x05\x61\x74\x96\x95\xbe\x7f\x84\xd0\x7d\x4e\xde\x42\xb7\xe4\xbe\x46\xbb\x14\x5b\x48\x4e\xe8\xba\x90\x05\xa1\x19\xd0\x34\xae\xc4\xce\xbe\xbc\x9a\xbf\x9c\x15\x7f\x5d\x57\xc5\x42\x10\x01\x27\x89\xe2\x48\x51\xb9\xda\x40\xd5\x87\x37\xc0\x15\x5f\x88\xad\x90\xdc\x10\x81\x42\x16\xa4\x31\x50\x39\x2f\x38\xad\xab\xb0\x53\xd8\xac\x94\x56\x6f\xc3\x84\xf4\x11\xa4\x50\xb3\xfa\xe9\xd3\x6f\x9f\x3e\xdf\x2f\xd0\xeb\x8f\x1f\x3f\x7e\xbc\xfe\xf6\xe9\xf7\xaf\x5f\x7f\xfc\x18\x7e\xfb\xec\xfb\xc7\xb3\x36\x79\x54\x43\xe8\x29\xc5\x31\x20\xc6\x11\x49\x9e\xe5\x12\x41\x66\xa0\xe8\xed\x1d\x8e\x93\x08\x5e\xa3\x27\x3b\xc3\x7c\xa2\x73\xba\xc4\x02\x2e\xb0\xdc\xf4\xe5\x76\xd1\xca\x96\xa2\x8a\x94\xcd\x21\xc9\x6c\xec\x2c\x70\x42\x9e\x34\x74\x9d\x19\x7c\xcd\x20\x9c\xea\x2e\x0a\xfe\x42\x84\xd4\x29\x04\x8c\x8a\xb4\x41\xa2\xc1\xdc\x19\x8a\x88\x90\x4a\x49\xef\xce\xdf\xbd\x45\x4a\x52\x81\x70\x10\x40\x22\x21\x44\xcb\x6d\xc5\xec\x4e\x3c\x1c\x45\xef\x57\x9a\xb5\x7d\xae\xfe\xe5\xe4\x31\x86\x90\xe0\xab\x6d\x02\x3b\x2e\xcb\x11\x90\xd9\xa8\xc6\x77\xc2\x59\x98\x06\xfd\xf9\x2e\x78\x45\x01\xa6\xa8\xa0\x71\x5c\xbe\x33\xa7\xd2\xd9\x5f\x95\xef\xd9\xd5\xac\xfd\xdc\x5d\xbf\x5e\xb8\xd1\x3e\xc7\x31\x48\xe0\x5e\x4c\x14\x65\xdf\xb8\xa8\x71\x10\x09\xa3\xc2\xc7\x02\xcb\xa2\x4e\x5a\x02\x82\x94\x13\xb9\xf5\x30\xe6\xb2\xa4\xb5\xfe\x9b\x3e\x7a\xb2\x55\xd2\xa8\x4a\xbc\x16\xb6\x71\x8e\x39\xc7\xdb\x9d\xe1\x10\x09\x71\xbd\x9c\xb3\x41\x89\xd7\xa5\x89\xdc\x57\xb5\x53\x4a\xfe\x4c\xe1\xbc\xa0\x21\x79\x0a\x1a\x0f\x70\xa7\x5c\x08\x8e\xde\xb0\xc0\x43\x24\xad\x74\x63\x0e\xb1\xd9\x90\xe1\xb0\x2d\x13\xa7\x6d\x78\xfd\x04\x14\x38\x8e\x90\xaa\xce\x63\xac\x3e\x23\xbc\x64\xa9\xb4\xf8\x03\x63\xde\xcd\xbe\x16\x13\x4a\x55\xac\x82\x12\xc6\xac\xd4\x35\xf7\x22\xd4\x3a\xff\x22\x73\x0e\x6e\x51\xa0\x75\x1e\xae\x8f\xe8\x5d\xc7\x59\xe6\xe4\x9a\x18\x8d\xd6\x1c\x53\x84\x4d\xb7\x67\x28\x37\x09\x84\x69\x88\x12\x0e\x01\x11\x80\x32\xa2\xf5\xb9\xaa\xc6\xd9\x73\x53\xab\xfb\xb4\x2e\x20\xc6\x54\x92\xa0\x9a\xf3\x69\x1a\x2f\x81\x77\x37\xae\x53\x1a\xce\x40\xc4\xa8\x82\x1c\xb5\xef\xda\x24\x7d\xb9\x61\x69\x14\xa2\x25\xa0\x90\xac\x56\xc0\x81\x4a\xb4\xe2\x2c\xce\x4a\x64\x7a\x9a\x23\xf4\x13\x91\x3f\xa7\x4b\xf4\x63\x84\x6f\x18\x87\x10\xbd\xc3\xfc\x8f\x90\xdd\x52\x44\x04\xc2\x51\xc4\x6e\x21\x74\x48\x21\x81\xc7\xe2\xfd\xea\x12\xf8\x0d\x09\xf6\xe9\x47\x35\xaf\x67\xc4\x14\xf7\x22\x27\x97\xe1\xe2\x76\x2d\x06\x8c\x4a\x1c\x48\x3f\x73\x2d\x0b\x5b\x29\x45\x24\x00\x2a\x0c\x11\xec\x94\xca\xc2\xa6\xc1\x37\x21\x43\x83\x3b\x5f\x97\xf1\x43\x5e\x53\x73\x19\xa5\x36\xd8\x2d\x05\x2e\x34\x0b\xeb\x39\xfc\x1d\x63\x51\x01\xbd\x3d\xbb\x90\x84\x40\x25\x59\x6d\x09\x5d\xa3\x1c\x37\xe6\x5c\x16\x9a\x40\x09\x70\xc1\xe8\x82\xf1\x35\xa6\xe4\xdf\x99\x5c\x8e\x9e\x4d\x79\xb4\x27\x2f\xbf\x7e\xf8\x05\x25\x8c\x50\xa9\x98\x29\x90\x62\x60\xea\x75\xae\x13\xca\xbf\x2b\x1a\x29\x27\x76\xd6\x20\xc6\x64\x5f\xe6\x32\x1a\x08\x87\x21\x07\x21\xbc\xb4\xe4\xe0\x32\x67\xa6\xcd\xf3\x1e\xcd\xd9\x6b\xb6\x6f\x8e\x27\xa7\xed\xdb\xe7\xbc\xcc\x1a\x07\xce\x6f\x87\x33\xf0\xba\x51\x17\x22\x66\x78\x79\x8e\xce\xe5\x13\x81\x80\x06\x2c\xe5\x78\x0d\xa1\xb2\xb8\x54\xa8\x79\x09\xbd\xbf\x3c\x47\x01\x8b\x13\x2c\xc9\x32\xaa\xaa\x1d\xd5\xee\xab\x36\xbd\x6c\xfd\x54\x6c\xc8\x08\x01\x3c\xbd\xe7\x07\x88\xb0\x24\x37\x79\x90\x28\x4a\x1d\x10\x1a\x92\x1b\x12\xa6\x38\x42\x40\xc3\x4c\x43\x62\x8e\xae\x36\xb0\x45\x71\x2a\xa4\x9a\x23\x79\x59\xb1\xa8\xf2\xa4\x0c\x60\x9f\xcc\x8d\x40\xf5\x80\xca\xa8\x99\xc3\xa7\x85\x1f\x31\x25\xa9\x82\xc5\x6d\xbd\xd8\x36\x76\x7c\x02\x28\x97\xf6\x1d\x74\x3b\x11\x7e\x91\xae\x32\xf8\x6c\xf4\xe6\x7b\x9a\xa5\x1f\x62\xc6\x21\xcf\x9a\xe5\xed\x8b\x02\xf3\x2c\x33\x33\xdf\x00\xca\xc9\x09\xb4\x04\xf5\xa5\x08\xd7\xc3\x02\x18\x66\xf1\xab\x1e\x83\x37\x4c\xcd\x12\xc1\x1d\x50\xf6\xaa\xbd\xfe\xe2\x73\x48\x38\x08\xa0\x32\x9b\x18\x44\x86\x0b\x6a\xc1\xaa\x26\x96\x2d\x96\x3c\xa0\x54\x65\x73\x87\x15\xca\x15\xe5\xf5\x94\x46\x9f\x33\x1a\x0c\x9a\xb1\x5a\xd9\x6a\x95\xcd\xcb\x7e\xec\x9a\xc5\x94\x3b\x37\x26\x31\xd7\xfc\xe4\x1f\x13\x8c\x31\x75\x9c\xba\xf7\x87\x3c\xa1\xb7\x4f\x17\x1b\x09\x82\x98\xc4\x70\x95\xd3\xe8\x4c\x48\x5a\xa6\xd6\x2a\x3d\x56\x42\x80\x9f\xaf\xae\x2e\x50\x0c\x42\xe0\x35\x34\x3c\x8a\x62\x03\x37\xba\xb2\x27\x04\xda\x25\x8d\x06\xe2\xa0\x13\x8a\xf3\xf5\xec\x10\x72\x67\x88\x90\x3d\x4b\x64\xeb\xaa\xda\x8f\xf7\x5a\x75\x47\x9a\xa8\x51\x70\x26\xd2\x38\xc6\x7c\xbb\x57\xfc\xbd\xe4\x04\x56\xa8\xa0\x54\x9a\x45\xd5\xf7\x0f\x16\xfc\x57\x1c\x3c\xdf\x23\xba\x77\x38\xda\x16\x4b\x31\x53\x6a\x4d\x9a\x15\x63\xe7\xe1\x18\x69\x9f\x22\xe0\x24\xbb\x94\x4b\x97\xee\x2d\xf9\x70\x87\x72\x7b\xe6\xc4\x33\x2a\x66\x5e\x1c\x35\x72\xe3\x2d\xda\x73\xe4\xc7\x51\x6d\xa4\xa1\x2a\x4f\xde\x94\xcb\xb2\x3e\x31\x48\xae\x82\xce\xc9\xc8\x65\xcd\xc3\xb7\x34\xb6\x2b\xdf\x58\x65\x78\x6e\x73\xac\x5e\x24\x0d\x3f\xdc\x70\x23\xc6\xda\x52\x0b\x2d\x63\x7d\xa9\x49\x2d\x54\x48\x28\xc0\x12\x9c\xe3\x63\xc9\x58\x04\x98\x36\x07\xc8\x0a\xa7\x91\xd4\xf0\xbc\xc1\xa8\xb9\x70\xd0\xc6\xa9\xb6\x78\x80\x5a\xa3\xb4\x2c\xf4\x18\x0b\x8a\x9d\xd0\xb4\x55\x10\xee\x0d\xc5\xd6\xe0\x99\x93\xdc\xa1\x04\xbb\xf1\xa7\x23\xd1\xd1\x97\x8c\x87\x13\x0a\x21\x02\xe9\x99\x25\xed\x20\xc5\x92\x66\x3c\x32\x9c\xd6\x06\xb0\x31\x5c\x86\x29\x0a\xcb\x60\x33\x12\xa5\x91\xfc\x96\x75\xd0\x59\xd7\x13\xbd\xd3\x23\x79\xdd\x2a\x90\xa6\x38\x06\x91\x39\x7f\x20\x72\x03\x1c\x2d\x01\x61\xba\x45\x37\x38\x22\x61\x8e\x71\x85\xc4\x32\x15\x28\x60\x61\x16\xb8\x3d\x29\xdc\x4d\x3d\x2f\x12\x13\x7d\xc8\x7e\x37\xee\xa8\x7f\xfa\xdb\xcb\x17\xff\x77\xfd\xf9\x7f\xee\x9f\x3d\xfe\xcf\xa7\xa7\x45\xfb\xcf\x1e\xf7\xf3\xe0\xff\xc4\x51\x0a\x8e\x4c\xcb\x01\xdc\x0a\x65\xb2\x01\x83\xed\x3d\xe4\xa9\xa3\x4e\x2d\x59\xc5\xe8\x2f\x48\x7d\x5a\x6e\x37\xbf\x5c\x9f\x35\x13\x64\x14\xfa\xef\x0b\x68\xa6\x0d\xb4\x8e\xf1\xa8\xff\xbb\x60\xf4\x03\x64\xab\x5b\x81\x65\x51\xe6\xda\xca\xfa\xf0\xb0\xac\x3e\x9c\xca\x26\x0e\x1d\xdb\x57\x5b\xbb\xb4\x9a\xa6\xb6\x9b\x1a\x6b\xd1\x9a\x9e\x7e\x33\x9a\xec\x41\x69\x45\x22\xb8\xb4\x51\xeb\x04\x77\xca\x6f\x7b\x7b\xc8\xb2\xb0\x95\x92\x25\x5b\xd0\x42\xaa\x2a\xdd\x32\x78\x4f\x0c\xab\x68\x46\x6c\xea\x6d\xf4\x5c\x5e\xde\xc4\xac\xa5\xf9\xd1\x00\x9f\x7d\x98\x65\x24\xbd\xc7\x97\xd4\xb3\x3a\xa8\x2b\xa0\x34\x76\xf9\x65\x5f\x2d\x25\x95\x1b\xcf\xd6\xf4\x9b\x5f\x09\x95\xb0\x36\x3f\xdb\xd0\x39\x2a\x93\x1c\x9d\x03\xa2\x4a\xca\xf5\xf6\x10\xb6\x94\x89\x0b\x6a\x70\x12\x13\x49\x6e\x40\xe4\x29\x12\x2b\xbd\x80\x45\x11\x04\xaa\xc2\x8f\x56\x9e\x5c\x6b\xec\x8d\x5a\x0e\x14\x59\x06\x2b\x1e\x24\xcb\xc2\x56\x4a\x31\xbe\x23\x71\x1a\xfb\x51\x2a\x0b\x3b\x1c\x48\x10\xa5\x82\xdc\xc0\xbb\x3e\x24\x8d\x5a\x76\x2e\x09\xed\xc1\x65\x51\xb8\x83\xcb\x3e\x24\x8d\x5a\x2e\x5d\xfe\x02\x74\x2d\x3d\xf1\xef\xae\xb8\x4b\xe6\x5e\xd4\xaa\xe2\x2e\x5c\x5e\xec\x0e\xf5\x5b\x0c\xcb\x0a\xbb\xa4\x3c\xf7\x1f\x2a\x55\x69\x97\x8c\x7d\x68\x95\xa5\xad\xb4\xf4\x9c\xa5\x07\xb9\x7a\x05\xbb\xad\x50\x6f\xfb\xa0\x4e\x9b\x48\x23\x49\x92\x28\x87\x19\x3e\x32\xee\xca\x3b\x46\x7e\x7f\x18\x64\xcc\xcc\x0f\x34\xe9\x36\x8b\xb7\x6c\xa8\xa5\x5b\x54\x4c\x54\x5b\x15\x3a\xf1\x6c\x2d\xfe\x96\xc8\x0d\xba\x7b\x81\x88\xc8\x23\xab\xee\x7d\x3b\x92\xa7\x60\x29\xe3\xdc\xff\xb8\x64\xe1\xf6\xa2\x5a\x59\xdc\x6f\xeb\x45\x7d\x6a\xd1\x76\x1e\xea\xb8\xf1\xfa\x14\xd3\x36\x63\xe5\xd7\xf3\xe4\xbe\x25\xbd\x5e\x05\xeb\x73\x74\xb5\x21\x2a\x2e\x4e\xa3\x30\xdf\xbf\x43\x28\x2a\xd1\xa5\x2a\x9d\x8a\xfd\x76\xd8\x8d\xbc\x67\x65\xc7\xb8\x03\x45\xec\xa3\xb0\x37\x8a\x70\x4c\x68\x91\x51\x8e\x58\x80\xed\x4a\xf3\x81\x62\xca\x96\xbb\xf1\x52\xcd\x80\xfb\xe4\x4a\x5d\x6c\xdf\x6e\x20\x4b\x80\x30\x8e\x28\x93\xf9\xe9\x8d\x8a\x6d\xd5\x59\x65\x7b\xaa\x44\x9e\xc0\xc2\xd1\x7c\x40\x26\xd6\x1a\xce\xf9\xc5\x69\x7b\x6c\xec\xc8\x71\x7b\xe5\x21\x2e\xd3\xe5\x65\x93\x91\x53\x0b\x7b\x3a\xc7\xfa\x17\x6a\x01\xa7\x33\xd0\xf4\x40\x0f\x39\x87\xda\xe4\x54\x87\x3a\xd5\xe3\xc7\xa6\x8e\x20\xd4\x11\xb2\x4e\xb1\xe9\x14\x9b\x4e\xb1\xe9\x14\x9b\xfe\x15\x63\xd3\x47\xf5\xff\x97\x38\xe9\xcf\x14\xf8\x76\x82\x49\x13\x4c\xaa\x7d\xcd\x6c\x62\x42\x49\x87\x43\x49\x19\x33\x6f\xe3\x44\x6e\x9b\xab\x8a\x3e\x86\xaa\x99\x52\x1b\x5b\x59\x33\x02\x09\xa0\x21\xa1\x6b\x84\x6b\x66\xbb\xdc\x16\x0c\xd3\x68\xab\xec\x36\x4b\xd8\x60\x8a\x40\x31\x85\x6e\x14\x57\x13\xc2\xfb\x92\x10\xde\xbf\x88\xdc\xbc\x53\x5e\x7f\x82\x7a\x13\xd4\x9b\xa0\xde\x04\xf5\x90\x01\xf5\x94\xcb\x7b\x83\x25\x9e\xd0\xde\x84\xf6\x6a\x5f\x4b\xb3\x98\x00\xdf\x04\xf8\x6c\xbc\x7f\x19\x80\xaf\xf1\x71\x45\x22\x98\x40\xe0\x04\x02\x27\x10\xd8\x29\xf5\x04\x02\xff\x4a\x20\x30\xc1\x72\xf3\x65\x02\x40\xd7\xc1\xd1\xe2\x6b\xf1\xa9\x7b\xfb\xe4\x20\xc0\x68\x9d\xd4\xb4\xd3\x96\xb5\xa6\xd1\x41\x20\xe6\x89\xc3\x48\x65\x58\x13\x84\x9c\x56\x56\x3b\x0c\xe0\x6b\x83\x5c\x13\xd2\x9a\x90\xd6\x84\xb4\x26\xa4\x85\x0c\xa4\x45\x19\xfd\xff\x63\x6c\x52\xb5\x1f\x1e\x19\x74\x3a\xcd\xb9\x69\xce\xa6\x3a\x0f\x7a\x2d\x19\xc7\x81\x14\x5d\xcb\xd5\x03\xc9\x39\xd0\xb0\xd1\xb3\xcd\xfb\x7a\x2d\x5d\x3a\x48\xe1\xfa\x2e\xe6\x81\x42\x18\x86\xd6\xc1\xbe\xb1\x23\xd3\xf7\x34\xed\x19\x0a\x0b\xc4\x48\x44\xfd\x22\x50\xb6\x42\x58\xbb\xe5\x3d\xa7\x73\xd4\x8b\xc4\x8c\x70\x61\xec\x73\xee\xc3\x81\x8b\xf5\xe2\xd7\x52\x3e\xcf\xeb\xeb\x17\x3b\x71\x16\xda\x7d\xb8\xde\xf0\x7a\x8f\x06\x2d\xa7\x40\x7b\xc1\x9d\x41\x4d\xb6\x61\xa2\x4e\x9f\x3d\xa0\xc5\xae\xe3\x1c\x1d\x40\x6c\x48\x8b\x63\xa0\xb5\x01\xed\x8e\x02\xe9\x86\xc8\x3b\x06\xee\xdb\x4b\xde\xbd\xc0\xa1\x6f\xcb\xda\xfc\xc2\x44\x16\x87\x9c\x17\x31\xd3\x30\x20\x39\x42\xcb\x6f\xf2\xf1\xf4\x72\x10\xf8\x1c\xa0\xf3\xbd\x10\xea\x21\x35\x7d\xe8\x86\xdb\x15\xed\x81\x81\x07\x28\xbb\x13\x28\xc7\xf8\xce\x7d\x8d\xc2\x31\xb4\x7e\x94\xd6\xdb\x55\xef\x4a\xfb\xed\xc3\x40\x3e\xeb\x9f\xe9\x99\x0f\xdf\x08\x65\x88\x27\x73\x86\x31\x9d\x47\xdf\x55\x19\xba\x3d\xee\x15\x0a\xcd\x8c\xaa\x5e\xb9\xf6\x57\x33\x73\x5a\xa1\x89\x7b\x3b\xa0\xb2\xa4\xc2\xf6\xc1\x53\xb5\x00\xca\x23\xe5\xf4\x60\x6a\xb4\x2d\x74\xea\x4e\xed\x3b\xe3\x47\xfb\xed\x82\x3d\x19\xd4\x3b\x6b\xaf\xae\x2b\x2f\x57\xb3\x82\x68\xcb\xed\x88\x2e\xe1\x5c\xd7\x26\xfa\x0a\x65\xe7\xce\x11\x33\xb4\xdd\x66\xe3\x37\xf6\xfa\x70\xd6\x4f\xa1\x21\x51\xd8\x3c\x26\x14\x4b\xc6\x87\x44\x27\x1c\x70\xf8\x9e\x46\xce\xab\x21\x07\x5f\xc1\x76\x17\x1b\x77\xb4\xda\x75\xa0\x0a\x3a\x30\xe1\xf8\x97\x32\x16\x2b\x00\x75\x85\xee\x62\x46\xef\xd3\x85\xb5\x6b\x60\xbe\xf2\x30\x7a\x8c\x0b\x4b\xa6\xd0\xf9\x64\x42\xe7\x07\x41\x41\xe3\x2c\x5d\xf9\x6d\xe9\x39\x98\x3b\x3b\x5d\x67\xd4\x5c\xed\xf2\xf0\x48\x7b\xbd\x2d\x31\xdd\x3f\x34\xad\x44\x76\x51\x9a\x56\x22\xa7\x95\xc8\x69\x25\xf2\xe1\x56\x22\x1f\x00\x32\x6a\x73\x92\xed\xe1\xc6\x7d\x9f\x49\x2c\x69\x7e\xc8\x31\x4c\x0c\xb4\xf2\x54\x3b\x79\x3b\x9e\x4d\xb4\xd1\x18\x3e\x5f\x9a\x93\xa2\x11\xc3\xda\x27\x0b\xaf\x37\x2e\x5c\x37\xfb\xeb\x9a\xd6\xc3\xac\xc3\xcc\xf8\x1e\x5b\x9d\xac\x22\x64\xb7\xed\x26\xb8\xf3\xb9\x3c\xbb\x1f\xe2\xb0\x22\x77\x43\x6a\x62\x29\x39\x59\xa6\xe6\xe5\xcd\x7b\x83\xc0\x5b\x8e\x93\x64\xac\xeb\xca\x4f\x65\xac\x4a\xbc\x1e\xcd\x82\xfa\x3c\x70\x36\xb6\xb5\xed\x79\xef\xec\x68\x00\xff\x54\xfa\xb5\xe3\xf1\xdb\xe1\xbe\xce\x76\x17\xaf\x57\xb6\x6b\x89\x05\x09\xce\x52\xb9\x01\x2a\x49\xbe\xd9\xf4\xd2\xb8\x7a\xbf\x91\x02\xf3\x22\x8c\x13\xf2\x77\xd8\x8e\x43\x8b\xe1\x54\x6e\x5e\x9d\xc7\x49\x44\x02\x22\xc7\xa4\x79\x81\x85\xb8\x65\x3c\x1c\x93\xe6\x59\xa2\xf8\x1c\x51\x95\x05\xd9\x20\x00\x21\x7e\x60\x21\x58\xa9\x56\xff\xbe\xb6\x5a\x5e\x5b\x3f\x1f\xd6\xd3\x3c\xc4\x4d\xba\x99\xb4\x63\x6e\x7d\x3e\x3d\x57\xd2\x18\x5f\x47\xe8\xc3\x06\x8a\x68\x6c\x7f\x3b\x72\x0f\xe7\xe2\x77\x77\xf1\xd0\x99\xab\xdf\x2e\xfe\xd6\xbb\xcd\x1a\xb9\x90\xd1\xaf\xf2\x38\x3d\xdb\x74\xf8\xeb\xe3\xda\xe8\x2a\x62\xb7\xda\x1b\x07\xa9\xdc\x30\x5e\xbc\x68\xfb\x6b\x9f\x97\xf1\xc6\xb1\xd8\x5c\x29\x1e\x49\x30\xc5\xf7\xde\xad\x91\x42\xf9\xdd\xed\x89\x80\x25\xbe\x37\xd7\xe7\x32\x5c\xe6\x35\xac\xd4\x0c\x2d\xf7\x90\xc4\xe3\xf5\xe3\x2f\x7f\x54\x18\x88\xe3\x61\x47\x85\x64\x7f\xc0\xd7\x3f\x1a\x92\x42\xe9\xc7\x1e\x0d\x95\x76\xa7\x51\xa0\x8f\x02\x1b\x46\x9e\x06\x42\xd1\xf2\x01\x07\x02\xde\xe9\x7d\x1a\x0b\xa7\x32\x16\xcc\xc0\xee\xc4\x90\xd2\x5f\x6f\x98\x54\x5d\xf2\x95\xe1\xa7\x69\x10\x3a\x06\xe1\x65\xb3\x17\x47\x58\x78\xd0\x45\xd6\x5b\xd5\x5f\x25\x1d\x71\x49\xa6\x7a\x64\xda\xd0\x6f\xc7\x3a\x4c\xe3\x09\xc0\x6e\x96\x2c\xa7\xa7\x77\x34\x10\x05\x08\x21\x44\x92\x65\x77\xdf\x20\x5c\xbc\xe7\x97\x3f\xf4\x1a\x45\xd6\xe7\x27\x4a\xde\x74\x27\x66\x11\x7d\x70\xba\xd3\x78\xf9\x1e\x0d\xca\xc8\x39\xde\x7c\xb3\xa6\xe1\xbc\xd7\xc1\x6a\x6f\xb3\x0e\x52\xbe\xe4\x98\x8a\x15\x70\x94\x70\x26\x59\xc0\xa2\xf2\x1c\xfb\xd9\xc5\xf9\xbc\xd5\x92\x9c\xa3\xdf\xe6\x1e\xb3\x0d\x49\xba\x87\x50\x5f\x84\xfe\xe9\xd6\xf8\xbb\xe6\xf0\x7a\xeb\xa6\x65\x3b\x86\x8b\x79\x93\xf5\x59\x20\x6e\xb4\xa7\x44\xf4\x3f\xa5\xfe\x67\x42\x12\xdb\xd3\xe7\xbb\xa5\xa3\x8c\x5c\x2b\x97\xbb\xbb\x7f\x8e\xc5\x6e\xed\x43\x5c\xbf\x74\xc8\x8f\xff\xe6\xd6\xbe\x91\xb6\xf5\x95\xe4\xed\x93\xc4\xa8\x5b\xf9\x76\x4d\x35\xb7\xd8\x8c\xb6\x7d\xaf\x72\xe0\xb6\xbd\x01\x63\x9e\x76\xab\x1a\x32\x76\xe4\x8c\x76\xc2\xad\x6c\xa2\x65\xf7\xcf\xf8\xa7\xda\x2a\xb9\x8c\x3d\x3c\xa3\x9d\x64\x33\xe5\x1a\xb5\x2d\xfb\x86\xa2\x5a\x7f\x19\x5b\x7f\xc6\x3f\xd1\x53\xd3\xe2\x41\x5b\xd3\x4f\xf0\xec\xb0\x42\x73\x43\xd2\x68\x27\xd3\x6a\x6a\x34\xf6\x4e\x1e\x52\x8b\x87\x6c\xcc\xae\x44\xfb\x9e\xa7\x51\x4f\x9d\x55\x03\x81\x8e\x67\xfc\xb4\x69\xf0\x3a\x18\xf2\x40\xd0\xf6\xa8\x34\xe3\xc9\x98\xaf\xf6\xda\x24\xd3\xeb\x60\xb9\x0e\xd3\x1f\xa9\xff\xee\x1f\xfd\x37\x00\x00\xff\xff\x69\x5d\x0a\x6a\x39\x9d\x00\x00") - -func v2SchemaJSONBytes() ([]byte, error) { - return bindataRead( - _v2SchemaJSON, - "v2/schema.json", - ) -} - -func v2SchemaJSON() (*asset, error) { - bytes, err := v2SchemaJSONBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "v2/schema.json", size: 40249, mode: os.FileMode(420), modTime: time.Unix(1523760397, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -// Asset loads and returns the asset for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func Asset(name string) ([]byte, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) - } - return a.bytes, nil - } - return nil, fmt.Errorf("Asset %s not found", name) -} - -// MustAsset is like Asset but panics when Asset would return an error. -// It simplifies safe initialization of global variables. -func MustAsset(name string) []byte { - a, err := Asset(name) - if err != nil { - panic("asset: Asset(" + name + "): " + err.Error()) - } - - return a -} - -// AssetInfo loads and returns the asset info for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func AssetInfo(name string) (os.FileInfo, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) - } - return a.info, nil - } - return nil, fmt.Errorf("AssetInfo %s not found", name) -} - -// AssetNames returns the names of the assets. -func AssetNames() []string { - names := make([]string, 0, len(_bindata)) - for name := range _bindata { - names = append(names, name) - } - return names -} - -// _bindata is a table, holding each asset generator, mapped to its name. -var _bindata = map[string]func() (*asset, error){ - "jsonschema-draft-04.json": jsonschemaDraft04JSON, - "v2/schema.json": v2SchemaJSON, -} - -// AssetDir returns the file names below a certain -// directory embedded in the file by go-bindata. -// For example if you run go-bindata on data/... and data contains the -// following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png -// then AssetDir("data") would return []string{"foo.txt", "img"} -// AssetDir("data/img") would return []string{"a.png", "b.png"} -// AssetDir("foo.txt") and AssetDir("notexist") would return an error -// AssetDir("") will return []string{"data"}. -func AssetDir(name string) ([]string, error) { - node := _bintree - if len(name) != 0 { - cannonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(cannonicalName, "/") - for _, p := range pathList { - node = node.Children[p] - if node == nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - } - } - if node.Func != nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - rv := make([]string, 0, len(node.Children)) - for childName := range node.Children { - rv = append(rv, childName) - } - return rv, nil -} - -type bintree struct { - Func func() (*asset, error) - Children map[string]*bintree -} -var _bintree = &bintree{nil, map[string]*bintree{ - "jsonschema-draft-04.json": &bintree{jsonschemaDraft04JSON, map[string]*bintree{}}, - "v2": &bintree{nil, map[string]*bintree{ - "schema.json": &bintree{v2SchemaJSON, map[string]*bintree{}}, - }}, -}} - -// RestoreAsset restores an asset under the given directory -func RestoreAsset(dir, name string) error { - data, err := Asset(name) - if err != nil { - return err - } - info, err := AssetInfo(name) - if err != nil { - return err - } - err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) - if err != nil { - return err - } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) - if err != nil { - return err - } - err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) - if err != nil { - return err - } - return nil -} - -// RestoreAssets restores an asset under the given directory recursively -func RestoreAssets(dir, name string) error { - children, err := AssetDir(name) - // File - if err != nil { - return RestoreAsset(dir, name) - } - // Dir - for _, child := range children { - err = RestoreAssets(dir, filepath.Join(name, child)) - if err != nil { - return err - } - } - return nil -} - -func _filePath(dir, name string) string { - cannonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) -} - diff --git a/vendor/github.com/go-openapi/spec/contact_info.go b/vendor/github.com/go-openapi/spec/contact_info.go deleted file mode 100644 index f285970aa..000000000 --- a/vendor/github.com/go-openapi/spec/contact_info.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -// ContactInfo contact information for the exposed API. -// -// For more information: http://goo.gl/8us55a#contactObject -type ContactInfo struct { - Name string `json:"name,omitempty"` - URL string `json:"url,omitempty"` - Email string `json:"email,omitempty"` -} diff --git a/vendor/github.com/go-openapi/spec/expander.go b/vendor/github.com/go-openapi/spec/expander.go deleted file mode 100644 index ad1529db5..000000000 --- a/vendor/github.com/go-openapi/spec/expander.go +++ /dev/null @@ -1,1048 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - "fmt" - "log" - "net/url" - "os" - "path" - "path/filepath" - "reflect" - "strings" - "sync" - - "github.com/go-openapi/jsonpointer" - "github.com/go-openapi/swag" -) - -var ( - // Debug enables logging when SWAGGER_DEBUG env var is not empty - Debug = os.Getenv("SWAGGER_DEBUG") != "" -) - -// ExpandOptions provides options for expand. -type ExpandOptions struct { - RelativeBase string - SkipSchemas bool - ContinueOnError bool -} - -// ResolutionCache a cache for resolving urls -type ResolutionCache interface { - Get(string) (interface{}, bool) - Set(string, interface{}) -} - -type simpleCache struct { - lock sync.Mutex - store map[string]interface{} -} - -var resCache ResolutionCache - -func init() { - resCache = initResolutionCache() -} - -func initResolutionCache() ResolutionCache { - return &simpleCache{store: map[string]interface{}{ - "http://swagger.io/v2/schema.json": MustLoadSwagger20Schema(), - "http://json-schema.org/draft-04/schema": MustLoadJSONSchemaDraft04(), - }} -} - -func (s *simpleCache) Get(uri string) (interface{}, bool) { - debugLog("getting %q from resolution cache", uri) - s.lock.Lock() - v, ok := s.store[uri] - debugLog("got %q from resolution cache: %t", uri, ok) - - s.lock.Unlock() - return v, ok -} - -func (s *simpleCache) Set(uri string, data interface{}) { - s.lock.Lock() - s.store[uri] = data - s.lock.Unlock() -} - -// ResolveRefWithBase resolves a reference against a context root with preservation of base path -func ResolveRefWithBase(root interface{}, ref *Ref, opts *ExpandOptions) (*Schema, error) { - resolver, err := defaultSchemaLoader(root, opts, nil) - if err != nil { - return nil, err - } - specBasePath := "" - if opts != nil && opts.RelativeBase != "" { - specBasePath, _ = absPath(opts.RelativeBase) - } - - result := new(Schema) - if err := resolver.Resolve(ref, result, specBasePath); err != nil { - return nil, err - } - return result, nil -} - -// ResolveRef resolves a reference against a context root -// ref is guaranteed to be in root (no need to go to external files) -// ResolveRef is ONLY called from the code generation module -func ResolveRef(root interface{}, ref *Ref) (*Schema, error) { - res, _, err := ref.GetPointer().Get(root) - if err != nil { - panic(err) - } - switch sch := res.(type) { - case Schema: - return &sch, nil - case *Schema: - return sch, nil - case map[string]interface{}: - b, _ := json.Marshal(sch) - newSch := new(Schema) - json.Unmarshal(b, newSch) - return newSch, nil - default: - return nil, fmt.Errorf("unknown type for the resolved reference") - } -} - -// ResolveParameter resolves a paramter reference against a context root -func ResolveParameter(root interface{}, ref Ref) (*Parameter, error) { - return ResolveParameterWithBase(root, ref, nil) -} - -// ResolveParameterWithBase resolves a paramter reference against a context root and base path -func ResolveParameterWithBase(root interface{}, ref Ref, opts *ExpandOptions) (*Parameter, error) { - resolver, err := defaultSchemaLoader(root, opts, nil) - if err != nil { - return nil, err - } - - result := new(Parameter) - if err := resolver.Resolve(&ref, result, ""); err != nil { - return nil, err - } - return result, nil -} - -// ResolveResponse resolves response a reference against a context root -func ResolveResponse(root interface{}, ref Ref) (*Response, error) { - return ResolveResponseWithBase(root, ref, nil) -} - -// ResolveResponseWithBase resolves response a reference against a context root and base path -func ResolveResponseWithBase(root interface{}, ref Ref, opts *ExpandOptions) (*Response, error) { - resolver, err := defaultSchemaLoader(root, opts, nil) - if err != nil { - return nil, err - } - - result := new(Response) - if err := resolver.Resolve(&ref, result, ""); err != nil { - return nil, err - } - return result, nil -} - -// ResolveItems resolves header and parameter items reference against a context root and base path -func ResolveItems(root interface{}, ref Ref, opts *ExpandOptions) (*Items, error) { - resolver, err := defaultSchemaLoader(root, opts, nil) - if err != nil { - return nil, err - } - basePath := "" - if opts.RelativeBase != "" { - basePath = opts.RelativeBase - } - result := new(Items) - if err := resolver.Resolve(&ref, result, basePath); err != nil { - return nil, err - } - return result, nil -} - -// ResolvePathItem resolves response a path item against a context root and base path -func ResolvePathItem(root interface{}, ref Ref, opts *ExpandOptions) (*PathItem, error) { - resolver, err := defaultSchemaLoader(root, opts, nil) - if err != nil { - return nil, err - } - basePath := "" - if opts.RelativeBase != "" { - basePath = opts.RelativeBase - } - result := new(PathItem) - if err := resolver.Resolve(&ref, result, basePath); err != nil { - return nil, err - } - return result, nil -} - -type schemaLoader struct { - root interface{} - options *ExpandOptions - cache ResolutionCache - loadDoc func(string) (json.RawMessage, error) -} - -var idPtr, _ = jsonpointer.New("/id") -var refPtr, _ = jsonpointer.New("/$ref") - -// PathLoader function to use when loading remote refs -var PathLoader func(string) (json.RawMessage, error) - -func init() { - PathLoader = func(path string) (json.RawMessage, error) { - data, err := swag.LoadFromFileOrHTTP(path) - if err != nil { - return nil, err - } - return json.RawMessage(data), nil - } -} - -func defaultSchemaLoader( - root interface{}, - expandOptions *ExpandOptions, - cache ResolutionCache) (*schemaLoader, error) { - - if cache == nil { - cache = resCache - } - if expandOptions == nil { - expandOptions = &ExpandOptions{} - } - - return &schemaLoader{ - root: root, - options: expandOptions, - cache: cache, - loadDoc: func(path string) (json.RawMessage, error) { - debugLog("fetching document at %q", path) - return PathLoader(path) - }, - }, nil -} - -func idFromNode(node interface{}) (*Ref, error) { - if idValue, _, err := idPtr.Get(node); err == nil { - if refStr, ok := idValue.(string); ok && refStr != "" { - idRef, err := NewRef(refStr) - if err != nil { - return nil, err - } - return &idRef, nil - } - } - return nil, nil -} - -func nextRef(startingNode interface{}, startingRef *Ref, ptr *jsonpointer.Pointer) *Ref { - if startingRef == nil { - return nil - } - - if ptr == nil { - return startingRef - } - - ret := startingRef - var idRef *Ref - node := startingNode - - for _, tok := range ptr.DecodedTokens() { - node, _, _ = jsonpointer.GetForToken(node, tok) - if node == nil { - break - } - - idRef, _ = idFromNode(node) - if idRef != nil { - nw, err := ret.Inherits(*idRef) - if err != nil { - break - } - ret = nw - } - - refRef, _, _ := refPtr.Get(node) - if refRef != nil { - var rf Ref - switch value := refRef.(type) { - case string: - rf, _ = NewRef(value) - } - nw, err := ret.Inherits(rf) - if err != nil { - break - } - nwURL := nw.GetURL() - if nwURL.Scheme == "file" || (nwURL.Scheme == "" && nwURL.Host == "") { - nwpt := filepath.ToSlash(nwURL.Path) - if filepath.IsAbs(nwpt) { - _, err := os.Stat(nwpt) - if err != nil { - nwURL.Path = filepath.Join(".", nwpt) - } - } - } - - ret = nw - } - - } - - return ret -} - -func debugLog(msg string, args ...interface{}) { - if Debug { - log.Printf(msg, args...) - } -} - -// normalize absolute path for cache. -// on Windows, drive letters should be converted to lower as scheme in net/url.URL -func normalizeAbsPath(path string) string { - u, err := url.Parse(path) - if err != nil { - debugLog("normalize absolute path failed: %s", err) - return path - } - return u.String() -} - -// base or refPath could be a file path or a URL -// given a base absolute path and a ref path, return the absolute path of refPath -// 1) if refPath is absolute, return it -// 2) if refPath is relative, join it with basePath keeping the scheme, hosts, and ports if exists -// base could be a directory or a full file path -func normalizePaths(refPath, base string) string { - refURL, _ := url.Parse(refPath) - if path.IsAbs(refURL.Path) || filepath.IsAbs(refPath) { - // refPath is actually absolute - if refURL.Host != "" { - return refPath - } - parts := strings.Split(refPath, "#") - result := filepath.FromSlash(parts[0]) - if len(parts) == 2 { - result += "#" + parts[1] - } - return result - } - - // relative refPath - baseURL, _ := url.Parse(base) - if !strings.HasPrefix(refPath, "#") { - // combining paths - if baseURL.Host != "" { - baseURL.Path = path.Join(path.Dir(baseURL.Path), refURL.Path) - } else { // base is a file - newBase := fmt.Sprintf("%s#%s", filepath.Join(filepath.Dir(base), filepath.FromSlash(refURL.Path)), refURL.Fragment) - return newBase - } - - } - // copying fragment from ref to base - baseURL.Fragment = refURL.Fragment - return baseURL.String() -} - -// relativeBase could be an ABSOLUTE file path or an ABSOLUTE URL -func normalizeFileRef(ref *Ref, relativeBase string) *Ref { - // This is important for when the reference is pointing to the root schema - if ref.String() == "" { - r, _ := NewRef(relativeBase) - return &r - } - - refURL := ref.GetURL() - debugLog("normalizing %s against %s (%s)", ref.String(), relativeBase, refURL.String()) - - s := normalizePaths(ref.String(), relativeBase) - r, _ := NewRef(s) - return &r -} - -func (r *schemaLoader) resolveRef(ref *Ref, target interface{}, basePath string) error { - tgt := reflect.ValueOf(target) - if tgt.Kind() != reflect.Ptr { - return fmt.Errorf("resolve ref: target needs to be a pointer") - } - - refURL := ref.GetURL() - if refURL == nil { - return nil - } - - var res interface{} - var data interface{} - var err error - // Resolve against the root if it isn't nil, and if ref is pointing at the root, or has a fragment only which means - // it is pointing somewhere in the root. - root := r.root - if (ref.IsRoot() || ref.HasFragmentOnly) && root == nil && basePath != "" { - if baseRef, err := NewRef(basePath); err == nil { - root, _, _, _ = r.load(baseRef.GetURL()) - } - } - if (ref.IsRoot() || ref.HasFragmentOnly) && root != nil { - data = root - } else { - baseRef := normalizeFileRef(ref, basePath) - debugLog("current ref is: %s", ref.String()) - debugLog("current ref normalized file: %s", baseRef.String()) - data, _, _, err = r.load(baseRef.GetURL()) - if err != nil { - return err - } - } - - res = data - if ref.String() != "" { - res, _, err = ref.GetPointer().Get(data) - if err != nil { - return err - } - } - if err := swag.DynamicJSONToStruct(res, target); err != nil { - return err - } - - return nil -} - -func (r *schemaLoader) load(refURL *url.URL) (interface{}, url.URL, bool, error) { - debugLog("loading schema from url: %s", refURL) - toFetch := *refURL - toFetch.Fragment = "" - - normalized := normalizeAbsPath(toFetch.String()) - - data, fromCache := r.cache.Get(normalized) - if !fromCache { - b, err := r.loadDoc(normalized) - if err != nil { - return nil, url.URL{}, false, err - } - - if err := json.Unmarshal(b, &data); err != nil { - return nil, url.URL{}, false, err - } - r.cache.Set(normalized, data) - } - - return data, toFetch, fromCache, nil -} - -// Resolve resolves a reference against basePath and stores the result in target -// Resolve is not in charge of following references, it only resolves ref by following its URL -// if the schema that ref is referring to has more refs in it. Resolve doesn't resolve them -// if basePath is an empty string, ref is resolved against the root schema stored in the schemaLoader struct -func (r *schemaLoader) Resolve(ref *Ref, target interface{}, basePath string) error { - return r.resolveRef(ref, target, basePath) -} - -// absPath returns the absolute path of a file -func absPath(fname string) (string, error) { - if strings.HasPrefix(fname, "http") { - return fname, nil - } - if filepath.IsAbs(fname) { - return fname, nil - } - wd, err := os.Getwd() - return filepath.Join(wd, fname), err -} - -// ExpandSpec expands the references in a swagger spec -func ExpandSpec(spec *Swagger, options *ExpandOptions) error { - resolver, err := defaultSchemaLoader(spec, options, nil) - // Just in case this ever returns an error. - if shouldStopOnError(err, resolver.options) { - return err - } - - // getting the base path of the spec to adjust all subsequent reference resolutions - specBasePath := "" - if options != nil && options.RelativeBase != "" { - specBasePath, _ = absPath(options.RelativeBase) - } - - if options == nil || !options.SkipSchemas { - for key, definition := range spec.Definitions { - var def *Schema - var err error - if def, err = expandSchema(definition, []string{fmt.Sprintf("#/definitions/%s", key)}, resolver, specBasePath); shouldStopOnError(err, resolver.options) { - return err - } - if def != nil { - spec.Definitions[key] = *def - } - } - } - - for key, parameter := range spec.Parameters { - if err := expandParameter(¶meter, resolver, specBasePath); shouldStopOnError(err, resolver.options) { - return err - } - spec.Parameters[key] = parameter - } - - for key, response := range spec.Responses { - if err := expandResponse(&response, resolver, specBasePath); shouldStopOnError(err, resolver.options) { - return err - } - spec.Responses[key] = response - } - - if spec.Paths != nil { - for key, path := range spec.Paths.Paths { - if err := expandPathItem(&path, resolver, specBasePath); shouldStopOnError(err, resolver.options) { - return err - } - spec.Paths.Paths[key] = path - } - } - - return nil -} - -func shouldStopOnError(err error, opts *ExpandOptions) bool { - if err != nil && !opts.ContinueOnError { - return true - } - - if err != nil { - log.Println(err) - } - - return false -} - -// ExpandSchema expands the refs in the schema object with reference to the root object -// go-openapi/validate uses this function -// notice that it is impossible to reference a json scema in a different file other than root -func ExpandSchema(schema *Schema, root interface{}, cache ResolutionCache) error { - // Only save the root to a tmp file if it isn't nil. - var base string - if root != nil { - base, _ = absPath("root") - if cache == nil { - cache = resCache - } - cache.Set(normalizeAbsPath(base), root) - base = "root" - } - - opts := &ExpandOptions{ - RelativeBase: base, - SkipSchemas: false, - ContinueOnError: false, - } - return ExpandSchemaWithBasePath(schema, cache, opts) -} - -// ExpandSchemaWithBasePath expands the refs in the schema object, base path configured through expand options -func ExpandSchemaWithBasePath(schema *Schema, cache ResolutionCache, opts *ExpandOptions) error { - if schema == nil { - return nil - } - - var basePath string - if opts.RelativeBase != "" { - basePath, _ = absPath(opts.RelativeBase) - } - - resolver, err := defaultSchemaLoader(nil, opts, cache) - if err != nil { - return err - } - - refs := []string{""} - var s *Schema - if s, err = expandSchema(*schema, refs, resolver, basePath); err != nil { - return err - } - *schema = *s - return nil -} - -func expandItems(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) { - if target.Items != nil { - if target.Items.Schema != nil { - t, err := expandSchema(*target.Items.Schema, parentRefs, resolver, basePath) - if err != nil { - return nil, err - } - *target.Items.Schema = *t - } - for i := range target.Items.Schemas { - t, err := expandSchema(target.Items.Schemas[i], parentRefs, resolver, basePath) - if err != nil { - return nil, err - } - target.Items.Schemas[i] = *t - } - } - return &target, nil -} - -// basePathFromSchemaID returns a new basePath based on an existing basePath and a schema ID -func basePathFromSchemaID(oldBasePath, id string) string { - u, err := url.Parse(oldBasePath) - if err != nil { - panic(err) - } - uid, err := url.Parse(id) - if err != nil { - panic(err) - } - - if path.IsAbs(uid.Path) { - return id - } - u.Path = path.Join(path.Dir(u.Path), uid.Path) - return u.String() -} - -func isCircular(ref *Ref, basePath string, parentRefs ...string) bool { - return basePath != "" && swag.ContainsStringsCI(parentRefs, ref.String()) -} - -func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) { - if target.Ref.String() == "" && target.Ref.IsRoot() { - // normalizing is important - newRef := normalizeFileRef(&target.Ref, basePath) - target.Ref = *newRef - return &target, nil - - } - - /* change the base path of resolution when an ID is encountered - otherwise the basePath should inherit the parent's */ - // important: ID can be relative path - if target.ID != "" { - // handling the case when id is a folder - // remember that basePath has to be a file - refPath := target.ID - if strings.HasSuffix(target.ID, "/") { - // path.Clean here would not work correctly if basepath is http - refPath = fmt.Sprintf("%s%s", refPath, "placeholder.json") - } - basePath = normalizePaths(refPath, basePath) - } - - /* Explain here what this function does */ - - var t *Schema - /* if Ref is found, everything else doesn't matter */ - /* Ref also changes the resolution scope of children expandSchema */ - if target.Ref.String() != "" { - /* Here the resolution scope is changed because a $ref was encountered */ - normalizedRef := normalizeFileRef(&target.Ref, basePath) - normalizedBasePath := normalizedRef.RemoteURI() - - /* this means there is a circle in the recursion tree */ - /* return the Ref */ - if isCircular(normalizedRef, basePath, parentRefs...) { - target.Ref = *normalizedRef - return &target, nil - } - - debugLog("\nbasePath: %s", basePath) - if Debug { - b, _ := json.Marshal(target) - debugLog("calling Resolve with target: %s", string(b)) - } - if err := resolver.Resolve(&target.Ref, &t, basePath); shouldStopOnError(err, resolver.options) { - return nil, err - } - - if t != nil { - parentRefs = append(parentRefs, normalizedRef.String()) - var err error - resolver, err = transitiveResolver(basePath, target.Ref, resolver) - if shouldStopOnError(err, resolver.options) { - return nil, err - } - - return expandSchema(*t, parentRefs, resolver, normalizedBasePath) - } - } - - t, err := expandItems(target, parentRefs, resolver, basePath) - if shouldStopOnError(err, resolver.options) { - return &target, err - } - if t != nil { - target = *t - } - - for i := range target.AllOf { - t, err := expandSchema(target.AllOf[i], parentRefs, resolver, basePath) - if shouldStopOnError(err, resolver.options) { - return &target, err - } - target.AllOf[i] = *t - } - for i := range target.AnyOf { - t, err := expandSchema(target.AnyOf[i], parentRefs, resolver, basePath) - if shouldStopOnError(err, resolver.options) { - return &target, err - } - target.AnyOf[i] = *t - } - for i := range target.OneOf { - t, err := expandSchema(target.OneOf[i], parentRefs, resolver, basePath) - if shouldStopOnError(err, resolver.options) { - return &target, err - } - if t != nil { - target.OneOf[i] = *t - } - } - if target.Not != nil { - t, err := expandSchema(*target.Not, parentRefs, resolver, basePath) - if shouldStopOnError(err, resolver.options) { - return &target, err - } - if t != nil { - *target.Not = *t - } - } - for k := range target.Properties { - t, err := expandSchema(target.Properties[k], parentRefs, resolver, basePath) - if shouldStopOnError(err, resolver.options) { - return &target, err - } - if t != nil { - target.Properties[k] = *t - } - } - if target.AdditionalProperties != nil && target.AdditionalProperties.Schema != nil { - t, err := expandSchema(*target.AdditionalProperties.Schema, parentRefs, resolver, basePath) - if shouldStopOnError(err, resolver.options) { - return &target, err - } - if t != nil { - *target.AdditionalProperties.Schema = *t - } - } - for k := range target.PatternProperties { - t, err := expandSchema(target.PatternProperties[k], parentRefs, resolver, basePath) - if shouldStopOnError(err, resolver.options) { - return &target, err - } - if t != nil { - target.PatternProperties[k] = *t - } - } - for k := range target.Dependencies { - if target.Dependencies[k].Schema != nil { - t, err := expandSchema(*target.Dependencies[k].Schema, parentRefs, resolver, basePath) - if shouldStopOnError(err, resolver.options) { - return &target, err - } - if t != nil { - *target.Dependencies[k].Schema = *t - } - } - } - if target.AdditionalItems != nil && target.AdditionalItems.Schema != nil { - t, err := expandSchema(*target.AdditionalItems.Schema, parentRefs, resolver, basePath) - if shouldStopOnError(err, resolver.options) { - return &target, err - } - if t != nil { - *target.AdditionalItems.Schema = *t - } - } - for k := range target.Definitions { - t, err := expandSchema(target.Definitions[k], parentRefs, resolver, basePath) - if shouldStopOnError(err, resolver.options) { - return &target, err - } - if t != nil { - target.Definitions[k] = *t - } - } - return &target, nil -} - -func derefPathItem(pathItem *PathItem, parentRefs []string, resolver *schemaLoader, basePath string) error { - curRef := pathItem.Ref.String() - if curRef != "" { - normalizedRef := normalizeFileRef(&pathItem.Ref, basePath) - normalizedBasePath := normalizedRef.RemoteURI() - - if isCircular(normalizedRef, basePath, parentRefs...) { - return nil - } - - if err := resolver.Resolve(&pathItem.Ref, pathItem, basePath); shouldStopOnError(err, resolver.options) { - return err - } - - if pathItem.Ref.String() != "" && pathItem.Ref.String() != curRef && basePath != normalizedBasePath { - parentRefs = append(parentRefs, normalizedRef.String()) - return derefPathItem(pathItem, parentRefs, resolver, normalizedBasePath) - } - } - - return nil -} - -func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string) error { - if pathItem == nil { - return nil - } - - parentRefs := []string{} - if err := derefPathItem(pathItem, parentRefs, resolver, basePath); shouldStopOnError(err, resolver.options) { - return err - } - if pathItem.Ref.String() != "" { - var err error - resolver, err = transitiveResolver(basePath, pathItem.Ref, resolver) - if shouldStopOnError(err, resolver.options) { - return err - } - } - pathItem.Ref = Ref{} - - parentRefs = parentRefs[0:] - - for idx := range pathItem.Parameters { - if err := expandParameter(&(pathItem.Parameters[idx]), resolver, basePath); shouldStopOnError(err, resolver.options) { - return err - } - } - if err := expandOperation(pathItem.Get, resolver, basePath); shouldStopOnError(err, resolver.options) { - return err - } - if err := expandOperation(pathItem.Head, resolver, basePath); shouldStopOnError(err, resolver.options) { - return err - } - if err := expandOperation(pathItem.Options, resolver, basePath); shouldStopOnError(err, resolver.options) { - return err - } - if err := expandOperation(pathItem.Put, resolver, basePath); shouldStopOnError(err, resolver.options) { - return err - } - if err := expandOperation(pathItem.Post, resolver, basePath); shouldStopOnError(err, resolver.options) { - return err - } - if err := expandOperation(pathItem.Patch, resolver, basePath); shouldStopOnError(err, resolver.options) { - return err - } - if err := expandOperation(pathItem.Delete, resolver, basePath); shouldStopOnError(err, resolver.options) { - return err - } - return nil -} - -func expandOperation(op *Operation, resolver *schemaLoader, basePath string) error { - if op == nil { - return nil - } - - for i, param := range op.Parameters { - if err := expandParameter(¶m, resolver, basePath); shouldStopOnError(err, resolver.options) { - return err - } - op.Parameters[i] = param - } - - if op.Responses != nil { - responses := op.Responses - if err := expandResponse(responses.Default, resolver, basePath); shouldStopOnError(err, resolver.options) { - return err - } - for code, response := range responses.StatusCodeResponses { - if err := expandResponse(&response, resolver, basePath); shouldStopOnError(err, resolver.options) { - return err - } - responses.StatusCodeResponses[code] = response - } - } - return nil -} - -func transitiveResolver(basePath string, ref Ref, resolver *schemaLoader) (*schemaLoader, error) { - if ref.IsRoot() || ref.HasFragmentOnly { - return resolver, nil - } - - baseRef, _ := NewRef(basePath) - currentRef := normalizeFileRef(&ref, basePath) - // Set a new root to resolve against - if !strings.HasPrefix(currentRef.String(), baseRef.String()) { - rootURL := currentRef.GetURL() - rootURL.Fragment = "" - root, _ := resolver.cache.Get(rootURL.String()) - var err error - resolver, err = defaultSchemaLoader(root, resolver.options, resolver.cache) - if err != nil { - return nil, err - } - } - - return resolver, nil -} - -// ExpandResponse expands a response based on a basepath -// This is the exported version of expandResponse -// all refs inside response will be resolved relative to basePath -func ExpandResponse(response *Response, basePath string) error { - opts := &ExpandOptions{ - RelativeBase: basePath, - } - resolver, err := defaultSchemaLoader(nil, opts, nil) - if err != nil { - return err - } - - return expandResponse(response, resolver, basePath) -} - -func derefResponse(response *Response, parentRefs []string, resolver *schemaLoader, basePath string) error { - curRef := response.Ref.String() - if curRef != "" { - /* Here the resolution scope is changed because a $ref was encountered */ - normalizedRef := normalizeFileRef(&response.Ref, basePath) - normalizedBasePath := normalizedRef.RemoteURI() - - if isCircular(normalizedRef, basePath, parentRefs...) { - return nil - } - - if err := resolver.Resolve(&response.Ref, response, basePath); shouldStopOnError(err, resolver.options) { - return err - } - - if response.Ref.String() != "" && response.Ref.String() != curRef && basePath != normalizedBasePath { - parentRefs = append(parentRefs, normalizedRef.String()) - return derefResponse(response, parentRefs, resolver, normalizedBasePath) - } - } - - return nil -} - -func expandResponse(response *Response, resolver *schemaLoader, basePath string) error { - if response == nil { - return nil - } - - parentRefs := []string{} - if err := derefResponse(response, parentRefs, resolver, basePath); shouldStopOnError(err, resolver.options) { - return err - } - if response.Ref.String() != "" { - var err error - resolver, err = transitiveResolver(basePath, response.Ref, resolver) - if shouldStopOnError(err, resolver.options) { - return err - } - } - response.Ref = Ref{} - - parentRefs = parentRefs[0:] - if !resolver.options.SkipSchemas && response.Schema != nil { - parentRefs = append(parentRefs, response.Schema.Ref.String()) - s, err := expandSchema(*response.Schema, parentRefs, resolver, basePath) - if shouldStopOnError(err, resolver.options) { - return err - } - *response.Schema = *s - } - - return nil -} - -// ExpandParameter expands a parameter based on a basepath -// This is the exported version of expandParameter -// all refs inside parameter will be resolved relative to basePath -func ExpandParameter(parameter *Parameter, basePath string) error { - opts := &ExpandOptions{ - RelativeBase: basePath, - } - resolver, err := defaultSchemaLoader(nil, opts, nil) - if err != nil { - return err - } - - return expandParameter(parameter, resolver, basePath) -} - -func derefParameter(parameter *Parameter, parentRefs []string, resolver *schemaLoader, basePath string) error { - curRef := parameter.Ref.String() - if curRef != "" { - normalizedRef := normalizeFileRef(¶meter.Ref, basePath) - normalizedBasePath := normalizedRef.RemoteURI() - - if isCircular(normalizedRef, basePath, parentRefs...) { - return nil - } - - if err := resolver.Resolve(¶meter.Ref, parameter, basePath); shouldStopOnError(err, resolver.options) { - return err - } - - if parameter.Ref.String() != "" && parameter.Ref.String() != curRef && basePath != normalizedBasePath { - parentRefs = append(parentRefs, normalizedRef.String()) - return derefParameter(parameter, parentRefs, resolver, normalizedBasePath) - } - } - - return nil -} - -func expandParameter(parameter *Parameter, resolver *schemaLoader, basePath string) error { - if parameter == nil { - return nil - } - - parentRefs := []string{} - if err := derefParameter(parameter, parentRefs, resolver, basePath); shouldStopOnError(err, resolver.options) { - return err - } - if parameter.Ref.String() != "" { - var err error - resolver, err = transitiveResolver(basePath, parameter.Ref, resolver) - if shouldStopOnError(err, resolver.options) { - return err - } - } - parameter.Ref = Ref{} - - parentRefs = parentRefs[0:] - if !resolver.options.SkipSchemas && parameter.Schema != nil { - parentRefs = append(parentRefs, parameter.Schema.Ref.String()) - s, err := expandSchema(*parameter.Schema, parentRefs, resolver, basePath) - if shouldStopOnError(err, resolver.options) { - return err - } - *parameter.Schema = *s - } - return nil -} diff --git a/vendor/github.com/go-openapi/spec/external_docs.go b/vendor/github.com/go-openapi/spec/external_docs.go deleted file mode 100644 index 88add91b2..000000000 --- a/vendor/github.com/go-openapi/spec/external_docs.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -// ExternalDocumentation allows referencing an external resource for -// extended documentation. -// -// For more information: http://goo.gl/8us55a#externalDocumentationObject -type ExternalDocumentation struct { - Description string `json:"description,omitempty"` - URL string `json:"url,omitempty"` -} diff --git a/vendor/github.com/go-openapi/spec/header.go b/vendor/github.com/go-openapi/spec/header.go deleted file mode 100644 index 85c4d454c..000000000 --- a/vendor/github.com/go-openapi/spec/header.go +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - "strings" - - "github.com/go-openapi/jsonpointer" - "github.com/go-openapi/swag" -) - -type HeaderProps struct { - Description string `json:"description,omitempty"` -} - -// Header describes a header for a response of the API -// -// For more information: http://goo.gl/8us55a#headerObject -type Header struct { - CommonValidations - SimpleSchema - VendorExtensible - HeaderProps -} - -// ResponseHeader creates a new header instance for use in a response -func ResponseHeader() *Header { - return new(Header) -} - -// WithDescription sets the description on this response, allows for chaining -func (h *Header) WithDescription(description string) *Header { - h.Description = description - return h -} - -// Typed a fluent builder method for the type of parameter -func (h *Header) Typed(tpe, format string) *Header { - h.Type = tpe - h.Format = format - return h -} - -// CollectionOf a fluent builder method for an array item -func (h *Header) CollectionOf(items *Items, format string) *Header { - h.Type = "array" - h.Items = items - h.CollectionFormat = format - return h -} - -// WithDefault sets the default value on this item -func (h *Header) WithDefault(defaultValue interface{}) *Header { - h.Default = defaultValue - return h -} - -// WithMaxLength sets a max length value -func (h *Header) WithMaxLength(max int64) *Header { - h.MaxLength = &max - return h -} - -// WithMinLength sets a min length value -func (h *Header) WithMinLength(min int64) *Header { - h.MinLength = &min - return h -} - -// WithPattern sets a pattern value -func (h *Header) WithPattern(pattern string) *Header { - h.Pattern = pattern - return h -} - -// WithMultipleOf sets a multiple of value -func (h *Header) WithMultipleOf(number float64) *Header { - h.MultipleOf = &number - return h -} - -// WithMaximum sets a maximum number value -func (h *Header) WithMaximum(max float64, exclusive bool) *Header { - h.Maximum = &max - h.ExclusiveMaximum = exclusive - return h -} - -// WithMinimum sets a minimum number value -func (h *Header) WithMinimum(min float64, exclusive bool) *Header { - h.Minimum = &min - h.ExclusiveMinimum = exclusive - return h -} - -// WithEnum sets a the enum values (replace) -func (h *Header) WithEnum(values ...interface{}) *Header { - h.Enum = append([]interface{}{}, values...) - return h -} - -// WithMaxItems sets the max items -func (h *Header) WithMaxItems(size int64) *Header { - h.MaxItems = &size - return h -} - -// WithMinItems sets the min items -func (h *Header) WithMinItems(size int64) *Header { - h.MinItems = &size - return h -} - -// UniqueValues dictates that this array can only have unique items -func (h *Header) UniqueValues() *Header { - h.UniqueItems = true - return h -} - -// AllowDuplicates this array can have duplicates -func (h *Header) AllowDuplicates() *Header { - h.UniqueItems = false - return h -} - -// MarshalJSON marshal this to JSON -func (h Header) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(h.CommonValidations) - if err != nil { - return nil, err - } - b2, err := json.Marshal(h.SimpleSchema) - if err != nil { - return nil, err - } - b3, err := json.Marshal(h.HeaderProps) - if err != nil { - return nil, err - } - return swag.ConcatJSON(b1, b2, b3), nil -} - -// UnmarshalJSON marshal this from JSON -func (h *Header) UnmarshalJSON(data []byte) error { - if err := json.Unmarshal(data, &h.CommonValidations); err != nil { - return err - } - if err := json.Unmarshal(data, &h.SimpleSchema); err != nil { - return err - } - if err := json.Unmarshal(data, &h.VendorExtensible); err != nil { - return err - } - if err := json.Unmarshal(data, &h.HeaderProps); err != nil { - return err - } - return nil -} - -// JSONLookup look up a value by the json property name -func (p Header) JSONLookup(token string) (interface{}, error) { - if ex, ok := p.Extensions[token]; ok { - return &ex, nil - } - - r, _, err := jsonpointer.GetForToken(p.CommonValidations, token) - if err != nil && !strings.HasPrefix(err.Error(), "object has no field") { - return nil, err - } - if r != nil { - return r, nil - } - r, _, err = jsonpointer.GetForToken(p.SimpleSchema, token) - if err != nil && !strings.HasPrefix(err.Error(), "object has no field") { - return nil, err - } - if r != nil { - return r, nil - } - r, _, err = jsonpointer.GetForToken(p.HeaderProps, token) - return r, err -} diff --git a/vendor/github.com/go-openapi/spec/info.go b/vendor/github.com/go-openapi/spec/info.go deleted file mode 100644 index fb8b7c4ac..000000000 --- a/vendor/github.com/go-openapi/spec/info.go +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - "strings" - - "github.com/go-openapi/jsonpointer" - "github.com/go-openapi/swag" -) - -// Extensions vendor specific extensions -type Extensions map[string]interface{} - -// Add adds a value to these extensions -func (e Extensions) Add(key string, value interface{}) { - realKey := strings.ToLower(key) - e[realKey] = value -} - -// GetString gets a string value from the extensions -func (e Extensions) GetString(key string) (string, bool) { - if v, ok := e[strings.ToLower(key)]; ok { - str, ok := v.(string) - return str, ok - } - return "", false -} - -// GetBool gets a string value from the extensions -func (e Extensions) GetBool(key string) (bool, bool) { - if v, ok := e[strings.ToLower(key)]; ok { - str, ok := v.(bool) - return str, ok - } - return false, false -} - -// GetStringSlice gets a string value from the extensions -func (e Extensions) GetStringSlice(key string) ([]string, bool) { - if v, ok := e[strings.ToLower(key)]; ok { - arr, ok := v.([]interface{}) - if !ok { - return nil, false - } - var strs []string - for _, iface := range arr { - str, ok := iface.(string) - if !ok { - return nil, false - } - strs = append(strs, str) - } - return strs, ok - } - return nil, false -} - -// VendorExtensible composition block. -type VendorExtensible struct { - Extensions Extensions -} - -// AddExtension adds an extension to this extensible object -func (v *VendorExtensible) AddExtension(key string, value interface{}) { - if value == nil { - return - } - if v.Extensions == nil { - v.Extensions = make(map[string]interface{}) - } - v.Extensions.Add(key, value) -} - -// MarshalJSON marshals the extensions to json -func (v VendorExtensible) MarshalJSON() ([]byte, error) { - toser := make(map[string]interface{}) - for k, v := range v.Extensions { - lk := strings.ToLower(k) - if strings.HasPrefix(lk, "x-") { - toser[k] = v - } - } - return json.Marshal(toser) -} - -// UnmarshalJSON for this extensible object -func (v *VendorExtensible) UnmarshalJSON(data []byte) error { - var d map[string]interface{} - if err := json.Unmarshal(data, &d); err != nil { - return err - } - for k, vv := range d { - lk := strings.ToLower(k) - if strings.HasPrefix(lk, "x-") { - if v.Extensions == nil { - v.Extensions = map[string]interface{}{} - } - v.Extensions[k] = vv - } - } - return nil -} - -// InfoProps the properties for an info definition -type InfoProps struct { - Description string `json:"description,omitempty"` - Title string `json:"title,omitempty"` - TermsOfService string `json:"termsOfService,omitempty"` - Contact *ContactInfo `json:"contact,omitempty"` - License *License `json:"license,omitempty"` - Version string `json:"version,omitempty"` -} - -// Info object provides metadata about the API. -// The metadata can be used by the clients if needed, and can be presented in the Swagger-UI for convenience. -// -// For more information: http://goo.gl/8us55a#infoObject -type Info struct { - VendorExtensible - InfoProps -} - -// JSONLookup look up a value by the json property name -func (i Info) JSONLookup(token string) (interface{}, error) { - if ex, ok := i.Extensions[token]; ok { - return &ex, nil - } - r, _, err := jsonpointer.GetForToken(i.InfoProps, token) - return r, err -} - -// MarshalJSON marshal this to JSON -func (i Info) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(i.InfoProps) - if err != nil { - return nil, err - } - b2, err := json.Marshal(i.VendorExtensible) - if err != nil { - return nil, err - } - return swag.ConcatJSON(b1, b2), nil -} - -// UnmarshalJSON marshal this from JSON -func (i *Info) UnmarshalJSON(data []byte) error { - if err := json.Unmarshal(data, &i.InfoProps); err != nil { - return err - } - if err := json.Unmarshal(data, &i.VendorExtensible); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/go-openapi/spec/items.go b/vendor/github.com/go-openapi/spec/items.go deleted file mode 100644 index 492423ef7..000000000 --- a/vendor/github.com/go-openapi/spec/items.go +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - "strings" - - "github.com/go-openapi/jsonpointer" - "github.com/go-openapi/swag" -) - -type SimpleSchema struct { - Type string `json:"type,omitempty"` - Format string `json:"format,omitempty"` - Items *Items `json:"items,omitempty"` - CollectionFormat string `json:"collectionFormat,omitempty"` - Default interface{} `json:"default,omitempty"` - Example interface{} `json:"example,omitempty"` -} - -func (s *SimpleSchema) TypeName() string { - if s.Format != "" { - return s.Format - } - return s.Type -} - -func (s *SimpleSchema) ItemsTypeName() string { - if s.Items == nil { - return "" - } - return s.Items.TypeName() -} - -type CommonValidations struct { - Maximum *float64 `json:"maximum,omitempty"` - ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"` - Minimum *float64 `json:"minimum,omitempty"` - ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"` - MaxLength *int64 `json:"maxLength,omitempty"` - MinLength *int64 `json:"minLength,omitempty"` - Pattern string `json:"pattern,omitempty"` - MaxItems *int64 `json:"maxItems,omitempty"` - MinItems *int64 `json:"minItems,omitempty"` - UniqueItems bool `json:"uniqueItems,omitempty"` - MultipleOf *float64 `json:"multipleOf,omitempty"` - Enum []interface{} `json:"enum,omitempty"` -} - -// Items a limited subset of JSON-Schema's items object. -// It is used by parameter definitions that are not located in "body". -// -// For more information: http://goo.gl/8us55a#items-object -type Items struct { - Refable - CommonValidations - SimpleSchema - VendorExtensible -} - -// NewItems creates a new instance of items -func NewItems() *Items { - return &Items{} -} - -// Typed a fluent builder method for the type of item -func (i *Items) Typed(tpe, format string) *Items { - i.Type = tpe - i.Format = format - return i -} - -// CollectionOf a fluent builder method for an array item -func (i *Items) CollectionOf(items *Items, format string) *Items { - i.Type = "array" - i.Items = items - i.CollectionFormat = format - return i -} - -// WithDefault sets the default value on this item -func (i *Items) WithDefault(defaultValue interface{}) *Items { - i.Default = defaultValue - return i -} - -// WithMaxLength sets a max length value -func (i *Items) WithMaxLength(max int64) *Items { - i.MaxLength = &max - return i -} - -// WithMinLength sets a min length value -func (i *Items) WithMinLength(min int64) *Items { - i.MinLength = &min - return i -} - -// WithPattern sets a pattern value -func (i *Items) WithPattern(pattern string) *Items { - i.Pattern = pattern - return i -} - -// WithMultipleOf sets a multiple of value -func (i *Items) WithMultipleOf(number float64) *Items { - i.MultipleOf = &number - return i -} - -// WithMaximum sets a maximum number value -func (i *Items) WithMaximum(max float64, exclusive bool) *Items { - i.Maximum = &max - i.ExclusiveMaximum = exclusive - return i -} - -// WithMinimum sets a minimum number value -func (i *Items) WithMinimum(min float64, exclusive bool) *Items { - i.Minimum = &min - i.ExclusiveMinimum = exclusive - return i -} - -// WithEnum sets a the enum values (replace) -func (i *Items) WithEnum(values ...interface{}) *Items { - i.Enum = append([]interface{}{}, values...) - return i -} - -// WithMaxItems sets the max items -func (i *Items) WithMaxItems(size int64) *Items { - i.MaxItems = &size - return i -} - -// WithMinItems sets the min items -func (i *Items) WithMinItems(size int64) *Items { - i.MinItems = &size - return i -} - -// UniqueValues dictates that this array can only have unique items -func (i *Items) UniqueValues() *Items { - i.UniqueItems = true - return i -} - -// AllowDuplicates this array can have duplicates -func (i *Items) AllowDuplicates() *Items { - i.UniqueItems = false - return i -} - -// UnmarshalJSON hydrates this items instance with the data from JSON -func (i *Items) UnmarshalJSON(data []byte) error { - var validations CommonValidations - if err := json.Unmarshal(data, &validations); err != nil { - return err - } - var ref Refable - if err := json.Unmarshal(data, &ref); err != nil { - return err - } - var simpleSchema SimpleSchema - if err := json.Unmarshal(data, &simpleSchema); err != nil { - return err - } - var vendorExtensible VendorExtensible - if err := json.Unmarshal(data, &vendorExtensible); err != nil { - return err - } - i.Refable = ref - i.CommonValidations = validations - i.SimpleSchema = simpleSchema - i.VendorExtensible = vendorExtensible - return nil -} - -// MarshalJSON converts this items object to JSON -func (i Items) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(i.CommonValidations) - if err != nil { - return nil, err - } - b2, err := json.Marshal(i.SimpleSchema) - if err != nil { - return nil, err - } - b3, err := json.Marshal(i.Refable) - if err != nil { - return nil, err - } - b4, err := json.Marshal(i.VendorExtensible) - if err != nil { - return nil, err - } - return swag.ConcatJSON(b4, b3, b1, b2), nil -} - -// JSONLookup look up a value by the json property name -func (p Items) JSONLookup(token string) (interface{}, error) { - if token == "$ref" { - return &p.Ref, nil - } - - r, _, err := jsonpointer.GetForToken(p.CommonValidations, token) - if err != nil && !strings.HasPrefix(err.Error(), "object has no field") { - return nil, err - } - if r != nil { - return r, nil - } - r, _, err = jsonpointer.GetForToken(p.SimpleSchema, token) - return r, err -} diff --git a/vendor/github.com/go-openapi/spec/license.go b/vendor/github.com/go-openapi/spec/license.go deleted file mode 100644 index f20961b4f..000000000 --- a/vendor/github.com/go-openapi/spec/license.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -// License information for the exposed API. -// -// For more information: http://goo.gl/8us55a#licenseObject -type License struct { - Name string `json:"name,omitempty"` - URL string `json:"url,omitempty"` -} diff --git a/vendor/github.com/go-openapi/spec/operation.go b/vendor/github.com/go-openapi/spec/operation.go deleted file mode 100644 index e698f9e8a..000000000 --- a/vendor/github.com/go-openapi/spec/operation.go +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - - "github.com/go-openapi/jsonpointer" - "github.com/go-openapi/swag" -) - -type OperationProps struct { - Description string `json:"description,omitempty"` - Consumes []string `json:"consumes,omitempty"` - Produces []string `json:"produces,omitempty"` - Schemes []string `json:"schemes,omitempty"` // the scheme, when present must be from [http, https, ws, wss] - Tags []string `json:"tags,omitempty"` - Summary string `json:"summary,omitempty"` - ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"` - ID string `json:"operationId,omitempty"` - Deprecated bool `json:"deprecated,omitempty"` - Security []map[string][]string `json:"security,omitempty"` //Special case, see MarshalJSON function - Parameters []Parameter `json:"parameters,omitempty"` - Responses *Responses `json:"responses,omitempty"` -} - -// MarshalJSON takes care of serializing operation properties to JSON -// -// We use a custom marhaller here to handle a special cases related -// the Security field. We need to preserve zero length slice -// while omiting the field when the value is nil/unset. -func (op OperationProps) MarshalJSON() ([]byte, error) { - type Alias OperationProps - if op.Security == nil { - return json.Marshal(&struct { - Security []map[string][]string `json:"security,omitempty"` - *Alias - }{ - Security: op.Security, - Alias: (*Alias)(&op), - }) - } - return json.Marshal(&struct { - Security []map[string][]string `json:"security"` - *Alias - }{ - Security: op.Security, - Alias: (*Alias)(&op), - }) -} - -// Operation describes a single API operation on a path. -// -// For more information: http://goo.gl/8us55a#operationObject -type Operation struct { - VendorExtensible - OperationProps -} - -// SuccessResponse gets a success response model -func (o *Operation) SuccessResponse() (*Response, int, bool) { - if o.Responses == nil { - return nil, 0, false - } - - for k, v := range o.Responses.StatusCodeResponses { - if k/100 == 2 { - return &v, k, true - } - } - - return o.Responses.Default, 0, false -} - -// JSONLookup look up a value by the json property name -func (o Operation) JSONLookup(token string) (interface{}, error) { - if ex, ok := o.Extensions[token]; ok { - return &ex, nil - } - r, _, err := jsonpointer.GetForToken(o.OperationProps, token) - return r, err -} - -// UnmarshalJSON hydrates this items instance with the data from JSON -func (o *Operation) UnmarshalJSON(data []byte) error { - if err := json.Unmarshal(data, &o.OperationProps); err != nil { - return err - } - if err := json.Unmarshal(data, &o.VendorExtensible); err != nil { - return err - } - return nil -} - -// MarshalJSON converts this items object to JSON -func (o Operation) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(o.OperationProps) - if err != nil { - return nil, err - } - b2, err := json.Marshal(o.VendorExtensible) - if err != nil { - return nil, err - } - concated := swag.ConcatJSON(b1, b2) - return concated, nil -} - -// NewOperation creates a new operation instance. -// It expects an ID as parameter but not passing an ID is also valid. -func NewOperation(id string) *Operation { - op := new(Operation) - op.ID = id - return op -} - -// WithID sets the ID property on this operation, allows for chaining. -func (o *Operation) WithID(id string) *Operation { - o.ID = id - return o -} - -// WithDescription sets the description on this operation, allows for chaining -func (o *Operation) WithDescription(description string) *Operation { - o.Description = description - return o -} - -// WithSummary sets the summary on this operation, allows for chaining -func (o *Operation) WithSummary(summary string) *Operation { - o.Summary = summary - return o -} - -// WithExternalDocs sets/removes the external docs for/from this operation. -// When you pass empty strings as params the external documents will be removed. -// When you pass non-empty string as one value then those values will be used on the external docs object. -// So when you pass a non-empty description, you should also pass the url and vice versa. -func (o *Operation) WithExternalDocs(description, url string) *Operation { - if description == "" && url == "" { - o.ExternalDocs = nil - return o - } - - if o.ExternalDocs == nil { - o.ExternalDocs = &ExternalDocumentation{} - } - o.ExternalDocs.Description = description - o.ExternalDocs.URL = url - return o -} - -// Deprecate marks the operation as deprecated -func (o *Operation) Deprecate() *Operation { - o.Deprecated = true - return o -} - -// Undeprecate marks the operation as not deprected -func (o *Operation) Undeprecate() *Operation { - o.Deprecated = false - return o -} - -// WithConsumes adds media types for incoming body values -func (o *Operation) WithConsumes(mediaTypes ...string) *Operation { - o.Consumes = append(o.Consumes, mediaTypes...) - return o -} - -// WithProduces adds media types for outgoing body values -func (o *Operation) WithProduces(mediaTypes ...string) *Operation { - o.Produces = append(o.Produces, mediaTypes...) - return o -} - -// WithTags adds tags for this operation -func (o *Operation) WithTags(tags ...string) *Operation { - o.Tags = append(o.Tags, tags...) - return o -} - -// AddParam adds a parameter to this operation, when a parameter for that location -// and with that name already exists it will be replaced -func (o *Operation) AddParam(param *Parameter) *Operation { - if param == nil { - return o - } - - for i, p := range o.Parameters { - if p.Name == param.Name && p.In == param.In { - params := append(o.Parameters[:i], *param) - params = append(params, o.Parameters[i+1:]...) - o.Parameters = params - return o - } - } - - o.Parameters = append(o.Parameters, *param) - return o -} - -// RemoveParam removes a parameter from the operation -func (o *Operation) RemoveParam(name, in string) *Operation { - for i, p := range o.Parameters { - if p.Name == name && p.In == name { - o.Parameters = append(o.Parameters[:i], o.Parameters[i+1:]...) - return o - } - } - return o -} - -// SecuredWith adds a security scope to this operation. -func (o *Operation) SecuredWith(name string, scopes ...string) *Operation { - o.Security = append(o.Security, map[string][]string{name: scopes}) - return o -} - -// WithDefaultResponse adds a default response to the operation. -// Passing a nil value will remove the response -func (o *Operation) WithDefaultResponse(response *Response) *Operation { - return o.RespondsWith(0, response) -} - -// RespondsWith adds a status code response to the operation. -// When the code is 0 the value of the response will be used as default response value. -// When the value of the response is nil it will be removed from the operation -func (o *Operation) RespondsWith(code int, response *Response) *Operation { - if o.Responses == nil { - o.Responses = new(Responses) - } - if code == 0 { - o.Responses.Default = response - return o - } - if response == nil { - delete(o.Responses.StatusCodeResponses, code) - return o - } - if o.Responses.StatusCodeResponses == nil { - o.Responses.StatusCodeResponses = make(map[int]Response) - } - o.Responses.StatusCodeResponses[code] = *response - return o -} diff --git a/vendor/github.com/go-openapi/spec/parameter.go b/vendor/github.com/go-openapi/spec/parameter.go deleted file mode 100644 index 71aee1e80..000000000 --- a/vendor/github.com/go-openapi/spec/parameter.go +++ /dev/null @@ -1,301 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - "strings" - - "github.com/go-openapi/jsonpointer" - "github.com/go-openapi/swag" -) - -// QueryParam creates a query parameter -func QueryParam(name string) *Parameter { - return &Parameter{ParamProps: ParamProps{Name: name, In: "query"}} -} - -// HeaderParam creates a header parameter, this is always required by default -func HeaderParam(name string) *Parameter { - return &Parameter{ParamProps: ParamProps{Name: name, In: "header", Required: true}} -} - -// PathParam creates a path parameter, this is always required -func PathParam(name string) *Parameter { - return &Parameter{ParamProps: ParamProps{Name: name, In: "path", Required: true}} -} - -// BodyParam creates a body parameter -func BodyParam(name string, schema *Schema) *Parameter { - return &Parameter{ParamProps: ParamProps{Name: name, In: "body", Schema: schema}, SimpleSchema: SimpleSchema{Type: "object"}} -} - -// FormDataParam creates a body parameter -func FormDataParam(name string) *Parameter { - return &Parameter{ParamProps: ParamProps{Name: name, In: "formData"}} -} - -// FileParam creates a body parameter -func FileParam(name string) *Parameter { - return &Parameter{ParamProps: ParamProps{Name: name, In: "formData"}, SimpleSchema: SimpleSchema{Type: "file"}} -} - -// SimpleArrayParam creates a param for a simple array (string, int, date etc) -func SimpleArrayParam(name, tpe, fmt string) *Parameter { - return &Parameter{ParamProps: ParamProps{Name: name}, SimpleSchema: SimpleSchema{Type: "array", CollectionFormat: "csv", Items: &Items{SimpleSchema: SimpleSchema{Type: "string", Format: fmt}}}} -} - -// ParamRef creates a parameter that's a json reference -func ParamRef(uri string) *Parameter { - p := new(Parameter) - p.Ref = MustCreateRef(uri) - return p -} - -type ParamProps struct { - Description string `json:"description,omitempty"` - Name string `json:"name,omitempty"` - In string `json:"in,omitempty"` - Required bool `json:"required,omitempty"` - Schema *Schema `json:"schema,omitempty"` // when in == "body" - AllowEmptyValue bool `json:"allowEmptyValue,omitempty"` // when in == "query" || "formData" -} - -// Parameter a unique parameter is defined by a combination of a [name](#parameterName) and [location](#parameterIn). -// -// There are five possible parameter types. -// * Path - Used together with [Path Templating](#pathTemplating), where the parameter value is actually part of the operation's URL. This does not include the host or base path of the API. For example, in `/items/{itemId}`, the path parameter is `itemId`. -// * Query - Parameters that are appended to the URL. For example, in `/items?id=###`, the query parameter is `id`. -// * Header - Custom headers that are expected as part of the request. -// * Body - The payload that's appended to the HTTP request. Since there can only be one payload, there can only be *one* body parameter. The name of the body parameter has no effect on the parameter itself and is used for documentation purposes only. Since Form parameters are also in the payload, body and form parameters cannot exist together for the same operation. -// * Form - Used to describe the payload of an HTTP request when either `application/x-www-form-urlencoded` or `multipart/form-data` are used as the content type of the request (in Swagger's definition, the [`consumes`](#operationConsumes) property of an operation). This is the only parameter type that can be used to send files, thus supporting the `file` type. Since form parameters are sent in the payload, they cannot be declared together with a body parameter for the same operation. Form parameters have a different format based on the content-type used (for further details, consult http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4): -// * `application/x-www-form-urlencoded` - Similar to the format of Query parameters but as a payload. For example, `foo=1&bar=swagger` - both `foo` and `bar` are form parameters. This is normally used for simple parameters that are being transferred. -// * `multipart/form-data` - each parameter takes a section in the payload with an internal header. For example, for the header `Content-Disposition: form-data; name="submit-name"` the name of the parameter is `submit-name`. This type of form parameters is more commonly used for file transfers. -// -// For more information: http://goo.gl/8us55a#parameterObject -type Parameter struct { - Refable - CommonValidations - SimpleSchema - VendorExtensible - ParamProps -} - -// JSONLookup look up a value by the json property name -func (p Parameter) JSONLookup(token string) (interface{}, error) { - if ex, ok := p.Extensions[token]; ok { - return &ex, nil - } - if token == "$ref" { - return &p.Ref, nil - } - - r, _, err := jsonpointer.GetForToken(p.CommonValidations, token) - if err != nil && !strings.HasPrefix(err.Error(), "object has no field") { - return nil, err - } - if r != nil { - return r, nil - } - r, _, err = jsonpointer.GetForToken(p.SimpleSchema, token) - if err != nil && !strings.HasPrefix(err.Error(), "object has no field") { - return nil, err - } - if r != nil { - return r, nil - } - r, _, err = jsonpointer.GetForToken(p.ParamProps, token) - return r, err -} - -// WithDescription a fluent builder method for the description of the parameter -func (p *Parameter) WithDescription(description string) *Parameter { - p.Description = description - return p -} - -// Named a fluent builder method to override the name of the parameter -func (p *Parameter) Named(name string) *Parameter { - p.Name = name - return p -} - -// WithLocation a fluent builder method to override the location of the parameter -func (p *Parameter) WithLocation(in string) *Parameter { - p.In = in - return p -} - -// Typed a fluent builder method for the type of the parameter value -func (p *Parameter) Typed(tpe, format string) *Parameter { - p.Type = tpe - p.Format = format - return p -} - -// CollectionOf a fluent builder method for an array parameter -func (p *Parameter) CollectionOf(items *Items, format string) *Parameter { - p.Type = "array" - p.Items = items - p.CollectionFormat = format - return p -} - -// WithDefault sets the default value on this parameter -func (p *Parameter) WithDefault(defaultValue interface{}) *Parameter { - p.AsOptional() // with default implies optional - p.Default = defaultValue - return p -} - -// AllowsEmptyValues flags this parameter as being ok with empty values -func (p *Parameter) AllowsEmptyValues() *Parameter { - p.AllowEmptyValue = true - return p -} - -// NoEmptyValues flags this parameter as not liking empty values -func (p *Parameter) NoEmptyValues() *Parameter { - p.AllowEmptyValue = false - return p -} - -// AsOptional flags this parameter as optional -func (p *Parameter) AsOptional() *Parameter { - p.Required = false - return p -} - -// AsRequired flags this parameter as required -func (p *Parameter) AsRequired() *Parameter { - if p.Default != nil { // with a default required makes no sense - return p - } - p.Required = true - return p -} - -// WithMaxLength sets a max length value -func (p *Parameter) WithMaxLength(max int64) *Parameter { - p.MaxLength = &max - return p -} - -// WithMinLength sets a min length value -func (p *Parameter) WithMinLength(min int64) *Parameter { - p.MinLength = &min - return p -} - -// WithPattern sets a pattern value -func (p *Parameter) WithPattern(pattern string) *Parameter { - p.Pattern = pattern - return p -} - -// WithMultipleOf sets a multiple of value -func (p *Parameter) WithMultipleOf(number float64) *Parameter { - p.MultipleOf = &number - return p -} - -// WithMaximum sets a maximum number value -func (p *Parameter) WithMaximum(max float64, exclusive bool) *Parameter { - p.Maximum = &max - p.ExclusiveMaximum = exclusive - return p -} - -// WithMinimum sets a minimum number value -func (p *Parameter) WithMinimum(min float64, exclusive bool) *Parameter { - p.Minimum = &min - p.ExclusiveMinimum = exclusive - return p -} - -// WithEnum sets a the enum values (replace) -func (p *Parameter) WithEnum(values ...interface{}) *Parameter { - p.Enum = append([]interface{}{}, values...) - return p -} - -// WithMaxItems sets the max items -func (p *Parameter) WithMaxItems(size int64) *Parameter { - p.MaxItems = &size - return p -} - -// WithMinItems sets the min items -func (p *Parameter) WithMinItems(size int64) *Parameter { - p.MinItems = &size - return p -} - -// UniqueValues dictates that this array can only have unique items -func (p *Parameter) UniqueValues() *Parameter { - p.UniqueItems = true - return p -} - -// AllowDuplicates this array can have duplicates -func (p *Parameter) AllowDuplicates() *Parameter { - p.UniqueItems = false - return p -} - -// UnmarshalJSON hydrates this items instance with the data from JSON -func (p *Parameter) UnmarshalJSON(data []byte) error { - if err := json.Unmarshal(data, &p.CommonValidations); err != nil { - return err - } - if err := json.Unmarshal(data, &p.Refable); err != nil { - return err - } - if err := json.Unmarshal(data, &p.SimpleSchema); err != nil { - return err - } - if err := json.Unmarshal(data, &p.VendorExtensible); err != nil { - return err - } - if err := json.Unmarshal(data, &p.ParamProps); err != nil { - return err - } - return nil -} - -// MarshalJSON converts this items object to JSON -func (p Parameter) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(p.CommonValidations) - if err != nil { - return nil, err - } - b2, err := json.Marshal(p.SimpleSchema) - if err != nil { - return nil, err - } - b3, err := json.Marshal(p.Refable) - if err != nil { - return nil, err - } - b4, err := json.Marshal(p.VendorExtensible) - if err != nil { - return nil, err - } - b5, err := json.Marshal(p.ParamProps) - if err != nil { - return nil, err - } - return swag.ConcatJSON(b3, b1, b2, b4, b5), nil -} diff --git a/vendor/github.com/go-openapi/spec/path_item.go b/vendor/github.com/go-openapi/spec/path_item.go deleted file mode 100644 index 9ab3ec538..000000000 --- a/vendor/github.com/go-openapi/spec/path_item.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - - "github.com/go-openapi/jsonpointer" - "github.com/go-openapi/swag" -) - -// pathItemProps the path item specific properties -type PathItemProps struct { - Get *Operation `json:"get,omitempty"` - Put *Operation `json:"put,omitempty"` - Post *Operation `json:"post,omitempty"` - Delete *Operation `json:"delete,omitempty"` - Options *Operation `json:"options,omitempty"` - Head *Operation `json:"head,omitempty"` - Patch *Operation `json:"patch,omitempty"` - Parameters []Parameter `json:"parameters,omitempty"` -} - -// PathItem describes the operations available on a single path. -// A Path Item may be empty, due to [ACL constraints](http://goo.gl/8us55a#securityFiltering). -// The path itself is still exposed to the documentation viewer but they will -// not know which operations and parameters are available. -// -// For more information: http://goo.gl/8us55a#pathItemObject -type PathItem struct { - Refable - VendorExtensible - PathItemProps -} - -// JSONLookup look up a value by the json property name -func (p PathItem) JSONLookup(token string) (interface{}, error) { - if ex, ok := p.Extensions[token]; ok { - return &ex, nil - } - if token == "$ref" { - return &p.Ref, nil - } - r, _, err := jsonpointer.GetForToken(p.PathItemProps, token) - return r, err -} - -// UnmarshalJSON hydrates this items instance with the data from JSON -func (p *PathItem) UnmarshalJSON(data []byte) error { - if err := json.Unmarshal(data, &p.Refable); err != nil { - return err - } - if err := json.Unmarshal(data, &p.VendorExtensible); err != nil { - return err - } - if err := json.Unmarshal(data, &p.PathItemProps); err != nil { - return err - } - return nil -} - -// MarshalJSON converts this items object to JSON -func (p PathItem) MarshalJSON() ([]byte, error) { - b3, err := json.Marshal(p.Refable) - if err != nil { - return nil, err - } - b4, err := json.Marshal(p.VendorExtensible) - if err != nil { - return nil, err - } - b5, err := json.Marshal(p.PathItemProps) - if err != nil { - return nil, err - } - concated := swag.ConcatJSON(b3, b4, b5) - return concated, nil -} diff --git a/vendor/github.com/go-openapi/spec/paths.go b/vendor/github.com/go-openapi/spec/paths.go deleted file mode 100644 index 9dc82a290..000000000 --- a/vendor/github.com/go-openapi/spec/paths.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - "fmt" - "strings" - - "github.com/go-openapi/swag" -) - -// Paths holds the relative paths to the individual endpoints. -// The path is appended to the [`basePath`](http://goo.gl/8us55a#swaggerBasePath) in order -// to construct the full URL. -// The Paths may be empty, due to [ACL constraints](http://goo.gl/8us55a#securityFiltering). -// -// For more information: http://goo.gl/8us55a#pathsObject -type Paths struct { - VendorExtensible - Paths map[string]PathItem `json:"-"` // custom serializer to flatten this, each entry must start with "/" -} - -// JSONLookup look up a value by the json property name -func (p Paths) JSONLookup(token string) (interface{}, error) { - if pi, ok := p.Paths[token]; ok { - return &pi, nil - } - if ex, ok := p.Extensions[token]; ok { - return &ex, nil - } - return nil, fmt.Errorf("object has no field %q", token) -} - -// UnmarshalJSON hydrates this items instance with the data from JSON -func (p *Paths) UnmarshalJSON(data []byte) error { - var res map[string]json.RawMessage - if err := json.Unmarshal(data, &res); err != nil { - return err - } - for k, v := range res { - if strings.HasPrefix(strings.ToLower(k), "x-") { - if p.Extensions == nil { - p.Extensions = make(map[string]interface{}) - } - var d interface{} - if err := json.Unmarshal(v, &d); err != nil { - return err - } - p.Extensions[k] = d - } - if strings.HasPrefix(k, "/") { - if p.Paths == nil { - p.Paths = make(map[string]PathItem) - } - var pi PathItem - if err := json.Unmarshal(v, &pi); err != nil { - return err - } - p.Paths[k] = pi - } - } - return nil -} - -// MarshalJSON converts this items object to JSON -func (p Paths) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(p.VendorExtensible) - if err != nil { - return nil, err - } - - pths := make(map[string]PathItem) - for k, v := range p.Paths { - if strings.HasPrefix(k, "/") { - pths[k] = v - } - } - b2, err := json.Marshal(pths) - if err != nil { - return nil, err - } - concated := swag.ConcatJSON(b1, b2) - return concated, nil -} diff --git a/vendor/github.com/go-openapi/spec/ref.go b/vendor/github.com/go-openapi/spec/ref.go deleted file mode 100644 index 1405bfd8e..000000000 --- a/vendor/github.com/go-openapi/spec/ref.go +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - "net/http" - "os" - "path/filepath" - - "github.com/go-openapi/jsonreference" -) - -// Refable is a struct for things that accept a $ref property -type Refable struct { - Ref Ref -} - -// MarshalJSON marshals the ref to json -func (r Refable) MarshalJSON() ([]byte, error) { - return r.Ref.MarshalJSON() -} - -// UnmarshalJSON unmarshalss the ref from json -func (r *Refable) UnmarshalJSON(d []byte) error { - return json.Unmarshal(d, &r.Ref) -} - -// Ref represents a json reference that is potentially resolved -type Ref struct { - jsonreference.Ref -} - -// RemoteURI gets the remote uri part of the ref -func (r *Ref) RemoteURI() string { - if r.String() == "" { - return r.String() - } - - u := *r.GetURL() - u.Fragment = "" - return u.String() -} - -// IsValidURI returns true when the url the ref points to can be found -func (r *Ref) IsValidURI(basepaths ...string) bool { - if r.String() == "" { - return true - } - - v := r.RemoteURI() - if v == "" { - return true - } - - if r.HasFullURL { - rr, err := http.Get(v) - if err != nil { - return false - } - - return rr.StatusCode/100 == 2 - } - - if !(r.HasFileScheme || r.HasFullFilePath || r.HasURLPathOnly) { - return false - } - - // check for local file - pth := v - if r.HasURLPathOnly { - base := "." - if len(basepaths) > 0 { - base = filepath.Dir(filepath.Join(basepaths...)) - } - p, e := filepath.Abs(filepath.ToSlash(filepath.Join(base, pth))) - if e != nil { - return false - } - pth = p - } - - fi, err := os.Stat(filepath.ToSlash(pth)) - if err != nil { - return false - } - - return !fi.IsDir() -} - -// Inherits creates a new reference from a parent and a child -// If the child cannot inherit from the parent, an error is returned -func (r *Ref) Inherits(child Ref) (*Ref, error) { - ref, err := r.Ref.Inherits(child.Ref) - if err != nil { - return nil, err - } - return &Ref{Ref: *ref}, nil -} - -// NewRef creates a new instance of a ref object -// returns an error when the reference uri is an invalid uri -func NewRef(refURI string) (Ref, error) { - ref, err := jsonreference.New(refURI) - if err != nil { - return Ref{}, err - } - return Ref{Ref: ref}, nil -} - -// MustCreateRef creates a ref object but panics when refURI is invalid. -// Use the NewRef method for a version that returns an error. -func MustCreateRef(refURI string) Ref { - return Ref{Ref: jsonreference.MustCreateRef(refURI)} -} - -// MarshalJSON marshals this ref into a JSON object -func (r Ref) MarshalJSON() ([]byte, error) { - str := r.String() - if str == "" { - if r.IsRoot() { - return []byte(`{"$ref":""}`), nil - } - return []byte("{}"), nil - } - v := map[string]interface{}{"$ref": str} - return json.Marshal(v) -} - -// UnmarshalJSON unmarshals this ref from a JSON object -func (r *Ref) UnmarshalJSON(d []byte) error { - var v map[string]interface{} - if err := json.Unmarshal(d, &v); err != nil { - return err - } - return r.fromMap(v) -} - -func (r *Ref) fromMap(v map[string]interface{}) error { - if v == nil { - return nil - } - - if vv, ok := v["$ref"]; ok { - if str, ok := vv.(string); ok { - ref, err := jsonreference.New(str) - if err != nil { - return err - } - *r = Ref{Ref: ref} - } - } - - return nil -} diff --git a/vendor/github.com/go-openapi/spec/response.go b/vendor/github.com/go-openapi/spec/response.go deleted file mode 100644 index a32b039ea..000000000 --- a/vendor/github.com/go-openapi/spec/response.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - - "github.com/go-openapi/jsonpointer" - "github.com/go-openapi/swag" -) - -// ResponseProps properties specific to a response -type ResponseProps struct { - Description string `json:"description,omitempty"` - Schema *Schema `json:"schema,omitempty"` - Headers map[string]Header `json:"headers,omitempty"` - Examples map[string]interface{} `json:"examples,omitempty"` -} - -// Response describes a single response from an API Operation. -// -// For more information: http://goo.gl/8us55a#responseObject -type Response struct { - Refable - ResponseProps - VendorExtensible -} - -// JSONLookup look up a value by the json property name -func (p Response) JSONLookup(token string) (interface{}, error) { - if ex, ok := p.Extensions[token]; ok { - return &ex, nil - } - if token == "$ref" { - return &p.Ref, nil - } - r, _, err := jsonpointer.GetForToken(p.ResponseProps, token) - return r, err -} - -// UnmarshalJSON hydrates this items instance with the data from JSON -func (r *Response) UnmarshalJSON(data []byte) error { - if err := json.Unmarshal(data, &r.ResponseProps); err != nil { - return err - } - if err := json.Unmarshal(data, &r.Refable); err != nil { - return err - } - if err := json.Unmarshal(data, &r.VendorExtensible); err != nil { - return err - } - return nil -} - -// MarshalJSON converts this items object to JSON -func (r Response) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(r.ResponseProps) - if err != nil { - return nil, err - } - b2, err := json.Marshal(r.Refable) - if err != nil { - return nil, err - } - b3, err := json.Marshal(r.VendorExtensible) - if err != nil { - return nil, err - } - return swag.ConcatJSON(b1, b2, b3), nil -} - -// NewResponse creates a new response instance -func NewResponse() *Response { - return new(Response) -} - -// ResponseRef creates a response as a json reference -func ResponseRef(url string) *Response { - resp := NewResponse() - resp.Ref = MustCreateRef(url) - return resp -} - -// WithDescription sets the description on this response, allows for chaining -func (r *Response) WithDescription(description string) *Response { - r.Description = description - return r -} - -// WithSchema sets the schema on this response, allows for chaining. -// Passing a nil argument removes the schema from this response -func (r *Response) WithSchema(schema *Schema) *Response { - r.Schema = schema - return r -} - -// AddHeader adds a header to this response -func (r *Response) AddHeader(name string, header *Header) *Response { - if header == nil { - return r.RemoveHeader(name) - } - if r.Headers == nil { - r.Headers = make(map[string]Header) - } - r.Headers[name] = *header - return r -} - -// RemoveHeader removes a header from this response -func (r *Response) RemoveHeader(name string) *Response { - delete(r.Headers, name) - return r -} - -// AddExample adds an example to this response -func (r *Response) AddExample(mediaType string, example interface{}) *Response { - if r.Examples == nil { - r.Examples = make(map[string]interface{}) - } - r.Examples[mediaType] = example - return r -} diff --git a/vendor/github.com/go-openapi/spec/responses.go b/vendor/github.com/go-openapi/spec/responses.go deleted file mode 100644 index 3ab06697f..000000000 --- a/vendor/github.com/go-openapi/spec/responses.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - "fmt" - "reflect" - "strconv" - - "github.com/go-openapi/swag" -) - -// Responses is a container for the expected responses of an operation. -// The container maps a HTTP response code to the expected response. -// It is not expected from the documentation to necessarily cover all possible HTTP response codes, -// since they may not be known in advance. However, it is expected from the documentation to cover -// a successful operation response and any known errors. -// -// The `default` can be used a default response object for all HTTP codes that are not covered -// individually by the specification. -// -// The `Responses Object` MUST contain at least one response code, and it SHOULD be the response -// for a successful operation call. -// -// For more information: http://goo.gl/8us55a#responsesObject -type Responses struct { - VendorExtensible - ResponsesProps -} - -// JSONLookup implements an interface to customize json pointer lookup -func (r Responses) JSONLookup(token string) (interface{}, error) { - if token == "default" { - return r.Default, nil - } - if ex, ok := r.Extensions[token]; ok { - return &ex, nil - } - if i, err := strconv.Atoi(token); err == nil { - if scr, ok := r.StatusCodeResponses[i]; ok { - return scr, nil - } - } - return nil, fmt.Errorf("object has no field %q", token) -} - -// UnmarshalJSON hydrates this items instance with the data from JSON -func (r *Responses) UnmarshalJSON(data []byte) error { - if err := json.Unmarshal(data, &r.ResponsesProps); err != nil { - return err - } - if err := json.Unmarshal(data, &r.VendorExtensible); err != nil { - return err - } - if reflect.DeepEqual(ResponsesProps{}, r.ResponsesProps) { - r.ResponsesProps = ResponsesProps{} - } - return nil -} - -// MarshalJSON converts this items object to JSON -func (r Responses) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(r.ResponsesProps) - if err != nil { - return nil, err - } - b2, err := json.Marshal(r.VendorExtensible) - if err != nil { - return nil, err - } - concated := swag.ConcatJSON(b1, b2) - return concated, nil -} - -type ResponsesProps struct { - Default *Response - StatusCodeResponses map[int]Response -} - -func (r ResponsesProps) MarshalJSON() ([]byte, error) { - toser := map[string]Response{} - if r.Default != nil { - toser["default"] = *r.Default - } - for k, v := range r.StatusCodeResponses { - toser[strconv.Itoa(k)] = v - } - return json.Marshal(toser) -} - -func (r *ResponsesProps) UnmarshalJSON(data []byte) error { - var res map[string]Response - if err := json.Unmarshal(data, &res); err != nil { - return nil - } - if v, ok := res["default"]; ok { - r.Default = &v - delete(res, "default") - } - for k, v := range res { - if nk, err := strconv.Atoi(k); err == nil { - if r.StatusCodeResponses == nil { - r.StatusCodeResponses = map[int]Response{} - } - r.StatusCodeResponses[nk] = v - } - } - return nil -} diff --git a/vendor/github.com/go-openapi/spec/schema.go b/vendor/github.com/go-openapi/spec/schema.go deleted file mode 100644 index 05c1a4aa0..000000000 --- a/vendor/github.com/go-openapi/spec/schema.go +++ /dev/null @@ -1,634 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - "fmt" - "net/url" - "strings" - - "github.com/go-openapi/jsonpointer" - "github.com/go-openapi/swag" -) - -// BooleanProperty creates a boolean property -func BooleanProperty() *Schema { - return &Schema{SchemaProps: SchemaProps{Type: []string{"boolean"}}} -} - -// BoolProperty creates a boolean property -func BoolProperty() *Schema { return BooleanProperty() } - -// StringProperty creates a string property -func StringProperty() *Schema { - return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}}} -} - -// CharProperty creates a string property -func CharProperty() *Schema { - return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}}} -} - -// Float64Property creates a float64/double property -func Float64Property() *Schema { - return &Schema{SchemaProps: SchemaProps{Type: []string{"number"}, Format: "double"}} -} - -// Float32Property creates a float32/float property -func Float32Property() *Schema { - return &Schema{SchemaProps: SchemaProps{Type: []string{"number"}, Format: "float"}} -} - -// Int8Property creates an int8 property -func Int8Property() *Schema { - return &Schema{SchemaProps: SchemaProps{Type: []string{"integer"}, Format: "int8"}} -} - -// Int16Property creates an int16 property -func Int16Property() *Schema { - return &Schema{SchemaProps: SchemaProps{Type: []string{"integer"}, Format: "int16"}} -} - -// Int32Property creates an int32 property -func Int32Property() *Schema { - return &Schema{SchemaProps: SchemaProps{Type: []string{"integer"}, Format: "int32"}} -} - -// Int64Property creates an int64 property -func Int64Property() *Schema { - return &Schema{SchemaProps: SchemaProps{Type: []string{"integer"}, Format: "int64"}} -} - -// StrFmtProperty creates a property for the named string format -func StrFmtProperty(format string) *Schema { - return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}, Format: format}} -} - -// DateProperty creates a date property -func DateProperty() *Schema { - return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}, Format: "date"}} -} - -// DateTimeProperty creates a date time property -func DateTimeProperty() *Schema { - return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}, Format: "date-time"}} -} - -// MapProperty creates a map property -func MapProperty(property *Schema) *Schema { - return &Schema{SchemaProps: SchemaProps{Type: []string{"object"}, AdditionalProperties: &SchemaOrBool{Allows: true, Schema: property}}} -} - -// RefProperty creates a ref property -func RefProperty(name string) *Schema { - return &Schema{SchemaProps: SchemaProps{Ref: MustCreateRef(name)}} -} - -// RefSchema creates a ref property -func RefSchema(name string) *Schema { - return &Schema{SchemaProps: SchemaProps{Ref: MustCreateRef(name)}} -} - -// ArrayProperty creates an array property -func ArrayProperty(items *Schema) *Schema { - if items == nil { - return &Schema{SchemaProps: SchemaProps{Type: []string{"array"}}} - } - return &Schema{SchemaProps: SchemaProps{Items: &SchemaOrArray{Schema: items}, Type: []string{"array"}}} -} - -// ComposedSchema creates a schema with allOf -func ComposedSchema(schemas ...Schema) *Schema { - s := new(Schema) - s.AllOf = schemas - return s -} - -// SchemaURL represents a schema url -type SchemaURL string - -// MarshalJSON marshal this to JSON -func (r SchemaURL) MarshalJSON() ([]byte, error) { - if r == "" { - return []byte("{}"), nil - } - v := map[string]interface{}{"$schema": string(r)} - return json.Marshal(v) -} - -// UnmarshalJSON unmarshal this from JSON -func (r *SchemaURL) UnmarshalJSON(data []byte) error { - var v map[string]interface{} - if err := json.Unmarshal(data, &v); err != nil { - return err - } - return r.fromMap(v) -} - -func (r *SchemaURL) fromMap(v map[string]interface{}) error { - if v == nil { - return nil - } - if vv, ok := v["$schema"]; ok { - if str, ok := vv.(string); ok { - u, err := url.Parse(str) - if err != nil { - return err - } - - *r = SchemaURL(u.String()) - } - } - return nil -} - -// type ExtraSchemaProps map[string]interface{} - -// // JSONSchema represents a structure that is a json schema draft 04 -// type JSONSchema struct { -// SchemaProps -// ExtraSchemaProps -// } - -// // MarshalJSON marshal this to JSON -// func (s JSONSchema) MarshalJSON() ([]byte, error) { -// b1, err := json.Marshal(s.SchemaProps) -// if err != nil { -// return nil, err -// } -// b2, err := s.Ref.MarshalJSON() -// if err != nil { -// return nil, err -// } -// b3, err := s.Schema.MarshalJSON() -// if err != nil { -// return nil, err -// } -// b4, err := json.Marshal(s.ExtraSchemaProps) -// if err != nil { -// return nil, err -// } -// return swag.ConcatJSON(b1, b2, b3, b4), nil -// } - -// // UnmarshalJSON marshal this from JSON -// func (s *JSONSchema) UnmarshalJSON(data []byte) error { -// var sch JSONSchema -// if err := json.Unmarshal(data, &sch.SchemaProps); err != nil { -// return err -// } -// if err := json.Unmarshal(data, &sch.Ref); err != nil { -// return err -// } -// if err := json.Unmarshal(data, &sch.Schema); err != nil { -// return err -// } -// if err := json.Unmarshal(data, &sch.ExtraSchemaProps); err != nil { -// return err -// } -// *s = sch -// return nil -// } - -type SchemaProps struct { - ID string `json:"id,omitempty"` - Ref Ref `json:"-"` - Schema SchemaURL `json:"-"` - Description string `json:"description,omitempty"` - Type StringOrArray `json:"type,omitempty"` - Format string `json:"format,omitempty"` - Title string `json:"title,omitempty"` - Default interface{} `json:"default,omitempty"` - Maximum *float64 `json:"maximum,omitempty"` - ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"` - Minimum *float64 `json:"minimum,omitempty"` - ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"` - MaxLength *int64 `json:"maxLength,omitempty"` - MinLength *int64 `json:"minLength,omitempty"` - Pattern string `json:"pattern,omitempty"` - MaxItems *int64 `json:"maxItems,omitempty"` - MinItems *int64 `json:"minItems,omitempty"` - UniqueItems bool `json:"uniqueItems,omitempty"` - MultipleOf *float64 `json:"multipleOf,omitempty"` - Enum []interface{} `json:"enum,omitempty"` - MaxProperties *int64 `json:"maxProperties,omitempty"` - MinProperties *int64 `json:"minProperties,omitempty"` - Required []string `json:"required,omitempty"` - Items *SchemaOrArray `json:"items,omitempty"` - AllOf []Schema `json:"allOf,omitempty"` - OneOf []Schema `json:"oneOf,omitempty"` - AnyOf []Schema `json:"anyOf,omitempty"` - Not *Schema `json:"not,omitempty"` - Properties map[string]Schema `json:"properties,omitempty"` - AdditionalProperties *SchemaOrBool `json:"additionalProperties,omitempty"` - PatternProperties map[string]Schema `json:"patternProperties,omitempty"` - Dependencies Dependencies `json:"dependencies,omitempty"` - AdditionalItems *SchemaOrBool `json:"additionalItems,omitempty"` - Definitions Definitions `json:"definitions,omitempty"` -} - -type SwaggerSchemaProps struct { - Discriminator string `json:"discriminator,omitempty"` - ReadOnly bool `json:"readOnly,omitempty"` - XML *XMLObject `json:"xml,omitempty"` - ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"` - Example interface{} `json:"example,omitempty"` -} - -// Schema the schema object allows the definition of input and output data types. -// These types can be objects, but also primitives and arrays. -// This object is based on the [JSON Schema Specification Draft 4](http://json-schema.org/) -// and uses a predefined subset of it. -// On top of this subset, there are extensions provided by this specification to allow for more complete documentation. -// -// For more information: http://goo.gl/8us55a#schemaObject -type Schema struct { - VendorExtensible - SchemaProps - SwaggerSchemaProps - ExtraProps map[string]interface{} `json:"-"` -} - -// JSONLookup implements an interface to customize json pointer lookup -func (s Schema) JSONLookup(token string) (interface{}, error) { - if ex, ok := s.Extensions[token]; ok { - return &ex, nil - } - - if ex, ok := s.ExtraProps[token]; ok { - return &ex, nil - } - - r, _, err := jsonpointer.GetForToken(s.SchemaProps, token) - if r != nil || (err != nil && !strings.HasPrefix(err.Error(), "object has no field")) { - return r, err - } - r, _, err = jsonpointer.GetForToken(s.SwaggerSchemaProps, token) - return r, err -} - -// WithID sets the id for this schema, allows for chaining -func (s *Schema) WithID(id string) *Schema { - s.ID = id - return s -} - -// WithTitle sets the title for this schema, allows for chaining -func (s *Schema) WithTitle(title string) *Schema { - s.Title = title - return s -} - -// WithDescription sets the description for this schema, allows for chaining -func (s *Schema) WithDescription(description string) *Schema { - s.Description = description - return s -} - -// WithProperties sets the properties for this schema -func (s *Schema) WithProperties(schemas map[string]Schema) *Schema { - s.Properties = schemas - return s -} - -// SetProperty sets a property on this schema -func (s *Schema) SetProperty(name string, schema Schema) *Schema { - if s.Properties == nil { - s.Properties = make(map[string]Schema) - } - s.Properties[name] = schema - return s -} - -// WithAllOf sets the all of property -func (s *Schema) WithAllOf(schemas ...Schema) *Schema { - s.AllOf = schemas - return s -} - -// WithMaxProperties sets the max number of properties an object can have -func (s *Schema) WithMaxProperties(max int64) *Schema { - s.MaxProperties = &max - return s -} - -// WithMinProperties sets the min number of properties an object must have -func (s *Schema) WithMinProperties(min int64) *Schema { - s.MinProperties = &min - return s -} - -// Typed sets the type of this schema for a single value item -func (s *Schema) Typed(tpe, format string) *Schema { - s.Type = []string{tpe} - s.Format = format - return s -} - -// AddType adds a type with potential format to the types for this schema -func (s *Schema) AddType(tpe, format string) *Schema { - s.Type = append(s.Type, tpe) - if format != "" { - s.Format = format - } - return s -} - -// CollectionOf a fluent builder method for an array parameter -func (s *Schema) CollectionOf(items Schema) *Schema { - s.Type = []string{"array"} - s.Items = &SchemaOrArray{Schema: &items} - return s -} - -// WithDefault sets the default value on this parameter -func (s *Schema) WithDefault(defaultValue interface{}) *Schema { - s.Default = defaultValue - return s -} - -// WithRequired flags this parameter as required -func (s *Schema) WithRequired(items ...string) *Schema { - s.Required = items - return s -} - -// AddRequired adds field names to the required properties array -func (s *Schema) AddRequired(items ...string) *Schema { - s.Required = append(s.Required, items...) - return s -} - -// WithMaxLength sets a max length value -func (s *Schema) WithMaxLength(max int64) *Schema { - s.MaxLength = &max - return s -} - -// WithMinLength sets a min length value -func (s *Schema) WithMinLength(min int64) *Schema { - s.MinLength = &min - return s -} - -// WithPattern sets a pattern value -func (s *Schema) WithPattern(pattern string) *Schema { - s.Pattern = pattern - return s -} - -// WithMultipleOf sets a multiple of value -func (s *Schema) WithMultipleOf(number float64) *Schema { - s.MultipleOf = &number - return s -} - -// WithMaximum sets a maximum number value -func (s *Schema) WithMaximum(max float64, exclusive bool) *Schema { - s.Maximum = &max - s.ExclusiveMaximum = exclusive - return s -} - -// WithMinimum sets a minimum number value -func (s *Schema) WithMinimum(min float64, exclusive bool) *Schema { - s.Minimum = &min - s.ExclusiveMinimum = exclusive - return s -} - -// WithEnum sets a the enum values (replace) -func (s *Schema) WithEnum(values ...interface{}) *Schema { - s.Enum = append([]interface{}{}, values...) - return s -} - -// WithMaxItems sets the max items -func (s *Schema) WithMaxItems(size int64) *Schema { - s.MaxItems = &size - return s -} - -// WithMinItems sets the min items -func (s *Schema) WithMinItems(size int64) *Schema { - s.MinItems = &size - return s -} - -// UniqueValues dictates that this array can only have unique items -func (s *Schema) UniqueValues() *Schema { - s.UniqueItems = true - return s -} - -// AllowDuplicates this array can have duplicates -func (s *Schema) AllowDuplicates() *Schema { - s.UniqueItems = false - return s -} - -// AddToAllOf adds a schema to the allOf property -func (s *Schema) AddToAllOf(schemas ...Schema) *Schema { - s.AllOf = append(s.AllOf, schemas...) - return s -} - -// WithDiscriminator sets the name of the discriminator field -func (s *Schema) WithDiscriminator(discriminator string) *Schema { - s.Discriminator = discriminator - return s -} - -// AsReadOnly flags this schema as readonly -func (s *Schema) AsReadOnly() *Schema { - s.ReadOnly = true - return s -} - -// AsWritable flags this schema as writeable (not read-only) -func (s *Schema) AsWritable() *Schema { - s.ReadOnly = false - return s -} - -// WithExample sets the example for this schema -func (s *Schema) WithExample(example interface{}) *Schema { - s.Example = example - return s -} - -// WithExternalDocs sets/removes the external docs for/from this schema. -// When you pass empty strings as params the external documents will be removed. -// When you pass non-empty string as one value then those values will be used on the external docs object. -// So when you pass a non-empty description, you should also pass the url and vice versa. -func (s *Schema) WithExternalDocs(description, url string) *Schema { - if description == "" && url == "" { - s.ExternalDocs = nil - return s - } - - if s.ExternalDocs == nil { - s.ExternalDocs = &ExternalDocumentation{} - } - s.ExternalDocs.Description = description - s.ExternalDocs.URL = url - return s -} - -// WithXMLName sets the xml name for the object -func (s *Schema) WithXMLName(name string) *Schema { - if s.XML == nil { - s.XML = new(XMLObject) - } - s.XML.Name = name - return s -} - -// WithXMLNamespace sets the xml namespace for the object -func (s *Schema) WithXMLNamespace(namespace string) *Schema { - if s.XML == nil { - s.XML = new(XMLObject) - } - s.XML.Namespace = namespace - return s -} - -// WithXMLPrefix sets the xml prefix for the object -func (s *Schema) WithXMLPrefix(prefix string) *Schema { - if s.XML == nil { - s.XML = new(XMLObject) - } - s.XML.Prefix = prefix - return s -} - -// AsXMLAttribute flags this object as xml attribute -func (s *Schema) AsXMLAttribute() *Schema { - if s.XML == nil { - s.XML = new(XMLObject) - } - s.XML.Attribute = true - return s -} - -// AsXMLElement flags this object as an xml node -func (s *Schema) AsXMLElement() *Schema { - if s.XML == nil { - s.XML = new(XMLObject) - } - s.XML.Attribute = false - return s -} - -// AsWrappedXML flags this object as wrapped, this is mostly useful for array types -func (s *Schema) AsWrappedXML() *Schema { - if s.XML == nil { - s.XML = new(XMLObject) - } - s.XML.Wrapped = true - return s -} - -// AsUnwrappedXML flags this object as an xml node -func (s *Schema) AsUnwrappedXML() *Schema { - if s.XML == nil { - s.XML = new(XMLObject) - } - s.XML.Wrapped = false - return s -} - -// MarshalJSON marshal this to JSON -func (s Schema) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(s.SchemaProps) - if err != nil { - return nil, fmt.Errorf("schema props %v", err) - } - b2, err := json.Marshal(s.VendorExtensible) - if err != nil { - return nil, fmt.Errorf("vendor props %v", err) - } - b3, err := s.Ref.MarshalJSON() - if err != nil { - return nil, fmt.Errorf("ref prop %v", err) - } - b4, err := s.Schema.MarshalJSON() - if err != nil { - return nil, fmt.Errorf("schema prop %v", err) - } - b5, err := json.Marshal(s.SwaggerSchemaProps) - if err != nil { - return nil, fmt.Errorf("common validations %v", err) - } - var b6 []byte - if s.ExtraProps != nil { - jj, err := json.Marshal(s.ExtraProps) - if err != nil { - return nil, fmt.Errorf("extra props %v", err) - } - b6 = jj - } - return swag.ConcatJSON(b1, b2, b3, b4, b5, b6), nil -} - -// UnmarshalJSON marshal this from JSON -func (s *Schema) UnmarshalJSON(data []byte) error { - props := struct { - SchemaProps - SwaggerSchemaProps - }{} - if err := json.Unmarshal(data, &props); err != nil { - return err - } - - sch := Schema{ - SchemaProps: props.SchemaProps, - SwaggerSchemaProps: props.SwaggerSchemaProps, - } - - var d map[string]interface{} - if err := json.Unmarshal(data, &d); err != nil { - return err - } - - sch.Ref.fromMap(d) - sch.Schema.fromMap(d) - - delete(d, "$ref") - delete(d, "$schema") - for _, pn := range swag.DefaultJSONNameProvider.GetJSONNames(s) { - delete(d, pn) - } - - for k, vv := range d { - lk := strings.ToLower(k) - if strings.HasPrefix(lk, "x-") { - if sch.Extensions == nil { - sch.Extensions = map[string]interface{}{} - } - sch.Extensions[k] = vv - continue - } - if sch.ExtraProps == nil { - sch.ExtraProps = map[string]interface{}{} - } - sch.ExtraProps[k] = vv - } - - *s = sch - - return nil -} diff --git a/vendor/github.com/go-openapi/spec/security_scheme.go b/vendor/github.com/go-openapi/spec/security_scheme.go deleted file mode 100644 index 22d4f10af..000000000 --- a/vendor/github.com/go-openapi/spec/security_scheme.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - - "github.com/go-openapi/jsonpointer" - "github.com/go-openapi/swag" -) - -const ( - basic = "basic" - apiKey = "apiKey" - oauth2 = "oauth2" - implicit = "implicit" - password = "password" - application = "application" - accessCode = "accessCode" -) - -// BasicAuth creates a basic auth security scheme -func BasicAuth() *SecurityScheme { - return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{Type: basic}} -} - -// APIKeyAuth creates an api key auth security scheme -func APIKeyAuth(fieldName, valueSource string) *SecurityScheme { - return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{Type: apiKey, Name: fieldName, In: valueSource}} -} - -// OAuth2Implicit creates an implicit flow oauth2 security scheme -func OAuth2Implicit(authorizationURL string) *SecurityScheme { - return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{ - Type: oauth2, - Flow: implicit, - AuthorizationURL: authorizationURL, - }} -} - -// OAuth2Password creates a password flow oauth2 security scheme -func OAuth2Password(tokenURL string) *SecurityScheme { - return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{ - Type: oauth2, - Flow: password, - TokenURL: tokenURL, - }} -} - -// OAuth2Application creates an application flow oauth2 security scheme -func OAuth2Application(tokenURL string) *SecurityScheme { - return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{ - Type: oauth2, - Flow: application, - TokenURL: tokenURL, - }} -} - -// OAuth2AccessToken creates an access token flow oauth2 security scheme -func OAuth2AccessToken(authorizationURL, tokenURL string) *SecurityScheme { - return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{ - Type: oauth2, - Flow: accessCode, - AuthorizationURL: authorizationURL, - TokenURL: tokenURL, - }} -} - -type SecuritySchemeProps struct { - Description string `json:"description,omitempty"` - Type string `json:"type"` - Name string `json:"name,omitempty"` // api key - In string `json:"in,omitempty"` // api key - Flow string `json:"flow,omitempty"` // oauth2 - AuthorizationURL string `json:"authorizationUrl,omitempty"` // oauth2 - TokenURL string `json:"tokenUrl,omitempty"` // oauth2 - Scopes map[string]string `json:"scopes,omitempty"` // oauth2 -} - -// AddScope adds a scope to this security scheme -func (s *SecuritySchemeProps) AddScope(scope, description string) { - if s.Scopes == nil { - s.Scopes = make(map[string]string) - } - s.Scopes[scope] = description -} - -// SecurityScheme allows the definition of a security scheme that can be used by the operations. -// Supported schemes are basic authentication, an API key (either as a header or as a query parameter) -// and OAuth2's common flows (implicit, password, application and access code). -// -// For more information: http://goo.gl/8us55a#securitySchemeObject -type SecurityScheme struct { - VendorExtensible - SecuritySchemeProps -} - -// JSONLookup implements an interface to customize json pointer lookup -func (s SecurityScheme) JSONLookup(token string) (interface{}, error) { - if ex, ok := s.Extensions[token]; ok { - return &ex, nil - } - - r, _, err := jsonpointer.GetForToken(s.SecuritySchemeProps, token) - return r, err -} - -// MarshalJSON marshal this to JSON -func (s SecurityScheme) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(s.SecuritySchemeProps) - if err != nil { - return nil, err - } - b2, err := json.Marshal(s.VendorExtensible) - if err != nil { - return nil, err - } - return swag.ConcatJSON(b1, b2), nil -} - -// UnmarshalJSON marshal this from JSON -func (s *SecurityScheme) UnmarshalJSON(data []byte) error { - if err := json.Unmarshal(data, &s.SecuritySchemeProps); err != nil { - return err - } - if err := json.Unmarshal(data, &s.VendorExtensible); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/go-openapi/spec/spec.go b/vendor/github.com/go-openapi/spec/spec.go deleted file mode 100644 index 0bb045bc0..000000000 --- a/vendor/github.com/go-openapi/spec/spec.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import "encoding/json" - -//go:generate curl -L --progress -o ./schemas/v2/schema.json http://swagger.io/v2/schema.json -//go:generate curl -L --progress -o ./schemas/jsonschema-draft-04.json http://json-schema.org/draft-04/schema -//go:generate go-bindata -pkg=spec -prefix=./schemas -ignore=.*\.md ./schemas/... -//go:generate perl -pi -e s,Json,JSON,g bindata.go - -const ( - // SwaggerSchemaURL the url for the swagger 2.0 schema to validate specs - SwaggerSchemaURL = "http://swagger.io/v2/schema.json#" - // JSONSchemaURL the url for the json schema schema - JSONSchemaURL = "http://json-schema.org/draft-04/schema#" -) - -var ( - jsonSchema *Schema - swaggerSchema *Schema -) - -func init() { - jsonSchema = MustLoadJSONSchemaDraft04() - swaggerSchema = MustLoadSwagger20Schema() -} - -// MustLoadJSONSchemaDraft04 panics when Swagger20Schema returns an error -func MustLoadJSONSchemaDraft04() *Schema { - d, e := JSONSchemaDraft04() - if e != nil { - panic(e) - } - return d -} - -// JSONSchemaDraft04 loads the json schema document for json shema draft04 -func JSONSchemaDraft04() (*Schema, error) { - b, err := Asset("jsonschema-draft-04.json") - if err != nil { - return nil, err - } - - schema := new(Schema) - if err := json.Unmarshal(b, schema); err != nil { - return nil, err - } - return schema, nil -} - -// MustLoadSwagger20Schema panics when Swagger20Schema returns an error -func MustLoadSwagger20Schema() *Schema { - d, e := Swagger20Schema() - if e != nil { - panic(e) - } - return d -} - -// Swagger20Schema loads the swagger 2.0 schema from the embedded assets -func Swagger20Schema() (*Schema, error) { - - b, err := Asset("v2/schema.json") - if err != nil { - return nil, err - } - - schema := new(Schema) - if err := json.Unmarshal(b, schema); err != nil { - return nil, err - } - return schema, nil -} diff --git a/vendor/github.com/go-openapi/spec/swagger.go b/vendor/github.com/go-openapi/spec/swagger.go deleted file mode 100644 index 23780c78a..000000000 --- a/vendor/github.com/go-openapi/spec/swagger.go +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - "fmt" - "strconv" - - "github.com/go-openapi/jsonpointer" - "github.com/go-openapi/swag" -) - -// Swagger this is the root document object for the API specification. -// It combines what previously was the Resource Listing and API Declaration (version 1.2 and earlier) together into one document. -// -// For more information: http://goo.gl/8us55a#swagger-object- -type Swagger struct { - VendorExtensible - SwaggerProps -} - -// JSONLookup look up a value by the json property name -func (s Swagger) JSONLookup(token string) (interface{}, error) { - if ex, ok := s.Extensions[token]; ok { - return &ex, nil - } - r, _, err := jsonpointer.GetForToken(s.SwaggerProps, token) - return r, err -} - -// MarshalJSON marshals this swagger structure to json -func (s Swagger) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(s.SwaggerProps) - if err != nil { - return nil, err - } - b2, err := json.Marshal(s.VendorExtensible) - if err != nil { - return nil, err - } - return swag.ConcatJSON(b1, b2), nil -} - -// UnmarshalJSON unmarshals a swagger spec from json -func (s *Swagger) UnmarshalJSON(data []byte) error { - var sw Swagger - if err := json.Unmarshal(data, &sw.SwaggerProps); err != nil { - return err - } - if err := json.Unmarshal(data, &sw.VendorExtensible); err != nil { - return err - } - *s = sw - return nil -} - -type SwaggerProps struct { - ID string `json:"id,omitempty"` - Consumes []string `json:"consumes,omitempty"` - Produces []string `json:"produces,omitempty"` - Schemes []string `json:"schemes,omitempty"` // the scheme, when present must be from [http, https, ws, wss] - Swagger string `json:"swagger,omitempty"` - Info *Info `json:"info,omitempty"` - Host string `json:"host,omitempty"` - BasePath string `json:"basePath,omitempty"` // must start with a leading "/" - Paths *Paths `json:"paths"` // required - Definitions Definitions `json:"definitions,omitempty"` - Parameters map[string]Parameter `json:"parameters,omitempty"` - Responses map[string]Response `json:"responses,omitempty"` - SecurityDefinitions SecurityDefinitions `json:"securityDefinitions,omitempty"` - Security []map[string][]string `json:"security,omitempty"` - Tags []Tag `json:"tags,omitempty"` - ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"` -} - -// Dependencies represent a dependencies property -type Dependencies map[string]SchemaOrStringArray - -// SchemaOrBool represents a schema or boolean value, is biased towards true for the boolean property -type SchemaOrBool struct { - Allows bool - Schema *Schema -} - -// JSONLookup implements an interface to customize json pointer lookup -func (s SchemaOrBool) JSONLookup(token string) (interface{}, error) { - if token == "allows" { - return s.Allows, nil - } - r, _, err := jsonpointer.GetForToken(s.Schema, token) - return r, err -} - -var jsTrue = []byte("true") -var jsFalse = []byte("false") - -// MarshalJSON convert this object to JSON -func (s SchemaOrBool) MarshalJSON() ([]byte, error) { - if s.Schema != nil { - return json.Marshal(s.Schema) - } - - if s.Schema == nil && !s.Allows { - return jsFalse, nil - } - return jsTrue, nil -} - -// UnmarshalJSON converts this bool or schema object from a JSON structure -func (s *SchemaOrBool) UnmarshalJSON(data []byte) error { - var nw SchemaOrBool - if len(data) >= 4 { - if data[0] == '{' { - var sch Schema - if err := json.Unmarshal(data, &sch); err != nil { - return err - } - nw.Schema = &sch - } - nw.Allows = !(data[0] == 'f' && data[1] == 'a' && data[2] == 'l' && data[3] == 's' && data[4] == 'e') - } - *s = nw - return nil -} - -// SchemaOrStringArray represents a schema or a string array -type SchemaOrStringArray struct { - Schema *Schema - Property []string -} - -// JSONLookup implements an interface to customize json pointer lookup -func (s SchemaOrStringArray) JSONLookup(token string) (interface{}, error) { - r, _, err := jsonpointer.GetForToken(s.Schema, token) - return r, err -} - -// MarshalJSON converts this schema object or array into JSON structure -func (s SchemaOrStringArray) MarshalJSON() ([]byte, error) { - if len(s.Property) > 0 { - return json.Marshal(s.Property) - } - if s.Schema != nil { - return json.Marshal(s.Schema) - } - return []byte("null"), nil -} - -// UnmarshalJSON converts this schema object or array from a JSON structure -func (s *SchemaOrStringArray) UnmarshalJSON(data []byte) error { - var first byte - if len(data) > 1 { - first = data[0] - } - var nw SchemaOrStringArray - if first == '{' { - var sch Schema - if err := json.Unmarshal(data, &sch); err != nil { - return err - } - nw.Schema = &sch - } - if first == '[' { - if err := json.Unmarshal(data, &nw.Property); err != nil { - return err - } - } - *s = nw - return nil -} - -// Definitions contains the models explicitly defined in this spec -// An object to hold data types that can be consumed and produced by operations. -// These data types can be primitives, arrays or models. -// -// For more information: http://goo.gl/8us55a#definitionsObject -type Definitions map[string]Schema - -// SecurityDefinitions a declaration of the security schemes available to be used in the specification. -// This does not enforce the security schemes on the operations and only serves to provide -// the relevant details for each scheme. -// -// For more information: http://goo.gl/8us55a#securityDefinitionsObject -type SecurityDefinitions map[string]*SecurityScheme - -// StringOrArray represents a value that can either be a string -// or an array of strings. Mainly here for serialization purposes -type StringOrArray []string - -// Contains returns true when the value is contained in the slice -func (s StringOrArray) Contains(value string) bool { - for _, str := range s { - if str == value { - return true - } - } - return false -} - -// JSONLookup implements an interface to customize json pointer lookup -func (s SchemaOrArray) JSONLookup(token string) (interface{}, error) { - if _, err := strconv.Atoi(token); err == nil { - r, _, err := jsonpointer.GetForToken(s.Schemas, token) - return r, err - } - r, _, err := jsonpointer.GetForToken(s.Schema, token) - return r, err -} - -// UnmarshalJSON unmarshals this string or array object from a JSON array or JSON string -func (s *StringOrArray) UnmarshalJSON(data []byte) error { - var first byte - if len(data) > 1 { - first = data[0] - } - - if first == '[' { - var parsed []string - if err := json.Unmarshal(data, &parsed); err != nil { - return err - } - *s = StringOrArray(parsed) - return nil - } - - var single interface{} - if err := json.Unmarshal(data, &single); err != nil { - return err - } - if single == nil { - return nil - } - switch single.(type) { - case string: - *s = StringOrArray([]string{single.(string)}) - return nil - default: - return fmt.Errorf("only string or array is allowed, not %T", single) - } -} - -// MarshalJSON converts this string or array to a JSON array or JSON string -func (s StringOrArray) MarshalJSON() ([]byte, error) { - if len(s) == 1 { - return json.Marshal([]string(s)[0]) - } - return json.Marshal([]string(s)) -} - -// SchemaOrArray represents a value that can either be a Schema -// or an array of Schema. Mainly here for serialization purposes -type SchemaOrArray struct { - Schema *Schema - Schemas []Schema -} - -// Len returns the number of schemas in this property -func (s SchemaOrArray) Len() int { - if s.Schema != nil { - return 1 - } - return len(s.Schemas) -} - -// ContainsType returns true when one of the schemas is of the specified type -func (s *SchemaOrArray) ContainsType(name string) bool { - if s.Schema != nil { - return s.Schema.Type != nil && s.Schema.Type.Contains(name) - } - return false -} - -// MarshalJSON converts this schema object or array into JSON structure -func (s SchemaOrArray) MarshalJSON() ([]byte, error) { - if len(s.Schemas) > 0 { - return json.Marshal(s.Schemas) - } - return json.Marshal(s.Schema) -} - -// UnmarshalJSON converts this schema object or array from a JSON structure -func (s *SchemaOrArray) UnmarshalJSON(data []byte) error { - var nw SchemaOrArray - var first byte - if len(data) > 1 { - first = data[0] - } - if first == '{' { - var sch Schema - if err := json.Unmarshal(data, &sch); err != nil { - return err - } - nw.Schema = &sch - } - if first == '[' { - if err := json.Unmarshal(data, &nw.Schemas); err != nil { - return err - } - } - *s = nw - return nil -} - -// vim:set ft=go noet sts=2 sw=2 ts=2: diff --git a/vendor/github.com/go-openapi/spec/tag.go b/vendor/github.com/go-openapi/spec/tag.go deleted file mode 100644 index 97f555840..000000000 --- a/vendor/github.com/go-openapi/spec/tag.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -import ( - "encoding/json" - - "github.com/go-openapi/jsonpointer" - "github.com/go-openapi/swag" -) - -type TagProps struct { - Description string `json:"description,omitempty"` - Name string `json:"name,omitempty"` - ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"` -} - -// NewTag creates a new tag -func NewTag(name, description string, externalDocs *ExternalDocumentation) Tag { - return Tag{TagProps: TagProps{description, name, externalDocs}} -} - -// Tag allows adding meta data to a single tag that is used by the [Operation Object](http://goo.gl/8us55a#operationObject). -// It is not mandatory to have a Tag Object per tag used there. -// -// For more information: http://goo.gl/8us55a#tagObject -type Tag struct { - VendorExtensible - TagProps -} - -// JSONLookup implements an interface to customize json pointer lookup -func (t Tag) JSONLookup(token string) (interface{}, error) { - if ex, ok := t.Extensions[token]; ok { - return &ex, nil - } - - r, _, err := jsonpointer.GetForToken(t.TagProps, token) - return r, err -} - -// MarshalJSON marshal this to JSON -func (t Tag) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(t.TagProps) - if err != nil { - return nil, err - } - b2, err := json.Marshal(t.VendorExtensible) - if err != nil { - return nil, err - } - return swag.ConcatJSON(b1, b2), nil -} - -// UnmarshalJSON marshal this from JSON -func (t *Tag) UnmarshalJSON(data []byte) error { - if err := json.Unmarshal(data, &t.TagProps); err != nil { - return err - } - return json.Unmarshal(data, &t.VendorExtensible) -} diff --git a/vendor/github.com/go-openapi/spec/xml_object.go b/vendor/github.com/go-openapi/spec/xml_object.go deleted file mode 100644 index 945a46703..000000000 --- a/vendor/github.com/go-openapi/spec/xml_object.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package spec - -// XMLObject a metadata object that allows for more fine-tuned XML model definitions. -// -// For more information: http://goo.gl/8us55a#xmlObject -type XMLObject struct { - Name string `json:"name,omitempty"` - Namespace string `json:"namespace,omitempty"` - Prefix string `json:"prefix,omitempty"` - Attribute bool `json:"attribute,omitempty"` - Wrapped bool `json:"wrapped,omitempty"` -} - -// WithName sets the xml name for the object -func (x *XMLObject) WithName(name string) *XMLObject { - x.Name = name - return x -} - -// WithNamespace sets the xml namespace for the object -func (x *XMLObject) WithNamespace(namespace string) *XMLObject { - x.Namespace = namespace - return x -} - -// WithPrefix sets the xml prefix for the object -func (x *XMLObject) WithPrefix(prefix string) *XMLObject { - x.Prefix = prefix - return x -} - -// AsAttribute flags this object as xml attribute -func (x *XMLObject) AsAttribute() *XMLObject { - x.Attribute = true - return x -} - -// AsElement flags this object as an xml node -func (x *XMLObject) AsElement() *XMLObject { - x.Attribute = false - return x -} - -// AsWrapped flags this object as wrapped, this is mostly useful for array types -func (x *XMLObject) AsWrapped() *XMLObject { - x.Wrapped = true - return x -} - -// AsUnwrapped flags this object as an xml node -func (x *XMLObject) AsUnwrapped() *XMLObject { - x.Wrapped = false - return x -} diff --git a/vendor/github.com/go-openapi/swag/LICENSE b/vendor/github.com/go-openapi/swag/LICENSE deleted file mode 100644 index d64569567..000000000 --- a/vendor/github.com/go-openapi/swag/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/go-openapi/swag/convert.go b/vendor/github.com/go-openapi/swag/convert.go deleted file mode 100644 index 2bf5ecbba..000000000 --- a/vendor/github.com/go-openapi/swag/convert.go +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import ( - "math" - "strconv" - "strings" -) - -// same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER -const ( - maxJSONFloat = float64(1<<53 - 1) // 9007199254740991.0 2^53 - 1 - minJSONFloat = -float64(1<<53 - 1) //-9007199254740991.0 -2^53 - 1 -) - -// IsFloat64AJSONInteger allow for integers [-2^53, 2^53-1] inclusive -func IsFloat64AJSONInteger(f float64) bool { - if math.IsNaN(f) || math.IsInf(f, 0) || f < minJSONFloat || f > maxJSONFloat { - return false - } - - return f == float64(int64(f)) || f == float64(uint64(f)) -} - -var evaluatesAsTrue = map[string]struct{}{ - "true": struct{}{}, - "1": struct{}{}, - "yes": struct{}{}, - "ok": struct{}{}, - "y": struct{}{}, - "on": struct{}{}, - "selected": struct{}{}, - "checked": struct{}{}, - "t": struct{}{}, - "enabled": struct{}{}, -} - -// ConvertBool turn a string into a boolean -func ConvertBool(str string) (bool, error) { - _, ok := evaluatesAsTrue[strings.ToLower(str)] - return ok, nil -} - -// ConvertFloat32 turn a string into a float32 -func ConvertFloat32(str string) (float32, error) { - f, err := strconv.ParseFloat(str, 32) - if err != nil { - return 0, err - } - return float32(f), nil -} - -// ConvertFloat64 turn a string into a float64 -func ConvertFloat64(str string) (float64, error) { - return strconv.ParseFloat(str, 64) -} - -// ConvertInt8 turn a string into int8 boolean -func ConvertInt8(str string) (int8, error) { - i, err := strconv.ParseInt(str, 10, 8) - if err != nil { - return 0, err - } - return int8(i), nil -} - -// ConvertInt16 turn a string into a int16 -func ConvertInt16(str string) (int16, error) { - i, err := strconv.ParseInt(str, 10, 16) - if err != nil { - return 0, err - } - return int16(i), nil -} - -// ConvertInt32 turn a string into a int32 -func ConvertInt32(str string) (int32, error) { - i, err := strconv.ParseInt(str, 10, 32) - if err != nil { - return 0, err - } - return int32(i), nil -} - -// ConvertInt64 turn a string into a int64 -func ConvertInt64(str string) (int64, error) { - return strconv.ParseInt(str, 10, 64) -} - -// ConvertUint8 turn a string into a uint8 -func ConvertUint8(str string) (uint8, error) { - i, err := strconv.ParseUint(str, 10, 8) - if err != nil { - return 0, err - } - return uint8(i), nil -} - -// ConvertUint16 turn a string into a uint16 -func ConvertUint16(str string) (uint16, error) { - i, err := strconv.ParseUint(str, 10, 16) - if err != nil { - return 0, err - } - return uint16(i), nil -} - -// ConvertUint32 turn a string into a uint32 -func ConvertUint32(str string) (uint32, error) { - i, err := strconv.ParseUint(str, 10, 32) - if err != nil { - return 0, err - } - return uint32(i), nil -} - -// ConvertUint64 turn a string into a uint64 -func ConvertUint64(str string) (uint64, error) { - return strconv.ParseUint(str, 10, 64) -} - -// FormatBool turns a boolean into a string -func FormatBool(value bool) string { - return strconv.FormatBool(value) -} - -// FormatFloat32 turns a float32 into a string -func FormatFloat32(value float32) string { - return strconv.FormatFloat(float64(value), 'f', -1, 32) -} - -// FormatFloat64 turns a float64 into a string -func FormatFloat64(value float64) string { - return strconv.FormatFloat(value, 'f', -1, 64) -} - -// FormatInt8 turns an int8 into a string -func FormatInt8(value int8) string { - return strconv.FormatInt(int64(value), 10) -} - -// FormatInt16 turns an int16 into a string -func FormatInt16(value int16) string { - return strconv.FormatInt(int64(value), 10) -} - -// FormatInt32 turns an int32 into a string -func FormatInt32(value int32) string { - return strconv.Itoa(int(value)) -} - -// FormatInt64 turns an int64 into a string -func FormatInt64(value int64) string { - return strconv.FormatInt(value, 10) -} - -// FormatUint8 turns an uint8 into a string -func FormatUint8(value uint8) string { - return strconv.FormatUint(uint64(value), 10) -} - -// FormatUint16 turns an uint16 into a string -func FormatUint16(value uint16) string { - return strconv.FormatUint(uint64(value), 10) -} - -// FormatUint32 turns an uint32 into a string -func FormatUint32(value uint32) string { - return strconv.FormatUint(uint64(value), 10) -} - -// FormatUint64 turns an uint64 into a string -func FormatUint64(value uint64) string { - return strconv.FormatUint(value, 10) -} diff --git a/vendor/github.com/go-openapi/swag/convert_types.go b/vendor/github.com/go-openapi/swag/convert_types.go deleted file mode 100644 index c95e4e78b..000000000 --- a/vendor/github.com/go-openapi/swag/convert_types.go +++ /dev/null @@ -1,595 +0,0 @@ -package swag - -import "time" - -// This file was taken from the aws go sdk - -// String returns a pointer to of the string value passed in. -func String(v string) *string { - return &v -} - -// StringValue returns the value of the string pointer passed in or -// "" if the pointer is nil. -func StringValue(v *string) string { - if v != nil { - return *v - } - return "" -} - -// StringSlice converts a slice of string values into a slice of -// string pointers -func StringSlice(src []string) []*string { - dst := make([]*string, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// StringValueSlice converts a slice of string pointers into a slice of -// string values -func StringValueSlice(src []*string) []string { - dst := make([]string, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// StringMap converts a string map of string values into a string -// map of string pointers -func StringMap(src map[string]string) map[string]*string { - dst := make(map[string]*string) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// StringValueMap converts a string map of string pointers into a string -// map of string values -func StringValueMap(src map[string]*string) map[string]string { - dst := make(map[string]string) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Bool returns a pointer to of the bool value passed in. -func Bool(v bool) *bool { - return &v -} - -// BoolValue returns the value of the bool pointer passed in or -// false if the pointer is nil. -func BoolValue(v *bool) bool { - if v != nil { - return *v - } - return false -} - -// BoolSlice converts a slice of bool values into a slice of -// bool pointers -func BoolSlice(src []bool) []*bool { - dst := make([]*bool, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// BoolValueSlice converts a slice of bool pointers into a slice of -// bool values -func BoolValueSlice(src []*bool) []bool { - dst := make([]bool, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// BoolMap converts a string map of bool values into a string -// map of bool pointers -func BoolMap(src map[string]bool) map[string]*bool { - dst := make(map[string]*bool) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// BoolValueMap converts a string map of bool pointers into a string -// map of bool values -func BoolValueMap(src map[string]*bool) map[string]bool { - dst := make(map[string]bool) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Int returns a pointer to of the int value passed in. -func Int(v int) *int { - return &v -} - -// IntValue returns the value of the int pointer passed in or -// 0 if the pointer is nil. -func IntValue(v *int) int { - if v != nil { - return *v - } - return 0 -} - -// IntSlice converts a slice of int values into a slice of -// int pointers -func IntSlice(src []int) []*int { - dst := make([]*int, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// IntValueSlice converts a slice of int pointers into a slice of -// int values -func IntValueSlice(src []*int) []int { - dst := make([]int, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// IntMap converts a string map of int values into a string -// map of int pointers -func IntMap(src map[string]int) map[string]*int { - dst := make(map[string]*int) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// IntValueMap converts a string map of int pointers into a string -// map of int values -func IntValueMap(src map[string]*int) map[string]int { - dst := make(map[string]int) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Int32 returns a pointer to of the int64 value passed in. -func Int32(v int32) *int32 { - return &v -} - -// Int32Value returns the value of the int64 pointer passed in or -// 0 if the pointer is nil. -func Int32Value(v *int32) int32 { - if v != nil { - return *v - } - return 0 -} - -// Int32Slice converts a slice of int64 values into a slice of -// int32 pointers -func Int32Slice(src []int32) []*int32 { - dst := make([]*int32, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Int32ValueSlice converts a slice of int32 pointers into a slice of -// int32 values -func Int32ValueSlice(src []*int32) []int32 { - dst := make([]int32, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Int32Map converts a string map of int32 values into a string -// map of int32 pointers -func Int32Map(src map[string]int32) map[string]*int32 { - dst := make(map[string]*int32) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Int32ValueMap converts a string map of int32 pointers into a string -// map of int32 values -func Int32ValueMap(src map[string]*int32) map[string]int32 { - dst := make(map[string]int32) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Int64 returns a pointer to of the int64 value passed in. -func Int64(v int64) *int64 { - return &v -} - -// Int64Value returns the value of the int64 pointer passed in or -// 0 if the pointer is nil. -func Int64Value(v *int64) int64 { - if v != nil { - return *v - } - return 0 -} - -// Int64Slice converts a slice of int64 values into a slice of -// int64 pointers -func Int64Slice(src []int64) []*int64 { - dst := make([]*int64, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Int64ValueSlice converts a slice of int64 pointers into a slice of -// int64 values -func Int64ValueSlice(src []*int64) []int64 { - dst := make([]int64, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Int64Map converts a string map of int64 values into a string -// map of int64 pointers -func Int64Map(src map[string]int64) map[string]*int64 { - dst := make(map[string]*int64) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Int64ValueMap converts a string map of int64 pointers into a string -// map of int64 values -func Int64ValueMap(src map[string]*int64) map[string]int64 { - dst := make(map[string]int64) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Uint returns a pouinter to of the uint value passed in. -func Uint(v uint) *uint { - return &v -} - -// UintValue returns the value of the uint pouinter passed in or -// 0 if the pouinter is nil. -func UintValue(v *uint) uint { - if v != nil { - return *v - } - return 0 -} - -// UintSlice converts a slice of uint values uinto a slice of -// uint pouinters -func UintSlice(src []uint) []*uint { - dst := make([]*uint, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// UintValueSlice converts a slice of uint pouinters uinto a slice of -// uint values -func UintValueSlice(src []*uint) []uint { - dst := make([]uint, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// UintMap converts a string map of uint values uinto a string -// map of uint pouinters -func UintMap(src map[string]uint) map[string]*uint { - dst := make(map[string]*uint) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// UintValueMap converts a string map of uint pouinters uinto a string -// map of uint values -func UintValueMap(src map[string]*uint) map[string]uint { - dst := make(map[string]uint) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Uint32 returns a pouinter to of the uint64 value passed in. -func Uint32(v uint32) *uint32 { - return &v -} - -// Uint32Value returns the value of the uint64 pouinter passed in or -// 0 if the pouinter is nil. -func Uint32Value(v *uint32) uint32 { - if v != nil { - return *v - } - return 0 -} - -// Uint32Slice converts a slice of uint64 values uinto a slice of -// uint32 pouinters -func Uint32Slice(src []uint32) []*uint32 { - dst := make([]*uint32, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Uint32ValueSlice converts a slice of uint32 pouinters uinto a slice of -// uint32 values -func Uint32ValueSlice(src []*uint32) []uint32 { - dst := make([]uint32, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Uint32Map converts a string map of uint32 values uinto a string -// map of uint32 pouinters -func Uint32Map(src map[string]uint32) map[string]*uint32 { - dst := make(map[string]*uint32) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Uint32ValueMap converts a string map of uint32 pouinters uinto a string -// map of uint32 values -func Uint32ValueMap(src map[string]*uint32) map[string]uint32 { - dst := make(map[string]uint32) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Uint64 returns a pouinter to of the uint64 value passed in. -func Uint64(v uint64) *uint64 { - return &v -} - -// Uint64Value returns the value of the uint64 pouinter passed in or -// 0 if the pouinter is nil. -func Uint64Value(v *uint64) uint64 { - if v != nil { - return *v - } - return 0 -} - -// Uint64Slice converts a slice of uint64 values uinto a slice of -// uint64 pouinters -func Uint64Slice(src []uint64) []*uint64 { - dst := make([]*uint64, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Uint64ValueSlice converts a slice of uint64 pouinters uinto a slice of -// uint64 values -func Uint64ValueSlice(src []*uint64) []uint64 { - dst := make([]uint64, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Uint64Map converts a string map of uint64 values uinto a string -// map of uint64 pouinters -func Uint64Map(src map[string]uint64) map[string]*uint64 { - dst := make(map[string]*uint64) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Uint64ValueMap converts a string map of uint64 pouinters uinto a string -// map of uint64 values -func Uint64ValueMap(src map[string]*uint64) map[string]uint64 { - dst := make(map[string]uint64) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Float64 returns a pointer to of the float64 value passed in. -func Float64(v float64) *float64 { - return &v -} - -// Float64Value returns the value of the float64 pointer passed in or -// 0 if the pointer is nil. -func Float64Value(v *float64) float64 { - if v != nil { - return *v - } - return 0 -} - -// Float64Slice converts a slice of float64 values into a slice of -// float64 pointers -func Float64Slice(src []float64) []*float64 { - dst := make([]*float64, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Float64ValueSlice converts a slice of float64 pointers into a slice of -// float64 values -func Float64ValueSlice(src []*float64) []float64 { - dst := make([]float64, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Float64Map converts a string map of float64 values into a string -// map of float64 pointers -func Float64Map(src map[string]float64) map[string]*float64 { - dst := make(map[string]*float64) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Float64ValueMap converts a string map of float64 pointers into a string -// map of float64 values -func Float64ValueMap(src map[string]*float64) map[string]float64 { - dst := make(map[string]float64) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Time returns a pointer to of the time.Time value passed in. -func Time(v time.Time) *time.Time { - return &v -} - -// TimeValue returns the value of the time.Time pointer passed in or -// time.Time{} if the pointer is nil. -func TimeValue(v *time.Time) time.Time { - if v != nil { - return *v - } - return time.Time{} -} - -// TimeSlice converts a slice of time.Time values into a slice of -// time.Time pointers -func TimeSlice(src []time.Time) []*time.Time { - dst := make([]*time.Time, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// TimeValueSlice converts a slice of time.Time pointers into a slice of -// time.Time values -func TimeValueSlice(src []*time.Time) []time.Time { - dst := make([]time.Time, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// TimeMap converts a string map of time.Time values into a string -// map of time.Time pointers -func TimeMap(src map[string]time.Time) map[string]*time.Time { - dst := make(map[string]*time.Time) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// TimeValueMap converts a string map of time.Time pointers into a string -// map of time.Time values -func TimeValueMap(src map[string]*time.Time) map[string]time.Time { - dst := make(map[string]time.Time) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} diff --git a/vendor/github.com/go-openapi/swag/json.go b/vendor/github.com/go-openapi/swag/json.go deleted file mode 100644 index 274331ef1..000000000 --- a/vendor/github.com/go-openapi/swag/json.go +++ /dev/null @@ -1,310 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import ( - "bytes" - "encoding/json" - "log" - "reflect" - "strings" - "sync" - - "github.com/mailru/easyjson/jlexer" - "github.com/mailru/easyjson/jwriter" -) - -// nullJSON represents a JSON object with null type -var nullJSON = []byte("null") - -// DefaultJSONNameProvider the default cache for types -var DefaultJSONNameProvider = NewNameProvider() - -const comma = byte(',') - -var closers = map[byte]byte{ - '{': '}', - '[': ']', -} - -type ejMarshaler interface { - MarshalEasyJSON(w *jwriter.Writer) -} - -type ejUnmarshaler interface { - UnmarshalEasyJSON(w *jlexer.Lexer) -} - -// WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaller -// so it takes the fastest option available. -func WriteJSON(data interface{}) ([]byte, error) { - if d, ok := data.(ejMarshaler); ok { - jw := new(jwriter.Writer) - d.MarshalEasyJSON(jw) - return jw.BuildBytes() - } - if d, ok := data.(json.Marshaler); ok { - return d.MarshalJSON() - } - return json.Marshal(data) -} - -// ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaller -// so it takes the fastes option available -func ReadJSON(data []byte, value interface{}) error { - if d, ok := value.(ejUnmarshaler); ok { - jl := &jlexer.Lexer{Data: data} - d.UnmarshalEasyJSON(jl) - return jl.Error() - } - if d, ok := value.(json.Unmarshaler); ok { - return d.UnmarshalJSON(data) - } - return json.Unmarshal(data, value) -} - -// DynamicJSONToStruct converts an untyped json structure into a struct -func DynamicJSONToStruct(data interface{}, target interface{}) error { - // TODO: convert straight to a json typed map (mergo + iterate?) - b, err := WriteJSON(data) - if err != nil { - return err - } - if err := ReadJSON(b, target); err != nil { - return err - } - return nil -} - -// ConcatJSON concatenates multiple json objects efficiently -func ConcatJSON(blobs ...[]byte) []byte { - if len(blobs) == 0 { - return nil - } - - last := len(blobs) - 1 - for blobs[last] == nil || bytes.Equal(blobs[last], nullJSON) { - // strips trailing null objects - last = last - 1 - if last < 0 { - // there was nothing but "null"s or nil... - return nil - } - } - if last == 0 { - return blobs[0] - } - - var opening, closing byte - var idx, a int - buf := bytes.NewBuffer(nil) - - for i, b := range blobs[:last+1] { - if b == nil || bytes.Equal(b, nullJSON) { - // a null object is in the list: skip it - continue - } - if len(b) > 0 && opening == 0 { // is this an array or an object? - opening, closing = b[0], closers[b[0]] - } - - if opening != '{' && opening != '[' { - continue // don't know how to concatenate non container objects - } - - if len(b) < 3 { // yep empty but also the last one, so closing this thing - if i == last && a > 0 { - if err := buf.WriteByte(closing); err != nil { - log.Println(err) - } - } - continue - } - - idx = 0 - if a > 0 { // we need to join with a comma for everything beyond the first non-empty item - if err := buf.WriteByte(comma); err != nil { - log.Println(err) - } - idx = 1 // this is not the first or the last so we want to drop the leading bracket - } - - if i != last { // not the last one, strip brackets - if _, err := buf.Write(b[idx : len(b)-1]); err != nil { - log.Println(err) - } - } else { // last one, strip only the leading bracket - if _, err := buf.Write(b[idx:]); err != nil { - log.Println(err) - } - } - a++ - } - // somehow it ended up being empty, so provide a default value - if buf.Len() == 0 { - if err := buf.WriteByte(opening); err != nil { - log.Println(err) - } - if err := buf.WriteByte(closing); err != nil { - log.Println(err) - } - } - return buf.Bytes() -} - -// ToDynamicJSON turns an object into a properly JSON typed structure -func ToDynamicJSON(data interface{}) interface{} { - // TODO: convert straight to a json typed map (mergo + iterate?) - b, err := json.Marshal(data) - if err != nil { - log.Println(err) - } - var res interface{} - if err := json.Unmarshal(b, &res); err != nil { - log.Println(err) - } - return res -} - -// FromDynamicJSON turns an object into a properly JSON typed structure -func FromDynamicJSON(data, target interface{}) error { - b, err := json.Marshal(data) - if err != nil { - log.Println(err) - } - return json.Unmarshal(b, target) -} - -// NameProvider represents an object capabale of translating from go property names -// to json property names -// This type is thread-safe. -type NameProvider struct { - lock *sync.Mutex - index map[reflect.Type]nameIndex -} - -type nameIndex struct { - jsonNames map[string]string - goNames map[string]string -} - -// NewNameProvider creates a new name provider -func NewNameProvider() *NameProvider { - return &NameProvider{ - lock: &sync.Mutex{}, - index: make(map[reflect.Type]nameIndex), - } -} - -func buildnameIndex(tpe reflect.Type, idx, reverseIdx map[string]string) { - for i := 0; i < tpe.NumField(); i++ { - targetDes := tpe.Field(i) - - if targetDes.PkgPath != "" { // unexported - continue - } - - if targetDes.Anonymous { // walk embedded structures tree down first - buildnameIndex(targetDes.Type, idx, reverseIdx) - continue - } - - if tag := targetDes.Tag.Get("json"); tag != "" { - - parts := strings.Split(tag, ",") - if len(parts) == 0 { - continue - } - - nm := parts[0] - if nm == "-" { - continue - } - if nm == "" { // empty string means we want to use the Go name - nm = targetDes.Name - } - - idx[nm] = targetDes.Name - reverseIdx[targetDes.Name] = nm - } - } -} - -func newNameIndex(tpe reflect.Type) nameIndex { - var idx = make(map[string]string, tpe.NumField()) - var reverseIdx = make(map[string]string, tpe.NumField()) - - buildnameIndex(tpe, idx, reverseIdx) - return nameIndex{jsonNames: idx, goNames: reverseIdx} -} - -// GetJSONNames gets all the json property names for a type -func (n *NameProvider) GetJSONNames(subject interface{}) []string { - n.lock.Lock() - defer n.lock.Unlock() - tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() - names, ok := n.index[tpe] - if !ok { - names = n.makeNameIndex(tpe) - } - - var res []string - for k := range names.jsonNames { - res = append(res, k) - } - return res -} - -// GetJSONName gets the json name for a go property name -func (n *NameProvider) GetJSONName(subject interface{}, name string) (string, bool) { - tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() - return n.GetJSONNameForType(tpe, name) -} - -// GetJSONNameForType gets the json name for a go property name on a given type -func (n *NameProvider) GetJSONNameForType(tpe reflect.Type, name string) (string, bool) { - n.lock.Lock() - defer n.lock.Unlock() - names, ok := n.index[tpe] - if !ok { - names = n.makeNameIndex(tpe) - } - nme, ok := names.goNames[name] - return nme, ok -} - -func (n *NameProvider) makeNameIndex(tpe reflect.Type) nameIndex { - names := newNameIndex(tpe) - n.index[tpe] = names - return names -} - -// GetGoName gets the go name for a json property name -func (n *NameProvider) GetGoName(subject interface{}, name string) (string, bool) { - tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() - return n.GetGoNameForType(tpe, name) -} - -// GetGoNameForType gets the go name for a given type for a json property name -func (n *NameProvider) GetGoNameForType(tpe reflect.Type, name string) (string, bool) { - n.lock.Lock() - defer n.lock.Unlock() - names, ok := n.index[tpe] - if !ok { - names = n.makeNameIndex(tpe) - } - nme, ok := names.jsonNames[name] - return nme, ok -} diff --git a/vendor/github.com/go-openapi/swag/loading.go b/vendor/github.com/go-openapi/swag/loading.go deleted file mode 100644 index 70f4fb361..000000000 --- a/vendor/github.com/go-openapi/swag/loading.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import ( - "fmt" - "io/ioutil" - "log" - "net/http" - "path/filepath" - "strings" - "time" -) - -// LoadHTTPTimeout the default timeout for load requests -var LoadHTTPTimeout = 30 * time.Second - -// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in -func LoadFromFileOrHTTP(path string) ([]byte, error) { - return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path) -} - -// LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in -// timeout arg allows for per request overriding of the request timeout -func LoadFromFileOrHTTPWithTimeout(path string, timeout time.Duration) ([]byte, error) { - return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(timeout))(path) -} - -// LoadStrategy returns a loader function for a given path or uri -func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) { - if strings.HasPrefix(path, "http") { - return remote - } - return func(pth string) ([]byte, error) { - upth, err := pathUnescape(pth) - if err != nil { - return nil, err - } - return local(filepath.FromSlash(upth)) - } -} - -func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) { - return func(path string) ([]byte, error) { - client := &http.Client{Timeout: timeout} - req, err := http.NewRequest("GET", path, nil) - if err != nil { - return nil, err - } - resp, err := client.Do(req) - defer func() { - if resp != nil { - if e := resp.Body.Close(); e != nil { - log.Println(e) - } - } - }() - if err != nil { - return nil, err - } - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("could not access document at %q [%s] ", path, resp.Status) - } - - return ioutil.ReadAll(resp.Body) - } -} diff --git a/vendor/github.com/go-openapi/swag/net.go b/vendor/github.com/go-openapi/swag/net.go deleted file mode 100644 index 8323fa37b..000000000 --- a/vendor/github.com/go-openapi/swag/net.go +++ /dev/null @@ -1,24 +0,0 @@ -package swag - -import ( - "net" - "strconv" -) - -// SplitHostPort splits a network address into a host and a port. -// The port is -1 when there is no port to be found -func SplitHostPort(addr string) (host string, port int, err error) { - h, p, err := net.SplitHostPort(addr) - if err != nil { - return "", -1, err - } - if p == "" { - return "", -1, &net.AddrError{Err: "missing port in address", Addr: addr} - } - - pi, err := strconv.Atoi(p) - if err != nil { - return "", -1, err - } - return h, pi, nil -} diff --git a/vendor/github.com/go-openapi/swag/path.go b/vendor/github.com/go-openapi/swag/path.go deleted file mode 100644 index 941bd0176..000000000 --- a/vendor/github.com/go-openapi/swag/path.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import ( - "os" - "path/filepath" - "runtime" - "strings" -) - -const ( - // GOPATHKey represents the env key for gopath - GOPATHKey = "GOPATH" -) - -// FindInSearchPath finds a package in a provided lists of paths -func FindInSearchPath(searchPath, pkg string) string { - pathsList := filepath.SplitList(searchPath) - for _, path := range pathsList { - if evaluatedPath, err := filepath.EvalSymlinks(filepath.Join(path, "src", pkg)); err == nil { - if _, err := os.Stat(evaluatedPath); err == nil { - return evaluatedPath - } - } - } - return "" -} - -// FindInGoSearchPath finds a package in the $GOPATH:$GOROOT -func FindInGoSearchPath(pkg string) string { - return FindInSearchPath(FullGoSearchPath(), pkg) -} - -// FullGoSearchPath gets the search paths for finding packages -func FullGoSearchPath() string { - allPaths := os.Getenv(GOPATHKey) - if allPaths == "" { - allPaths = filepath.Join(os.Getenv("HOME"), "go") - } - if allPaths != "" { - allPaths = strings.Join([]string{allPaths, runtime.GOROOT()}, ":") - } else { - allPaths = runtime.GOROOT() - } - return allPaths -} diff --git a/vendor/github.com/go-openapi/swag/post_go18.go b/vendor/github.com/go-openapi/swag/post_go18.go deleted file mode 100644 index ef48086db..000000000 --- a/vendor/github.com/go-openapi/swag/post_go18.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build go1.8 - -package swag - -import "net/url" - -func pathUnescape(path string) (string, error) { - return url.PathUnescape(path) -} diff --git a/vendor/github.com/go-openapi/swag/pre_go18.go b/vendor/github.com/go-openapi/swag/pre_go18.go deleted file mode 100644 index 860bb2bbb..000000000 --- a/vendor/github.com/go-openapi/swag/pre_go18.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build !go1.8 - -package swag - -import "net/url" - -func pathUnescape(path string) (string, error) { - return url.QueryUnescape(path) -} diff --git a/vendor/github.com/go-openapi/swag/util.go b/vendor/github.com/go-openapi/swag/util.go deleted file mode 100644 index 7e0f80a41..000000000 --- a/vendor/github.com/go-openapi/swag/util.go +++ /dev/null @@ -1,362 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import ( - "math" - "reflect" - "regexp" - "sort" - "strings" - "sync" - "unicode" -) - -// Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769 -var commonInitialisms = map[string]bool{ - "ACL": true, - "API": true, - "ASCII": true, - "CPU": true, - "CSS": true, - "DNS": true, - "EOF": true, - "GUID": true, - "HTML": true, - "HTTPS": true, - "HTTP": true, - "ID": true, - "IP": true, - "JSON": true, - "LHS": true, - "OAI": true, - "QPS": true, - "RAM": true, - "RHS": true, - "RPC": true, - "SLA": true, - "SMTP": true, - "SQL": true, - "SSH": true, - "TCP": true, - "TLS": true, - "TTL": true, - "UDP": true, - "UI": true, - "UID": true, - "UUID": true, - "URI": true, - "URL": true, - "UTF8": true, - "VM": true, - "XML": true, - "XMPP": true, - "XSRF": true, - "XSS": true, -} -var initialisms []string - -var once sync.Once - -func sortInitialisms() { - for k := range commonInitialisms { - initialisms = append(initialisms, k) - } - sort.Sort(sort.Reverse(byLength(initialisms))) -} - -// JoinByFormat joins a string array by a known format: -// ssv: space separated value -// tsv: tab separated value -// pipes: pipe (|) separated value -// csv: comma separated value (default) -func JoinByFormat(data []string, format string) []string { - if len(data) == 0 { - return data - } - var sep string - switch format { - case "ssv": - sep = " " - case "tsv": - sep = "\t" - case "pipes": - sep = "|" - case "multi": - return data - default: - sep = "," - } - return []string{strings.Join(data, sep)} -} - -// SplitByFormat splits a string by a known format: -// ssv: space separated value -// tsv: tab separated value -// pipes: pipe (|) separated value -// csv: comma separated value (default) -func SplitByFormat(data, format string) []string { - if data == "" { - return nil - } - var sep string - switch format { - case "ssv": - sep = " " - case "tsv": - sep = "\t" - case "pipes": - sep = "|" - case "multi": - return nil - default: - sep = "," - } - var result []string - for _, s := range strings.Split(data, sep) { - if ts := strings.TrimSpace(s); ts != "" { - result = append(result, ts) - } - } - return result -} - -type byLength []string - -func (s byLength) Len() int { - return len(s) -} -func (s byLength) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} -func (s byLength) Less(i, j int) bool { - return len(s[i]) < len(s[j]) -} - -// Prepares strings by splitting by caps, spaces, dashes, and underscore -func split(str string) (words []string) { - repl := strings.NewReplacer( - "@", "At ", - "&", "And ", - "|", "Pipe ", - "$", "Dollar ", - "!", "Bang ", - "-", " ", - "_", " ", - ) - - rex1 := regexp.MustCompile(`(\p{Lu})`) - rex2 := regexp.MustCompile(`(\pL|\pM|\pN|\p{Pc})+`) - - str = trim(str) - - // Convert dash and underscore to spaces - str = repl.Replace(str) - - // Split when uppercase is found (needed for Snake) - str = rex1.ReplaceAllString(str, " $1") - - // check if consecutive single char things make up an initialism - once.Do(sortInitialisms) - for _, k := range initialisms { - str = strings.Replace(str, rex1.ReplaceAllString(k, " $1"), " "+k, -1) - } - // Get the final list of words - words = rex2.FindAllString(str, -1) - - return -} - -// Removes leading whitespaces -func trim(str string) string { - return strings.Trim(str, " ") -} - -// Shortcut to strings.ToUpper() -func upper(str string) string { - return strings.ToUpper(trim(str)) -} - -// Shortcut to strings.ToLower() -func lower(str string) string { - return strings.ToLower(trim(str)) -} - -// Camelize an uppercased word -func Camelize(word string) (camelized string) { - for pos, ru := range word { - if pos > 0 { - camelized += string(unicode.ToLower(ru)) - } else { - camelized += string(unicode.ToUpper(ru)) - } - } - return -} - -// ToFileName lowercases and underscores a go type name -func ToFileName(name string) string { - var out []string - - for _, w := range split(name) { - out = append(out, lower(w)) - } - - return strings.Join(out, "_") -} - -// ToCommandName lowercases and underscores a go type name -func ToCommandName(name string) string { - var out []string - for _, w := range split(name) { - out = append(out, lower(w)) - } - return strings.Join(out, "-") -} - -// ToHumanNameLower represents a code name as a human series of words -func ToHumanNameLower(name string) string { - var out []string - for _, w := range split(name) { - if !commonInitialisms[upper(w)] { - out = append(out, lower(w)) - } else { - out = append(out, w) - } - } - return strings.Join(out, " ") -} - -// ToHumanNameTitle represents a code name as a human series of words with the first letters titleized -func ToHumanNameTitle(name string) string { - var out []string - for _, w := range split(name) { - uw := upper(w) - if !commonInitialisms[uw] { - out = append(out, upper(w[:1])+lower(w[1:])) - } else { - out = append(out, w) - } - } - return strings.Join(out, " ") -} - -// ToJSONName camelcases a name which can be underscored or pascal cased -func ToJSONName(name string) string { - var out []string - for i, w := range split(name) { - if i == 0 { - out = append(out, lower(w)) - continue - } - out = append(out, upper(w[:1])+lower(w[1:])) - } - return strings.Join(out, "") -} - -// ToVarName camelcases a name which can be underscored or pascal cased -func ToVarName(name string) string { - res := ToGoName(name) - if _, ok := commonInitialisms[res]; ok { - return lower(res) - } - if len(res) <= 1 { - return lower(res) - } - return lower(res[:1]) + res[1:] -} - -// ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes -func ToGoName(name string) string { - var out []string - for _, w := range split(name) { - uw := upper(w) - mod := int(math.Min(float64(len(uw)), 2)) - if !commonInitialisms[uw] && !commonInitialisms[uw[:len(uw)-mod]] { - uw = upper(w[:1]) + lower(w[1:]) - } - out = append(out, uw) - } - - result := strings.Join(out, "") - if len(result) > 0 { - ud := upper(result[:1]) - ru := []rune(ud) - if unicode.IsUpper(ru[0]) { - result = ud + result[1:] - } else { - result = "X" + ud + result[1:] - } - } - return result -} - -// ContainsStringsCI searches a slice of strings for a case-insensitive match -func ContainsStringsCI(coll []string, item string) bool { - for _, a := range coll { - if strings.EqualFold(a, item) { - return true - } - } - return false -} - -type zeroable interface { - IsZero() bool -} - -// IsZero returns true when the value passed into the function is a zero value. -// This allows for safer checking of interface values. -func IsZero(data interface{}) bool { - // check for things that have an IsZero method instead - if vv, ok := data.(zeroable); ok { - return vv.IsZero() - } - // continue with slightly more complex reflection - v := reflect.ValueOf(data) - switch v.Kind() { - case reflect.String: - return v.Len() == 0 - case reflect.Bool: - return !v.Bool() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return v.IsNil() - case reflect.Struct, reflect.Array: - return reflect.DeepEqual(data, reflect.Zero(v.Type()).Interface()) - case reflect.Invalid: - return true - } - return false -} - -// AddInitialisms add additional initialisms -func AddInitialisms(words ...string) { - for _, word := range words { - commonInitialisms[upper(word)] = true - } -} - -// CommandLineOptionsGroup represents a group of user-defined command line options -type CommandLineOptionsGroup struct { - ShortDescription string - LongDescription string - Options interface{} -} diff --git a/vendor/github.com/go-openapi/swag/yaml.go b/vendor/github.com/go-openapi/swag/yaml.go deleted file mode 100644 index e2eff7568..000000000 --- a/vendor/github.com/go-openapi/swag/yaml.go +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import ( - "encoding/json" - "fmt" - "path/filepath" - "strconv" - - "github.com/mailru/easyjson/jlexer" - "github.com/mailru/easyjson/jwriter" - - yaml "gopkg.in/yaml.v2" -) - -// YAMLMatcher matches yaml -func YAMLMatcher(path string) bool { - ext := filepath.Ext(path) - return ext == ".yaml" || ext == ".yml" -} - -// YAMLToJSON converts YAML unmarshaled data into json compatible data -func YAMLToJSON(data interface{}) (json.RawMessage, error) { - jm, err := transformData(data) - if err != nil { - return nil, err - } - b, err := WriteJSON(jm) - return json.RawMessage(b), err -} - -// BytesToYAMLDoc converts a byte slice into a YAML document -func BytesToYAMLDoc(data []byte) (interface{}, error) { - var canary map[interface{}]interface{} // validate this is an object and not a different type - if err := yaml.Unmarshal(data, &canary); err != nil { - return nil, err - } - - var document yaml.MapSlice // preserve order that is present in the document - if err := yaml.Unmarshal(data, &document); err != nil { - return nil, err - } - return document, nil -} - -type JSONMapSlice []JSONMapItem - -func (s JSONMapSlice) MarshalJSON() ([]byte, error) { - w := &jwriter.Writer{Flags: jwriter.NilMapAsEmpty | jwriter.NilSliceAsEmpty} - s.MarshalEasyJSON(w) - return w.BuildBytes() -} - -func (s JSONMapSlice) MarshalEasyJSON(w *jwriter.Writer) { - w.RawByte('{') - - ln := len(s) - last := ln - 1 - for i := 0; i < ln; i++ { - s[i].MarshalEasyJSON(w) - if i != last { // last item - w.RawByte(',') - } - } - - w.RawByte('}') -} - -func (s *JSONMapSlice) UnmarshalJSON(data []byte) error { - l := jlexer.Lexer{Data: data} - s.UnmarshalEasyJSON(&l) - return l.Error() -} -func (s *JSONMapSlice) UnmarshalEasyJSON(in *jlexer.Lexer) { - if in.IsNull() { - in.Skip() - return - } - - var result JSONMapSlice - in.Delim('{') - for !in.IsDelim('}') { - var mi JSONMapItem - mi.UnmarshalEasyJSON(in) - result = append(result, mi) - } - *s = result -} - -type JSONMapItem struct { - Key string - Value interface{} -} - -func (s JSONMapItem) MarshalJSON() ([]byte, error) { - w := &jwriter.Writer{Flags: jwriter.NilMapAsEmpty | jwriter.NilSliceAsEmpty} - s.MarshalEasyJSON(w) - return w.BuildBytes() -} - -func (s JSONMapItem) MarshalEasyJSON(w *jwriter.Writer) { - w.String(s.Key) - w.RawByte(':') - w.Raw(WriteJSON(s.Value)) -} - -func (s *JSONMapItem) UnmarshalEasyJSON(in *jlexer.Lexer) { - key := in.UnsafeString() - in.WantColon() - value := in.Interface() - in.WantComma() - s.Key = key - s.Value = value -} -func (s *JSONMapItem) UnmarshalJSON(data []byte) error { - l := jlexer.Lexer{Data: data} - s.UnmarshalEasyJSON(&l) - return l.Error() -} - -func transformData(input interface{}) (out interface{}, err error) { - switch in := input.(type) { - case yaml.MapSlice: - - o := make(JSONMapSlice, len(in)) - for i, mi := range in { - var nmi JSONMapItem - switch k := mi.Key.(type) { - case string: - nmi.Key = k - case int: - nmi.Key = strconv.Itoa(k) - default: - return nil, fmt.Errorf("types don't match expect map key string or int got: %T", mi.Key) - } - - v, err := transformData(mi.Value) - if err != nil { - return nil, err - } - nmi.Value = v - o[i] = nmi - } - return o, nil - case map[interface{}]interface{}: - o := make(JSONMapSlice, 0, len(in)) - for ke, va := range in { - var nmi JSONMapItem - switch k := ke.(type) { - case string: - nmi.Key = k - case int: - nmi.Key = strconv.Itoa(k) - default: - return nil, fmt.Errorf("types don't match expect map key string or int got: %T", ke) - } - - v, err := transformData(va) - if err != nil { - return nil, err - } - nmi.Value = v - o = append(o, nmi) - } - return o, nil - case []interface{}: - len1 := len(in) - o := make([]interface{}, len1) - for i := 0; i < len1; i++ { - o[i], err = transformData(in[i]) - if err != nil { - return nil, err - } - } - return o, nil - } - return input, nil -} - -// YAMLDoc loads a yaml document from either http or a file and converts it to json -func YAMLDoc(path string) (json.RawMessage, error) { - yamlDoc, err := YAMLData(path) - if err != nil { - return nil, err - } - - data, err := YAMLToJSON(yamlDoc) - if err != nil { - return nil, err - } - - return json.RawMessage(data), nil -} - -// YAMLData loads a yaml document from either http or a file -func YAMLData(path string) (interface{}, error) { - data, err := LoadFromFileOrHTTP(path) - if err != nil { - return nil, err - } - - return BytesToYAMLDoc(data) -} diff --git a/vendor/github.com/gogo/protobuf/AUTHORS b/vendor/github.com/gogo/protobuf/AUTHORS deleted file mode 100644 index 3d97fc7a2..000000000 --- a/vendor/github.com/gogo/protobuf/AUTHORS +++ /dev/null @@ -1,15 +0,0 @@ -# This is the official list of GoGo authors for copyright purposes. -# This file is distinct from the CONTRIBUTORS file, which -# lists people. For example, employees are listed in CONTRIBUTORS, -# but not in AUTHORS, because the employer holds the copyright. - -# Names should be added to this file as one of -# Organization's name -# Individual's name -# Individual's name - -# Please keep the list sorted. - -Sendgrid, Inc -Vastech SA (PTY) LTD -Walter Schulze diff --git a/vendor/github.com/gogo/protobuf/CONTRIBUTORS b/vendor/github.com/gogo/protobuf/CONTRIBUTORS deleted file mode 100644 index 1b4f6c208..000000000 --- a/vendor/github.com/gogo/protobuf/CONTRIBUTORS +++ /dev/null @@ -1,23 +0,0 @@ -Anton Povarov -Brian Goff -Clayton Coleman -Denis Smirnov -DongYun Kang -Dwayne Schultz -Georg Apitz -Gustav Paul -Johan Brandhorst -John Shahid -John Tuley -Laurent -Patrick Lee -Peter Edge -Roger Johansson -Sam Nguyen -Sergio Arbeo -Stephen J Day -Tamir Duberstein -Todd Eisenberger -Tormod Erevik Lea -Vyacheslav Kim -Walter Schulze diff --git a/vendor/github.com/gogo/protobuf/GOLANG_CONTRIBUTORS b/vendor/github.com/gogo/protobuf/GOLANG_CONTRIBUTORS deleted file mode 100644 index b368efb7f..000000000 --- a/vendor/github.com/gogo/protobuf/GOLANG_CONTRIBUTORS +++ /dev/null @@ -1,5 +0,0 @@ -The contributors to the Go protobuf repository: - -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. \ No newline at end of file diff --git a/vendor/github.com/gogo/protobuf/LICENSE b/vendor/github.com/gogo/protobuf/LICENSE deleted file mode 100644 index 7be0cc7b6..000000000 --- a/vendor/github.com/gogo/protobuf/LICENSE +++ /dev/null @@ -1,36 +0,0 @@ -Protocol Buffers for Go with Gadgets - -Copyright (c) 2013, The GoGo Authors. All rights reserved. -http://github.com/gogo/protobuf - -Go support for Protocol Buffers - Google's data interchange format - -Copyright 2010 The Go Authors. All rights reserved. -https://github.com/golang/protobuf - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/vendor/github.com/gogo/protobuf/proto/clone.go b/vendor/github.com/gogo/protobuf/proto/clone.go deleted file mode 100644 index 5d4cba4b5..000000000 --- a/vendor/github.com/gogo/protobuf/proto/clone.go +++ /dev/null @@ -1,234 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2011 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Protocol buffer deep copy and merge. -// TODO: RawMessage. - -package proto - -import ( - "log" - "reflect" - "strings" -) - -// Clone returns a deep copy of a protocol buffer. -func Clone(pb Message) Message { - in := reflect.ValueOf(pb) - if in.IsNil() { - return pb - } - - out := reflect.New(in.Type().Elem()) - // out is empty so a merge is a deep copy. - mergeStruct(out.Elem(), in.Elem()) - return out.Interface().(Message) -} - -// Merge merges src into dst. -// Required and optional fields that are set in src will be set to that value in dst. -// Elements of repeated fields will be appended. -// Merge panics if src and dst are not the same type, or if dst is nil. -func Merge(dst, src Message) { - in := reflect.ValueOf(src) - out := reflect.ValueOf(dst) - if out.IsNil() { - panic("proto: nil destination") - } - if in.Type() != out.Type() { - // Explicit test prior to mergeStruct so that mistyped nils will fail - panic("proto: type mismatch") - } - if in.IsNil() { - // Merging nil into non-nil is a quiet no-op - return - } - mergeStruct(out.Elem(), in.Elem()) -} - -func mergeStruct(out, in reflect.Value) { - sprop := GetProperties(in.Type()) - for i := 0; i < in.NumField(); i++ { - f := in.Type().Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) - } - - if emIn, ok := in.Addr().Interface().(extensionsBytes); ok { - emOut := out.Addr().Interface().(extensionsBytes) - bIn := emIn.GetExtensions() - bOut := emOut.GetExtensions() - *bOut = append(*bOut, *bIn...) - } else if emIn, ok := extendable(in.Addr().Interface()); ok { - emOut, _ := extendable(out.Addr().Interface()) - mIn, muIn := emIn.extensionsRead() - if mIn != nil { - mOut := emOut.extensionsWrite() - muIn.Lock() - mergeExtension(mOut, mIn) - muIn.Unlock() - } - } - - uf := in.FieldByName("XXX_unrecognized") - if !uf.IsValid() { - return - } - uin := uf.Bytes() - if len(uin) > 0 { - out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...)) - } -} - -// mergeAny performs a merge between two values of the same type. -// viaPtr indicates whether the values were indirected through a pointer (implying proto2). -// prop is set if this is a struct field (it may be nil). -func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) { - if in.Type() == protoMessageType { - if !in.IsNil() { - if out.IsNil() { - out.Set(reflect.ValueOf(Clone(in.Interface().(Message)))) - } else { - Merge(out.Interface().(Message), in.Interface().(Message)) - } - } - return - } - switch in.Kind() { - case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, - reflect.String, reflect.Uint32, reflect.Uint64: - if !viaPtr && isProto3Zero(in) { - return - } - out.Set(in) - case reflect.Interface: - // Probably a oneof field; copy non-nil values. - if in.IsNil() { - return - } - // Allocate destination if it is not set, or set to a different type. - // Otherwise we will merge as normal. - if out.IsNil() || out.Elem().Type() != in.Elem().Type() { - out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T) - } - mergeAny(out.Elem(), in.Elem(), false, nil) - case reflect.Map: - if in.Len() == 0 { - return - } - if out.IsNil() { - out.Set(reflect.MakeMap(in.Type())) - } - // For maps with value types of *T or []byte we need to deep copy each value. - elemKind := in.Type().Elem().Kind() - for _, key := range in.MapKeys() { - var val reflect.Value - switch elemKind { - case reflect.Ptr: - val = reflect.New(in.Type().Elem().Elem()) - mergeAny(val, in.MapIndex(key), false, nil) - case reflect.Slice: - val = in.MapIndex(key) - val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) - default: - val = in.MapIndex(key) - } - out.SetMapIndex(key, val) - } - case reflect.Ptr: - if in.IsNil() { - return - } - if out.IsNil() { - out.Set(reflect.New(in.Elem().Type())) - } - mergeAny(out.Elem(), in.Elem(), true, nil) - case reflect.Slice: - if in.IsNil() { - return - } - if in.Type().Elem().Kind() == reflect.Uint8 { - // []byte is a scalar bytes field, not a repeated field. - - // Edge case: if this is in a proto3 message, a zero length - // bytes field is considered the zero value, and should not - // be merged. - if prop != nil && prop.proto3 && in.Len() == 0 { - return - } - - // Make a deep copy. - // Append to []byte{} instead of []byte(nil) so that we never end up - // with a nil result. - out.SetBytes(append([]byte{}, in.Bytes()...)) - return - } - n := in.Len() - if out.IsNil() { - out.Set(reflect.MakeSlice(in.Type(), 0, n)) - } - switch in.Type().Elem().Kind() { - case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, - reflect.String, reflect.Uint32, reflect.Uint64: - out.Set(reflect.AppendSlice(out, in)) - default: - for i := 0; i < n; i++ { - x := reflect.Indirect(reflect.New(in.Type().Elem())) - mergeAny(x, in.Index(i), false, nil) - out.Set(reflect.Append(out, x)) - } - } - case reflect.Struct: - mergeStruct(out, in) - default: - // unknown type, so not a protocol buffer - log.Printf("proto: don't know how to copy %v", in) - } -} - -func mergeExtension(out, in map[int32]Extension) { - for extNum, eIn := range in { - eOut := Extension{desc: eIn.desc} - if eIn.value != nil { - v := reflect.New(reflect.TypeOf(eIn.value)).Elem() - mergeAny(v, reflect.ValueOf(eIn.value), false, nil) - eOut.value = v.Interface() - } - if eIn.enc != nil { - eOut.enc = make([]byte, len(eIn.enc)) - copy(eOut.enc, eIn.enc) - } - - out[extNum] = eOut - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/decode.go b/vendor/github.com/gogo/protobuf/proto/decode.go deleted file mode 100644 index 737f2731d..000000000 --- a/vendor/github.com/gogo/protobuf/proto/decode.go +++ /dev/null @@ -1,978 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Routines for decoding protocol buffer data to construct in-memory representations. - */ - -import ( - "errors" - "fmt" - "io" - "os" - "reflect" -) - -// errOverflow is returned when an integer is too large to be represented. -var errOverflow = errors.New("proto: integer overflow") - -// ErrInternalBadWireType is returned by generated code when an incorrect -// wire type is encountered. It does not get returned to user code. -var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") - -// The fundamental decoders that interpret bytes on the wire. -// Those that take integer types all return uint64 and are -// therefore of type valueDecoder. - -// DecodeVarint reads a varint-encoded integer from the slice. -// It returns the integer and the number of bytes consumed, or -// zero if there is not enough. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func DecodeVarint(buf []byte) (x uint64, n int) { - for shift := uint(0); shift < 64; shift += 7 { - if n >= len(buf) { - return 0, 0 - } - b := uint64(buf[n]) - n++ - x |= (b & 0x7F) << shift - if (b & 0x80) == 0 { - return x, n - } - } - - // The number is too large to represent in a 64-bit value. - return 0, 0 -} - -func (p *Buffer) decodeVarintSlow() (x uint64, err error) { - i := p.index - l := len(p.buf) - - for shift := uint(0); shift < 64; shift += 7 { - if i >= l { - err = io.ErrUnexpectedEOF - return - } - b := p.buf[i] - i++ - x |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - p.index = i - return - } - } - - // The number is too large to represent in a 64-bit value. - err = errOverflow - return -} - -// DecodeVarint reads a varint-encoded integer from the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (p *Buffer) DecodeVarint() (x uint64, err error) { - i := p.index - buf := p.buf - - if i >= len(buf) { - return 0, io.ErrUnexpectedEOF - } else if buf[i] < 0x80 { - p.index++ - return uint64(buf[i]), nil - } else if len(buf)-i < 10 { - return p.decodeVarintSlow() - } - - var b uint64 - // we already checked the first byte - x = uint64(buf[i]) - 0x80 - i++ - - b = uint64(buf[i]) - i++ - x += b << 7 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 7 - - b = uint64(buf[i]) - i++ - x += b << 14 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 14 - - b = uint64(buf[i]) - i++ - x += b << 21 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 21 - - b = uint64(buf[i]) - i++ - x += b << 28 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 28 - - b = uint64(buf[i]) - i++ - x += b << 35 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 35 - - b = uint64(buf[i]) - i++ - x += b << 42 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 42 - - b = uint64(buf[i]) - i++ - x += b << 49 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 49 - - b = uint64(buf[i]) - i++ - x += b << 56 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 56 - - b = uint64(buf[i]) - i++ - x += b << 63 - if b&0x80 == 0 { - goto done - } - // x -= 0x80 << 63 // Always zero. - - return 0, errOverflow - -done: - p.index = i - return x, nil -} - -// DecodeFixed64 reads a 64-bit integer from the Buffer. -// This is the format for the -// fixed64, sfixed64, and double protocol buffer types. -func (p *Buffer) DecodeFixed64() (x uint64, err error) { - // x, err already 0 - i := p.index + 8 - if i < 0 || i > len(p.buf) { - err = io.ErrUnexpectedEOF - return - } - p.index = i - - x = uint64(p.buf[i-8]) - x |= uint64(p.buf[i-7]) << 8 - x |= uint64(p.buf[i-6]) << 16 - x |= uint64(p.buf[i-5]) << 24 - x |= uint64(p.buf[i-4]) << 32 - x |= uint64(p.buf[i-3]) << 40 - x |= uint64(p.buf[i-2]) << 48 - x |= uint64(p.buf[i-1]) << 56 - return -} - -// DecodeFixed32 reads a 32-bit integer from the Buffer. -// This is the format for the -// fixed32, sfixed32, and float protocol buffer types. -func (p *Buffer) DecodeFixed32() (x uint64, err error) { - // x, err already 0 - i := p.index + 4 - if i < 0 || i > len(p.buf) { - err = io.ErrUnexpectedEOF - return - } - p.index = i - - x = uint64(p.buf[i-4]) - x |= uint64(p.buf[i-3]) << 8 - x |= uint64(p.buf[i-2]) << 16 - x |= uint64(p.buf[i-1]) << 24 - return -} - -// DecodeZigzag64 reads a zigzag-encoded 64-bit integer -// from the Buffer. -// This is the format used for the sint64 protocol buffer type. -func (p *Buffer) DecodeZigzag64() (x uint64, err error) { - x, err = p.DecodeVarint() - if err != nil { - return - } - x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63) - return -} - -// DecodeZigzag32 reads a zigzag-encoded 32-bit integer -// from the Buffer. -// This is the format used for the sint32 protocol buffer type. -func (p *Buffer) DecodeZigzag32() (x uint64, err error) { - x, err = p.DecodeVarint() - if err != nil { - return - } - x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31)) - return -} - -// These are not ValueDecoders: they produce an array of bytes or a string. -// bytes, embedded messages - -// DecodeRawBytes reads a count-delimited byte buffer from the Buffer. -// This is the format used for the bytes protocol buffer -// type and for embedded messages. -func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { - n, err := p.DecodeVarint() - if err != nil { - return nil, err - } - - nb := int(n) - if nb < 0 { - return nil, fmt.Errorf("proto: bad byte length %d", nb) - } - end := p.index + nb - if end < p.index || end > len(p.buf) { - return nil, io.ErrUnexpectedEOF - } - - if !alloc { - // todo: check if can get more uses of alloc=false - buf = p.buf[p.index:end] - p.index += nb - return - } - - buf = make([]byte, nb) - copy(buf, p.buf[p.index:]) - p.index += nb - return -} - -// DecodeStringBytes reads an encoded string from the Buffer. -// This is the format used for the proto2 string type. -func (p *Buffer) DecodeStringBytes() (s string, err error) { - buf, err := p.DecodeRawBytes(false) - if err != nil { - return - } - return string(buf), nil -} - -// Skip the next item in the buffer. Its wire type is decoded and presented as an argument. -// If the protocol buffer has extensions, and the field matches, add it as an extension. -// Otherwise, if the XXX_unrecognized field exists, append the skipped data there. -func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error { - oi := o.index - - err := o.skip(t, tag, wire) - if err != nil { - return err - } - - if !unrecField.IsValid() { - return nil - } - - ptr := structPointer_Bytes(base, unrecField) - - // Add the skipped field to struct field - obuf := o.buf - - o.buf = *ptr - o.EncodeVarint(uint64(tag<<3 | wire)) - *ptr = append(o.buf, obuf[oi:o.index]...) - - o.buf = obuf - - return nil -} - -// Skip the next item in the buffer. Its wire type is decoded and presented as an argument. -func (o *Buffer) skip(t reflect.Type, tag, wire int) error { - - var u uint64 - var err error - - switch wire { - case WireVarint: - _, err = o.DecodeVarint() - case WireFixed64: - _, err = o.DecodeFixed64() - case WireBytes: - _, err = o.DecodeRawBytes(false) - case WireFixed32: - _, err = o.DecodeFixed32() - case WireStartGroup: - for { - u, err = o.DecodeVarint() - if err != nil { - break - } - fwire := int(u & 0x7) - if fwire == WireEndGroup { - break - } - ftag := int(u >> 3) - err = o.skip(t, ftag, fwire) - if err != nil { - break - } - } - default: - err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t) - } - return err -} - -// Unmarshaler is the interface representing objects that can -// unmarshal themselves. The method should reset the receiver before -// decoding starts. The argument points to data that may be -// overwritten, so implementations should not keep references to the -// buffer. -type Unmarshaler interface { - Unmarshal([]byte) error -} - -// Unmarshal parses the protocol buffer representation in buf and places the -// decoded result in pb. If the struct underlying pb does not match -// the data in buf, the results can be unpredictable. -// -// Unmarshal resets pb before starting to unmarshal, so any -// existing data in pb is always removed. Use UnmarshalMerge -// to preserve and append to existing data. -func Unmarshal(buf []byte, pb Message) error { - pb.Reset() - return UnmarshalMerge(buf, pb) -} - -// UnmarshalMerge parses the protocol buffer representation in buf and -// writes the decoded result to pb. If the struct underlying pb does not match -// the data in buf, the results can be unpredictable. -// -// UnmarshalMerge merges into existing data in pb. -// Most code should use Unmarshal instead. -func UnmarshalMerge(buf []byte, pb Message) error { - // If the object can unmarshal itself, let it. - if u, ok := pb.(Unmarshaler); ok { - return u.Unmarshal(buf) - } - return NewBuffer(buf).Unmarshal(pb) -} - -// DecodeMessage reads a count-delimited message from the Buffer. -func (p *Buffer) DecodeMessage(pb Message) error { - enc, err := p.DecodeRawBytes(false) - if err != nil { - return err - } - return NewBuffer(enc).Unmarshal(pb) -} - -// DecodeGroup reads a tag-delimited group from the Buffer. -func (p *Buffer) DecodeGroup(pb Message) error { - typ, base, err := getbase(pb) - if err != nil { - return err - } - return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), true, base) -} - -// Unmarshal parses the protocol buffer representation in the -// Buffer and places the decoded result in pb. If the struct -// underlying pb does not match the data in the buffer, the results can be -// unpredictable. -// -// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal. -func (p *Buffer) Unmarshal(pb Message) error { - // If the object can unmarshal itself, let it. - if u, ok := pb.(Unmarshaler); ok { - err := u.Unmarshal(p.buf[p.index:]) - p.index = len(p.buf) - return err - } - - typ, base, err := getbase(pb) - if err != nil { - return err - } - - err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base) - - if collectStats { - stats.Decode++ - } - - return err -} - -// unmarshalType does the work of unmarshaling a structure. -func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error { - var state errorState - required, reqFields := prop.reqCount, uint64(0) - - var err error - for err == nil && o.index < len(o.buf) { - oi := o.index - var u uint64 - u, err = o.DecodeVarint() - if err != nil { - break - } - wire := int(u & 0x7) - if wire == WireEndGroup { - if is_group { - if required > 0 { - // Not enough information to determine the exact field. - // (See below.) - return &RequiredNotSetError{"{Unknown}"} - } - return nil // input is satisfied - } - return fmt.Errorf("proto: %s: wiretype end group for non-group", st) - } - tag := int(u >> 3) - if tag <= 0 { - return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire) - } - fieldnum, ok := prop.decoderTags.get(tag) - if !ok { - // Maybe it's an extension? - if prop.extendable { - if e, eok := structPointer_Interface(base, st).(extensionsBytes); eok { - if isExtensionField(e, int32(tag)) { - if err = o.skip(st, tag, wire); err == nil { - ext := e.GetExtensions() - *ext = append(*ext, o.buf[oi:o.index]...) - } - continue - } - } else if e, _ := extendable(structPointer_Interface(base, st)); isExtensionField(e, int32(tag)) { - if err = o.skip(st, tag, wire); err == nil { - extmap := e.extensionsWrite() - ext := extmap[int32(tag)] // may be missing - ext.enc = append(ext.enc, o.buf[oi:o.index]...) - extmap[int32(tag)] = ext - } - continue - } - } - // Maybe it's a oneof? - if prop.oneofUnmarshaler != nil { - m := structPointer_Interface(base, st).(Message) - // First return value indicates whether tag is a oneof field. - ok, err = prop.oneofUnmarshaler(m, tag, wire, o) - if err == ErrInternalBadWireType { - // Map the error to something more descriptive. - // Do the formatting here to save generated code space. - err = fmt.Errorf("bad wiretype for oneof field in %T", m) - } - if ok { - continue - } - } - err = o.skipAndSave(st, tag, wire, base, prop.unrecField) - continue - } - p := prop.Prop[fieldnum] - - if p.dec == nil { - fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name) - continue - } - dec := p.dec - if wire != WireStartGroup && wire != p.WireType { - if wire == WireBytes && p.packedDec != nil { - // a packable field - dec = p.packedDec - } else { - err = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType) - continue - } - } - decErr := dec(o, p, base) - if decErr != nil && !state.shouldContinue(decErr, p) { - err = decErr - } - if err == nil && p.Required { - // Successfully decoded a required field. - if tag <= 64 { - // use bitmap for fields 1-64 to catch field reuse. - var mask uint64 = 1 << uint64(tag-1) - if reqFields&mask == 0 { - // new required field - reqFields |= mask - required-- - } - } else { - // This is imprecise. It can be fooled by a required field - // with a tag > 64 that is encoded twice; that's very rare. - // A fully correct implementation would require allocating - // a data structure, which we would like to avoid. - required-- - } - } - } - if err == nil { - if is_group { - return io.ErrUnexpectedEOF - } - if state.err != nil { - return state.err - } - if required > 0 { - // Not enough information to determine the exact field. If we use extra - // CPU, we could determine the field only if the missing required field - // has a tag <= 64 and we check reqFields. - return &RequiredNotSetError{"{Unknown}"} - } - } - return err -} - -// Individual type decoders -// For each, -// u is the decoded value, -// v is a pointer to the field (pointer) in the struct - -// Sizes of the pools to allocate inside the Buffer. -// The goal is modest amortization and allocation -// on at least 16-byte boundaries. -const ( - boolPoolSize = 16 - uint32PoolSize = 8 - uint64PoolSize = 4 -) - -// Decode a bool. -func (o *Buffer) dec_bool(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - if len(o.bools) == 0 { - o.bools = make([]bool, boolPoolSize) - } - o.bools[0] = u != 0 - *structPointer_Bool(base, p.field) = &o.bools[0] - o.bools = o.bools[1:] - return nil -} - -func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - *structPointer_BoolVal(base, p.field) = u != 0 - return nil -} - -// Decode an int32. -func (o *Buffer) dec_int32(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - word32_Set(structPointer_Word32(base, p.field), o, uint32(u)) - return nil -} - -func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u)) - return nil -} - -// Decode an int64. -func (o *Buffer) dec_int64(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - word64_Set(structPointer_Word64(base, p.field), o, u) - return nil -} - -func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - word64Val_Set(structPointer_Word64Val(base, p.field), o, u) - return nil -} - -// Decode a string. -func (o *Buffer) dec_string(p *Properties, base structPointer) error { - s, err := o.DecodeStringBytes() - if err != nil { - return err - } - *structPointer_String(base, p.field) = &s - return nil -} - -func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error { - s, err := o.DecodeStringBytes() - if err != nil { - return err - } - *structPointer_StringVal(base, p.field) = s - return nil -} - -// Decode a slice of bytes ([]byte). -func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error { - b, err := o.DecodeRawBytes(true) - if err != nil { - return err - } - *structPointer_Bytes(base, p.field) = b - return nil -} - -// Decode a slice of bools ([]bool). -func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - v := structPointer_BoolSlice(base, p.field) - *v = append(*v, u != 0) - return nil -} - -// Decode a slice of bools ([]bool) in packed format. -func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error { - v := structPointer_BoolSlice(base, p.field) - - nn, err := o.DecodeVarint() - if err != nil { - return err - } - nb := int(nn) // number of bytes of encoded bools - fin := o.index + nb - if fin < o.index { - return errOverflow - } - - y := *v - for o.index < fin { - u, err := p.valDec(o) - if err != nil { - return err - } - y = append(y, u != 0) - } - - *v = y - return nil -} - -// Decode a slice of int32s ([]int32). -func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - structPointer_Word32Slice(base, p.field).Append(uint32(u)) - return nil -} - -// Decode a slice of int32s ([]int32) in packed format. -func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error { - v := structPointer_Word32Slice(base, p.field) - - nn, err := o.DecodeVarint() - if err != nil { - return err - } - nb := int(nn) // number of bytes of encoded int32s - - fin := o.index + nb - if fin < o.index { - return errOverflow - } - for o.index < fin { - u, err := p.valDec(o) - if err != nil { - return err - } - v.Append(uint32(u)) - } - return nil -} - -// Decode a slice of int64s ([]int64). -func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - - structPointer_Word64Slice(base, p.field).Append(u) - return nil -} - -// Decode a slice of int64s ([]int64) in packed format. -func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error { - v := structPointer_Word64Slice(base, p.field) - - nn, err := o.DecodeVarint() - if err != nil { - return err - } - nb := int(nn) // number of bytes of encoded int64s - - fin := o.index + nb - if fin < o.index { - return errOverflow - } - for o.index < fin { - u, err := p.valDec(o) - if err != nil { - return err - } - v.Append(u) - } - return nil -} - -// Decode a slice of strings ([]string). -func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error { - s, err := o.DecodeStringBytes() - if err != nil { - return err - } - v := structPointer_StringSlice(base, p.field) - *v = append(*v, s) - return nil -} - -// Decode a slice of slice of bytes ([][]byte). -func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error { - b, err := o.DecodeRawBytes(true) - if err != nil { - return err - } - v := structPointer_BytesSlice(base, p.field) - *v = append(*v, b) - return nil -} - -// Decode a map field. -func (o *Buffer) dec_new_map(p *Properties, base structPointer) error { - raw, err := o.DecodeRawBytes(false) - if err != nil { - return err - } - oi := o.index // index at the end of this map entry - o.index -= len(raw) // move buffer back to start of map entry - - mptr := structPointer_NewAt(base, p.field, p.mtype) // *map[K]V - if mptr.Elem().IsNil() { - mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem())) - } - v := mptr.Elem() // map[K]V - - // Prepare addressable doubly-indirect placeholders for the key and value types. - // See enc_new_map for why. - keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K - keybase := toStructPointer(keyptr.Addr()) // **K - - var valbase structPointer - var valptr reflect.Value - switch p.mtype.Elem().Kind() { - case reflect.Slice: - // []byte - var dummy []byte - valptr = reflect.ValueOf(&dummy) // *[]byte - valbase = toStructPointer(valptr) // *[]byte - case reflect.Ptr: - // message; valptr is **Msg; need to allocate the intermediate pointer - valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V - valptr.Set(reflect.New(valptr.Type().Elem())) - valbase = toStructPointer(valptr) - default: - // everything else - valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V - valbase = toStructPointer(valptr.Addr()) // **V - } - - // Decode. - // This parses a restricted wire format, namely the encoding of a message - // with two fields. See enc_new_map for the format. - for o.index < oi { - // tagcode for key and value properties are always a single byte - // because they have tags 1 and 2. - tagcode := o.buf[o.index] - o.index++ - switch tagcode { - case p.mkeyprop.tagcode[0]: - if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil { - return err - } - case p.mvalprop.tagcode[0]: - if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil { - return err - } - default: - // TODO: Should we silently skip this instead? - return fmt.Errorf("proto: bad map data tag %d", raw[0]) - } - } - keyelem, valelem := keyptr.Elem(), valptr.Elem() - if !keyelem.IsValid() { - keyelem = reflect.Zero(p.mtype.Key()) - } - if !valelem.IsValid() { - valelem = reflect.Zero(p.mtype.Elem()) - } - - v.SetMapIndex(keyelem, valelem) - return nil -} - -// Decode a group. -func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error { - bas := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(bas) { - // allocate new nested message - bas = toStructPointer(reflect.New(p.stype)) - structPointer_SetStructPointer(base, p.field, bas) - } - return o.unmarshalType(p.stype, p.sprop, true, bas) -} - -// Decode an embedded message. -func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) { - raw, e := o.DecodeRawBytes(false) - if e != nil { - return e - } - - bas := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(bas) { - // allocate new nested message - bas = toStructPointer(reflect.New(p.stype)) - structPointer_SetStructPointer(base, p.field, bas) - } - - // If the object can unmarshal itself, let it. - if p.isUnmarshaler { - iv := structPointer_Interface(bas, p.stype) - return iv.(Unmarshaler).Unmarshal(raw) - } - - obuf := o.buf - oi := o.index - o.buf = raw - o.index = 0 - - err = o.unmarshalType(p.stype, p.sprop, false, bas) - o.buf = obuf - o.index = oi - - return err -} - -// Decode a slice of embedded messages. -func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error { - return o.dec_slice_struct(p, false, base) -} - -// Decode a slice of embedded groups. -func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error { - return o.dec_slice_struct(p, true, base) -} - -// Decode a slice of structs ([]*struct). -func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error { - v := reflect.New(p.stype) - bas := toStructPointer(v) - structPointer_StructPointerSlice(base, p.field).Append(bas) - - if is_group { - err := o.unmarshalType(p.stype, p.sprop, is_group, bas) - return err - } - - raw, err := o.DecodeRawBytes(false) - if err != nil { - return err - } - - // If the object can unmarshal itself, let it. - if p.isUnmarshaler { - iv := v.Interface() - return iv.(Unmarshaler).Unmarshal(raw) - } - - obuf := o.buf - oi := o.index - o.buf = raw - o.index = 0 - - err = o.unmarshalType(p.stype, p.sprop, is_group, bas) - - o.buf = obuf - o.index = oi - - return err -} diff --git a/vendor/github.com/gogo/protobuf/proto/decode_gogo.go b/vendor/github.com/gogo/protobuf/proto/decode_gogo.go deleted file mode 100644 index 6fb74de4c..000000000 --- a/vendor/github.com/gogo/protobuf/proto/decode_gogo.go +++ /dev/null @@ -1,172 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "reflect" -) - -// Decode a reference to a struct pointer. -func (o *Buffer) dec_ref_struct_message(p *Properties, base structPointer) (err error) { - raw, e := o.DecodeRawBytes(false) - if e != nil { - return e - } - - // If the object can unmarshal itself, let it. - if p.isUnmarshaler { - panic("not supported, since this is a pointer receiver") - } - - obuf := o.buf - oi := o.index - o.buf = raw - o.index = 0 - - bas := structPointer_FieldPointer(base, p.field) - - err = o.unmarshalType(p.stype, p.sprop, false, bas) - o.buf = obuf - o.index = oi - - return err -} - -// Decode a slice of references to struct pointers ([]struct). -func (o *Buffer) dec_slice_ref_struct(p *Properties, is_group bool, base structPointer) error { - newBas := appendStructPointer(base, p.field, p.sstype) - - if is_group { - panic("not supported, maybe in future, if requested.") - } - - raw, err := o.DecodeRawBytes(false) - if err != nil { - return err - } - - // If the object can unmarshal itself, let it. - if p.isUnmarshaler { - panic("not supported, since this is not a pointer receiver.") - } - - obuf := o.buf - oi := o.index - o.buf = raw - o.index = 0 - - err = o.unmarshalType(p.stype, p.sprop, is_group, newBas) - - o.buf = obuf - o.index = oi - - return err -} - -// Decode a slice of references to struct pointers. -func (o *Buffer) dec_slice_ref_struct_message(p *Properties, base structPointer) error { - return o.dec_slice_ref_struct(p, false, base) -} - -func setPtrCustomType(base structPointer, f field, v interface{}) { - if v == nil { - return - } - structPointer_SetStructPointer(base, f, toStructPointer(reflect.ValueOf(v))) -} - -func setCustomType(base structPointer, f field, value interface{}) { - if value == nil { - return - } - v := reflect.ValueOf(value).Elem() - t := reflect.TypeOf(value).Elem() - kind := t.Kind() - switch kind { - case reflect.Slice: - slice := reflect.MakeSlice(t, v.Len(), v.Cap()) - reflect.Copy(slice, v) - oldHeader := structPointer_GetSliceHeader(base, f) - oldHeader.Data = slice.Pointer() - oldHeader.Len = v.Len() - oldHeader.Cap = v.Cap() - default: - size := reflect.TypeOf(value).Elem().Size() - structPointer_Copy(toStructPointer(reflect.ValueOf(value)), structPointer_Add(base, f), int(size)) - } -} - -func (o *Buffer) dec_custom_bytes(p *Properties, base structPointer) error { - b, err := o.DecodeRawBytes(true) - if err != nil { - return err - } - i := reflect.New(p.ctype.Elem()).Interface() - custom := (i).(Unmarshaler) - if err := custom.Unmarshal(b); err != nil { - return err - } - setPtrCustomType(base, p.field, custom) - return nil -} - -func (o *Buffer) dec_custom_ref_bytes(p *Properties, base structPointer) error { - b, err := o.DecodeRawBytes(true) - if err != nil { - return err - } - i := reflect.New(p.ctype).Interface() - custom := (i).(Unmarshaler) - if err := custom.Unmarshal(b); err != nil { - return err - } - if custom != nil { - setCustomType(base, p.field, custom) - } - return nil -} - -// Decode a slice of bytes ([]byte) into a slice of custom types. -func (o *Buffer) dec_custom_slice_bytes(p *Properties, base structPointer) error { - b, err := o.DecodeRawBytes(true) - if err != nil { - return err - } - i := reflect.New(p.ctype.Elem()).Interface() - custom := (i).(Unmarshaler) - if err := custom.Unmarshal(b); err != nil { - return err - } - newBas := appendStructPointer(base, p.field, p.ctype) - - var zero field - setCustomType(newBas, zero, custom) - - return nil -} diff --git a/vendor/github.com/gogo/protobuf/proto/discard.go b/vendor/github.com/gogo/protobuf/proto/discard.go deleted file mode 100644 index bd0e3bb4c..000000000 --- a/vendor/github.com/gogo/protobuf/proto/discard.go +++ /dev/null @@ -1,151 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2017 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "reflect" - "strings" -) - -// DiscardUnknown recursively discards all unknown fields from this message -// and all embedded messages. -// -// When unmarshaling a message with unrecognized fields, the tags and values -// of such fields are preserved in the Message. This allows a later call to -// marshal to be able to produce a message that continues to have those -// unrecognized fields. To avoid this, DiscardUnknown is used to -// explicitly clear the unknown fields after unmarshaling. -// -// For proto2 messages, the unknown fields of message extensions are only -// discarded from messages that have been accessed via GetExtension. -func DiscardUnknown(m Message) { - discardLegacy(m) -} - -func discardLegacy(m Message) { - v := reflect.ValueOf(m) - if v.Kind() != reflect.Ptr || v.IsNil() { - return - } - v = v.Elem() - if v.Kind() != reflect.Struct { - return - } - t := v.Type() - - for i := 0; i < v.NumField(); i++ { - f := t.Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - vf := v.Field(i) - tf := f.Type - - // Unwrap tf to get its most basic type. - var isPointer, isSlice bool - if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { - isSlice = true - tf = tf.Elem() - } - if tf.Kind() == reflect.Ptr { - isPointer = true - tf = tf.Elem() - } - if isPointer && isSlice && tf.Kind() != reflect.Struct { - panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name)) - } - - switch tf.Kind() { - case reflect.Struct: - switch { - case !isPointer: - panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name)) - case isSlice: // E.g., []*pb.T - for j := 0; j < vf.Len(); j++ { - discardLegacy(vf.Index(j).Interface().(Message)) - } - default: // E.g., *pb.T - discardLegacy(vf.Interface().(Message)) - } - case reflect.Map: - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name)) - default: // E.g., map[K]V - tv := vf.Type().Elem() - if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T) - for _, key := range vf.MapKeys() { - val := vf.MapIndex(key) - discardLegacy(val.Interface().(Message)) - } - } - } - case reflect.Interface: - // Must be oneof field. - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name)) - default: // E.g., test_proto.isCommunique_Union interface - if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" { - vf = vf.Elem() // E.g., *test_proto.Communique_Msg - if !vf.IsNil() { - vf = vf.Elem() // E.g., test_proto.Communique_Msg - vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value - if vf.Kind() == reflect.Ptr { - discardLegacy(vf.Interface().(Message)) - } - } - } - } - } - } - - if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() { - if vf.Type() != reflect.TypeOf([]byte{}) { - panic("expected XXX_unrecognized to be of type []byte") - } - vf.Set(reflect.ValueOf([]byte(nil))) - } - - // For proto2 messages, only discard unknown fields in message extensions - // that have been accessed via GetExtension. - if em, ok := extendable(m); ok { - // Ignore lock since discardLegacy is not concurrency safe. - emm, _ := em.extensionsRead() - for _, mx := range emm { - if m, ok := mx.value.(Message); ok { - discardLegacy(m) - } - } - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/duration.go b/vendor/github.com/gogo/protobuf/proto/duration.go deleted file mode 100644 index 93464c91c..000000000 --- a/vendor/github.com/gogo/protobuf/proto/duration.go +++ /dev/null @@ -1,100 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// This file implements conversions between google.protobuf.Duration -// and time.Duration. - -import ( - "errors" - "fmt" - "time" -) - -const ( - // Range of a Duration in seconds, as specified in - // google/protobuf/duration.proto. This is about 10,000 years in seconds. - maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) - minSeconds = -maxSeconds -) - -// validateDuration determines whether the Duration is valid according to the -// definition in google/protobuf/duration.proto. A valid Duration -// may still be too large to fit into a time.Duration (the range of Duration -// is about 10,000 years, and the range of time.Duration is about 290). -func validateDuration(d *duration) error { - if d == nil { - return errors.New("duration: nil Duration") - } - if d.Seconds < minSeconds || d.Seconds > maxSeconds { - return fmt.Errorf("duration: %#v: seconds out of range", d) - } - if d.Nanos <= -1e9 || d.Nanos >= 1e9 { - return fmt.Errorf("duration: %#v: nanos out of range", d) - } - // Seconds and Nanos must have the same sign, unless d.Nanos is zero. - if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) { - return fmt.Errorf("duration: %#v: seconds and nanos have different signs", d) - } - return nil -} - -// DurationFromProto converts a Duration to a time.Duration. DurationFromProto -// returns an error if the Duration is invalid or is too large to be -// represented in a time.Duration. -func durationFromProto(p *duration) (time.Duration, error) { - if err := validateDuration(p); err != nil { - return 0, err - } - d := time.Duration(p.Seconds) * time.Second - if int64(d/time.Second) != p.Seconds { - return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p) - } - if p.Nanos != 0 { - d += time.Duration(p.Nanos) - if (d < 0) != (p.Nanos < 0) { - return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p) - } - } - return d, nil -} - -// DurationProto converts a time.Duration to a Duration. -func durationProto(d time.Duration) *duration { - nanos := d.Nanoseconds() - secs := nanos / 1e9 - nanos -= secs * 1e9 - return &duration{ - Seconds: secs, - Nanos: int32(nanos), - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/duration_gogo.go b/vendor/github.com/gogo/protobuf/proto/duration_gogo.go deleted file mode 100644 index 18e2a5f77..000000000 --- a/vendor/github.com/gogo/protobuf/proto/duration_gogo.go +++ /dev/null @@ -1,203 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2016, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "reflect" - "time" -) - -var durationType = reflect.TypeOf((*time.Duration)(nil)).Elem() - -type duration struct { - Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` - Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` -} - -func (m *duration) Reset() { *m = duration{} } -func (*duration) ProtoMessage() {} -func (*duration) String() string { return "duration" } - -func init() { - RegisterType((*duration)(nil), "gogo.protobuf.proto.duration") -} - -func (o *Buffer) decDuration() (time.Duration, error) { - b, err := o.DecodeRawBytes(true) - if err != nil { - return 0, err - } - dproto := &duration{} - if err := Unmarshal(b, dproto); err != nil { - return 0, err - } - return durationFromProto(dproto) -} - -func (o *Buffer) dec_duration(p *Properties, base structPointer) error { - d, err := o.decDuration() - if err != nil { - return err - } - word64_Set(structPointer_Word64(base, p.field), o, uint64(d)) - return nil -} - -func (o *Buffer) dec_ref_duration(p *Properties, base structPointer) error { - d, err := o.decDuration() - if err != nil { - return err - } - word64Val_Set(structPointer_Word64Val(base, p.field), o, uint64(d)) - return nil -} - -func (o *Buffer) dec_slice_duration(p *Properties, base structPointer) error { - d, err := o.decDuration() - if err != nil { - return err - } - newBas := appendStructPointer(base, p.field, reflect.SliceOf(reflect.PtrTo(durationType))) - var zero field - setPtrCustomType(newBas, zero, &d) - return nil -} - -func (o *Buffer) dec_slice_ref_duration(p *Properties, base structPointer) error { - d, err := o.decDuration() - if err != nil { - return err - } - structPointer_Word64Slice(base, p.field).Append(uint64(d)) - return nil -} - -func size_duration(p *Properties, base structPointer) (n int) { - structp := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(structp) { - return 0 - } - dur := structPointer_Interface(structp, durationType).(*time.Duration) - d := durationProto(*dur) - size := Size(d) - return size + sizeVarint(uint64(size)) + len(p.tagcode) -} - -func (o *Buffer) enc_duration(p *Properties, base structPointer) error { - structp := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(structp) { - return ErrNil - } - dur := structPointer_Interface(structp, durationType).(*time.Duration) - d := durationProto(*dur) - data, err := Marshal(d) - if err != nil { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - return nil -} - -func size_ref_duration(p *Properties, base structPointer) (n int) { - dur := structPointer_InterfaceAt(base, p.field, durationType).(*time.Duration) - d := durationProto(*dur) - size := Size(d) - return size + sizeVarint(uint64(size)) + len(p.tagcode) -} - -func (o *Buffer) enc_ref_duration(p *Properties, base structPointer) error { - dur := structPointer_InterfaceAt(base, p.field, durationType).(*time.Duration) - d := durationProto(*dur) - data, err := Marshal(d) - if err != nil { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - return nil -} - -func size_slice_duration(p *Properties, base structPointer) (n int) { - pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(durationType))).(*[]*time.Duration) - durs := *pdurs - for i := 0; i < len(durs); i++ { - if durs[i] == nil { - return 0 - } - dproto := durationProto(*durs[i]) - size := Size(dproto) - n += len(p.tagcode) + size + sizeVarint(uint64(size)) - } - return n -} - -func (o *Buffer) enc_slice_duration(p *Properties, base structPointer) error { - pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(durationType))).(*[]*time.Duration) - durs := *pdurs - for i := 0; i < len(durs); i++ { - if durs[i] == nil { - return errRepeatedHasNil - } - dproto := durationProto(*durs[i]) - data, err := Marshal(dproto) - if err != nil { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - } - return nil -} - -func size_slice_ref_duration(p *Properties, base structPointer) (n int) { - pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(durationType)).(*[]time.Duration) - durs := *pdurs - for i := 0; i < len(durs); i++ { - dproto := durationProto(durs[i]) - size := Size(dproto) - n += len(p.tagcode) + size + sizeVarint(uint64(size)) - } - return n -} - -func (o *Buffer) enc_slice_ref_duration(p *Properties, base structPointer) error { - pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(durationType)).(*[]time.Duration) - durs := *pdurs - for i := 0; i < len(durs); i++ { - dproto := durationProto(durs[i]) - data, err := Marshal(dproto) - if err != nil { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - } - return nil -} diff --git a/vendor/github.com/gogo/protobuf/proto/encode.go b/vendor/github.com/gogo/protobuf/proto/encode.go deleted file mode 100644 index 8b84d1b22..000000000 --- a/vendor/github.com/gogo/protobuf/proto/encode.go +++ /dev/null @@ -1,1362 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Routines for encoding data into the wire format for protocol buffers. - */ - -import ( - "errors" - "fmt" - "reflect" - "sort" -) - -// RequiredNotSetError is the error returned if Marshal is called with -// a protocol buffer struct whose required fields have not -// all been initialized. It is also the error returned if Unmarshal is -// called with an encoded protocol buffer that does not include all the -// required fields. -// -// When printed, RequiredNotSetError reports the first unset required field in a -// message. If the field cannot be precisely determined, it is reported as -// "{Unknown}". -type RequiredNotSetError struct { - field string -} - -func (e *RequiredNotSetError) Error() string { - return fmt.Sprintf("proto: required field %q not set", e.field) -} - -var ( - // errRepeatedHasNil is the error returned if Marshal is called with - // a struct with a repeated field containing a nil element. - errRepeatedHasNil = errors.New("proto: repeated field has nil element") - - // errOneofHasNil is the error returned if Marshal is called with - // a struct with a oneof field containing a nil element. - errOneofHasNil = errors.New("proto: oneof field has nil value") - - // ErrNil is the error returned if Marshal is called with nil. - ErrNil = errors.New("proto: Marshal called with nil") - - // ErrTooLarge is the error returned if Marshal is called with a - // message that encodes to >2GB. - ErrTooLarge = errors.New("proto: message encodes to over 2 GB") -) - -// The fundamental encoders that put bytes on the wire. -// Those that take integer types all accept uint64 and are -// therefore of type valueEncoder. - -const maxVarintBytes = 10 // maximum length of a varint - -// maxMarshalSize is the largest allowed size of an encoded protobuf, -// since C++ and Java use signed int32s for the size. -const maxMarshalSize = 1<<31 - 1 - -// EncodeVarint returns the varint encoding of x. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -// Not used by the package itself, but helpful to clients -// wishing to use the same encoding. -func EncodeVarint(x uint64) []byte { - var buf [maxVarintBytes]byte - var n int - for n = 0; x > 127; n++ { - buf[n] = 0x80 | uint8(x&0x7F) - x >>= 7 - } - buf[n] = uint8(x) - n++ - return buf[0:n] -} - -// EncodeVarint writes a varint-encoded integer to the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (p *Buffer) EncodeVarint(x uint64) error { - for x >= 1<<7 { - p.buf = append(p.buf, uint8(x&0x7f|0x80)) - x >>= 7 - } - p.buf = append(p.buf, uint8(x)) - return nil -} - -// SizeVarint returns the varint encoding size of an integer. -func SizeVarint(x uint64) int { - return sizeVarint(x) -} - -func sizeVarint(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } - } - return n -} - -// EncodeFixed64 writes a 64-bit integer to the Buffer. -// This is the format for the -// fixed64, sfixed64, and double protocol buffer types. -func (p *Buffer) EncodeFixed64(x uint64) error { - p.buf = append(p.buf, - uint8(x), - uint8(x>>8), - uint8(x>>16), - uint8(x>>24), - uint8(x>>32), - uint8(x>>40), - uint8(x>>48), - uint8(x>>56)) - return nil -} - -func sizeFixed64(x uint64) int { - return 8 -} - -// EncodeFixed32 writes a 32-bit integer to the Buffer. -// This is the format for the -// fixed32, sfixed32, and float protocol buffer types. -func (p *Buffer) EncodeFixed32(x uint64) error { - p.buf = append(p.buf, - uint8(x), - uint8(x>>8), - uint8(x>>16), - uint8(x>>24)) - return nil -} - -func sizeFixed32(x uint64) int { - return 4 -} - -// EncodeZigzag64 writes a zigzag-encoded 64-bit integer -// to the Buffer. -// This is the format used for the sint64 protocol buffer type. -func (p *Buffer) EncodeZigzag64(x uint64) error { - // use signed number to get arithmetic right shift. - return p.EncodeVarint((x << 1) ^ uint64((int64(x) >> 63))) -} - -func sizeZigzag64(x uint64) int { - return sizeVarint((x << 1) ^ uint64((int64(x) >> 63))) -} - -// EncodeZigzag32 writes a zigzag-encoded 32-bit integer -// to the Buffer. -// This is the format used for the sint32 protocol buffer type. -func (p *Buffer) EncodeZigzag32(x uint64) error { - // use signed number to get arithmetic right shift. - return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) -} - -func sizeZigzag32(x uint64) int { - return sizeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) -} - -// EncodeRawBytes writes a count-delimited byte buffer to the Buffer. -// This is the format used for the bytes protocol buffer -// type and for embedded messages. -func (p *Buffer) EncodeRawBytes(b []byte) error { - p.EncodeVarint(uint64(len(b))) - p.buf = append(p.buf, b...) - return nil -} - -func sizeRawBytes(b []byte) int { - return sizeVarint(uint64(len(b))) + - len(b) -} - -// EncodeStringBytes writes an encoded string to the Buffer. -// This is the format used for the proto2 string type. -func (p *Buffer) EncodeStringBytes(s string) error { - p.EncodeVarint(uint64(len(s))) - p.buf = append(p.buf, s...) - return nil -} - -func sizeStringBytes(s string) int { - return sizeVarint(uint64(len(s))) + - len(s) -} - -// Marshaler is the interface representing objects that can marshal themselves. -type Marshaler interface { - Marshal() ([]byte, error) -} - -// Marshal takes the protocol buffer -// and encodes it into the wire format, returning the data. -func Marshal(pb Message) ([]byte, error) { - // Can the object marshal itself? - if m, ok := pb.(Marshaler); ok { - return m.Marshal() - } - p := NewBuffer(nil) - err := p.Marshal(pb) - if p.buf == nil && err == nil { - // Return a non-nil slice on success. - return []byte{}, nil - } - return p.buf, err -} - -// EncodeMessage writes the protocol buffer to the Buffer, -// prefixed by a varint-encoded length. -func (p *Buffer) EncodeMessage(pb Message) error { - t, base, err := getbase(pb) - if structPointer_IsNil(base) { - return ErrNil - } - if err == nil { - var state errorState - err = p.enc_len_struct(GetProperties(t.Elem()), base, &state) - } - return err -} - -// Marshal takes the protocol buffer -// and encodes it into the wire format, writing the result to the -// Buffer. -func (p *Buffer) Marshal(pb Message) error { - // Can the object marshal itself? - if m, ok := pb.(Marshaler); ok { - data, err := m.Marshal() - p.buf = append(p.buf, data...) - return err - } - - t, base, err := getbase(pb) - if structPointer_IsNil(base) { - return ErrNil - } - if err == nil { - err = p.enc_struct(GetProperties(t.Elem()), base) - } - - if collectStats { - (stats).Encode++ // Parens are to work around a goimports bug. - } - - if len(p.buf) > maxMarshalSize { - return ErrTooLarge - } - return err -} - -// Size returns the encoded size of a protocol buffer. -func Size(pb Message) (n int) { - // Can the object marshal itself? If so, Size is slow. - // TODO: add Size to Marshaler, or add a Sizer interface. - if m, ok := pb.(Marshaler); ok { - b, _ := m.Marshal() - return len(b) - } - - t, base, err := getbase(pb) - if structPointer_IsNil(base) { - return 0 - } - if err == nil { - n = size_struct(GetProperties(t.Elem()), base) - } - - if collectStats { - (stats).Size++ // Parens are to work around a goimports bug. - } - - return -} - -// Individual type encoders. - -// Encode a bool. -func (o *Buffer) enc_bool(p *Properties, base structPointer) error { - v := *structPointer_Bool(base, p.field) - if v == nil { - return ErrNil - } - x := 0 - if *v { - x = 1 - } - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, uint64(x)) - return nil -} - -func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error { - v := *structPointer_BoolVal(base, p.field) - if !v { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, 1) - return nil -} - -func size_bool(p *Properties, base structPointer) int { - v := *structPointer_Bool(base, p.field) - if v == nil { - return 0 - } - return len(p.tagcode) + 1 // each bool takes exactly one byte -} - -func size_proto3_bool(p *Properties, base structPointer) int { - v := *structPointer_BoolVal(base, p.field) - if !v && !p.oneof { - return 0 - } - return len(p.tagcode) + 1 // each bool takes exactly one byte -} - -// Encode an int32. -func (o *Buffer) enc_int32(p *Properties, base structPointer) error { - v := structPointer_Word32(base, p.field) - if word32_IsNil(v) { - return ErrNil - } - x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, uint64(x)) - return nil -} - -func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error { - v := structPointer_Word32Val(base, p.field) - x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range - if x == 0 { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, uint64(x)) - return nil -} - -func size_int32(p *Properties, base structPointer) (n int) { - v := structPointer_Word32(base, p.field) - if word32_IsNil(v) { - return 0 - } - x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range - n += len(p.tagcode) - n += p.valSize(uint64(x)) - return -} - -func size_proto3_int32(p *Properties, base structPointer) (n int) { - v := structPointer_Word32Val(base, p.field) - x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range - if x == 0 && !p.oneof { - return 0 - } - n += len(p.tagcode) - n += p.valSize(uint64(x)) - return -} - -// Encode a uint32. -// Exactly the same as int32, except for no sign extension. -func (o *Buffer) enc_uint32(p *Properties, base structPointer) error { - v := structPointer_Word32(base, p.field) - if word32_IsNil(v) { - return ErrNil - } - x := word32_Get(v) - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, uint64(x)) - return nil -} - -func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error { - v := structPointer_Word32Val(base, p.field) - x := word32Val_Get(v) - if x == 0 { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, uint64(x)) - return nil -} - -func size_uint32(p *Properties, base structPointer) (n int) { - v := structPointer_Word32(base, p.field) - if word32_IsNil(v) { - return 0 - } - x := word32_Get(v) - n += len(p.tagcode) - n += p.valSize(uint64(x)) - return -} - -func size_proto3_uint32(p *Properties, base structPointer) (n int) { - v := structPointer_Word32Val(base, p.field) - x := word32Val_Get(v) - if x == 0 && !p.oneof { - return 0 - } - n += len(p.tagcode) - n += p.valSize(uint64(x)) - return -} - -// Encode an int64. -func (o *Buffer) enc_int64(p *Properties, base structPointer) error { - v := structPointer_Word64(base, p.field) - if word64_IsNil(v) { - return ErrNil - } - x := word64_Get(v) - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, x) - return nil -} - -func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error { - v := structPointer_Word64Val(base, p.field) - x := word64Val_Get(v) - if x == 0 { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, x) - return nil -} - -func size_int64(p *Properties, base structPointer) (n int) { - v := structPointer_Word64(base, p.field) - if word64_IsNil(v) { - return 0 - } - x := word64_Get(v) - n += len(p.tagcode) - n += p.valSize(x) - return -} - -func size_proto3_int64(p *Properties, base structPointer) (n int) { - v := structPointer_Word64Val(base, p.field) - x := word64Val_Get(v) - if x == 0 && !p.oneof { - return 0 - } - n += len(p.tagcode) - n += p.valSize(x) - return -} - -// Encode a string. -func (o *Buffer) enc_string(p *Properties, base structPointer) error { - v := *structPointer_String(base, p.field) - if v == nil { - return ErrNil - } - x := *v - o.buf = append(o.buf, p.tagcode...) - o.EncodeStringBytes(x) - return nil -} - -func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error { - v := *structPointer_StringVal(base, p.field) - if v == "" { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeStringBytes(v) - return nil -} - -func size_string(p *Properties, base structPointer) (n int) { - v := *structPointer_String(base, p.field) - if v == nil { - return 0 - } - x := *v - n += len(p.tagcode) - n += sizeStringBytes(x) - return -} - -func size_proto3_string(p *Properties, base structPointer) (n int) { - v := *structPointer_StringVal(base, p.field) - if v == "" && !p.oneof { - return 0 - } - n += len(p.tagcode) - n += sizeStringBytes(v) - return -} - -// All protocol buffer fields are nillable, but be careful. -func isNil(v reflect.Value) bool { - switch v.Kind() { - case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return v.IsNil() - } - return false -} - -// Encode a message struct. -func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error { - var state errorState - structp := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(structp) { - return ErrNil - } - - // Can the object marshal itself? - if p.isMarshaler { - m := structPointer_Interface(structp, p.stype).(Marshaler) - data, err := m.Marshal() - if err != nil && !state.shouldContinue(err, nil) { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - return state.err - } - - o.buf = append(o.buf, p.tagcode...) - return o.enc_len_struct(p.sprop, structp, &state) -} - -func size_struct_message(p *Properties, base structPointer) int { - structp := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(structp) { - return 0 - } - - // Can the object marshal itself? - if p.isMarshaler { - m := structPointer_Interface(structp, p.stype).(Marshaler) - data, _ := m.Marshal() - n0 := len(p.tagcode) - n1 := sizeRawBytes(data) - return n0 + n1 - } - - n0 := len(p.tagcode) - n1 := size_struct(p.sprop, structp) - n2 := sizeVarint(uint64(n1)) // size of encoded length - return n0 + n1 + n2 -} - -// Encode a group struct. -func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error { - var state errorState - b := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(b) { - return ErrNil - } - - o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup)) - err := o.enc_struct(p.sprop, b) - if err != nil && !state.shouldContinue(err, nil) { - return err - } - o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup)) - return state.err -} - -func size_struct_group(p *Properties, base structPointer) (n int) { - b := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(b) { - return 0 - } - - n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup)) - n += size_struct(p.sprop, b) - n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup)) - return -} - -// Encode a slice of bools ([]bool). -func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error { - s := *structPointer_BoolSlice(base, p.field) - l := len(s) - if l == 0 { - return ErrNil - } - for _, x := range s { - o.buf = append(o.buf, p.tagcode...) - v := uint64(0) - if x { - v = 1 - } - p.valEnc(o, v) - } - return nil -} - -func size_slice_bool(p *Properties, base structPointer) int { - s := *structPointer_BoolSlice(base, p.field) - l := len(s) - if l == 0 { - return 0 - } - return l * (len(p.tagcode) + 1) // each bool takes exactly one byte -} - -// Encode a slice of bools ([]bool) in packed format. -func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error { - s := *structPointer_BoolSlice(base, p.field) - l := len(s) - if l == 0 { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeVarint(uint64(l)) // each bool takes exactly one byte - for _, x := range s { - v := uint64(0) - if x { - v = 1 - } - p.valEnc(o, v) - } - return nil -} - -func size_slice_packed_bool(p *Properties, base structPointer) (n int) { - s := *structPointer_BoolSlice(base, p.field) - l := len(s) - if l == 0 { - return 0 - } - n += len(p.tagcode) - n += sizeVarint(uint64(l)) - n += l // each bool takes exactly one byte - return -} - -// Encode a slice of bytes ([]byte). -func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error { - s := *structPointer_Bytes(base, p.field) - if s == nil { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(s) - return nil -} - -func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error { - s := *structPointer_Bytes(base, p.field) - if len(s) == 0 { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(s) - return nil -} - -func size_slice_byte(p *Properties, base structPointer) (n int) { - s := *structPointer_Bytes(base, p.field) - if s == nil && !p.oneof { - return 0 - } - n += len(p.tagcode) - n += sizeRawBytes(s) - return -} - -func size_proto3_slice_byte(p *Properties, base structPointer) (n int) { - s := *structPointer_Bytes(base, p.field) - if len(s) == 0 && !p.oneof { - return 0 - } - n += len(p.tagcode) - n += sizeRawBytes(s) - return -} - -// Encode a slice of int32s ([]int32). -func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return ErrNil - } - for i := 0; i < l; i++ { - o.buf = append(o.buf, p.tagcode...) - x := int32(s.Index(i)) // permit sign extension to use full 64-bit range - p.valEnc(o, uint64(x)) - } - return nil -} - -func size_slice_int32(p *Properties, base structPointer) (n int) { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return 0 - } - for i := 0; i < l; i++ { - n += len(p.tagcode) - x := int32(s.Index(i)) // permit sign extension to use full 64-bit range - n += p.valSize(uint64(x)) - } - return -} - -// Encode a slice of int32s ([]int32) in packed format. -func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return ErrNil - } - // TODO: Reuse a Buffer. - buf := NewBuffer(nil) - for i := 0; i < l; i++ { - x := int32(s.Index(i)) // permit sign extension to use full 64-bit range - p.valEnc(buf, uint64(x)) - } - - o.buf = append(o.buf, p.tagcode...) - o.EncodeVarint(uint64(len(buf.buf))) - o.buf = append(o.buf, buf.buf...) - return nil -} - -func size_slice_packed_int32(p *Properties, base structPointer) (n int) { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return 0 - } - var bufSize int - for i := 0; i < l; i++ { - x := int32(s.Index(i)) // permit sign extension to use full 64-bit range - bufSize += p.valSize(uint64(x)) - } - - n += len(p.tagcode) - n += sizeVarint(uint64(bufSize)) - n += bufSize - return -} - -// Encode a slice of uint32s ([]uint32). -// Exactly the same as int32, except for no sign extension. -func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return ErrNil - } - for i := 0; i < l; i++ { - o.buf = append(o.buf, p.tagcode...) - x := s.Index(i) - p.valEnc(o, uint64(x)) - } - return nil -} - -func size_slice_uint32(p *Properties, base structPointer) (n int) { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return 0 - } - for i := 0; i < l; i++ { - n += len(p.tagcode) - x := s.Index(i) - n += p.valSize(uint64(x)) - } - return -} - -// Encode a slice of uint32s ([]uint32) in packed format. -// Exactly the same as int32, except for no sign extension. -func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return ErrNil - } - // TODO: Reuse a Buffer. - buf := NewBuffer(nil) - for i := 0; i < l; i++ { - p.valEnc(buf, uint64(s.Index(i))) - } - - o.buf = append(o.buf, p.tagcode...) - o.EncodeVarint(uint64(len(buf.buf))) - o.buf = append(o.buf, buf.buf...) - return nil -} - -func size_slice_packed_uint32(p *Properties, base structPointer) (n int) { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return 0 - } - var bufSize int - for i := 0; i < l; i++ { - bufSize += p.valSize(uint64(s.Index(i))) - } - - n += len(p.tagcode) - n += sizeVarint(uint64(bufSize)) - n += bufSize - return -} - -// Encode a slice of int64s ([]int64). -func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error { - s := structPointer_Word64Slice(base, p.field) - l := s.Len() - if l == 0 { - return ErrNil - } - for i := 0; i < l; i++ { - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, s.Index(i)) - } - return nil -} - -func size_slice_int64(p *Properties, base structPointer) (n int) { - s := structPointer_Word64Slice(base, p.field) - l := s.Len() - if l == 0 { - return 0 - } - for i := 0; i < l; i++ { - n += len(p.tagcode) - n += p.valSize(s.Index(i)) - } - return -} - -// Encode a slice of int64s ([]int64) in packed format. -func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error { - s := structPointer_Word64Slice(base, p.field) - l := s.Len() - if l == 0 { - return ErrNil - } - // TODO: Reuse a Buffer. - buf := NewBuffer(nil) - for i := 0; i < l; i++ { - p.valEnc(buf, s.Index(i)) - } - - o.buf = append(o.buf, p.tagcode...) - o.EncodeVarint(uint64(len(buf.buf))) - o.buf = append(o.buf, buf.buf...) - return nil -} - -func size_slice_packed_int64(p *Properties, base structPointer) (n int) { - s := structPointer_Word64Slice(base, p.field) - l := s.Len() - if l == 0 { - return 0 - } - var bufSize int - for i := 0; i < l; i++ { - bufSize += p.valSize(s.Index(i)) - } - - n += len(p.tagcode) - n += sizeVarint(uint64(bufSize)) - n += bufSize - return -} - -// Encode a slice of slice of bytes ([][]byte). -func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error { - ss := *structPointer_BytesSlice(base, p.field) - l := len(ss) - if l == 0 { - return ErrNil - } - for i := 0; i < l; i++ { - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(ss[i]) - } - return nil -} - -func size_slice_slice_byte(p *Properties, base structPointer) (n int) { - ss := *structPointer_BytesSlice(base, p.field) - l := len(ss) - if l == 0 { - return 0 - } - n += l * len(p.tagcode) - for i := 0; i < l; i++ { - n += sizeRawBytes(ss[i]) - } - return -} - -// Encode a slice of strings ([]string). -func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error { - ss := *structPointer_StringSlice(base, p.field) - l := len(ss) - for i := 0; i < l; i++ { - o.buf = append(o.buf, p.tagcode...) - o.EncodeStringBytes(ss[i]) - } - return nil -} - -func size_slice_string(p *Properties, base structPointer) (n int) { - ss := *structPointer_StringSlice(base, p.field) - l := len(ss) - n += l * len(p.tagcode) - for i := 0; i < l; i++ { - n += sizeStringBytes(ss[i]) - } - return -} - -// Encode a slice of message structs ([]*struct). -func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error { - var state errorState - s := structPointer_StructPointerSlice(base, p.field) - l := s.Len() - - for i := 0; i < l; i++ { - structp := s.Index(i) - if structPointer_IsNil(structp) { - return errRepeatedHasNil - } - - // Can the object marshal itself? - if p.isMarshaler { - m := structPointer_Interface(structp, p.stype).(Marshaler) - data, err := m.Marshal() - if err != nil && !state.shouldContinue(err, nil) { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - continue - } - - o.buf = append(o.buf, p.tagcode...) - err := o.enc_len_struct(p.sprop, structp, &state) - if err != nil && !state.shouldContinue(err, nil) { - if err == ErrNil { - return errRepeatedHasNil - } - return err - } - } - return state.err -} - -func size_slice_struct_message(p *Properties, base structPointer) (n int) { - s := structPointer_StructPointerSlice(base, p.field) - l := s.Len() - n += l * len(p.tagcode) - for i := 0; i < l; i++ { - structp := s.Index(i) - if structPointer_IsNil(structp) { - return // return the size up to this point - } - - // Can the object marshal itself? - if p.isMarshaler { - m := structPointer_Interface(structp, p.stype).(Marshaler) - data, _ := m.Marshal() - n += sizeRawBytes(data) - continue - } - - n0 := size_struct(p.sprop, structp) - n1 := sizeVarint(uint64(n0)) // size of encoded length - n += n0 + n1 - } - return -} - -// Encode a slice of group structs ([]*struct). -func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error { - var state errorState - s := structPointer_StructPointerSlice(base, p.field) - l := s.Len() - - for i := 0; i < l; i++ { - b := s.Index(i) - if structPointer_IsNil(b) { - return errRepeatedHasNil - } - - o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup)) - - err := o.enc_struct(p.sprop, b) - - if err != nil && !state.shouldContinue(err, nil) { - if err == ErrNil { - return errRepeatedHasNil - } - return err - } - - o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup)) - } - return state.err -} - -func size_slice_struct_group(p *Properties, base structPointer) (n int) { - s := structPointer_StructPointerSlice(base, p.field) - l := s.Len() - - n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup)) - n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup)) - for i := 0; i < l; i++ { - b := s.Index(i) - if structPointer_IsNil(b) { - return // return size up to this point - } - - n += size_struct(p.sprop, b) - } - return -} - -// Encode an extension map. -func (o *Buffer) enc_map(p *Properties, base structPointer) error { - exts := structPointer_ExtMap(base, p.field) - if err := encodeExtensionsMap(*exts); err != nil { - return err - } - - return o.enc_map_body(*exts) -} - -func (o *Buffer) enc_exts(p *Properties, base structPointer) error { - exts := structPointer_Extensions(base, p.field) - - v, mu := exts.extensionsRead() - if v == nil { - return nil - } - - mu.Lock() - defer mu.Unlock() - if err := encodeExtensionsMap(v); err != nil { - return err - } - - return o.enc_map_body(v) -} - -func (o *Buffer) enc_map_body(v map[int32]Extension) error { - // Fast-path for common cases: zero or one extensions. - if len(v) <= 1 { - for _, e := range v { - o.buf = append(o.buf, e.enc...) - } - return nil - } - - // Sort keys to provide a deterministic encoding. - keys := make([]int, 0, len(v)) - for k := range v { - keys = append(keys, int(k)) - } - sort.Ints(keys) - - for _, k := range keys { - o.buf = append(o.buf, v[int32(k)].enc...) - } - return nil -} - -func size_map(p *Properties, base structPointer) int { - v := structPointer_ExtMap(base, p.field) - return extensionsMapSize(*v) -} - -func size_exts(p *Properties, base structPointer) int { - v := structPointer_Extensions(base, p.field) - return extensionsSize(v) -} - -// Encode a map field. -func (o *Buffer) enc_new_map(p *Properties, base structPointer) error { - var state errorState // XXX: or do we need to plumb this through? - - /* - A map defined as - map map_field = N; - is encoded in the same way as - message MapFieldEntry { - key_type key = 1; - value_type value = 2; - } - repeated MapFieldEntry map_field = N; - */ - - v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V - if v.Len() == 0 { - return nil - } - - keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype) - - enc := func() error { - if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil { - return err - } - if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil && err != ErrNil { - return err - } - return nil - } - - // Don't sort map keys. It is not required by the spec, and C++ doesn't do it. - for _, key := range v.MapKeys() { - val := v.MapIndex(key) - - keycopy.Set(key) - valcopy.Set(val) - - o.buf = append(o.buf, p.tagcode...) - if err := o.enc_len_thing(enc, &state); err != nil { - return err - } - } - return nil -} - -func size_new_map(p *Properties, base structPointer) int { - v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V - - keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype) - - n := 0 - for _, key := range v.MapKeys() { - val := v.MapIndex(key) - keycopy.Set(key) - valcopy.Set(val) - - // Tag codes for key and val are the responsibility of the sub-sizer. - keysize := p.mkeyprop.size(p.mkeyprop, keybase) - valsize := p.mvalprop.size(p.mvalprop, valbase) - entry := keysize + valsize - // Add on tag code and length of map entry itself. - n += len(p.tagcode) + sizeVarint(uint64(entry)) + entry - } - return n -} - -// mapEncodeScratch returns a new reflect.Value matching the map's value type, -// and a structPointer suitable for passing to an encoder or sizer. -func mapEncodeScratch(mapType reflect.Type) (keycopy, valcopy reflect.Value, keybase, valbase structPointer) { - // Prepare addressable doubly-indirect placeholders for the key and value types. - // This is needed because the element-type encoders expect **T, but the map iteration produces T. - - keycopy = reflect.New(mapType.Key()).Elem() // addressable K - keyptr := reflect.New(reflect.PtrTo(keycopy.Type())).Elem() // addressable *K - keyptr.Set(keycopy.Addr()) // - keybase = toStructPointer(keyptr.Addr()) // **K - - // Value types are more varied and require special handling. - switch mapType.Elem().Kind() { - case reflect.Slice: - // []byte - var dummy []byte - valcopy = reflect.ValueOf(&dummy).Elem() // addressable []byte - valbase = toStructPointer(valcopy.Addr()) - case reflect.Ptr: - // message; the generated field type is map[K]*Msg (so V is *Msg), - // so we only need one level of indirection. - valcopy = reflect.New(mapType.Elem()).Elem() // addressable V - valbase = toStructPointer(valcopy.Addr()) - default: - // everything else - valcopy = reflect.New(mapType.Elem()).Elem() // addressable V - valptr := reflect.New(reflect.PtrTo(valcopy.Type())).Elem() // addressable *V - valptr.Set(valcopy.Addr()) // - valbase = toStructPointer(valptr.Addr()) // **V - } - return -} - -// Encode a struct. -func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error { - var state errorState - // Encode fields in tag order so that decoders may use optimizations - // that depend on the ordering. - // https://developers.google.com/protocol-buffers/docs/encoding#order - for _, i := range prop.order { - p := prop.Prop[i] - if p.enc != nil { - err := p.enc(o, p, base) - if err != nil { - if err == ErrNil { - if p.Required && state.err == nil { - state.err = &RequiredNotSetError{p.Name} - } - } else if err == errRepeatedHasNil { - // Give more context to nil values in repeated fields. - return errors.New("repeated field " + p.OrigName + " has nil element") - } else if !state.shouldContinue(err, p) { - return err - } - } - if len(o.buf) > maxMarshalSize { - return ErrTooLarge - } - } - } - - // Do oneof fields. - if prop.oneofMarshaler != nil { - m := structPointer_Interface(base, prop.stype).(Message) - if err := prop.oneofMarshaler(m, o); err == ErrNil { - return errOneofHasNil - } else if err != nil { - return err - } - } - - // Add unrecognized fields at the end. - if prop.unrecField.IsValid() { - v := *structPointer_Bytes(base, prop.unrecField) - if len(o.buf)+len(v) > maxMarshalSize { - return ErrTooLarge - } - if len(v) > 0 { - o.buf = append(o.buf, v...) - } - } - - return state.err -} - -func size_struct(prop *StructProperties, base structPointer) (n int) { - for _, i := range prop.order { - p := prop.Prop[i] - if p.size != nil { - n += p.size(p, base) - } - } - - // Add unrecognized fields at the end. - if prop.unrecField.IsValid() { - v := *structPointer_Bytes(base, prop.unrecField) - n += len(v) - } - - // Factor in any oneof fields. - if prop.oneofSizer != nil { - m := structPointer_Interface(base, prop.stype).(Message) - n += prop.oneofSizer(m) - } - - return -} - -var zeroes [20]byte // longer than any conceivable sizeVarint - -// Encode a struct, preceded by its encoded length (as a varint). -func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error { - return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state) -} - -// Encode something, preceded by its encoded length (as a varint). -func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error { - iLen := len(o.buf) - o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length - iMsg := len(o.buf) - err := enc() - if err != nil && !state.shouldContinue(err, nil) { - return err - } - lMsg := len(o.buf) - iMsg - lLen := sizeVarint(uint64(lMsg)) - switch x := lLen - (iMsg - iLen); { - case x > 0: // actual length is x bytes larger than the space we reserved - // Move msg x bytes right. - o.buf = append(o.buf, zeroes[:x]...) - copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg]) - case x < 0: // actual length is x bytes smaller than the space we reserved - // Move msg x bytes left. - copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg]) - o.buf = o.buf[:len(o.buf)+x] // x is negative - } - // Encode the length in the reserved space. - o.buf = o.buf[:iLen] - o.EncodeVarint(uint64(lMsg)) - o.buf = o.buf[:len(o.buf)+lMsg] - return state.err -} - -// errorState maintains the first error that occurs and updates that error -// with additional context. -type errorState struct { - err error -} - -// shouldContinue reports whether encoding should continue upon encountering the -// given error. If the error is RequiredNotSetError, shouldContinue returns true -// and, if this is the first appearance of that error, remembers it for future -// reporting. -// -// If prop is not nil, it may update any error with additional context about the -// field with the error. -func (s *errorState) shouldContinue(err error, prop *Properties) bool { - // Ignore unset required fields. - reqNotSet, ok := err.(*RequiredNotSetError) - if !ok { - return false - } - if s.err == nil { - if prop != nil { - err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field} - } - s.err = err - } - return true -} diff --git a/vendor/github.com/gogo/protobuf/proto/encode_gogo.go b/vendor/github.com/gogo/protobuf/proto/encode_gogo.go deleted file mode 100644 index 32111b7f4..000000000 --- a/vendor/github.com/gogo/protobuf/proto/encode_gogo.go +++ /dev/null @@ -1,350 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// http://github.com/golang/protobuf/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "reflect" -) - -func NewRequiredNotSetError(field string) *RequiredNotSetError { - return &RequiredNotSetError{field} -} - -type Sizer interface { - Size() int -} - -func (o *Buffer) enc_ext_slice_byte(p *Properties, base structPointer) error { - s := *structPointer_Bytes(base, p.field) - if s == nil { - return ErrNil - } - o.buf = append(o.buf, s...) - return nil -} - -func size_ext_slice_byte(p *Properties, base structPointer) (n int) { - s := *structPointer_Bytes(base, p.field) - if s == nil { - return 0 - } - n += len(s) - return -} - -// Encode a reference to bool pointer. -func (o *Buffer) enc_ref_bool(p *Properties, base structPointer) error { - v := *structPointer_BoolVal(base, p.field) - x := 0 - if v { - x = 1 - } - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, uint64(x)) - return nil -} - -func size_ref_bool(p *Properties, base structPointer) int { - return len(p.tagcode) + 1 // each bool takes exactly one byte -} - -// Encode a reference to int32 pointer. -func (o *Buffer) enc_ref_int32(p *Properties, base structPointer) error { - v := structPointer_Word32Val(base, p.field) - x := int32(word32Val_Get(v)) - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, uint64(x)) - return nil -} - -func size_ref_int32(p *Properties, base structPointer) (n int) { - v := structPointer_Word32Val(base, p.field) - x := int32(word32Val_Get(v)) - n += len(p.tagcode) - n += p.valSize(uint64(x)) - return -} - -func (o *Buffer) enc_ref_uint32(p *Properties, base structPointer) error { - v := structPointer_Word32Val(base, p.field) - x := word32Val_Get(v) - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, uint64(x)) - return nil -} - -func size_ref_uint32(p *Properties, base structPointer) (n int) { - v := structPointer_Word32Val(base, p.field) - x := word32Val_Get(v) - n += len(p.tagcode) - n += p.valSize(uint64(x)) - return -} - -// Encode a reference to an int64 pointer. -func (o *Buffer) enc_ref_int64(p *Properties, base structPointer) error { - v := structPointer_Word64Val(base, p.field) - x := word64Val_Get(v) - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, x) - return nil -} - -func size_ref_int64(p *Properties, base structPointer) (n int) { - v := structPointer_Word64Val(base, p.field) - x := word64Val_Get(v) - n += len(p.tagcode) - n += p.valSize(x) - return -} - -// Encode a reference to a string pointer. -func (o *Buffer) enc_ref_string(p *Properties, base structPointer) error { - v := *structPointer_StringVal(base, p.field) - o.buf = append(o.buf, p.tagcode...) - o.EncodeStringBytes(v) - return nil -} - -func size_ref_string(p *Properties, base structPointer) (n int) { - v := *structPointer_StringVal(base, p.field) - n += len(p.tagcode) - n += sizeStringBytes(v) - return -} - -// Encode a reference to a message struct. -func (o *Buffer) enc_ref_struct_message(p *Properties, base structPointer) error { - var state errorState - structp := structPointer_GetRefStructPointer(base, p.field) - if structPointer_IsNil(structp) { - return ErrNil - } - - // Can the object marshal itself? - if p.isMarshaler { - m := structPointer_Interface(structp, p.stype).(Marshaler) - data, err := m.Marshal() - if err != nil && !state.shouldContinue(err, nil) { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - return nil - } - - o.buf = append(o.buf, p.tagcode...) - return o.enc_len_struct(p.sprop, structp, &state) -} - -//TODO this is only copied, please fix this -func size_ref_struct_message(p *Properties, base structPointer) int { - structp := structPointer_GetRefStructPointer(base, p.field) - if structPointer_IsNil(structp) { - return 0 - } - - // Can the object marshal itself? - if p.isMarshaler { - m := structPointer_Interface(structp, p.stype).(Marshaler) - data, _ := m.Marshal() - n0 := len(p.tagcode) - n1 := sizeRawBytes(data) - return n0 + n1 - } - - n0 := len(p.tagcode) - n1 := size_struct(p.sprop, structp) - n2 := sizeVarint(uint64(n1)) // size of encoded length - return n0 + n1 + n2 -} - -// Encode a slice of references to message struct pointers ([]struct). -func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer) error { - var state errorState - ss := structPointer_StructRefSlice(base, p.field, p.stype.Size()) - l := ss.Len() - for i := 0; i < l; i++ { - structp := ss.Index(i) - if structPointer_IsNil(structp) { - return errRepeatedHasNil - } - - // Can the object marshal itself? - if p.isMarshaler { - m := structPointer_Interface(structp, p.stype).(Marshaler) - data, err := m.Marshal() - if err != nil && !state.shouldContinue(err, nil) { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - continue - } - - o.buf = append(o.buf, p.tagcode...) - err := o.enc_len_struct(p.sprop, structp, &state) - if err != nil && !state.shouldContinue(err, nil) { - if err == ErrNil { - return errRepeatedHasNil - } - return err - } - - } - return state.err -} - -//TODO this is only copied, please fix this -func size_slice_ref_struct_message(p *Properties, base structPointer) (n int) { - ss := structPointer_StructRefSlice(base, p.field, p.stype.Size()) - l := ss.Len() - n += l * len(p.tagcode) - for i := 0; i < l; i++ { - structp := ss.Index(i) - if structPointer_IsNil(structp) { - return // return the size up to this point - } - - // Can the object marshal itself? - if p.isMarshaler { - m := structPointer_Interface(structp, p.stype).(Marshaler) - data, _ := m.Marshal() - n += len(p.tagcode) - n += sizeRawBytes(data) - continue - } - - n0 := size_struct(p.sprop, structp) - n1 := sizeVarint(uint64(n0)) // size of encoded length - n += n0 + n1 - } - return -} - -func (o *Buffer) enc_custom_bytes(p *Properties, base structPointer) error { - i := structPointer_InterfaceRef(base, p.field, p.ctype) - if i == nil { - return ErrNil - } - custom := i.(Marshaler) - data, err := custom.Marshal() - if err != nil { - return err - } - if data == nil { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - return nil -} - -func size_custom_bytes(p *Properties, base structPointer) (n int) { - n += len(p.tagcode) - i := structPointer_InterfaceRef(base, p.field, p.ctype) - if i == nil { - return 0 - } - custom := i.(Marshaler) - data, _ := custom.Marshal() - n += sizeRawBytes(data) - return -} - -func (o *Buffer) enc_custom_ref_bytes(p *Properties, base structPointer) error { - custom := structPointer_InterfaceAt(base, p.field, p.ctype).(Marshaler) - data, err := custom.Marshal() - if err != nil { - return err - } - if data == nil { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - return nil -} - -func size_custom_ref_bytes(p *Properties, base structPointer) (n int) { - n += len(p.tagcode) - i := structPointer_InterfaceAt(base, p.field, p.ctype) - if i == nil { - return 0 - } - custom := i.(Marshaler) - data, _ := custom.Marshal() - n += sizeRawBytes(data) - return -} - -func (o *Buffer) enc_custom_slice_bytes(p *Properties, base structPointer) error { - inter := structPointer_InterfaceRef(base, p.field, p.ctype) - if inter == nil { - return ErrNil - } - slice := reflect.ValueOf(inter) - l := slice.Len() - for i := 0; i < l; i++ { - v := slice.Index(i) - custom := v.Interface().(Marshaler) - data, err := custom.Marshal() - if err != nil { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - } - return nil -} - -func size_custom_slice_bytes(p *Properties, base structPointer) (n int) { - inter := structPointer_InterfaceRef(base, p.field, p.ctype) - if inter == nil { - return 0 - } - slice := reflect.ValueOf(inter) - l := slice.Len() - n += l * len(p.tagcode) - for i := 0; i < l; i++ { - v := slice.Index(i) - custom := v.Interface().(Marshaler) - data, _ := custom.Marshal() - n += sizeRawBytes(data) - } - return -} diff --git a/vendor/github.com/gogo/protobuf/proto/equal.go b/vendor/github.com/gogo/protobuf/proto/equal.go deleted file mode 100644 index 2ed1cf596..000000000 --- a/vendor/github.com/gogo/protobuf/proto/equal.go +++ /dev/null @@ -1,300 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2011 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Protocol buffer comparison. - -package proto - -import ( - "bytes" - "log" - "reflect" - "strings" -) - -/* -Equal returns true iff protocol buffers a and b are equal. -The arguments must both be pointers to protocol buffer structs. - -Equality is defined in this way: - - Two messages are equal iff they are the same type, - corresponding fields are equal, unknown field sets - are equal, and extensions sets are equal. - - Two set scalar fields are equal iff their values are equal. - If the fields are of a floating-point type, remember that - NaN != x for all x, including NaN. If the message is defined - in a proto3 .proto file, fields are not "set"; specifically, - zero length proto3 "bytes" fields are equal (nil == {}). - - Two repeated fields are equal iff their lengths are the same, - and their corresponding elements are equal. Note a "bytes" field, - although represented by []byte, is not a repeated field and the - rule for the scalar fields described above applies. - - Two unset fields are equal. - - Two unknown field sets are equal if their current - encoded state is equal. - - Two extension sets are equal iff they have corresponding - elements that are pairwise equal. - - Two map fields are equal iff their lengths are the same, - and they contain the same set of elements. Zero-length map - fields are equal. - - Every other combination of things are not equal. - -The return value is undefined if a and b are not protocol buffers. -*/ -func Equal(a, b Message) bool { - if a == nil || b == nil { - return a == b - } - v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b) - if v1.Type() != v2.Type() { - return false - } - if v1.Kind() == reflect.Ptr { - if v1.IsNil() { - return v2.IsNil() - } - if v2.IsNil() { - return false - } - v1, v2 = v1.Elem(), v2.Elem() - } - if v1.Kind() != reflect.Struct { - return false - } - return equalStruct(v1, v2) -} - -// v1 and v2 are known to have the same type. -func equalStruct(v1, v2 reflect.Value) bool { - sprop := GetProperties(v1.Type()) - for i := 0; i < v1.NumField(); i++ { - f := v1.Type().Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - f1, f2 := v1.Field(i), v2.Field(i) - if f.Type.Kind() == reflect.Ptr { - if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 { - // both unset - continue - } else if n1 != n2 { - // set/unset mismatch - return false - } - b1, ok := f1.Interface().(raw) - if ok { - b2 := f2.Interface().(raw) - // RawMessage - if !bytes.Equal(b1.Bytes(), b2.Bytes()) { - return false - } - continue - } - f1, f2 = f1.Elem(), f2.Elem() - } - if !equalAny(f1, f2, sprop.Prop[i]) { - return false - } - } - - if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() { - em2 := v2.FieldByName("XXX_InternalExtensions") - if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) { - return false - } - } - - if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { - em2 := v2.FieldByName("XXX_extensions") - if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) { - return false - } - } - - uf := v1.FieldByName("XXX_unrecognized") - if !uf.IsValid() { - return true - } - - u1 := uf.Bytes() - u2 := v2.FieldByName("XXX_unrecognized").Bytes() - if !bytes.Equal(u1, u2) { - return false - } - - return true -} - -// v1 and v2 are known to have the same type. -// prop may be nil. -func equalAny(v1, v2 reflect.Value, prop *Properties) bool { - if v1.Type() == protoMessageType { - m1, _ := v1.Interface().(Message) - m2, _ := v2.Interface().(Message) - return Equal(m1, m2) - } - switch v1.Kind() { - case reflect.Bool: - return v1.Bool() == v2.Bool() - case reflect.Float32, reflect.Float64: - return v1.Float() == v2.Float() - case reflect.Int32, reflect.Int64: - return v1.Int() == v2.Int() - case reflect.Interface: - // Probably a oneof field; compare the inner values. - n1, n2 := v1.IsNil(), v2.IsNil() - if n1 || n2 { - return n1 == n2 - } - e1, e2 := v1.Elem(), v2.Elem() - if e1.Type() != e2.Type() { - return false - } - return equalAny(e1, e2, nil) - case reflect.Map: - if v1.Len() != v2.Len() { - return false - } - for _, key := range v1.MapKeys() { - val2 := v2.MapIndex(key) - if !val2.IsValid() { - // This key was not found in the second map. - return false - } - if !equalAny(v1.MapIndex(key), val2, nil) { - return false - } - } - return true - case reflect.Ptr: - // Maps may have nil values in them, so check for nil. - if v1.IsNil() && v2.IsNil() { - return true - } - if v1.IsNil() != v2.IsNil() { - return false - } - return equalAny(v1.Elem(), v2.Elem(), prop) - case reflect.Slice: - if v1.Type().Elem().Kind() == reflect.Uint8 { - // short circuit: []byte - - // Edge case: if this is in a proto3 message, a zero length - // bytes field is considered the zero value. - if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 { - return true - } - if v1.IsNil() != v2.IsNil() { - return false - } - return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte)) - } - - if v1.Len() != v2.Len() { - return false - } - for i := 0; i < v1.Len(); i++ { - if !equalAny(v1.Index(i), v2.Index(i), prop) { - return false - } - } - return true - case reflect.String: - return v1.Interface().(string) == v2.Interface().(string) - case reflect.Struct: - return equalStruct(v1, v2) - case reflect.Uint32, reflect.Uint64: - return v1.Uint() == v2.Uint() - } - - // unknown type, so not a protocol buffer - log.Printf("proto: don't know how to compare %v", v1) - return false -} - -// base is the struct type that the extensions are based on. -// x1 and x2 are InternalExtensions. -func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool { - em1, _ := x1.extensionsRead() - em2, _ := x2.extensionsRead() - return equalExtMap(base, em1, em2) -} - -func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool { - if len(em1) != len(em2) { - return false - } - - for extNum, e1 := range em1 { - e2, ok := em2[extNum] - if !ok { - return false - } - - m1, m2 := e1.value, e2.value - - if m1 != nil && m2 != nil { - // Both are unencoded. - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { - return false - } - continue - } - - // At least one is encoded. To do a semantically correct comparison - // we need to unmarshal them first. - var desc *ExtensionDesc - if m := extensionMaps[base]; m != nil { - desc = m[extNum] - } - if desc == nil { - log.Printf("proto: don't know how to compare extension %d of %v", extNum, base) - continue - } - var err error - if m1 == nil { - m1, err = decodeExtension(e1.enc, desc) - } - if m2 == nil && err == nil { - m2, err = decodeExtension(e2.enc, desc) - } - if err != nil { - // The encoded form is invalid. - log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err) - return false - } - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { - return false - } - } - - return true -} diff --git a/vendor/github.com/gogo/protobuf/proto/extensions.go b/vendor/github.com/gogo/protobuf/proto/extensions.go deleted file mode 100644 index 0dfcb538e..000000000 --- a/vendor/github.com/gogo/protobuf/proto/extensions.go +++ /dev/null @@ -1,693 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Types and routines for supporting protocol buffer extensions. - */ - -import ( - "errors" - "fmt" - "reflect" - "strconv" - "sync" -) - -// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message. -var ErrMissingExtension = errors.New("proto: missing extension") - -// ExtensionRange represents a range of message extensions for a protocol buffer. -// Used in code generated by the protocol compiler. -type ExtensionRange struct { - Start, End int32 // both inclusive -} - -// extendableProto is an interface implemented by any protocol buffer generated by the current -// proto compiler that may be extended. -type extendableProto interface { - Message - ExtensionRangeArray() []ExtensionRange - extensionsWrite() map[int32]Extension - extensionsRead() (map[int32]Extension, sync.Locker) -} - -// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous -// version of the proto compiler that may be extended. -type extendableProtoV1 interface { - Message - ExtensionRangeArray() []ExtensionRange - ExtensionMap() map[int32]Extension -} - -type extensionsBytes interface { - Message - ExtensionRangeArray() []ExtensionRange - GetExtensions() *[]byte -} - -// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto. -type extensionAdapter struct { - extendableProtoV1 -} - -func (e extensionAdapter) extensionsWrite() map[int32]Extension { - return e.ExtensionMap() -} - -func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) { - return e.ExtensionMap(), notLocker{} -} - -// notLocker is a sync.Locker whose Lock and Unlock methods are nops. -type notLocker struct{} - -func (n notLocker) Lock() {} -func (n notLocker) Unlock() {} - -// extendable returns the extendableProto interface for the given generated proto message. -// If the proto message has the old extension format, it returns a wrapper that implements -// the extendableProto interface. -func extendable(p interface{}) (extendableProto, bool) { - if ep, ok := p.(extendableProto); ok { - return ep, ok - } - if ep, ok := p.(extendableProtoV1); ok { - return extensionAdapter{ep}, ok - } - return nil, false -} - -// XXX_InternalExtensions is an internal representation of proto extensions. -// -// Each generated message struct type embeds an anonymous XXX_InternalExtensions field, -// thus gaining the unexported 'extensions' method, which can be called only from the proto package. -// -// The methods of XXX_InternalExtensions are not concurrency safe in general, -// but calls to logically read-only methods such as has and get may be executed concurrently. -type XXX_InternalExtensions struct { - // The struct must be indirect so that if a user inadvertently copies a - // generated message and its embedded XXX_InternalExtensions, they - // avoid the mayhem of a copied mutex. - // - // The mutex serializes all logically read-only operations to p.extensionMap. - // It is up to the client to ensure that write operations to p.extensionMap are - // mutually exclusive with other accesses. - p *struct { - mu sync.Mutex - extensionMap map[int32]Extension - } -} - -// extensionsWrite returns the extension map, creating it on first use. -func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension { - if e.p == nil { - e.p = new(struct { - mu sync.Mutex - extensionMap map[int32]Extension - }) - e.p.extensionMap = make(map[int32]Extension) - } - return e.p.extensionMap -} - -// extensionsRead returns the extensions map for read-only use. It may be nil. -// The caller must hold the returned mutex's lock when accessing Elements within the map. -func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) { - if e.p == nil { - return nil, nil - } - return e.p.extensionMap, &e.p.mu -} - -type extensionRange interface { - Message - ExtensionRangeArray() []ExtensionRange -} - -var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem() -var extendableProtoV1Type = reflect.TypeOf((*extendableProtoV1)(nil)).Elem() -var extendableBytesType = reflect.TypeOf((*extensionsBytes)(nil)).Elem() -var extensionRangeType = reflect.TypeOf((*extensionRange)(nil)).Elem() - -// ExtensionDesc represents an extension specification. -// Used in generated code from the protocol compiler. -type ExtensionDesc struct { - ExtendedType Message // nil pointer to the type that is being extended - ExtensionType interface{} // nil pointer to the extension type - Field int32 // field number - Name string // fully-qualified name of extension, for text formatting - Tag string // protobuf tag style - Filename string // name of the file in which the extension is defined -} - -func (ed *ExtensionDesc) repeated() bool { - t := reflect.TypeOf(ed.ExtensionType) - return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 -} - -// Extension represents an extension in a message. -type Extension struct { - // When an extension is stored in a message using SetExtension - // only desc and value are set. When the message is marshaled - // enc will be set to the encoded form of the message. - // - // When a message is unmarshaled and contains extensions, each - // extension will have only enc set. When such an extension is - // accessed using GetExtension (or GetExtensions) desc and value - // will be set. - desc *ExtensionDesc - value interface{} - enc []byte -} - -// SetRawExtension is for testing only. -func SetRawExtension(base Message, id int32, b []byte) { - if ebase, ok := base.(extensionsBytes); ok { - clearExtension(base, id) - ext := ebase.GetExtensions() - *ext = append(*ext, b...) - return - } - epb, ok := extendable(base) - if !ok { - return - } - extmap := epb.extensionsWrite() - extmap[id] = Extension{enc: b} -} - -// isExtensionField returns true iff the given field number is in an extension range. -func isExtensionField(pb extensionRange, field int32) bool { - for _, er := range pb.ExtensionRangeArray() { - if er.Start <= field && field <= er.End { - return true - } - } - return false -} - -// checkExtensionTypes checks that the given extension is valid for pb. -func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error { - var pbi interface{} = pb - // Check the extended type. - if ea, ok := pbi.(extensionAdapter); ok { - pbi = ea.extendableProtoV1 - } - if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b { - return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String()) - } - // Check the range. - if !isExtensionField(pb, extension.Field) { - return errors.New("proto: bad extension number; not in declared ranges") - } - return nil -} - -// extPropKey is sufficient to uniquely identify an extension. -type extPropKey struct { - base reflect.Type - field int32 -} - -var extProp = struct { - sync.RWMutex - m map[extPropKey]*Properties -}{ - m: make(map[extPropKey]*Properties), -} - -func extensionProperties(ed *ExtensionDesc) *Properties { - key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field} - - extProp.RLock() - if prop, ok := extProp.m[key]; ok { - extProp.RUnlock() - return prop - } - extProp.RUnlock() - - extProp.Lock() - defer extProp.Unlock() - // Check again. - if prop, ok := extProp.m[key]; ok { - return prop - } - - prop := new(Properties) - prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil) - extProp.m[key] = prop - return prop -} - -// encode encodes any unmarshaled (unencoded) extensions in e. -func encodeExtensions(e *XXX_InternalExtensions) error { - m, mu := e.extensionsRead() - if m == nil { - return nil // fast path - } - mu.Lock() - defer mu.Unlock() - return encodeExtensionsMap(m) -} - -// encode encodes any unmarshaled (unencoded) extensions in e. -func encodeExtensionsMap(m map[int32]Extension) error { - for k, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - et := reflect.TypeOf(e.desc.ExtensionType) - props := extensionProperties(e.desc) - - p := NewBuffer(nil) - // If e.value has type T, the encoder expects a *struct{ X T }. - // Pass a *T with a zero field and hope it all works out. - x := reflect.New(et) - x.Elem().Set(reflect.ValueOf(e.value)) - if err := props.enc(p, props, toStructPointer(x)); err != nil { - return err - } - e.enc = p.buf - m[k] = e - } - return nil -} - -func extensionsSize(e *XXX_InternalExtensions) (n int) { - m, mu := e.extensionsRead() - if m == nil { - return 0 - } - mu.Lock() - defer mu.Unlock() - return extensionsMapSize(m) -} - -func extensionsMapSize(m map[int32]Extension) (n int) { - for _, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - n += len(e.enc) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - et := reflect.TypeOf(e.desc.ExtensionType) - props := extensionProperties(e.desc) - - // If e.value has type T, the encoder expects a *struct{ X T }. - // Pass a *T with a zero field and hope it all works out. - x := reflect.New(et) - x.Elem().Set(reflect.ValueOf(e.value)) - n += props.size(props, toStructPointer(x)) - } - return -} - -// HasExtension returns whether the given extension is present in pb. -func HasExtension(pb Message, extension *ExtensionDesc) bool { - if epb, doki := pb.(extensionsBytes); doki { - ext := epb.GetExtensions() - buf := *ext - o := 0 - for o < len(buf) { - tag, n := DecodeVarint(buf[o:]) - fieldNum := int32(tag >> 3) - if int32(fieldNum) == extension.Field { - return true - } - wireType := int(tag & 0x7) - o += n - l, err := size(buf[o:], wireType) - if err != nil { - return false - } - o += l - } - return false - } - // TODO: Check types, field numbers, etc.? - epb, ok := extendable(pb) - if !ok { - return false - } - extmap, mu := epb.extensionsRead() - if extmap == nil { - return false - } - mu.Lock() - _, ok = extmap[extension.Field] - mu.Unlock() - return ok -} - -func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int { - ext := pb.GetExtensions() - for offset < len(*ext) { - tag, n1 := DecodeVarint((*ext)[offset:]) - fieldNum := int32(tag >> 3) - wireType := int(tag & 0x7) - n2, err := size((*ext)[offset+n1:], wireType) - if err != nil { - panic(err) - } - newOffset := offset + n1 + n2 - if fieldNum == theFieldNum { - *ext = append((*ext)[:offset], (*ext)[newOffset:]...) - return offset - } - offset = newOffset - } - return -1 -} - -// ClearExtension removes the given extension from pb. -func ClearExtension(pb Message, extension *ExtensionDesc) { - clearExtension(pb, extension.Field) -} - -func clearExtension(pb Message, fieldNum int32) { - if epb, doki := pb.(extensionsBytes); doki { - offset := 0 - for offset != -1 { - offset = deleteExtension(epb, fieldNum, offset) - } - return - } - epb, ok := extendable(pb) - if !ok { - return - } - // TODO: Check types, field numbers, etc.? - extmap := epb.extensionsWrite() - delete(extmap, fieldNum) -} - -// GetExtension parses and returns the given extension of pb. -// If the extension is not present and has no default value it returns ErrMissingExtension. -func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { - if epb, doki := pb.(extensionsBytes); doki { - ext := epb.GetExtensions() - o := 0 - for o < len(*ext) { - tag, n := DecodeVarint((*ext)[o:]) - fieldNum := int32(tag >> 3) - wireType := int(tag & 0x7) - l, err := size((*ext)[o+n:], wireType) - if err != nil { - return nil, err - } - if int32(fieldNum) == extension.Field { - v, err := decodeExtension((*ext)[o:o+n+l], extension) - if err != nil { - return nil, err - } - return v, nil - } - o += n + l - } - return defaultExtensionValue(extension) - } - epb, ok := extendable(pb) - if !ok { - return nil, errors.New("proto: not an extendable proto") - } - if err := checkExtensionTypes(epb, extension); err != nil { - return nil, err - } - - emap, mu := epb.extensionsRead() - if emap == nil { - return defaultExtensionValue(extension) - } - mu.Lock() - defer mu.Unlock() - e, ok := emap[extension.Field] - if !ok { - // defaultExtensionValue returns the default value or - // ErrMissingExtension if there is no default. - return defaultExtensionValue(extension) - } - - if e.value != nil { - // Already decoded. Check the descriptor, though. - if e.desc != extension { - // This shouldn't happen. If it does, it means that - // GetExtension was called twice with two different - // descriptors with the same field number. - return nil, errors.New("proto: descriptor conflict") - } - return e.value, nil - } - - v, err := decodeExtension(e.enc, extension) - if err != nil { - return nil, err - } - - // Remember the decoded version and drop the encoded version. - // That way it is safe to mutate what we return. - e.value = v - e.desc = extension - e.enc = nil - emap[extension.Field] = e - return e.value, nil -} - -// defaultExtensionValue returns the default value for extension. -// If no default for an extension is defined ErrMissingExtension is returned. -func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { - t := reflect.TypeOf(extension.ExtensionType) - props := extensionProperties(extension) - - sf, _, err := fieldDefault(t, props) - if err != nil { - return nil, err - } - - if sf == nil || sf.value == nil { - // There is no default value. - return nil, ErrMissingExtension - } - - if t.Kind() != reflect.Ptr { - // We do not need to return a Ptr, we can directly return sf.value. - return sf.value, nil - } - - // We need to return an interface{} that is a pointer to sf.value. - value := reflect.New(t).Elem() - value.Set(reflect.New(value.Type().Elem())) - if sf.kind == reflect.Int32 { - // We may have an int32 or an enum, but the underlying data is int32. - // Since we can't set an int32 into a non int32 reflect.value directly - // set it as a int32. - value.Elem().SetInt(int64(sf.value.(int32))) - } else { - value.Elem().Set(reflect.ValueOf(sf.value)) - } - return value.Interface(), nil -} - -// decodeExtension decodes an extension encoded in b. -func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { - o := NewBuffer(b) - - t := reflect.TypeOf(extension.ExtensionType) - - props := extensionProperties(extension) - - // t is a pointer to a struct, pointer to basic type or a slice. - // Allocate a "field" to store the pointer/slice itself; the - // pointer/slice will be stored here. We pass - // the address of this field to props.dec. - // This passes a zero field and a *t and lets props.dec - // interpret it as a *struct{ x t }. - value := reflect.New(t).Elem() - - for { - // Discard wire type and field number varint. It isn't needed. - if _, err := o.DecodeVarint(); err != nil { - return nil, err - } - - if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil { - return nil, err - } - - if o.index >= len(o.buf) { - break - } - } - return value.Interface(), nil -} - -// GetExtensions returns a slice of the extensions present in pb that are also listed in es. -// The returned slice has the same length as es; missing extensions will appear as nil elements. -func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) { - extensions = make([]interface{}, len(es)) - for i, e := range es { - extensions[i], err = GetExtension(pb, e) - if err == ErrMissingExtension { - err = nil - } - if err != nil { - return - } - } - return -} - -// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order. -// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing -// just the Field field, which defines the extension's field number. -func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) { - epb, ok := extendable(pb) - if !ok { - return nil, fmt.Errorf("proto: %T is not an extendable proto.Message", pb) - } - registeredExtensions := RegisteredExtensions(pb) - - emap, mu := epb.extensionsRead() - if emap == nil { - return nil, nil - } - mu.Lock() - defer mu.Unlock() - extensions := make([]*ExtensionDesc, 0, len(emap)) - for extid, e := range emap { - desc := e.desc - if desc == nil { - desc = registeredExtensions[extid] - if desc == nil { - desc = &ExtensionDesc{Field: extid} - } - } - - extensions = append(extensions, desc) - } - return extensions, nil -} - -// SetExtension sets the specified extension of pb to the specified value. -func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error { - if epb, doki := pb.(extensionsBytes); doki { - ClearExtension(pb, extension) - ext := epb.GetExtensions() - et := reflect.TypeOf(extension.ExtensionType) - props := extensionProperties(extension) - p := NewBuffer(nil) - x := reflect.New(et) - x.Elem().Set(reflect.ValueOf(value)) - if err := props.enc(p, props, toStructPointer(x)); err != nil { - return err - } - *ext = append(*ext, p.buf...) - return nil - } - epb, ok := extendable(pb) - if !ok { - return errors.New("proto: not an extendable proto") - } - if err := checkExtensionTypes(epb, extension); err != nil { - return err - } - typ := reflect.TypeOf(extension.ExtensionType) - if typ != reflect.TypeOf(value) { - return errors.New("proto: bad extension value type") - } - // nil extension values need to be caught early, because the - // encoder can't distinguish an ErrNil due to a nil extension - // from an ErrNil due to a missing field. Extensions are - // always optional, so the encoder would just swallow the error - // and drop all the extensions from the encoded message. - if reflect.ValueOf(value).IsNil() { - return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) - } - - extmap := epb.extensionsWrite() - extmap[extension.Field] = Extension{desc: extension, value: value} - return nil -} - -// ClearAllExtensions clears all extensions from pb. -func ClearAllExtensions(pb Message) { - if epb, doki := pb.(extensionsBytes); doki { - ext := epb.GetExtensions() - *ext = []byte{} - return - } - epb, ok := extendable(pb) - if !ok { - return - } - m := epb.extensionsWrite() - for k := range m { - delete(m, k) - } -} - -// A global registry of extensions. -// The generated code will register the generated descriptors by calling RegisterExtension. - -var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc) - -// RegisterExtension is called from the generated code. -func RegisterExtension(desc *ExtensionDesc) { - st := reflect.TypeOf(desc.ExtendedType).Elem() - m := extensionMaps[st] - if m == nil { - m = make(map[int32]*ExtensionDesc) - extensionMaps[st] = m - } - if _, ok := m[desc.Field]; ok { - panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field))) - } - m[desc.Field] = desc -} - -// RegisteredExtensions returns a map of the registered extensions of a -// protocol buffer struct, indexed by the extension number. -// The argument pb should be a nil pointer to the struct type. -func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { - return extensionMaps[reflect.TypeOf(pb).Elem()] -} diff --git a/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go b/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go deleted file mode 100644 index ea6478f00..000000000 --- a/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go +++ /dev/null @@ -1,294 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "bytes" - "errors" - "fmt" - "reflect" - "sort" - "strings" - "sync" -) - -func GetBoolExtension(pb Message, extension *ExtensionDesc, ifnotset bool) bool { - if reflect.ValueOf(pb).IsNil() { - return ifnotset - } - value, err := GetExtension(pb, extension) - if err != nil { - return ifnotset - } - if value == nil { - return ifnotset - } - if value.(*bool) == nil { - return ifnotset - } - return *(value.(*bool)) -} - -func (this *Extension) Equal(that *Extension) bool { - return bytes.Equal(this.enc, that.enc) -} - -func (this *Extension) Compare(that *Extension) int { - return bytes.Compare(this.enc, that.enc) -} - -func SizeOfInternalExtension(m extendableProto) (n int) { - return SizeOfExtensionMap(m.extensionsWrite()) -} - -func SizeOfExtensionMap(m map[int32]Extension) (n int) { - return extensionsMapSize(m) -} - -type sortableMapElem struct { - field int32 - ext Extension -} - -func newSortableExtensionsFromMap(m map[int32]Extension) sortableExtensions { - s := make(sortableExtensions, 0, len(m)) - for k, v := range m { - s = append(s, &sortableMapElem{field: k, ext: v}) - } - return s -} - -type sortableExtensions []*sortableMapElem - -func (this sortableExtensions) Len() int { return len(this) } - -func (this sortableExtensions) Swap(i, j int) { this[i], this[j] = this[j], this[i] } - -func (this sortableExtensions) Less(i, j int) bool { return this[i].field < this[j].field } - -func (this sortableExtensions) String() string { - sort.Sort(this) - ss := make([]string, len(this)) - for i := range this { - ss[i] = fmt.Sprintf("%d: %v", this[i].field, this[i].ext) - } - return "map[" + strings.Join(ss, ",") + "]" -} - -func StringFromInternalExtension(m extendableProto) string { - return StringFromExtensionsMap(m.extensionsWrite()) -} - -func StringFromExtensionsMap(m map[int32]Extension) string { - return newSortableExtensionsFromMap(m).String() -} - -func StringFromExtensionsBytes(ext []byte) string { - m, err := BytesToExtensionsMap(ext) - if err != nil { - panic(err) - } - return StringFromExtensionsMap(m) -} - -func EncodeInternalExtension(m extendableProto, data []byte) (n int, err error) { - return EncodeExtensionMap(m.extensionsWrite(), data) -} - -func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) { - if err := encodeExtensionsMap(m); err != nil { - return 0, err - } - keys := make([]int, 0, len(m)) - for k := range m { - keys = append(keys, int(k)) - } - sort.Ints(keys) - for _, k := range keys { - n += copy(data[n:], m[int32(k)].enc) - } - return n, nil -} - -func GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) { - if m[id].value == nil || m[id].desc == nil { - return m[id].enc, nil - } - if err := encodeExtensionsMap(m); err != nil { - return nil, err - } - return m[id].enc, nil -} - -func size(buf []byte, wire int) (int, error) { - switch wire { - case WireVarint: - _, n := DecodeVarint(buf) - return n, nil - case WireFixed64: - return 8, nil - case WireBytes: - v, n := DecodeVarint(buf) - return int(v) + n, nil - case WireFixed32: - return 4, nil - case WireStartGroup: - offset := 0 - for { - u, n := DecodeVarint(buf[offset:]) - fwire := int(u & 0x7) - offset += n - if fwire == WireEndGroup { - return offset, nil - } - s, err := size(buf[offset:], wire) - if err != nil { - return 0, err - } - offset += s - } - } - return 0, fmt.Errorf("proto: can't get size for unknown wire type %d", wire) -} - -func BytesToExtensionsMap(buf []byte) (map[int32]Extension, error) { - m := make(map[int32]Extension) - i := 0 - for i < len(buf) { - tag, n := DecodeVarint(buf[i:]) - if n <= 0 { - return nil, fmt.Errorf("unable to decode varint") - } - fieldNum := int32(tag >> 3) - wireType := int(tag & 0x7) - l, err := size(buf[i+n:], wireType) - if err != nil { - return nil, err - } - end := i + int(l) + n - m[int32(fieldNum)] = Extension{enc: buf[i:end]} - i = end - } - return m, nil -} - -func NewExtension(e []byte) Extension { - ee := Extension{enc: make([]byte, len(e))} - copy(ee.enc, e) - return ee -} - -func AppendExtension(e Message, tag int32, buf []byte) { - if ee, eok := e.(extensionsBytes); eok { - ext := ee.GetExtensions() - *ext = append(*ext, buf...) - return - } - if ee, eok := e.(extendableProto); eok { - m := ee.extensionsWrite() - ext := m[int32(tag)] // may be missing - ext.enc = append(ext.enc, buf...) - m[int32(tag)] = ext - } -} - -func encodeExtension(e *Extension) error { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - return nil - } - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - et := reflect.TypeOf(e.desc.ExtensionType) - props := extensionProperties(e.desc) - - p := NewBuffer(nil) - // If e.value has type T, the encoder expects a *struct{ X T }. - // Pass a *T with a zero field and hope it all works out. - x := reflect.New(et) - x.Elem().Set(reflect.ValueOf(e.value)) - if err := props.enc(p, props, toStructPointer(x)); err != nil { - return err - } - e.enc = p.buf - return nil -} - -func (this Extension) GoString() string { - if this.enc == nil { - if err := encodeExtension(&this); err != nil { - panic(err) - } - } - return fmt.Sprintf("proto.NewExtension(%#v)", this.enc) -} - -func SetUnsafeExtension(pb Message, fieldNum int32, value interface{}) error { - typ := reflect.TypeOf(pb).Elem() - ext, ok := extensionMaps[typ] - if !ok { - return fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String()) - } - desc, ok := ext[fieldNum] - if !ok { - return errors.New("proto: bad extension number; not in declared ranges") - } - return SetExtension(pb, desc, value) -} - -func GetUnsafeExtension(pb Message, fieldNum int32) (interface{}, error) { - typ := reflect.TypeOf(pb).Elem() - ext, ok := extensionMaps[typ] - if !ok { - return nil, fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String()) - } - desc, ok := ext[fieldNum] - if !ok { - return nil, fmt.Errorf("unregistered field number %d", fieldNum) - } - return GetExtension(pb, desc) -} - -func NewUnsafeXXX_InternalExtensions(m map[int32]Extension) XXX_InternalExtensions { - x := &XXX_InternalExtensions{ - p: new(struct { - mu sync.Mutex - extensionMap map[int32]Extension - }), - } - x.p.extensionMap = m - return *x -} - -func GetUnsafeExtensionsMap(extendable Message) map[int32]Extension { - pb := extendable.(extendableProto) - return pb.extensionsWrite() -} diff --git a/vendor/github.com/gogo/protobuf/proto/lib.go b/vendor/github.com/gogo/protobuf/proto/lib.go deleted file mode 100644 index c98d73da4..000000000 --- a/vendor/github.com/gogo/protobuf/proto/lib.go +++ /dev/null @@ -1,897 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/* -Package proto converts data structures to and from the wire format of -protocol buffers. It works in concert with the Go source code generated -for .proto files by the protocol compiler. - -A summary of the properties of the protocol buffer interface -for a protocol buffer variable v: - - - Names are turned from camel_case to CamelCase for export. - - There are no methods on v to set fields; just treat - them as structure fields. - - There are getters that return a field's value if set, - and return the field's default value if unset. - The getters work even if the receiver is a nil message. - - The zero value for a struct is its correct initialization state. - All desired fields must be set before marshaling. - - A Reset() method will restore a protobuf struct to its zero state. - - Non-repeated fields are pointers to the values; nil means unset. - That is, optional or required field int32 f becomes F *int32. - - Repeated fields are slices. - - Helper functions are available to aid the setting of fields. - msg.Foo = proto.String("hello") // set field - - Constants are defined to hold the default values of all fields that - have them. They have the form Default_StructName_FieldName. - Because the getter methods handle defaulted values, - direct use of these constants should be rare. - - Enums are given type names and maps from names to values. - Enum values are prefixed by the enclosing message's name, or by the - enum's type name if it is a top-level enum. Enum types have a String - method, and a Enum method to assist in message construction. - - Nested messages, groups and enums have type names prefixed with the name of - the surrounding message type. - - Extensions are given descriptor names that start with E_, - followed by an underscore-delimited list of the nested messages - that contain it (if any) followed by the CamelCased name of the - extension field itself. HasExtension, ClearExtension, GetExtension - and SetExtension are functions for manipulating extensions. - - Oneof field sets are given a single field in their message, - with distinguished wrapper types for each possible field value. - - Marshal and Unmarshal are functions to encode and decode the wire format. - -When the .proto file specifies `syntax="proto3"`, there are some differences: - - - Non-repeated fields of non-message type are values instead of pointers. - - Enum types do not get an Enum method. - -The simplest way to describe this is to see an example. -Given file test.proto, containing - - package example; - - enum FOO { X = 17; } - - message Test { - required string label = 1; - optional int32 type = 2 [default=77]; - repeated int64 reps = 3; - optional group OptionalGroup = 4 { - required string RequiredField = 5; - } - oneof union { - int32 number = 6; - string name = 7; - } - } - -The resulting file, test.pb.go, is: - - package example - - import proto "github.com/gogo/protobuf/proto" - import math "math" - - type FOO int32 - const ( - FOO_X FOO = 17 - ) - var FOO_name = map[int32]string{ - 17: "X", - } - var FOO_value = map[string]int32{ - "X": 17, - } - - func (x FOO) Enum() *FOO { - p := new(FOO) - *p = x - return p - } - func (x FOO) String() string { - return proto.EnumName(FOO_name, int32(x)) - } - func (x *FOO) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(FOO_value, data) - if err != nil { - return err - } - *x = FOO(value) - return nil - } - - type Test struct { - Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` - Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` - Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` - Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` - // Types that are valid to be assigned to Union: - // *Test_Number - // *Test_Name - Union isTest_Union `protobuf_oneof:"union"` - XXX_unrecognized []byte `json:"-"` - } - func (m *Test) Reset() { *m = Test{} } - func (m *Test) String() string { return proto.CompactTextString(m) } - func (*Test) ProtoMessage() {} - - type isTest_Union interface { - isTest_Union() - } - - type Test_Number struct { - Number int32 `protobuf:"varint,6,opt,name=number"` - } - type Test_Name struct { - Name string `protobuf:"bytes,7,opt,name=name"` - } - - func (*Test_Number) isTest_Union() {} - func (*Test_Name) isTest_Union() {} - - func (m *Test) GetUnion() isTest_Union { - if m != nil { - return m.Union - } - return nil - } - const Default_Test_Type int32 = 77 - - func (m *Test) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" - } - - func (m *Test) GetType() int32 { - if m != nil && m.Type != nil { - return *m.Type - } - return Default_Test_Type - } - - func (m *Test) GetOptionalgroup() *Test_OptionalGroup { - if m != nil { - return m.Optionalgroup - } - return nil - } - - type Test_OptionalGroup struct { - RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` - } - func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} } - func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) } - - func (m *Test_OptionalGroup) GetRequiredField() string { - if m != nil && m.RequiredField != nil { - return *m.RequiredField - } - return "" - } - - func (m *Test) GetNumber() int32 { - if x, ok := m.GetUnion().(*Test_Number); ok { - return x.Number - } - return 0 - } - - func (m *Test) GetName() string { - if x, ok := m.GetUnion().(*Test_Name); ok { - return x.Name - } - return "" - } - - func init() { - proto.RegisterEnum("example.FOO", FOO_name, FOO_value) - } - -To create and play with a Test object: - - package main - - import ( - "log" - - "github.com/gogo/protobuf/proto" - pb "./example.pb" - ) - - func main() { - test := &pb.Test{ - Label: proto.String("hello"), - Type: proto.Int32(17), - Reps: []int64{1, 2, 3}, - Optionalgroup: &pb.Test_OptionalGroup{ - RequiredField: proto.String("good bye"), - }, - Union: &pb.Test_Name{"fred"}, - } - data, err := proto.Marshal(test) - if err != nil { - log.Fatal("marshaling error: ", err) - } - newTest := &pb.Test{} - err = proto.Unmarshal(data, newTest) - if err != nil { - log.Fatal("unmarshaling error: ", err) - } - // Now test and newTest contain the same data. - if test.GetLabel() != newTest.GetLabel() { - log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) - } - // Use a type switch to determine which oneof was set. - switch u := test.Union.(type) { - case *pb.Test_Number: // u.Number contains the number. - case *pb.Test_Name: // u.Name contains the string. - } - // etc. - } -*/ -package proto - -import ( - "encoding/json" - "fmt" - "log" - "reflect" - "sort" - "strconv" - "sync" -) - -// Message is implemented by generated protocol buffer messages. -type Message interface { - Reset() - String() string - ProtoMessage() -} - -// Stats records allocation details about the protocol buffer encoders -// and decoders. Useful for tuning the library itself. -type Stats struct { - Emalloc uint64 // mallocs in encode - Dmalloc uint64 // mallocs in decode - Encode uint64 // number of encodes - Decode uint64 // number of decodes - Chit uint64 // number of cache hits - Cmiss uint64 // number of cache misses - Size uint64 // number of sizes -} - -// Set to true to enable stats collection. -const collectStats = false - -var stats Stats - -// GetStats returns a copy of the global Stats structure. -func GetStats() Stats { return stats } - -// A Buffer is a buffer manager for marshaling and unmarshaling -// protocol buffers. It may be reused between invocations to -// reduce memory usage. It is not necessary to use a Buffer; -// the global functions Marshal and Unmarshal create a -// temporary Buffer and are fine for most applications. -type Buffer struct { - buf []byte // encode/decode byte stream - index int // read point - - // pools of basic types to amortize allocation. - bools []bool - uint32s []uint32 - uint64s []uint64 - - // extra pools, only used with pointer_reflect.go - int32s []int32 - int64s []int64 - float32s []float32 - float64s []float64 -} - -// NewBuffer allocates a new Buffer and initializes its internal data to -// the contents of the argument slice. -func NewBuffer(e []byte) *Buffer { - return &Buffer{buf: e} -} - -// Reset resets the Buffer, ready for marshaling a new protocol buffer. -func (p *Buffer) Reset() { - p.buf = p.buf[0:0] // for reading/writing - p.index = 0 // for reading -} - -// SetBuf replaces the internal buffer with the slice, -// ready for unmarshaling the contents of the slice. -func (p *Buffer) SetBuf(s []byte) { - p.buf = s - p.index = 0 -} - -// Bytes returns the contents of the Buffer. -func (p *Buffer) Bytes() []byte { return p.buf } - -/* - * Helper routines for simplifying the creation of optional fields of basic type. - */ - -// Bool is a helper routine that allocates a new bool value -// to store v and returns a pointer to it. -func Bool(v bool) *bool { - return &v -} - -// Int32 is a helper routine that allocates a new int32 value -// to store v and returns a pointer to it. -func Int32(v int32) *int32 { - return &v -} - -// Int is a helper routine that allocates a new int32 value -// to store v and returns a pointer to it, but unlike Int32 -// its argument value is an int. -func Int(v int) *int32 { - p := new(int32) - *p = int32(v) - return p -} - -// Int64 is a helper routine that allocates a new int64 value -// to store v and returns a pointer to it. -func Int64(v int64) *int64 { - return &v -} - -// Float32 is a helper routine that allocates a new float32 value -// to store v and returns a pointer to it. -func Float32(v float32) *float32 { - return &v -} - -// Float64 is a helper routine that allocates a new float64 value -// to store v and returns a pointer to it. -func Float64(v float64) *float64 { - return &v -} - -// Uint32 is a helper routine that allocates a new uint32 value -// to store v and returns a pointer to it. -func Uint32(v uint32) *uint32 { - return &v -} - -// Uint64 is a helper routine that allocates a new uint64 value -// to store v and returns a pointer to it. -func Uint64(v uint64) *uint64 { - return &v -} - -// String is a helper routine that allocates a new string value -// to store v and returns a pointer to it. -func String(v string) *string { - return &v -} - -// EnumName is a helper function to simplify printing protocol buffer enums -// by name. Given an enum map and a value, it returns a useful string. -func EnumName(m map[int32]string, v int32) string { - s, ok := m[v] - if ok { - return s - } - return strconv.Itoa(int(v)) -} - -// UnmarshalJSONEnum is a helper function to simplify recovering enum int values -// from their JSON-encoded representation. Given a map from the enum's symbolic -// names to its int values, and a byte buffer containing the JSON-encoded -// value, it returns an int32 that can be cast to the enum type by the caller. -// -// The function can deal with both JSON representations, numeric and symbolic. -func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { - if data[0] == '"' { - // New style: enums are strings. - var repr string - if err := json.Unmarshal(data, &repr); err != nil { - return -1, err - } - val, ok := m[repr] - if !ok { - return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) - } - return val, nil - } - // Old style: enums are ints. - var val int32 - if err := json.Unmarshal(data, &val); err != nil { - return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) - } - return val, nil -} - -// DebugPrint dumps the encoded data in b in a debugging format with a header -// including the string s. Used in testing but made available for general debugging. -func (p *Buffer) DebugPrint(s string, b []byte) { - var u uint64 - - obuf := p.buf - sindex := p.index - p.buf = b - p.index = 0 - depth := 0 - - fmt.Printf("\n--- %s ---\n", s) - -out: - for { - for i := 0; i < depth; i++ { - fmt.Print(" ") - } - - index := p.index - if index == len(p.buf) { - break - } - - op, err := p.DecodeVarint() - if err != nil { - fmt.Printf("%3d: fetching op err %v\n", index, err) - break out - } - tag := op >> 3 - wire := op & 7 - - switch wire { - default: - fmt.Printf("%3d: t=%3d unknown wire=%d\n", - index, tag, wire) - break out - - case WireBytes: - var r []byte - - r, err = p.DecodeRawBytes(false) - if err != nil { - break out - } - fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r)) - if len(r) <= 6 { - for i := 0; i < len(r); i++ { - fmt.Printf(" %.2x", r[i]) - } - } else { - for i := 0; i < 3; i++ { - fmt.Printf(" %.2x", r[i]) - } - fmt.Printf(" ..") - for i := len(r) - 3; i < len(r); i++ { - fmt.Printf(" %.2x", r[i]) - } - } - fmt.Printf("\n") - - case WireFixed32: - u, err = p.DecodeFixed32() - if err != nil { - fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u) - - case WireFixed64: - u, err = p.DecodeFixed64() - if err != nil { - fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u) - - case WireVarint: - u, err = p.DecodeVarint() - if err != nil { - fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u) - - case WireStartGroup: - fmt.Printf("%3d: t=%3d start\n", index, tag) - depth++ - - case WireEndGroup: - depth-- - fmt.Printf("%3d: t=%3d end\n", index, tag) - } - } - - if depth != 0 { - fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth) - } - fmt.Printf("\n") - - p.buf = obuf - p.index = sindex -} - -// SetDefaults sets unset protocol buffer fields to their default values. -// It only modifies fields that are both unset and have defined defaults. -// It recursively sets default values in any non-nil sub-messages. -func SetDefaults(pb Message) { - setDefaults(reflect.ValueOf(pb), true, false) -} - -// v is a pointer to a struct. -func setDefaults(v reflect.Value, recur, zeros bool) { - v = v.Elem() - - defaultMu.RLock() - dm, ok := defaults[v.Type()] - defaultMu.RUnlock() - if !ok { - dm = buildDefaultMessage(v.Type()) - defaultMu.Lock() - defaults[v.Type()] = dm - defaultMu.Unlock() - } - - for _, sf := range dm.scalars { - f := v.Field(sf.index) - if !f.IsNil() { - // field already set - continue - } - dv := sf.value - if dv == nil && !zeros { - // no explicit default, and don't want to set zeros - continue - } - fptr := f.Addr().Interface() // **T - // TODO: Consider batching the allocations we do here. - switch sf.kind { - case reflect.Bool: - b := new(bool) - if dv != nil { - *b = dv.(bool) - } - *(fptr.(**bool)) = b - case reflect.Float32: - f := new(float32) - if dv != nil { - *f = dv.(float32) - } - *(fptr.(**float32)) = f - case reflect.Float64: - f := new(float64) - if dv != nil { - *f = dv.(float64) - } - *(fptr.(**float64)) = f - case reflect.Int32: - // might be an enum - if ft := f.Type(); ft != int32PtrType { - // enum - f.Set(reflect.New(ft.Elem())) - if dv != nil { - f.Elem().SetInt(int64(dv.(int32))) - } - } else { - // int32 field - i := new(int32) - if dv != nil { - *i = dv.(int32) - } - *(fptr.(**int32)) = i - } - case reflect.Int64: - i := new(int64) - if dv != nil { - *i = dv.(int64) - } - *(fptr.(**int64)) = i - case reflect.String: - s := new(string) - if dv != nil { - *s = dv.(string) - } - *(fptr.(**string)) = s - case reflect.Uint8: - // exceptional case: []byte - var b []byte - if dv != nil { - db := dv.([]byte) - b = make([]byte, len(db)) - copy(b, db) - } else { - b = []byte{} - } - *(fptr.(*[]byte)) = b - case reflect.Uint32: - u := new(uint32) - if dv != nil { - *u = dv.(uint32) - } - *(fptr.(**uint32)) = u - case reflect.Uint64: - u := new(uint64) - if dv != nil { - *u = dv.(uint64) - } - *(fptr.(**uint64)) = u - default: - log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind) - } - } - - for _, ni := range dm.nested { - f := v.Field(ni) - // f is *T or []*T or map[T]*T - switch f.Kind() { - case reflect.Ptr: - if f.IsNil() { - continue - } - setDefaults(f, recur, zeros) - - case reflect.Slice: - for i := 0; i < f.Len(); i++ { - e := f.Index(i) - if e.IsNil() { - continue - } - setDefaults(e, recur, zeros) - } - - case reflect.Map: - for _, k := range f.MapKeys() { - e := f.MapIndex(k) - if e.IsNil() { - continue - } - setDefaults(e, recur, zeros) - } - } - } -} - -var ( - // defaults maps a protocol buffer struct type to a slice of the fields, - // with its scalar fields set to their proto-declared non-zero default values. - defaultMu sync.RWMutex - defaults = make(map[reflect.Type]defaultMessage) - - int32PtrType = reflect.TypeOf((*int32)(nil)) -) - -// defaultMessage represents information about the default values of a message. -type defaultMessage struct { - scalars []scalarField - nested []int // struct field index of nested messages -} - -type scalarField struct { - index int // struct field index - kind reflect.Kind // element type (the T in *T or []T) - value interface{} // the proto-declared default value, or nil -} - -// t is a struct type. -func buildDefaultMessage(t reflect.Type) (dm defaultMessage) { - sprop := GetProperties(t) - for _, prop := range sprop.Prop { - fi, ok := sprop.decoderTags.get(prop.Tag) - if !ok { - // XXX_unrecognized - continue - } - ft := t.Field(fi).Type - - sf, nested, err := fieldDefault(ft, prop) - switch { - case err != nil: - log.Print(err) - case nested: - dm.nested = append(dm.nested, fi) - case sf != nil: - sf.index = fi - dm.scalars = append(dm.scalars, *sf) - } - } - - return dm -} - -// fieldDefault returns the scalarField for field type ft. -// sf will be nil if the field can not have a default. -// nestedMessage will be true if this is a nested message. -// Note that sf.index is not set on return. -func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) { - var canHaveDefault bool - switch ft.Kind() { - case reflect.Ptr: - if ft.Elem().Kind() == reflect.Struct { - nestedMessage = true - } else { - canHaveDefault = true // proto2 scalar field - } - - case reflect.Slice: - switch ft.Elem().Kind() { - case reflect.Ptr: - nestedMessage = true // repeated message - case reflect.Uint8: - canHaveDefault = true // bytes field - } - - case reflect.Map: - if ft.Elem().Kind() == reflect.Ptr { - nestedMessage = true // map with message values - } - } - - if !canHaveDefault { - if nestedMessage { - return nil, true, nil - } - return nil, false, nil - } - - // We now know that ft is a pointer or slice. - sf = &scalarField{kind: ft.Elem().Kind()} - - // scalar fields without defaults - if !prop.HasDefault { - return sf, false, nil - } - - // a scalar field: either *T or []byte - switch ft.Elem().Kind() { - case reflect.Bool: - x, err := strconv.ParseBool(prop.Default) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err) - } - sf.value = x - case reflect.Float32: - x, err := strconv.ParseFloat(prop.Default, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err) - } - sf.value = float32(x) - case reflect.Float64: - x, err := strconv.ParseFloat(prop.Default, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err) - } - sf.value = x - case reflect.Int32: - x, err := strconv.ParseInt(prop.Default, 10, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err) - } - sf.value = int32(x) - case reflect.Int64: - x, err := strconv.ParseInt(prop.Default, 10, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err) - } - sf.value = x - case reflect.String: - sf.value = prop.Default - case reflect.Uint8: - // []byte (not *uint8) - sf.value = []byte(prop.Default) - case reflect.Uint32: - x, err := strconv.ParseUint(prop.Default, 10, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err) - } - sf.value = uint32(x) - case reflect.Uint64: - x, err := strconv.ParseUint(prop.Default, 10, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err) - } - sf.value = x - default: - return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind()) - } - - return sf, false, nil -} - -// Map fields may have key types of non-float scalars, strings and enums. -// The easiest way to sort them in some deterministic order is to use fmt. -// If this turns out to be inefficient we can always consider other options, -// such as doing a Schwartzian transform. - -func mapKeys(vs []reflect.Value) sort.Interface { - s := mapKeySorter{ - vs: vs, - // default Less function: textual comparison - less: func(a, b reflect.Value) bool { - return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface()) - }, - } - - // Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps; - // numeric keys are sorted numerically. - if len(vs) == 0 { - return s - } - switch vs[0].Kind() { - case reflect.Int32, reflect.Int64: - s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() } - case reflect.Uint32, reflect.Uint64: - s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() } - } - - return s -} - -type mapKeySorter struct { - vs []reflect.Value - less func(a, b reflect.Value) bool -} - -func (s mapKeySorter) Len() int { return len(s.vs) } -func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] } -func (s mapKeySorter) Less(i, j int) bool { - return s.less(s.vs[i], s.vs[j]) -} - -// isProto3Zero reports whether v is a zero proto3 value. -func isProto3Zero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Bool: - return !v.Bool() - case reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint32, reflect.Uint64: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.String: - return v.String() == "" - } - return false -} - -// ProtoPackageIsVersion2 is referenced from generated protocol buffer files -// to assert that that code is compatible with this version of the proto package. -const GoGoProtoPackageIsVersion2 = true - -// ProtoPackageIsVersion1 is referenced from generated protocol buffer files -// to assert that that code is compatible with this version of the proto package. -const GoGoProtoPackageIsVersion1 = true diff --git a/vendor/github.com/gogo/protobuf/proto/lib_gogo.go b/vendor/github.com/gogo/protobuf/proto/lib_gogo.go deleted file mode 100644 index 4b4f7c909..000000000 --- a/vendor/github.com/gogo/protobuf/proto/lib_gogo.go +++ /dev/null @@ -1,42 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "encoding/json" - "strconv" -) - -func MarshalJSONEnum(m map[int32]string, value int32) ([]byte, error) { - s, ok := m[value] - if !ok { - s = strconv.Itoa(int(value)) - } - return json.Marshal(s) -} diff --git a/vendor/github.com/gogo/protobuf/proto/message_set.go b/vendor/github.com/gogo/protobuf/proto/message_set.go deleted file mode 100644 index fd982decd..000000000 --- a/vendor/github.com/gogo/protobuf/proto/message_set.go +++ /dev/null @@ -1,311 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Support for message sets. - */ - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "reflect" - "sort" -) - -// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. -// A message type ID is required for storing a protocol buffer in a message set. -var errNoMessageTypeID = errors.New("proto does not have a message type ID") - -// The first two types (_MessageSet_Item and messageSet) -// model what the protocol compiler produces for the following protocol message: -// message MessageSet { -// repeated group Item = 1 { -// required int32 type_id = 2; -// required string message = 3; -// }; -// } -// That is the MessageSet wire format. We can't use a proto to generate these -// because that would introduce a circular dependency between it and this package. - -type _MessageSet_Item struct { - TypeId *int32 `protobuf:"varint,2,req,name=type_id"` - Message []byte `protobuf:"bytes,3,req,name=message"` -} - -type messageSet struct { - Item []*_MessageSet_Item `protobuf:"group,1,rep"` - XXX_unrecognized []byte - // TODO: caching? -} - -// Make sure messageSet is a Message. -var _ Message = (*messageSet)(nil) - -// messageTypeIder is an interface satisfied by a protocol buffer type -// that may be stored in a MessageSet. -type messageTypeIder interface { - MessageTypeId() int32 -} - -func (ms *messageSet) find(pb Message) *_MessageSet_Item { - mti, ok := pb.(messageTypeIder) - if !ok { - return nil - } - id := mti.MessageTypeId() - for _, item := range ms.Item { - if *item.TypeId == id { - return item - } - } - return nil -} - -func (ms *messageSet) Has(pb Message) bool { - if ms.find(pb) != nil { - return true - } - return false -} - -func (ms *messageSet) Unmarshal(pb Message) error { - if item := ms.find(pb); item != nil { - return Unmarshal(item.Message, pb) - } - if _, ok := pb.(messageTypeIder); !ok { - return errNoMessageTypeID - } - return nil // TODO: return error instead? -} - -func (ms *messageSet) Marshal(pb Message) error { - msg, err := Marshal(pb) - if err != nil { - return err - } - if item := ms.find(pb); item != nil { - // reuse existing item - item.Message = msg - return nil - } - - mti, ok := pb.(messageTypeIder) - if !ok { - return errNoMessageTypeID - } - - mtid := mti.MessageTypeId() - ms.Item = append(ms.Item, &_MessageSet_Item{ - TypeId: &mtid, - Message: msg, - }) - return nil -} - -func (ms *messageSet) Reset() { *ms = messageSet{} } -func (ms *messageSet) String() string { return CompactTextString(ms) } -func (*messageSet) ProtoMessage() {} - -// Support for the message_set_wire_format message option. - -func skipVarint(buf []byte) []byte { - i := 0 - for ; buf[i]&0x80 != 0; i++ { - } - return buf[i+1:] -} - -// MarshalMessageSet encodes the extension map represented by m in the message set wire format. -// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option. -func MarshalMessageSet(exts interface{}) ([]byte, error) { - var m map[int32]Extension - switch exts := exts.(type) { - case *XXX_InternalExtensions: - if err := encodeExtensions(exts); err != nil { - return nil, err - } - m, _ = exts.extensionsRead() - case map[int32]Extension: - if err := encodeExtensionsMap(exts); err != nil { - return nil, err - } - m = exts - default: - return nil, errors.New("proto: not an extension map") - } - - // Sort extension IDs to provide a deterministic encoding. - // See also enc_map in encode.go. - ids := make([]int, 0, len(m)) - for id := range m { - ids = append(ids, int(id)) - } - sort.Ints(ids) - - ms := &messageSet{Item: make([]*_MessageSet_Item, 0, len(m))} - for _, id := range ids { - e := m[int32(id)] - // Remove the wire type and field number varint, as well as the length varint. - msg := skipVarint(skipVarint(e.enc)) - - ms.Item = append(ms.Item, &_MessageSet_Item{ - TypeId: Int32(int32(id)), - Message: msg, - }) - } - return Marshal(ms) -} - -// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. -// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option. -func UnmarshalMessageSet(buf []byte, exts interface{}) error { - var m map[int32]Extension - switch exts := exts.(type) { - case *XXX_InternalExtensions: - m = exts.extensionsWrite() - case map[int32]Extension: - m = exts - default: - return errors.New("proto: not an extension map") - } - - ms := new(messageSet) - if err := Unmarshal(buf, ms); err != nil { - return err - } - for _, item := range ms.Item { - id := *item.TypeId - msg := item.Message - - // Restore wire type and field number varint, plus length varint. - // Be careful to preserve duplicate items. - b := EncodeVarint(uint64(id)<<3 | WireBytes) - if ext, ok := m[id]; ok { - // Existing data; rip off the tag and length varint - // so we join the new data correctly. - // We can assume that ext.enc is set because we are unmarshaling. - o := ext.enc[len(b):] // skip wire type and field number - _, n := DecodeVarint(o) // calculate length of length varint - o = o[n:] // skip length varint - msg = append(o, msg...) // join old data and new data - } - b = append(b, EncodeVarint(uint64(len(msg)))...) - b = append(b, msg...) - - m[id] = Extension{enc: b} - } - return nil -} - -// MarshalMessageSetJSON encodes the extension map represented by m in JSON format. -// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option. -func MarshalMessageSetJSON(exts interface{}) ([]byte, error) { - var m map[int32]Extension - switch exts := exts.(type) { - case *XXX_InternalExtensions: - m, _ = exts.extensionsRead() - case map[int32]Extension: - m = exts - default: - return nil, errors.New("proto: not an extension map") - } - var b bytes.Buffer - b.WriteByte('{') - - // Process the map in key order for deterministic output. - ids := make([]int32, 0, len(m)) - for id := range m { - ids = append(ids, id) - } - sort.Sort(int32Slice(ids)) // int32Slice defined in text.go - - for i, id := range ids { - ext := m[id] - if i > 0 { - b.WriteByte(',') - } - - msd, ok := messageSetMap[id] - if !ok { - // Unknown type; we can't render it, so skip it. - continue - } - fmt.Fprintf(&b, `"[%s]":`, msd.name) - - x := ext.value - if x == nil { - x = reflect.New(msd.t.Elem()).Interface() - if err := Unmarshal(ext.enc, x.(Message)); err != nil { - return nil, err - } - } - d, err := json.Marshal(x) - if err != nil { - return nil, err - } - b.Write(d) - } - b.WriteByte('}') - return b.Bytes(), nil -} - -// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format. -// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option. -func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error { - // Common-case fast path. - if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) { - return nil - } - - // This is fairly tricky, and it's not clear that it is needed. - return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented") -} - -// A global registry of types that can be used in a MessageSet. - -var messageSetMap = make(map[int32]messageSetDesc) - -type messageSetDesc struct { - t reflect.Type // pointer to struct - name string -} - -// RegisterMessageSetType is called from the generated code. -func RegisterMessageSetType(m Message, fieldNum int32, name string) { - messageSetMap[fieldNum] = messageSetDesc{ - t: reflect.TypeOf(m), - name: name, - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go b/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go deleted file mode 100644 index fb512e2e1..000000000 --- a/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go +++ /dev/null @@ -1,484 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2012 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build appengine js - -// This file contains an implementation of proto field accesses using package reflect. -// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can -// be used on App Engine. - -package proto - -import ( - "math" - "reflect" -) - -// A structPointer is a pointer to a struct. -type structPointer struct { - v reflect.Value -} - -// toStructPointer returns a structPointer equivalent to the given reflect value. -// The reflect value must itself be a pointer to a struct. -func toStructPointer(v reflect.Value) structPointer { - return structPointer{v} -} - -// IsNil reports whether p is nil. -func structPointer_IsNil(p structPointer) bool { - return p.v.IsNil() -} - -// Interface returns the struct pointer as an interface value. -func structPointer_Interface(p structPointer, _ reflect.Type) interface{} { - return p.v.Interface() -} - -// A field identifies a field in a struct, accessible from a structPointer. -// In this implementation, a field is identified by the sequence of field indices -// passed to reflect's FieldByIndex. -type field []int - -// toField returns a field equivalent to the given reflect field. -func toField(f *reflect.StructField) field { - return f.Index -} - -// invalidField is an invalid field identifier. -var invalidField = field(nil) - -// IsValid reports whether the field identifier is valid. -func (f field) IsValid() bool { return f != nil } - -// field returns the given field in the struct as a reflect value. -func structPointer_field(p structPointer, f field) reflect.Value { - // Special case: an extension map entry with a value of type T - // passes a *T to the struct-handling code with a zero field, - // expecting that it will be treated as equivalent to *struct{ X T }, - // which has the same memory layout. We have to handle that case - // specially, because reflect will panic if we call FieldByIndex on a - // non-struct. - if f == nil { - return p.v.Elem() - } - - return p.v.Elem().FieldByIndex(f) -} - -// ifield returns the given field in the struct as an interface value. -func structPointer_ifield(p structPointer, f field) interface{} { - return structPointer_field(p, f).Addr().Interface() -} - -// Bytes returns the address of a []byte field in the struct. -func structPointer_Bytes(p structPointer, f field) *[]byte { - return structPointer_ifield(p, f).(*[]byte) -} - -// BytesSlice returns the address of a [][]byte field in the struct. -func structPointer_BytesSlice(p structPointer, f field) *[][]byte { - return structPointer_ifield(p, f).(*[][]byte) -} - -// Bool returns the address of a *bool field in the struct. -func structPointer_Bool(p structPointer, f field) **bool { - return structPointer_ifield(p, f).(**bool) -} - -// BoolVal returns the address of a bool field in the struct. -func structPointer_BoolVal(p structPointer, f field) *bool { - return structPointer_ifield(p, f).(*bool) -} - -// BoolSlice returns the address of a []bool field in the struct. -func structPointer_BoolSlice(p structPointer, f field) *[]bool { - return structPointer_ifield(p, f).(*[]bool) -} - -// String returns the address of a *string field in the struct. -func structPointer_String(p structPointer, f field) **string { - return structPointer_ifield(p, f).(**string) -} - -// StringVal returns the address of a string field in the struct. -func structPointer_StringVal(p structPointer, f field) *string { - return structPointer_ifield(p, f).(*string) -} - -// StringSlice returns the address of a []string field in the struct. -func structPointer_StringSlice(p structPointer, f field) *[]string { - return structPointer_ifield(p, f).(*[]string) -} - -// Extensions returns the address of an extension map field in the struct. -func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions { - return structPointer_ifield(p, f).(*XXX_InternalExtensions) -} - -// ExtMap returns the address of an extension map field in the struct. -func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { - return structPointer_ifield(p, f).(*map[int32]Extension) -} - -// NewAt returns the reflect.Value for a pointer to a field in the struct. -func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value { - return structPointer_field(p, f).Addr() -} - -// SetStructPointer writes a *struct field in the struct. -func structPointer_SetStructPointer(p structPointer, f field, q structPointer) { - structPointer_field(p, f).Set(q.v) -} - -// GetStructPointer reads a *struct field in the struct. -func structPointer_GetStructPointer(p structPointer, f field) structPointer { - return structPointer{structPointer_field(p, f)} -} - -// StructPointerSlice the address of a []*struct field in the struct. -func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice { - return structPointerSlice{structPointer_field(p, f)} -} - -// A structPointerSlice represents the address of a slice of pointers to structs -// (themselves messages or groups). That is, v.Type() is *[]*struct{...}. -type structPointerSlice struct { - v reflect.Value -} - -func (p structPointerSlice) Len() int { return p.v.Len() } -func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} } -func (p structPointerSlice) Append(q structPointer) { - p.v.Set(reflect.Append(p.v, q.v)) -} - -var ( - int32Type = reflect.TypeOf(int32(0)) - uint32Type = reflect.TypeOf(uint32(0)) - float32Type = reflect.TypeOf(float32(0)) - int64Type = reflect.TypeOf(int64(0)) - uint64Type = reflect.TypeOf(uint64(0)) - float64Type = reflect.TypeOf(float64(0)) -) - -// A word32 represents a field of type *int32, *uint32, *float32, or *enum. -// That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable. -type word32 struct { - v reflect.Value -} - -// IsNil reports whether p is nil. -func word32_IsNil(p word32) bool { - return p.v.IsNil() -} - -// Set sets p to point at a newly allocated word with bits set to x. -func word32_Set(p word32, o *Buffer, x uint32) { - t := p.v.Type().Elem() - switch t { - case int32Type: - if len(o.int32s) == 0 { - o.int32s = make([]int32, uint32PoolSize) - } - o.int32s[0] = int32(x) - p.v.Set(reflect.ValueOf(&o.int32s[0])) - o.int32s = o.int32s[1:] - return - case uint32Type: - if len(o.uint32s) == 0 { - o.uint32s = make([]uint32, uint32PoolSize) - } - o.uint32s[0] = x - p.v.Set(reflect.ValueOf(&o.uint32s[0])) - o.uint32s = o.uint32s[1:] - return - case float32Type: - if len(o.float32s) == 0 { - o.float32s = make([]float32, uint32PoolSize) - } - o.float32s[0] = math.Float32frombits(x) - p.v.Set(reflect.ValueOf(&o.float32s[0])) - o.float32s = o.float32s[1:] - return - } - - // must be enum - p.v.Set(reflect.New(t)) - p.v.Elem().SetInt(int64(int32(x))) -} - -// Get gets the bits pointed at by p, as a uint32. -func word32_Get(p word32) uint32 { - elem := p.v.Elem() - switch elem.Kind() { - case reflect.Int32: - return uint32(elem.Int()) - case reflect.Uint32: - return uint32(elem.Uint()) - case reflect.Float32: - return math.Float32bits(float32(elem.Float())) - } - panic("unreachable") -} - -// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct. -func structPointer_Word32(p structPointer, f field) word32 { - return word32{structPointer_field(p, f)} -} - -// A word32Val represents a field of type int32, uint32, float32, or enum. -// That is, v.Type() is int32, uint32, float32, or enum and v is assignable. -type word32Val struct { - v reflect.Value -} - -// Set sets *p to x. -func word32Val_Set(p word32Val, x uint32) { - switch p.v.Type() { - case int32Type: - p.v.SetInt(int64(x)) - return - case uint32Type: - p.v.SetUint(uint64(x)) - return - case float32Type: - p.v.SetFloat(float64(math.Float32frombits(x))) - return - } - - // must be enum - p.v.SetInt(int64(int32(x))) -} - -// Get gets the bits pointed at by p, as a uint32. -func word32Val_Get(p word32Val) uint32 { - elem := p.v - switch elem.Kind() { - case reflect.Int32: - return uint32(elem.Int()) - case reflect.Uint32: - return uint32(elem.Uint()) - case reflect.Float32: - return math.Float32bits(float32(elem.Float())) - } - panic("unreachable") -} - -// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct. -func structPointer_Word32Val(p structPointer, f field) word32Val { - return word32Val{structPointer_field(p, f)} -} - -// A word32Slice is a slice of 32-bit values. -// That is, v.Type() is []int32, []uint32, []float32, or []enum. -type word32Slice struct { - v reflect.Value -} - -func (p word32Slice) Append(x uint32) { - n, m := p.v.Len(), p.v.Cap() - if n < m { - p.v.SetLen(n + 1) - } else { - t := p.v.Type().Elem() - p.v.Set(reflect.Append(p.v, reflect.Zero(t))) - } - elem := p.v.Index(n) - switch elem.Kind() { - case reflect.Int32: - elem.SetInt(int64(int32(x))) - case reflect.Uint32: - elem.SetUint(uint64(x)) - case reflect.Float32: - elem.SetFloat(float64(math.Float32frombits(x))) - } -} - -func (p word32Slice) Len() int { - return p.v.Len() -} - -func (p word32Slice) Index(i int) uint32 { - elem := p.v.Index(i) - switch elem.Kind() { - case reflect.Int32: - return uint32(elem.Int()) - case reflect.Uint32: - return uint32(elem.Uint()) - case reflect.Float32: - return math.Float32bits(float32(elem.Float())) - } - panic("unreachable") -} - -// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct. -func structPointer_Word32Slice(p structPointer, f field) word32Slice { - return word32Slice{structPointer_field(p, f)} -} - -// word64 is like word32 but for 64-bit values. -type word64 struct { - v reflect.Value -} - -func word64_Set(p word64, o *Buffer, x uint64) { - t := p.v.Type().Elem() - switch t { - case int64Type: - if len(o.int64s) == 0 { - o.int64s = make([]int64, uint64PoolSize) - } - o.int64s[0] = int64(x) - p.v.Set(reflect.ValueOf(&o.int64s[0])) - o.int64s = o.int64s[1:] - return - case uint64Type: - if len(o.uint64s) == 0 { - o.uint64s = make([]uint64, uint64PoolSize) - } - o.uint64s[0] = x - p.v.Set(reflect.ValueOf(&o.uint64s[0])) - o.uint64s = o.uint64s[1:] - return - case float64Type: - if len(o.float64s) == 0 { - o.float64s = make([]float64, uint64PoolSize) - } - o.float64s[0] = math.Float64frombits(x) - p.v.Set(reflect.ValueOf(&o.float64s[0])) - o.float64s = o.float64s[1:] - return - } - panic("unreachable") -} - -func word64_IsNil(p word64) bool { - return p.v.IsNil() -} - -func word64_Get(p word64) uint64 { - elem := p.v.Elem() - switch elem.Kind() { - case reflect.Int64: - return uint64(elem.Int()) - case reflect.Uint64: - return elem.Uint() - case reflect.Float64: - return math.Float64bits(elem.Float()) - } - panic("unreachable") -} - -func structPointer_Word64(p structPointer, f field) word64 { - return word64{structPointer_field(p, f)} -} - -// word64Val is like word32Val but for 64-bit values. -type word64Val struct { - v reflect.Value -} - -func word64Val_Set(p word64Val, o *Buffer, x uint64) { - switch p.v.Type() { - case int64Type: - p.v.SetInt(int64(x)) - return - case uint64Type: - p.v.SetUint(x) - return - case float64Type: - p.v.SetFloat(math.Float64frombits(x)) - return - } - panic("unreachable") -} - -func word64Val_Get(p word64Val) uint64 { - elem := p.v - switch elem.Kind() { - case reflect.Int64: - return uint64(elem.Int()) - case reflect.Uint64: - return elem.Uint() - case reflect.Float64: - return math.Float64bits(elem.Float()) - } - panic("unreachable") -} - -func structPointer_Word64Val(p structPointer, f field) word64Val { - return word64Val{structPointer_field(p, f)} -} - -type word64Slice struct { - v reflect.Value -} - -func (p word64Slice) Append(x uint64) { - n, m := p.v.Len(), p.v.Cap() - if n < m { - p.v.SetLen(n + 1) - } else { - t := p.v.Type().Elem() - p.v.Set(reflect.Append(p.v, reflect.Zero(t))) - } - elem := p.v.Index(n) - switch elem.Kind() { - case reflect.Int64: - elem.SetInt(int64(int64(x))) - case reflect.Uint64: - elem.SetUint(uint64(x)) - case reflect.Float64: - elem.SetFloat(float64(math.Float64frombits(x))) - } -} - -func (p word64Slice) Len() int { - return p.v.Len() -} - -func (p word64Slice) Index(i int) uint64 { - elem := p.v.Index(i) - switch elem.Kind() { - case reflect.Int64: - return uint64(elem.Int()) - case reflect.Uint64: - return uint64(elem.Uint()) - case reflect.Float64: - return math.Float64bits(float64(elem.Float())) - } - panic("unreachable") -} - -func structPointer_Word64Slice(p structPointer, f field) word64Slice { - return word64Slice{structPointer_field(p, f)} -} diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go b/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go deleted file mode 100644 index 1763a5f22..000000000 --- a/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go +++ /dev/null @@ -1,85 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2016, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build appengine js - -package proto - -import ( - "reflect" -) - -func structPointer_FieldPointer(p structPointer, f field) structPointer { - panic("not implemented") -} - -func appendStructPointer(base structPointer, f field, typ reflect.Type) structPointer { - panic("not implemented") -} - -func structPointer_InterfaceAt(p structPointer, f field, t reflect.Type) interface{} { - panic("not implemented") -} - -func structPointer_InterfaceRef(p structPointer, f field, t reflect.Type) interface{} { - panic("not implemented") -} - -func structPointer_GetRefStructPointer(p structPointer, f field) structPointer { - panic("not implemented") -} - -func structPointer_Add(p structPointer, size field) structPointer { - panic("not implemented") -} - -func structPointer_Len(p structPointer, f field) int { - panic("not implemented") -} - -func structPointer_GetSliceHeader(p structPointer, f field) *reflect.SliceHeader { - panic("not implemented") -} - -func structPointer_Copy(oldptr structPointer, newptr structPointer, size int) { - panic("not implemented") -} - -func structPointer_StructRefSlice(p structPointer, f field, size uintptr) *structRefSlice { - panic("not implemented") -} - -type structRefSlice struct{} - -func (v *structRefSlice) Len() int { - panic("not implemented") -} - -func (v *structRefSlice) Index(i int) structPointer { - panic("not implemented") -} diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go b/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go deleted file mode 100644 index 6b5567d47..000000000 --- a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go +++ /dev/null @@ -1,270 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2012 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build !appengine,!js - -// This file contains the implementation of the proto field accesses using package unsafe. - -package proto - -import ( - "reflect" - "unsafe" -) - -// NOTE: These type_Foo functions would more idiomatically be methods, -// but Go does not allow methods on pointer types, and we must preserve -// some pointer type for the garbage collector. We use these -// funcs with clunky names as our poor approximation to methods. -// -// An alternative would be -// type structPointer struct { p unsafe.Pointer } -// but that does not registerize as well. - -// A structPointer is a pointer to a struct. -type structPointer unsafe.Pointer - -// toStructPointer returns a structPointer equivalent to the given reflect value. -func toStructPointer(v reflect.Value) structPointer { - return structPointer(unsafe.Pointer(v.Pointer())) -} - -// IsNil reports whether p is nil. -func structPointer_IsNil(p structPointer) bool { - return p == nil -} - -// Interface returns the struct pointer, assumed to have element type t, -// as an interface value. -func structPointer_Interface(p structPointer, t reflect.Type) interface{} { - return reflect.NewAt(t, unsafe.Pointer(p)).Interface() -} - -// A field identifies a field in a struct, accessible from a structPointer. -// In this implementation, a field is identified by its byte offset from the start of the struct. -type field uintptr - -// toField returns a field equivalent to the given reflect field. -func toField(f *reflect.StructField) field { - return field(f.Offset) -} - -// invalidField is an invalid field identifier. -const invalidField = ^field(0) - -// IsValid reports whether the field identifier is valid. -func (f field) IsValid() bool { - return f != ^field(0) -} - -// Bytes returns the address of a []byte field in the struct. -func structPointer_Bytes(p structPointer, f field) *[]byte { - return (*[]byte)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// BytesSlice returns the address of a [][]byte field in the struct. -func structPointer_BytesSlice(p structPointer, f field) *[][]byte { - return (*[][]byte)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// Bool returns the address of a *bool field in the struct. -func structPointer_Bool(p structPointer, f field) **bool { - return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// BoolVal returns the address of a bool field in the struct. -func structPointer_BoolVal(p structPointer, f field) *bool { - return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// BoolSlice returns the address of a []bool field in the struct. -func structPointer_BoolSlice(p structPointer, f field) *[]bool { - return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// String returns the address of a *string field in the struct. -func structPointer_String(p structPointer, f field) **string { - return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// StringVal returns the address of a string field in the struct. -func structPointer_StringVal(p structPointer, f field) *string { - return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// StringSlice returns the address of a []string field in the struct. -func structPointer_StringSlice(p structPointer, f field) *[]string { - return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// ExtMap returns the address of an extension map field in the struct. -func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions { - return (*XXX_InternalExtensions)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { - return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// NewAt returns the reflect.Value for a pointer to a field in the struct. -func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value { - return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f))) -} - -// SetStructPointer writes a *struct field in the struct. -func structPointer_SetStructPointer(p structPointer, f field, q structPointer) { - *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q -} - -// GetStructPointer reads a *struct field in the struct. -func structPointer_GetStructPointer(p structPointer, f field) structPointer { - return *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// StructPointerSlice the address of a []*struct field in the struct. -func structPointer_StructPointerSlice(p structPointer, f field) *structPointerSlice { - return (*structPointerSlice)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// A structPointerSlice represents a slice of pointers to structs (themselves submessages or groups). -type structPointerSlice []structPointer - -func (v *structPointerSlice) Len() int { return len(*v) } -func (v *structPointerSlice) Index(i int) structPointer { return (*v)[i] } -func (v *structPointerSlice) Append(p structPointer) { *v = append(*v, p) } - -// A word32 is the address of a "pointer to 32-bit value" field. -type word32 **uint32 - -// IsNil reports whether *v is nil. -func word32_IsNil(p word32) bool { - return *p == nil -} - -// Set sets *v to point at a newly allocated word set to x. -func word32_Set(p word32, o *Buffer, x uint32) { - if len(o.uint32s) == 0 { - o.uint32s = make([]uint32, uint32PoolSize) - } - o.uint32s[0] = x - *p = &o.uint32s[0] - o.uint32s = o.uint32s[1:] -} - -// Get gets the value pointed at by *v. -func word32_Get(p word32) uint32 { - return **p -} - -// Word32 returns the address of a *int32, *uint32, *float32, or *enum field in the struct. -func structPointer_Word32(p structPointer, f field) word32 { - return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f)))) -} - -// A word32Val is the address of a 32-bit value field. -type word32Val *uint32 - -// Set sets *p to x. -func word32Val_Set(p word32Val, x uint32) { - *p = x -} - -// Get gets the value pointed at by p. -func word32Val_Get(p word32Val) uint32 { - return *p -} - -// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct. -func structPointer_Word32Val(p structPointer, f field) word32Val { - return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f)))) -} - -// A word32Slice is a slice of 32-bit values. -type word32Slice []uint32 - -func (v *word32Slice) Append(x uint32) { *v = append(*v, x) } -func (v *word32Slice) Len() int { return len(*v) } -func (v *word32Slice) Index(i int) uint32 { return (*v)[i] } - -// Word32Slice returns the address of a []int32, []uint32, []float32, or []enum field in the struct. -func structPointer_Word32Slice(p structPointer, f field) *word32Slice { - return (*word32Slice)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// word64 is like word32 but for 64-bit values. -type word64 **uint64 - -func word64_Set(p word64, o *Buffer, x uint64) { - if len(o.uint64s) == 0 { - o.uint64s = make([]uint64, uint64PoolSize) - } - o.uint64s[0] = x - *p = &o.uint64s[0] - o.uint64s = o.uint64s[1:] -} - -func word64_IsNil(p word64) bool { - return *p == nil -} - -func word64_Get(p word64) uint64 { - return **p -} - -func structPointer_Word64(p structPointer, f field) word64 { - return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f)))) -} - -// word64Val is like word32Val but for 64-bit values. -type word64Val *uint64 - -func word64Val_Set(p word64Val, o *Buffer, x uint64) { - *p = x -} - -func word64Val_Get(p word64Val) uint64 { - return *p -} - -func structPointer_Word64Val(p structPointer, f field) word64Val { - return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f)))) -} - -// word64Slice is like word32Slice but for 64-bit values. -type word64Slice []uint64 - -func (v *word64Slice) Append(x uint64) { *v = append(*v, x) } -func (v *word64Slice) Len() int { return len(*v) } -func (v *word64Slice) Index(i int) uint64 { return (*v)[i] } - -func structPointer_Word64Slice(p structPointer, f field) *word64Slice { - return (*word64Slice)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go b/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go deleted file mode 100644 index f156a29f0..000000000 --- a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go +++ /dev/null @@ -1,128 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build !appengine,!js - -// This file contains the implementation of the proto field accesses using package unsafe. - -package proto - -import ( - "reflect" - "unsafe" -) - -func structPointer_InterfaceAt(p structPointer, f field, t reflect.Type) interface{} { - point := unsafe.Pointer(uintptr(p) + uintptr(f)) - r := reflect.NewAt(t, point) - return r.Interface() -} - -func structPointer_InterfaceRef(p structPointer, f field, t reflect.Type) interface{} { - point := unsafe.Pointer(uintptr(p) + uintptr(f)) - r := reflect.NewAt(t, point) - if r.Elem().IsNil() { - return nil - } - return r.Elem().Interface() -} - -func copyUintPtr(oldptr, newptr uintptr, size int) { - oldbytes := make([]byte, 0) - oldslice := (*reflect.SliceHeader)(unsafe.Pointer(&oldbytes)) - oldslice.Data = oldptr - oldslice.Len = size - oldslice.Cap = size - newbytes := make([]byte, 0) - newslice := (*reflect.SliceHeader)(unsafe.Pointer(&newbytes)) - newslice.Data = newptr - newslice.Len = size - newslice.Cap = size - copy(newbytes, oldbytes) -} - -func structPointer_Copy(oldptr structPointer, newptr structPointer, size int) { - copyUintPtr(uintptr(oldptr), uintptr(newptr), size) -} - -func appendStructPointer(base structPointer, f field, typ reflect.Type) structPointer { - size := typ.Elem().Size() - - oldHeader := structPointer_GetSliceHeader(base, f) - oldSlice := reflect.NewAt(typ, unsafe.Pointer(oldHeader)).Elem() - newLen := oldHeader.Len + 1 - newSlice := reflect.MakeSlice(typ, newLen, newLen) - reflect.Copy(newSlice, oldSlice) - bas := toStructPointer(newSlice) - oldHeader.Data = uintptr(bas) - oldHeader.Len = newLen - oldHeader.Cap = newLen - - return structPointer(unsafe.Pointer(uintptr(unsafe.Pointer(bas)) + uintptr(uintptr(newLen-1)*size))) -} - -func structPointer_FieldPointer(p structPointer, f field) structPointer { - return structPointer(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -func structPointer_GetRefStructPointer(p structPointer, f field) structPointer { - return structPointer((*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f)))) -} - -func structPointer_GetSliceHeader(p structPointer, f field) *reflect.SliceHeader { - return (*reflect.SliceHeader)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -func structPointer_Add(p structPointer, size field) structPointer { - return structPointer(unsafe.Pointer(uintptr(p) + uintptr(size))) -} - -func structPointer_Len(p structPointer, f field) int { - return len(*(*[]interface{})(unsafe.Pointer(structPointer_GetRefStructPointer(p, f)))) -} - -func structPointer_StructRefSlice(p structPointer, f field, size uintptr) *structRefSlice { - return &structRefSlice{p: p, f: f, size: size} -} - -// A structRefSlice represents a slice of structs (themselves submessages or groups). -type structRefSlice struct { - p structPointer - f field - size uintptr -} - -func (v *structRefSlice) Len() int { - return structPointer_Len(v.p, v.f) -} - -func (v *structRefSlice) Index(i int) structPointer { - ss := structPointer_GetStructPointer(v.p, v.f) - ss1 := structPointer_GetRefStructPointer(ss, 0) - return structPointer_Add(ss1, field(uintptr(i)*v.size)) -} diff --git a/vendor/github.com/gogo/protobuf/proto/properties.go b/vendor/github.com/gogo/protobuf/proto/properties.go deleted file mode 100644 index 2a69e8862..000000000 --- a/vendor/github.com/gogo/protobuf/proto/properties.go +++ /dev/null @@ -1,971 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Routines for encoding data into the wire format for protocol buffers. - */ - -import ( - "fmt" - "log" - "os" - "reflect" - "sort" - "strconv" - "strings" - "sync" -) - -const debug bool = false - -// Constants that identify the encoding of a value on the wire. -const ( - WireVarint = 0 - WireFixed64 = 1 - WireBytes = 2 - WireStartGroup = 3 - WireEndGroup = 4 - WireFixed32 = 5 -) - -const startSize = 10 // initial slice/string sizes - -// Encoders are defined in encode.go -// An encoder outputs the full representation of a field, including its -// tag and encoder type. -type encoder func(p *Buffer, prop *Properties, base structPointer) error - -// A valueEncoder encodes a single integer in a particular encoding. -type valueEncoder func(o *Buffer, x uint64) error - -// Sizers are defined in encode.go -// A sizer returns the encoded size of a field, including its tag and encoder -// type. -type sizer func(prop *Properties, base structPointer) int - -// A valueSizer returns the encoded size of a single integer in a particular -// encoding. -type valueSizer func(x uint64) int - -// Decoders are defined in decode.go -// A decoder creates a value from its wire representation. -// Unrecognized subelements are saved in unrec. -type decoder func(p *Buffer, prop *Properties, base structPointer) error - -// A valueDecoder decodes a single integer in a particular encoding. -type valueDecoder func(o *Buffer) (x uint64, err error) - -// A oneofMarshaler does the marshaling for all oneof fields in a message. -type oneofMarshaler func(Message, *Buffer) error - -// A oneofUnmarshaler does the unmarshaling for a oneof field in a message. -type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error) - -// A oneofSizer does the sizing for all oneof fields in a message. -type oneofSizer func(Message) int - -// tagMap is an optimization over map[int]int for typical protocol buffer -// use-cases. Encoded protocol buffers are often in tag order with small tag -// numbers. -type tagMap struct { - fastTags []int - slowTags map[int]int -} - -// tagMapFastLimit is the upper bound on the tag number that will be stored in -// the tagMap slice rather than its map. -const tagMapFastLimit = 1024 - -func (p *tagMap) get(t int) (int, bool) { - if t > 0 && t < tagMapFastLimit { - if t >= len(p.fastTags) { - return 0, false - } - fi := p.fastTags[t] - return fi, fi >= 0 - } - fi, ok := p.slowTags[t] - return fi, ok -} - -func (p *tagMap) put(t int, fi int) { - if t > 0 && t < tagMapFastLimit { - for len(p.fastTags) < t+1 { - p.fastTags = append(p.fastTags, -1) - } - p.fastTags[t] = fi - return - } - if p.slowTags == nil { - p.slowTags = make(map[int]int) - } - p.slowTags[t] = fi -} - -// StructProperties represents properties for all the fields of a struct. -// decoderTags and decoderOrigNames should only be used by the decoder. -type StructProperties struct { - Prop []*Properties // properties for each field - reqCount int // required count - decoderTags tagMap // map from proto tag to struct field number - decoderOrigNames map[string]int // map from original name to struct field number - order []int // list of struct field numbers in tag order - unrecField field // field id of the XXX_unrecognized []byte field - extendable bool // is this an extendable proto - - oneofMarshaler oneofMarshaler - oneofUnmarshaler oneofUnmarshaler - oneofSizer oneofSizer - stype reflect.Type - - // OneofTypes contains information about the oneof fields in this message. - // It is keyed by the original name of a field. - OneofTypes map[string]*OneofProperties -} - -// OneofProperties represents information about a specific field in a oneof. -type OneofProperties struct { - Type reflect.Type // pointer to generated struct type for this oneof field - Field int // struct field number of the containing oneof in the message - Prop *Properties -} - -// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. -// See encode.go, (*Buffer).enc_struct. - -func (sp *StructProperties) Len() int { return len(sp.order) } -func (sp *StructProperties) Less(i, j int) bool { - return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag -} -func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] } - -// Properties represents the protocol-specific behavior of a single struct field. -type Properties struct { - Name string // name of the field, for error messages - OrigName string // original name before protocol compiler (always set) - JSONName string // name to use for JSON; determined by protoc - Wire string - WireType int - Tag int - Required bool - Optional bool - Repeated bool - Packed bool // relevant for repeated primitives only - Enum string // set for enum types only - proto3 bool // whether this is known to be a proto3 field; set for []byte only - oneof bool // whether this is a oneof field - - Default string // default value - HasDefault bool // whether an explicit default was provided - CustomType string - CastType string - StdTime bool - StdDuration bool - - enc encoder - valEnc valueEncoder // set for bool and numeric types only - field field - tagcode []byte // encoding of EncodeVarint((Tag<<3)|WireType) - tagbuf [8]byte - stype reflect.Type // set for struct types only - sstype reflect.Type // set for slices of structs types only - ctype reflect.Type // set for custom types only - sprop *StructProperties // set for struct types only - isMarshaler bool - isUnmarshaler bool - - mtype reflect.Type // set for map types only - mkeyprop *Properties // set for map types only - mvalprop *Properties // set for map types only - - size sizer - valSize valueSizer // set for bool and numeric types only - - dec decoder - valDec valueDecoder // set for bool and numeric types only - - // If this is a packable field, this will be the decoder for the packed version of the field. - packedDec decoder -} - -// String formats the properties in the protobuf struct field tag style. -func (p *Properties) String() string { - s := p.Wire - s = "," - s += strconv.Itoa(p.Tag) - if p.Required { - s += ",req" - } - if p.Optional { - s += ",opt" - } - if p.Repeated { - s += ",rep" - } - if p.Packed { - s += ",packed" - } - s += ",name=" + p.OrigName - if p.JSONName != p.OrigName { - s += ",json=" + p.JSONName - } - if p.proto3 { - s += ",proto3" - } - if p.oneof { - s += ",oneof" - } - if len(p.Enum) > 0 { - s += ",enum=" + p.Enum - } - if p.HasDefault { - s += ",def=" + p.Default - } - return s -} - -// Parse populates p by parsing a string in the protobuf struct field tag style. -func (p *Properties) Parse(s string) { - // "bytes,49,opt,name=foo,def=hello!" - fields := strings.Split(s, ",") // breaks def=, but handled below. - if len(fields) < 2 { - fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s) - return - } - - p.Wire = fields[0] - switch p.Wire { - case "varint": - p.WireType = WireVarint - p.valEnc = (*Buffer).EncodeVarint - p.valDec = (*Buffer).DecodeVarint - p.valSize = sizeVarint - case "fixed32": - p.WireType = WireFixed32 - p.valEnc = (*Buffer).EncodeFixed32 - p.valDec = (*Buffer).DecodeFixed32 - p.valSize = sizeFixed32 - case "fixed64": - p.WireType = WireFixed64 - p.valEnc = (*Buffer).EncodeFixed64 - p.valDec = (*Buffer).DecodeFixed64 - p.valSize = sizeFixed64 - case "zigzag32": - p.WireType = WireVarint - p.valEnc = (*Buffer).EncodeZigzag32 - p.valDec = (*Buffer).DecodeZigzag32 - p.valSize = sizeZigzag32 - case "zigzag64": - p.WireType = WireVarint - p.valEnc = (*Buffer).EncodeZigzag64 - p.valDec = (*Buffer).DecodeZigzag64 - p.valSize = sizeZigzag64 - case "bytes", "group": - p.WireType = WireBytes - // no numeric converter for non-numeric types - default: - fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s) - return - } - - var err error - p.Tag, err = strconv.Atoi(fields[1]) - if err != nil { - return - } - - for i := 2; i < len(fields); i++ { - f := fields[i] - switch { - case f == "req": - p.Required = true - case f == "opt": - p.Optional = true - case f == "rep": - p.Repeated = true - case f == "packed": - p.Packed = true - case strings.HasPrefix(f, "name="): - p.OrigName = f[5:] - case strings.HasPrefix(f, "json="): - p.JSONName = f[5:] - case strings.HasPrefix(f, "enum="): - p.Enum = f[5:] - case f == "proto3": - p.proto3 = true - case f == "oneof": - p.oneof = true - case strings.HasPrefix(f, "def="): - p.HasDefault = true - p.Default = f[4:] // rest of string - if i+1 < len(fields) { - // Commas aren't escaped, and def is always last. - p.Default += "," + strings.Join(fields[i+1:], ",") - break - } - case strings.HasPrefix(f, "embedded="): - p.OrigName = strings.Split(f, "=")[1] - case strings.HasPrefix(f, "customtype="): - p.CustomType = strings.Split(f, "=")[1] - case strings.HasPrefix(f, "casttype="): - p.CastType = strings.Split(f, "=")[1] - case f == "stdtime": - p.StdTime = true - case f == "stdduration": - p.StdDuration = true - } - } -} - -func logNoSliceEnc(t1, t2 reflect.Type) { - fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2) -} - -var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() - -// Initialize the fields for encoding and decoding. -func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { - p.enc = nil - p.dec = nil - p.size = nil - isMap := typ.Kind() == reflect.Map - if len(p.CustomType) > 0 && !isMap { - p.setCustomEncAndDec(typ) - p.setTag(lockGetProp) - return - } - if p.StdTime && !isMap { - p.setTimeEncAndDec(typ) - p.setTag(lockGetProp) - return - } - if p.StdDuration && !isMap { - p.setDurationEncAndDec(typ) - p.setTag(lockGetProp) - return - } - switch t1 := typ; t1.Kind() { - default: - fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1) - - // proto3 scalar types - - case reflect.Bool: - if p.proto3 { - p.enc = (*Buffer).enc_proto3_bool - p.dec = (*Buffer).dec_proto3_bool - p.size = size_proto3_bool - } else { - p.enc = (*Buffer).enc_ref_bool - p.dec = (*Buffer).dec_proto3_bool - p.size = size_ref_bool - } - case reflect.Int32: - if p.proto3 { - p.enc = (*Buffer).enc_proto3_int32 - p.dec = (*Buffer).dec_proto3_int32 - p.size = size_proto3_int32 - } else { - p.enc = (*Buffer).enc_ref_int32 - p.dec = (*Buffer).dec_proto3_int32 - p.size = size_ref_int32 - } - case reflect.Uint32: - if p.proto3 { - p.enc = (*Buffer).enc_proto3_uint32 - p.dec = (*Buffer).dec_proto3_int32 // can reuse - p.size = size_proto3_uint32 - } else { - p.enc = (*Buffer).enc_ref_uint32 - p.dec = (*Buffer).dec_proto3_int32 // can reuse - p.size = size_ref_uint32 - } - case reflect.Int64, reflect.Uint64: - if p.proto3 { - p.enc = (*Buffer).enc_proto3_int64 - p.dec = (*Buffer).dec_proto3_int64 - p.size = size_proto3_int64 - } else { - p.enc = (*Buffer).enc_ref_int64 - p.dec = (*Buffer).dec_proto3_int64 - p.size = size_ref_int64 - } - case reflect.Float32: - if p.proto3 { - p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits - p.dec = (*Buffer).dec_proto3_int32 - p.size = size_proto3_uint32 - } else { - p.enc = (*Buffer).enc_ref_uint32 // can just treat them as bits - p.dec = (*Buffer).dec_proto3_int32 - p.size = size_ref_uint32 - } - case reflect.Float64: - if p.proto3 { - p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits - p.dec = (*Buffer).dec_proto3_int64 - p.size = size_proto3_int64 - } else { - p.enc = (*Buffer).enc_ref_int64 // can just treat them as bits - p.dec = (*Buffer).dec_proto3_int64 - p.size = size_ref_int64 - } - case reflect.String: - if p.proto3 { - p.enc = (*Buffer).enc_proto3_string - p.dec = (*Buffer).dec_proto3_string - p.size = size_proto3_string - } else { - p.enc = (*Buffer).enc_ref_string - p.dec = (*Buffer).dec_proto3_string - p.size = size_ref_string - } - case reflect.Struct: - p.stype = typ - p.isMarshaler = isMarshaler(typ) - p.isUnmarshaler = isUnmarshaler(typ) - if p.Wire == "bytes" { - p.enc = (*Buffer).enc_ref_struct_message - p.dec = (*Buffer).dec_ref_struct_message - p.size = size_ref_struct_message - } else { - fmt.Fprintf(os.Stderr, "proto: no coders for struct %T\n", typ) - } - - case reflect.Ptr: - switch t2 := t1.Elem(); t2.Kind() { - default: - fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2) - break - case reflect.Bool: - p.enc = (*Buffer).enc_bool - p.dec = (*Buffer).dec_bool - p.size = size_bool - case reflect.Int32: - p.enc = (*Buffer).enc_int32 - p.dec = (*Buffer).dec_int32 - p.size = size_int32 - case reflect.Uint32: - p.enc = (*Buffer).enc_uint32 - p.dec = (*Buffer).dec_int32 // can reuse - p.size = size_uint32 - case reflect.Int64, reflect.Uint64: - p.enc = (*Buffer).enc_int64 - p.dec = (*Buffer).dec_int64 - p.size = size_int64 - case reflect.Float32: - p.enc = (*Buffer).enc_uint32 // can just treat them as bits - p.dec = (*Buffer).dec_int32 - p.size = size_uint32 - case reflect.Float64: - p.enc = (*Buffer).enc_int64 // can just treat them as bits - p.dec = (*Buffer).dec_int64 - p.size = size_int64 - case reflect.String: - p.enc = (*Buffer).enc_string - p.dec = (*Buffer).dec_string - p.size = size_string - case reflect.Struct: - p.stype = t1.Elem() - p.isMarshaler = isMarshaler(t1) - p.isUnmarshaler = isUnmarshaler(t1) - if p.Wire == "bytes" { - p.enc = (*Buffer).enc_struct_message - p.dec = (*Buffer).dec_struct_message - p.size = size_struct_message - } else { - p.enc = (*Buffer).enc_struct_group - p.dec = (*Buffer).dec_struct_group - p.size = size_struct_group - } - } - - case reflect.Slice: - switch t2 := t1.Elem(); t2.Kind() { - default: - logNoSliceEnc(t1, t2) - break - case reflect.Bool: - if p.Packed { - p.enc = (*Buffer).enc_slice_packed_bool - p.size = size_slice_packed_bool - } else { - p.enc = (*Buffer).enc_slice_bool - p.size = size_slice_bool - } - p.dec = (*Buffer).dec_slice_bool - p.packedDec = (*Buffer).dec_slice_packed_bool - case reflect.Int32: - if p.Packed { - p.enc = (*Buffer).enc_slice_packed_int32 - p.size = size_slice_packed_int32 - } else { - p.enc = (*Buffer).enc_slice_int32 - p.size = size_slice_int32 - } - p.dec = (*Buffer).dec_slice_int32 - p.packedDec = (*Buffer).dec_slice_packed_int32 - case reflect.Uint32: - if p.Packed { - p.enc = (*Buffer).enc_slice_packed_uint32 - p.size = size_slice_packed_uint32 - } else { - p.enc = (*Buffer).enc_slice_uint32 - p.size = size_slice_uint32 - } - p.dec = (*Buffer).dec_slice_int32 - p.packedDec = (*Buffer).dec_slice_packed_int32 - case reflect.Int64, reflect.Uint64: - if p.Packed { - p.enc = (*Buffer).enc_slice_packed_int64 - p.size = size_slice_packed_int64 - } else { - p.enc = (*Buffer).enc_slice_int64 - p.size = size_slice_int64 - } - p.dec = (*Buffer).dec_slice_int64 - p.packedDec = (*Buffer).dec_slice_packed_int64 - case reflect.Uint8: - p.dec = (*Buffer).dec_slice_byte - if p.proto3 { - p.enc = (*Buffer).enc_proto3_slice_byte - p.size = size_proto3_slice_byte - } else { - p.enc = (*Buffer).enc_slice_byte - p.size = size_slice_byte - } - case reflect.Float32, reflect.Float64: - switch t2.Bits() { - case 32: - // can just treat them as bits - if p.Packed { - p.enc = (*Buffer).enc_slice_packed_uint32 - p.size = size_slice_packed_uint32 - } else { - p.enc = (*Buffer).enc_slice_uint32 - p.size = size_slice_uint32 - } - p.dec = (*Buffer).dec_slice_int32 - p.packedDec = (*Buffer).dec_slice_packed_int32 - case 64: - // can just treat them as bits - if p.Packed { - p.enc = (*Buffer).enc_slice_packed_int64 - p.size = size_slice_packed_int64 - } else { - p.enc = (*Buffer).enc_slice_int64 - p.size = size_slice_int64 - } - p.dec = (*Buffer).dec_slice_int64 - p.packedDec = (*Buffer).dec_slice_packed_int64 - default: - logNoSliceEnc(t1, t2) - break - } - case reflect.String: - p.enc = (*Buffer).enc_slice_string - p.dec = (*Buffer).dec_slice_string - p.size = size_slice_string - case reflect.Ptr: - switch t3 := t2.Elem(); t3.Kind() { - default: - fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3) - break - case reflect.Struct: - p.stype = t2.Elem() - p.isMarshaler = isMarshaler(t2) - p.isUnmarshaler = isUnmarshaler(t2) - if p.Wire == "bytes" { - p.enc = (*Buffer).enc_slice_struct_message - p.dec = (*Buffer).dec_slice_struct_message - p.size = size_slice_struct_message - } else { - p.enc = (*Buffer).enc_slice_struct_group - p.dec = (*Buffer).dec_slice_struct_group - p.size = size_slice_struct_group - } - } - case reflect.Slice: - switch t2.Elem().Kind() { - default: - fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem()) - break - case reflect.Uint8: - p.enc = (*Buffer).enc_slice_slice_byte - p.dec = (*Buffer).dec_slice_slice_byte - p.size = size_slice_slice_byte - } - case reflect.Struct: - p.setSliceOfNonPointerStructs(t1) - } - - case reflect.Map: - p.enc = (*Buffer).enc_new_map - p.dec = (*Buffer).dec_new_map - p.size = size_new_map - - p.mtype = t1 - p.mkeyprop = &Properties{} - p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) - p.mvalprop = &Properties{} - vtype := p.mtype.Elem() - if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { - // The value type is not a message (*T) or bytes ([]byte), - // so we need encoders for the pointer to this type. - vtype = reflect.PtrTo(vtype) - } - - p.mvalprop.CustomType = p.CustomType - p.mvalprop.StdDuration = p.StdDuration - p.mvalprop.StdTime = p.StdTime - p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) - } - p.setTag(lockGetProp) -} - -func (p *Properties) setTag(lockGetProp bool) { - // precalculate tag code - wire := p.WireType - if p.Packed { - wire = WireBytes - } - x := uint32(p.Tag)<<3 | uint32(wire) - i := 0 - for i = 0; x > 127; i++ { - p.tagbuf[i] = 0x80 | uint8(x&0x7F) - x >>= 7 - } - p.tagbuf[i] = uint8(x) - p.tagcode = p.tagbuf[0 : i+1] - - if p.stype != nil { - if lockGetProp { - p.sprop = GetProperties(p.stype) - } else { - p.sprop = getPropertiesLocked(p.stype) - } - } -} - -var ( - marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() - unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() -) - -// isMarshaler reports whether type t implements Marshaler. -func isMarshaler(t reflect.Type) bool { - return t.Implements(marshalerType) -} - -// isUnmarshaler reports whether type t implements Unmarshaler. -func isUnmarshaler(t reflect.Type) bool { - return t.Implements(unmarshalerType) -} - -// Init populates the properties from a protocol buffer struct tag. -func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { - p.init(typ, name, tag, f, true) -} - -func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) { - // "bytes,49,opt,def=hello!" - p.Name = name - p.OrigName = name - if f != nil { - p.field = toField(f) - } - if tag == "" { - return - } - p.Parse(tag) - p.setEncAndDec(typ, f, lockGetProp) -} - -var ( - propertiesMu sync.RWMutex - propertiesMap = make(map[reflect.Type]*StructProperties) -) - -// GetProperties returns the list of properties for the type represented by t. -// t must represent a generated struct type of a protocol message. -func GetProperties(t reflect.Type) *StructProperties { - if t.Kind() != reflect.Struct { - panic("proto: type must have kind struct") - } - - // Most calls to GetProperties in a long-running program will be - // retrieving details for types we have seen before. - propertiesMu.RLock() - sprop, ok := propertiesMap[t] - propertiesMu.RUnlock() - if ok { - if collectStats { - stats.Chit++ - } - return sprop - } - - propertiesMu.Lock() - sprop = getPropertiesLocked(t) - propertiesMu.Unlock() - return sprop -} - -// getPropertiesLocked requires that propertiesMu is held. -func getPropertiesLocked(t reflect.Type) *StructProperties { - if prop, ok := propertiesMap[t]; ok { - if collectStats { - stats.Chit++ - } - return prop - } - if collectStats { - stats.Cmiss++ - } - - prop := new(StructProperties) - // in case of recursive protos, fill this in now. - propertiesMap[t] = prop - - // build properties - prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) || - reflect.PtrTo(t).Implements(extendableProtoV1Type) || - reflect.PtrTo(t).Implements(extendableBytesType) - prop.unrecField = invalidField - prop.Prop = make([]*Properties, t.NumField()) - prop.order = make([]int, t.NumField()) - - isOneofMessage := false - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - p := new(Properties) - name := f.Name - p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false) - - if f.Name == "XXX_InternalExtensions" { // special case - p.enc = (*Buffer).enc_exts - p.dec = nil // not needed - p.size = size_exts - } else if f.Name == "XXX_extensions" { // special case - if len(f.Tag.Get("protobuf")) > 0 { - p.enc = (*Buffer).enc_ext_slice_byte - p.dec = nil // not needed - p.size = size_ext_slice_byte - } else { - p.enc = (*Buffer).enc_map - p.dec = nil // not needed - p.size = size_map - } - } else if f.Name == "XXX_unrecognized" { // special case - prop.unrecField = toField(&f) - } - oneof := f.Tag.Get("protobuf_oneof") // special case - if oneof != "" { - isOneofMessage = true - // Oneof fields don't use the traditional protobuf tag. - p.OrigName = oneof - } - prop.Prop[i] = p - prop.order[i] = i - if debug { - print(i, " ", f.Name, " ", t.String(), " ") - if p.Tag > 0 { - print(p.String()) - } - print("\n") - } - if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && oneof == "" { - fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]") - } - } - - // Re-order prop.order. - sort.Sort(prop) - - type oneofMessage interface { - XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) - } - if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); isOneofMessage && ok { - var oots []interface{} - prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs() - prop.stype = t - - // Interpret oneof metadata. - prop.OneofTypes = make(map[string]*OneofProperties) - for _, oot := range oots { - oop := &OneofProperties{ - Type: reflect.ValueOf(oot).Type(), // *T - Prop: new(Properties), - } - sft := oop.Type.Elem().Field(0) - oop.Prop.Name = sft.Name - oop.Prop.Parse(sft.Tag.Get("protobuf")) - // There will be exactly one interface field that - // this new value is assignable to. - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - if f.Type.Kind() != reflect.Interface { - continue - } - if !oop.Type.AssignableTo(f.Type) { - continue - } - oop.Field = i - break - } - prop.OneofTypes[oop.Prop.OrigName] = oop - } - } - - // build required counts - // build tags - reqCount := 0 - prop.decoderOrigNames = make(map[string]int) - for i, p := range prop.Prop { - if strings.HasPrefix(p.Name, "XXX_") { - // Internal fields should not appear in tags/origNames maps. - // They are handled specially when encoding and decoding. - continue - } - if p.Required { - reqCount++ - } - prop.decoderTags.put(p.Tag, i) - prop.decoderOrigNames[p.OrigName] = i - } - prop.reqCount = reqCount - - return prop -} - -// Return the Properties object for the x[0]'th field of the structure. -func propByIndex(t reflect.Type, x []int) *Properties { - if len(x) != 1 { - fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t) - return nil - } - prop := GetProperties(t) - return prop.Prop[x[0]] -} - -// Get the address and type of a pointer to a struct from an interface. -func getbase(pb Message) (t reflect.Type, b structPointer, err error) { - if pb == nil { - err = ErrNil - return - } - // get the reflect type of the pointer to the struct. - t = reflect.TypeOf(pb) - // get the address of the struct. - value := reflect.ValueOf(pb) - b = toStructPointer(value) - return -} - -// A global registry of enum types. -// The generated code will register the generated maps by calling RegisterEnum. - -var enumValueMaps = make(map[string]map[string]int32) -var enumStringMaps = make(map[string]map[int32]string) - -// RegisterEnum is called from the generated code to install the enum descriptor -// maps into the global table to aid parsing text format protocol buffers. -func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) { - if _, ok := enumValueMaps[typeName]; ok { - panic("proto: duplicate enum registered: " + typeName) - } - enumValueMaps[typeName] = valueMap - if _, ok := enumStringMaps[typeName]; ok { - panic("proto: duplicate enum registered: " + typeName) - } - enumStringMaps[typeName] = unusedNameMap -} - -// EnumValueMap returns the mapping from names to integers of the -// enum type enumType, or a nil if not found. -func EnumValueMap(enumType string) map[string]int32 { - return enumValueMaps[enumType] -} - -// A registry of all linked message types. -// The string is a fully-qualified proto name ("pkg.Message"). -var ( - protoTypes = make(map[string]reflect.Type) - revProtoTypes = make(map[reflect.Type]string) -) - -// RegisterType is called from generated code and maps from the fully qualified -// proto name to the type (pointer to struct) of the protocol buffer. -func RegisterType(x Message, name string) { - if _, ok := protoTypes[name]; ok { - // TODO: Some day, make this a panic. - log.Printf("proto: duplicate proto type registered: %s", name) - return - } - t := reflect.TypeOf(x) - protoTypes[name] = t - revProtoTypes[t] = name -} - -// MessageName returns the fully-qualified proto name for the given message type. -func MessageName(x Message) string { - type xname interface { - XXX_MessageName() string - } - if m, ok := x.(xname); ok { - return m.XXX_MessageName() - } - return revProtoTypes[reflect.TypeOf(x)] -} - -// MessageType returns the message type (pointer to struct) for a named message. -func MessageType(name string) reflect.Type { return protoTypes[name] } - -// A registry of all linked proto files. -var ( - protoFiles = make(map[string][]byte) // file name => fileDescriptor -) - -// RegisterFile is called from generated code and maps from the -// full file name of a .proto file to its compressed FileDescriptorProto. -func RegisterFile(filename string, fileDescriptor []byte) { - protoFiles[filename] = fileDescriptor -} - -// FileDescriptor returns the compressed FileDescriptorProto for a .proto file. -func FileDescriptor(filename string) []byte { return protoFiles[filename] } diff --git a/vendor/github.com/gogo/protobuf/proto/properties_gogo.go b/vendor/github.com/gogo/protobuf/proto/properties_gogo.go deleted file mode 100644 index b6b7176c5..000000000 --- a/vendor/github.com/gogo/protobuf/proto/properties_gogo.go +++ /dev/null @@ -1,111 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "os" - "reflect" -) - -func (p *Properties) setCustomEncAndDec(typ reflect.Type) { - p.ctype = typ - if p.Repeated { - p.enc = (*Buffer).enc_custom_slice_bytes - p.dec = (*Buffer).dec_custom_slice_bytes - p.size = size_custom_slice_bytes - } else if typ.Kind() == reflect.Ptr { - p.enc = (*Buffer).enc_custom_bytes - p.dec = (*Buffer).dec_custom_bytes - p.size = size_custom_bytes - } else { - p.enc = (*Buffer).enc_custom_ref_bytes - p.dec = (*Buffer).dec_custom_ref_bytes - p.size = size_custom_ref_bytes - } -} - -func (p *Properties) setDurationEncAndDec(typ reflect.Type) { - if p.Repeated { - if typ.Elem().Kind() == reflect.Ptr { - p.enc = (*Buffer).enc_slice_duration - p.dec = (*Buffer).dec_slice_duration - p.size = size_slice_duration - } else { - p.enc = (*Buffer).enc_slice_ref_duration - p.dec = (*Buffer).dec_slice_ref_duration - p.size = size_slice_ref_duration - } - } else if typ.Kind() == reflect.Ptr { - p.enc = (*Buffer).enc_duration - p.dec = (*Buffer).dec_duration - p.size = size_duration - } else { - p.enc = (*Buffer).enc_ref_duration - p.dec = (*Buffer).dec_ref_duration - p.size = size_ref_duration - } -} - -func (p *Properties) setTimeEncAndDec(typ reflect.Type) { - if p.Repeated { - if typ.Elem().Kind() == reflect.Ptr { - p.enc = (*Buffer).enc_slice_time - p.dec = (*Buffer).dec_slice_time - p.size = size_slice_time - } else { - p.enc = (*Buffer).enc_slice_ref_time - p.dec = (*Buffer).dec_slice_ref_time - p.size = size_slice_ref_time - } - } else if typ.Kind() == reflect.Ptr { - p.enc = (*Buffer).enc_time - p.dec = (*Buffer).dec_time - p.size = size_time - } else { - p.enc = (*Buffer).enc_ref_time - p.dec = (*Buffer).dec_ref_time - p.size = size_ref_time - } - -} - -func (p *Properties) setSliceOfNonPointerStructs(typ reflect.Type) { - t2 := typ.Elem() - p.sstype = typ - p.stype = t2 - p.isMarshaler = isMarshaler(t2) - p.isUnmarshaler = isUnmarshaler(t2) - p.enc = (*Buffer).enc_slice_ref_struct_message - p.dec = (*Buffer).dec_slice_ref_struct_message - p.size = size_slice_ref_struct_message - if p.Wire != "bytes" { - fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T \n", typ, t2) - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/skip_gogo.go b/vendor/github.com/gogo/protobuf/proto/skip_gogo.go deleted file mode 100644 index 5a5fd93f7..000000000 --- a/vendor/github.com/gogo/protobuf/proto/skip_gogo.go +++ /dev/null @@ -1,119 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "io" -) - -func Skip(data []byte) (n int, err error) { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return 0, io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for { - if index >= l { - return 0, io.ErrUnexpectedEOF - } - index++ - if data[index-1] < 0x80 { - break - } - } - return index, nil - case 1: - index += 8 - return index, nil - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if index >= l { - return 0, io.ErrUnexpectedEOF - } - b := data[index] - index++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - index += length - return index, nil - case 3: - for { - var innerWire uint64 - var start int = index - for shift := uint(0); ; shift += 7 { - if index >= l { - return 0, io.ErrUnexpectedEOF - } - b := data[index] - index++ - innerWire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - innerWireType := int(innerWire & 0x7) - if innerWireType == 4 { - break - } - next, err := Skip(data[start:]) - if err != nil { - return 0, err - } - index = start + next - } - return index, nil - case 4: - return index, nil - case 5: - index += 4 - return index, nil - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - } - panic("unreachable") -} diff --git a/vendor/github.com/gogo/protobuf/proto/text.go b/vendor/github.com/gogo/protobuf/proto/text.go deleted file mode 100644 index f609d1d45..000000000 --- a/vendor/github.com/gogo/protobuf/proto/text.go +++ /dev/null @@ -1,939 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// Functions for writing the text protocol buffer format. - -import ( - "bufio" - "bytes" - "encoding" - "errors" - "fmt" - "io" - "log" - "math" - "reflect" - "sort" - "strings" - "sync" - "time" -) - -var ( - newline = []byte("\n") - spaces = []byte(" ") - gtNewline = []byte(">\n") - endBraceNewline = []byte("}\n") - backslashN = []byte{'\\', 'n'} - backslashR = []byte{'\\', 'r'} - backslashT = []byte{'\\', 't'} - backslashDQ = []byte{'\\', '"'} - backslashBS = []byte{'\\', '\\'} - posInf = []byte("inf") - negInf = []byte("-inf") - nan = []byte("nan") -) - -type writer interface { - io.Writer - WriteByte(byte) error -} - -// textWriter is an io.Writer that tracks its indentation level. -type textWriter struct { - ind int - complete bool // if the current position is a complete line - compact bool // whether to write out as a one-liner - w writer -} - -func (w *textWriter) WriteString(s string) (n int, err error) { - if !strings.Contains(s, "\n") { - if !w.compact && w.complete { - w.writeIndent() - } - w.complete = false - return io.WriteString(w.w, s) - } - // WriteString is typically called without newlines, so this - // codepath and its copy are rare. We copy to avoid - // duplicating all of Write's logic here. - return w.Write([]byte(s)) -} - -func (w *textWriter) Write(p []byte) (n int, err error) { - newlines := bytes.Count(p, newline) - if newlines == 0 { - if !w.compact && w.complete { - w.writeIndent() - } - n, err = w.w.Write(p) - w.complete = false - return n, err - } - - frags := bytes.SplitN(p, newline, newlines+1) - if w.compact { - for i, frag := range frags { - if i > 0 { - if err := w.w.WriteByte(' '); err != nil { - return n, err - } - n++ - } - nn, err := w.w.Write(frag) - n += nn - if err != nil { - return n, err - } - } - return n, nil - } - - for i, frag := range frags { - if w.complete { - w.writeIndent() - } - nn, err := w.w.Write(frag) - n += nn - if err != nil { - return n, err - } - if i+1 < len(frags) { - if err := w.w.WriteByte('\n'); err != nil { - return n, err - } - n++ - } - } - w.complete = len(frags[len(frags)-1]) == 0 - return n, nil -} - -func (w *textWriter) WriteByte(c byte) error { - if w.compact && c == '\n' { - c = ' ' - } - if !w.compact && w.complete { - w.writeIndent() - } - err := w.w.WriteByte(c) - w.complete = c == '\n' - return err -} - -func (w *textWriter) indent() { w.ind++ } - -func (w *textWriter) unindent() { - if w.ind == 0 { - log.Print("proto: textWriter unindented too far") - return - } - w.ind-- -} - -func writeName(w *textWriter, props *Properties) error { - if _, err := w.WriteString(props.OrigName); err != nil { - return err - } - if props.Wire != "group" { - return w.WriteByte(':') - } - return nil -} - -// raw is the interface satisfied by RawMessage. -type raw interface { - Bytes() []byte -} - -func requiresQuotes(u string) bool { - // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted. - for _, ch := range u { - switch { - case ch == '.' || ch == '/' || ch == '_': - continue - case '0' <= ch && ch <= '9': - continue - case 'A' <= ch && ch <= 'Z': - continue - case 'a' <= ch && ch <= 'z': - continue - default: - return true - } - } - return false -} - -// isAny reports whether sv is a google.protobuf.Any message -func isAny(sv reflect.Value) bool { - type wkt interface { - XXX_WellKnownType() string - } - t, ok := sv.Addr().Interface().(wkt) - return ok && t.XXX_WellKnownType() == "Any" -} - -// writeProto3Any writes an expanded google.protobuf.Any message. -// -// It returns (false, nil) if sv value can't be unmarshaled (e.g. because -// required messages are not linked in). -// -// It returns (true, error) when sv was written in expanded format or an error -// was encountered. -func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) { - turl := sv.FieldByName("TypeUrl") - val := sv.FieldByName("Value") - if !turl.IsValid() || !val.IsValid() { - return true, errors.New("proto: invalid google.protobuf.Any message") - } - - b, ok := val.Interface().([]byte) - if !ok { - return true, errors.New("proto: invalid google.protobuf.Any message") - } - - parts := strings.Split(turl.String(), "/") - mt := MessageType(parts[len(parts)-1]) - if mt == nil { - return false, nil - } - m := reflect.New(mt.Elem()) - if err := Unmarshal(b, m.Interface().(Message)); err != nil { - return false, nil - } - w.Write([]byte("[")) - u := turl.String() - if requiresQuotes(u) { - writeString(w, u) - } else { - w.Write([]byte(u)) - } - if w.compact { - w.Write([]byte("]:<")) - } else { - w.Write([]byte("]: <\n")) - w.ind++ - } - if err := tm.writeStruct(w, m.Elem()); err != nil { - return true, err - } - if w.compact { - w.Write([]byte("> ")) - } else { - w.ind-- - w.Write([]byte(">\n")) - } - return true, nil -} - -func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error { - if tm.ExpandAny && isAny(sv) { - if canExpand, err := tm.writeProto3Any(w, sv); canExpand { - return err - } - } - st := sv.Type() - sprops := GetProperties(st) - for i := 0; i < sv.NumField(); i++ { - fv := sv.Field(i) - props := sprops.Prop[i] - name := st.Field(i).Name - - if strings.HasPrefix(name, "XXX_") { - // There are two XXX_ fields: - // XXX_unrecognized []byte - // XXX_extensions map[int32]proto.Extension - // The first is handled here; - // the second is handled at the bottom of this function. - if name == "XXX_unrecognized" && !fv.IsNil() { - if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil { - return err - } - } - continue - } - if fv.Kind() == reflect.Ptr && fv.IsNil() { - // Field not filled in. This could be an optional field or - // a required field that wasn't filled in. Either way, there - // isn't anything we can show for it. - continue - } - if fv.Kind() == reflect.Slice && fv.IsNil() { - // Repeated field that is empty, or a bytes field that is unused. - continue - } - - if props.Repeated && fv.Kind() == reflect.Slice { - // Repeated field. - for j := 0; j < fv.Len(); j++ { - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - v := fv.Index(j) - if v.Kind() == reflect.Ptr && v.IsNil() { - // A nil message in a repeated field is not valid, - // but we can handle that more gracefully than panicking. - if _, err := w.Write([]byte("\n")); err != nil { - return err - } - continue - } - if len(props.Enum) > 0 { - if err := tm.writeEnum(w, v, props); err != nil { - return err - } - } else if err := tm.writeAny(w, v, props); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - continue - } - if fv.Kind() == reflect.Map { - // Map fields are rendered as a repeated struct with key/value fields. - keys := fv.MapKeys() - sort.Sort(mapKeys(keys)) - for _, key := range keys { - val := fv.MapIndex(key) - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - // open struct - if err := w.WriteByte('<'); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte('\n'); err != nil { - return err - } - } - w.indent() - // key - if _, err := w.WriteString("key:"); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, key, props.mkeyprop); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - // nil values aren't legal, but we can avoid panicking because of them. - if val.Kind() != reflect.Ptr || !val.IsNil() { - // value - if _, err := w.WriteString("value:"); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, val, props.mvalprop); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - // close struct - w.unindent() - if err := w.WriteByte('>'); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - continue - } - if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 { - // empty bytes field - continue - } - if props.proto3 && fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice { - // proto3 non-repeated scalar field; skip if zero value - if isProto3Zero(fv) { - continue - } - } - - if fv.Kind() == reflect.Interface { - // Check if it is a oneof. - if st.Field(i).Tag.Get("protobuf_oneof") != "" { - // fv is nil, or holds a pointer to generated struct. - // That generated struct has exactly one field, - // which has a protobuf struct tag. - if fv.IsNil() { - continue - } - inner := fv.Elem().Elem() // interface -> *T -> T - tag := inner.Type().Field(0).Tag.Get("protobuf") - props = new(Properties) // Overwrite the outer props var, but not its pointee. - props.Parse(tag) - // Write the value in the oneof, not the oneof itself. - fv = inner.Field(0) - - // Special case to cope with malformed messages gracefully: - // If the value in the oneof is a nil pointer, don't panic - // in writeAny. - if fv.Kind() == reflect.Ptr && fv.IsNil() { - // Use errors.New so writeAny won't render quotes. - msg := errors.New("/* nil */") - fv = reflect.ValueOf(&msg).Elem() - } - } - } - - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if b, ok := fv.Interface().(raw); ok { - if err := writeRaw(w, b.Bytes()); err != nil { - return err - } - continue - } - - if len(props.Enum) > 0 { - if err := tm.writeEnum(w, fv, props); err != nil { - return err - } - } else if err := tm.writeAny(w, fv, props); err != nil { - return err - } - - if err := w.WriteByte('\n'); err != nil { - return err - } - } - - // Extensions (the XXX_extensions field). - pv := sv - if pv.CanAddr() { - pv = sv.Addr() - } else { - pv = reflect.New(sv.Type()) - pv.Elem().Set(sv) - } - if pv.Type().Implements(extensionRangeType) { - if err := tm.writeExtensions(w, pv); err != nil { - return err - } - } - - return nil -} - -// writeRaw writes an uninterpreted raw message. -func writeRaw(w *textWriter, b []byte) error { - if err := w.WriteByte('<'); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte('\n'); err != nil { - return err - } - } - w.indent() - if err := writeUnknownStruct(w, b); err != nil { - return err - } - w.unindent() - if err := w.WriteByte('>'); err != nil { - return err - } - return nil -} - -// writeAny writes an arbitrary field. -func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error { - v = reflect.Indirect(v) - - if props != nil { - if len(props.CustomType) > 0 { - custom, ok := v.Interface().(Marshaler) - if ok { - data, err := custom.Marshal() - if err != nil { - return err - } - if err := writeString(w, string(data)); err != nil { - return err - } - return nil - } - } else if len(props.CastType) > 0 { - if _, ok := v.Interface().(interface { - String() string - }); ok { - switch v.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - _, err := fmt.Fprintf(w, "%d", v.Interface()) - return err - } - } - } else if props.StdTime { - t, ok := v.Interface().(time.Time) - if !ok { - return fmt.Errorf("stdtime is not time.Time, but %T", v.Interface()) - } - tproto, err := timestampProto(t) - if err != nil { - return err - } - propsCopy := *props // Make a copy so that this is goroutine-safe - propsCopy.StdTime = false - err = tm.writeAny(w, reflect.ValueOf(tproto), &propsCopy) - return err - } else if props.StdDuration { - d, ok := v.Interface().(time.Duration) - if !ok { - return fmt.Errorf("stdtime is not time.Duration, but %T", v.Interface()) - } - dproto := durationProto(d) - propsCopy := *props // Make a copy so that this is goroutine-safe - propsCopy.StdDuration = false - err := tm.writeAny(w, reflect.ValueOf(dproto), &propsCopy) - return err - } - } - - // Floats have special cases. - if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { - x := v.Float() - var b []byte - switch { - case math.IsInf(x, 1): - b = posInf - case math.IsInf(x, -1): - b = negInf - case math.IsNaN(x): - b = nan - } - if b != nil { - _, err := w.Write(b) - return err - } - // Other values are handled below. - } - - // We don't attempt to serialise every possible value type; only those - // that can occur in protocol buffers. - switch v.Kind() { - case reflect.Slice: - // Should only be a []byte; repeated fields are handled in writeStruct. - if err := writeString(w, string(v.Bytes())); err != nil { - return err - } - case reflect.String: - if err := writeString(w, v.String()); err != nil { - return err - } - case reflect.Struct: - // Required/optional group/message. - var bra, ket byte = '<', '>' - if props != nil && props.Wire == "group" { - bra, ket = '{', '}' - } - if err := w.WriteByte(bra); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte('\n'); err != nil { - return err - } - } - w.indent() - if etm, ok := v.Interface().(encoding.TextMarshaler); ok { - text, err := etm.MarshalText() - if err != nil { - return err - } - if _, err = w.Write(text); err != nil { - return err - } - } else if err := tm.writeStruct(w, v); err != nil { - return err - } - w.unindent() - if err := w.WriteByte(ket); err != nil { - return err - } - default: - _, err := fmt.Fprint(w, v.Interface()) - return err - } - return nil -} - -// equivalent to C's isprint. -func isprint(c byte) bool { - return c >= 0x20 && c < 0x7f -} - -// writeString writes a string in the protocol buffer text format. -// It is similar to strconv.Quote except we don't use Go escape sequences, -// we treat the string as a byte sequence, and we use octal escapes. -// These differences are to maintain interoperability with the other -// languages' implementations of the text format. -func writeString(w *textWriter, s string) error { - // use WriteByte here to get any needed indent - if err := w.WriteByte('"'); err != nil { - return err - } - // Loop over the bytes, not the runes. - for i := 0; i < len(s); i++ { - var err error - // Divergence from C++: we don't escape apostrophes. - // There's no need to escape them, and the C++ parser - // copes with a naked apostrophe. - switch c := s[i]; c { - case '\n': - _, err = w.w.Write(backslashN) - case '\r': - _, err = w.w.Write(backslashR) - case '\t': - _, err = w.w.Write(backslashT) - case '"': - _, err = w.w.Write(backslashDQ) - case '\\': - _, err = w.w.Write(backslashBS) - default: - if isprint(c) { - err = w.w.WriteByte(c) - } else { - _, err = fmt.Fprintf(w.w, "\\%03o", c) - } - } - if err != nil { - return err - } - } - return w.WriteByte('"') -} - -func writeUnknownStruct(w *textWriter, data []byte) (err error) { - if !w.compact { - if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil { - return err - } - } - b := NewBuffer(data) - for b.index < len(b.buf) { - x, err := b.DecodeVarint() - if err != nil { - _, ferr := fmt.Fprintf(w, "/* %v */\n", err) - return ferr - } - wire, tag := x&7, x>>3 - if wire == WireEndGroup { - w.unindent() - if _, werr := w.Write(endBraceNewline); werr != nil { - return werr - } - continue - } - if _, ferr := fmt.Fprint(w, tag); ferr != nil { - return ferr - } - if wire != WireStartGroup { - if err = w.WriteByte(':'); err != nil { - return err - } - } - if !w.compact || wire == WireStartGroup { - if err = w.WriteByte(' '); err != nil { - return err - } - } - switch wire { - case WireBytes: - buf, e := b.DecodeRawBytes(false) - if e == nil { - _, err = fmt.Fprintf(w, "%q", buf) - } else { - _, err = fmt.Fprintf(w, "/* %v */", e) - } - case WireFixed32: - x, err = b.DecodeFixed32() - err = writeUnknownInt(w, x, err) - case WireFixed64: - x, err = b.DecodeFixed64() - err = writeUnknownInt(w, x, err) - case WireStartGroup: - err = w.WriteByte('{') - w.indent() - case WireVarint: - x, err = b.DecodeVarint() - err = writeUnknownInt(w, x, err) - default: - _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire) - } - if err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - return nil -} - -func writeUnknownInt(w *textWriter, x uint64, err error) error { - if err == nil { - _, err = fmt.Fprint(w, x) - } else { - _, err = fmt.Fprintf(w, "/* %v */", err) - } - return err -} - -type int32Slice []int32 - -func (s int32Slice) Len() int { return len(s) } -func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } -func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// writeExtensions writes all the extensions in pv. -// pv is assumed to be a pointer to a protocol message struct that is extendable. -func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error { - emap := extensionMaps[pv.Type().Elem()] - e := pv.Interface().(Message) - - var m map[int32]Extension - var mu sync.Locker - if em, ok := e.(extensionsBytes); ok { - eb := em.GetExtensions() - var err error - m, err = BytesToExtensionsMap(*eb) - if err != nil { - return err - } - mu = notLocker{} - } else if _, ok := e.(extendableProto); ok { - ep, _ := extendable(e) - m, mu = ep.extensionsRead() - if m == nil { - return nil - } - } - - // Order the extensions by ID. - // This isn't strictly necessary, but it will give us - // canonical output, which will also make testing easier. - - mu.Lock() - ids := make([]int32, 0, len(m)) - for id := range m { - ids = append(ids, id) - } - sort.Sort(int32Slice(ids)) - mu.Unlock() - - for _, extNum := range ids { - ext := m[extNum] - var desc *ExtensionDesc - if emap != nil { - desc = emap[extNum] - } - if desc == nil { - // Unknown extension. - if err := writeUnknownStruct(w, ext.enc); err != nil { - return err - } - continue - } - - pb, err := GetExtension(e, desc) - if err != nil { - return fmt.Errorf("failed getting extension: %v", err) - } - - // Repeated extensions will appear as a slice. - if !desc.repeated() { - if err := tm.writeExtension(w, desc.Name, pb); err != nil { - return err - } - } else { - v := reflect.ValueOf(pb) - for i := 0; i < v.Len(); i++ { - if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { - return err - } - } - } - } - return nil -} - -func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error { - if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - return nil -} - -func (w *textWriter) writeIndent() { - if !w.complete { - return - } - remain := w.ind * 2 - for remain > 0 { - n := remain - if n > len(spaces) { - n = len(spaces) - } - w.w.Write(spaces[:n]) - remain -= n - } - w.complete = false -} - -// TextMarshaler is a configurable text format marshaler. -type TextMarshaler struct { - Compact bool // use compact text format (one line). - ExpandAny bool // expand google.protobuf.Any messages of known types -} - -// Marshal writes a given protocol buffer in text format. -// The only errors returned are from w. -func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error { - val := reflect.ValueOf(pb) - if pb == nil || val.IsNil() { - w.Write([]byte("")) - return nil - } - var bw *bufio.Writer - ww, ok := w.(writer) - if !ok { - bw = bufio.NewWriter(w) - ww = bw - } - aw := &textWriter{ - w: ww, - complete: true, - compact: tm.Compact, - } - - if etm, ok := pb.(encoding.TextMarshaler); ok { - text, err := etm.MarshalText() - if err != nil { - return err - } - if _, err = aw.Write(text); err != nil { - return err - } - if bw != nil { - return bw.Flush() - } - return nil - } - // Dereference the received pointer so we don't have outer < and >. - v := reflect.Indirect(val) - if err := tm.writeStruct(aw, v); err != nil { - return err - } - if bw != nil { - return bw.Flush() - } - return nil -} - -// Text is the same as Marshal, but returns the string directly. -func (tm *TextMarshaler) Text(pb Message) string { - var buf bytes.Buffer - tm.Marshal(&buf, pb) - return buf.String() -} - -var ( - defaultTextMarshaler = TextMarshaler{} - compactTextMarshaler = TextMarshaler{Compact: true} -) - -// TODO: consider removing some of the Marshal functions below. - -// MarshalText writes a given protocol buffer in text format. -// The only errors returned are from w. -func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) } - -// MarshalTextString is the same as MarshalText, but returns the string directly. -func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) } - -// CompactText writes a given protocol buffer in compact text format (one line). -func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) } - -// CompactTextString is the same as CompactText, but returns the string directly. -func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) } diff --git a/vendor/github.com/gogo/protobuf/proto/text_gogo.go b/vendor/github.com/gogo/protobuf/proto/text_gogo.go deleted file mode 100644 index 1d6c6aa0e..000000000 --- a/vendor/github.com/gogo/protobuf/proto/text_gogo.go +++ /dev/null @@ -1,57 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "reflect" -) - -func (tm *TextMarshaler) writeEnum(w *textWriter, v reflect.Value, props *Properties) error { - m, ok := enumStringMaps[props.Enum] - if !ok { - if err := tm.writeAny(w, v, props); err != nil { - return err - } - } - key := int32(0) - if v.Kind() == reflect.Ptr { - key = int32(v.Elem().Int()) - } else { - key = int32(v.Int()) - } - s, ok := m[key] - if !ok { - if err := tm.writeAny(w, v, props); err != nil { - return err - } - } - _, err := fmt.Fprint(w, s) - return err -} diff --git a/vendor/github.com/gogo/protobuf/proto/text_parser.go b/vendor/github.com/gogo/protobuf/proto/text_parser.go deleted file mode 100644 index f1276729a..000000000 --- a/vendor/github.com/gogo/protobuf/proto/text_parser.go +++ /dev/null @@ -1,1013 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// Functions for parsing the Text protocol buffer format. -// TODO: message sets. - -import ( - "encoding" - "errors" - "fmt" - "reflect" - "strconv" - "strings" - "time" - "unicode/utf8" -) - -// Error string emitted when deserializing Any and fields are already set -const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set" - -type ParseError struct { - Message string - Line int // 1-based line number - Offset int // 0-based byte offset from start of input -} - -func (p *ParseError) Error() string { - if p.Line == 1 { - // show offset only for first line - return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message) - } - return fmt.Sprintf("line %d: %v", p.Line, p.Message) -} - -type token struct { - value string - err *ParseError - line int // line number - offset int // byte number from start of input, not start of line - unquoted string // the unquoted version of value, if it was a quoted string -} - -func (t *token) String() string { - if t.err == nil { - return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset) - } - return fmt.Sprintf("parse error: %v", t.err) -} - -type textParser struct { - s string // remaining input - done bool // whether the parsing is finished (success or error) - backed bool // whether back() was called - offset, line int - cur token -} - -func newTextParser(s string) *textParser { - p := new(textParser) - p.s = s - p.line = 1 - p.cur.line = 1 - return p -} - -func (p *textParser) errorf(format string, a ...interface{}) *ParseError { - pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset} - p.cur.err = pe - p.done = true - return pe -} - -// Numbers and identifiers are matched by [-+._A-Za-z0-9] -func isIdentOrNumberChar(c byte) bool { - switch { - case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z': - return true - case '0' <= c && c <= '9': - return true - } - switch c { - case '-', '+', '.', '_': - return true - } - return false -} - -func isWhitespace(c byte) bool { - switch c { - case ' ', '\t', '\n', '\r': - return true - } - return false -} - -func isQuote(c byte) bool { - switch c { - case '"', '\'': - return true - } - return false -} - -func (p *textParser) skipWhitespace() { - i := 0 - for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { - if p.s[i] == '#' { - // comment; skip to end of line or input - for i < len(p.s) && p.s[i] != '\n' { - i++ - } - if i == len(p.s) { - break - } - } - if p.s[i] == '\n' { - p.line++ - } - i++ - } - p.offset += i - p.s = p.s[i:len(p.s)] - if len(p.s) == 0 { - p.done = true - } -} - -func (p *textParser) advance() { - // Skip whitespace - p.skipWhitespace() - if p.done { - return - } - - // Start of non-whitespace - p.cur.err = nil - p.cur.offset, p.cur.line = p.offset, p.line - p.cur.unquoted = "" - switch p.s[0] { - case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/': - // Single symbol - p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] - case '"', '\'': - // Quoted string - i := 1 - for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { - if p.s[i] == '\\' && i+1 < len(p.s) { - // skip escaped char - i++ - } - i++ - } - if i >= len(p.s) || p.s[i] != p.s[0] { - p.errorf("unmatched quote") - return - } - unq, err := unquoteC(p.s[1:i], rune(p.s[0])) - if err != nil { - p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) - return - } - p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] - p.cur.unquoted = unq - default: - i := 0 - for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { - i++ - } - if i == 0 { - p.errorf("unexpected byte %#x", p.s[0]) - return - } - p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] - } - p.offset += len(p.cur.value) -} - -var ( - errBadUTF8 = errors.New("proto: bad UTF-8") - errBadHex = errors.New("proto: bad hexadecimal") -) - -func unquoteC(s string, quote rune) (string, error) { - // This is based on C++'s tokenizer.cc. - // Despite its name, this is *not* parsing C syntax. - // For instance, "\0" is an invalid quoted string. - - // Avoid allocation in trivial cases. - simple := true - for _, r := range s { - if r == '\\' || r == quote { - simple = false - break - } - } - if simple { - return s, nil - } - - buf := make([]byte, 0, 3*len(s)/2) - for len(s) > 0 { - r, n := utf8.DecodeRuneInString(s) - if r == utf8.RuneError && n == 1 { - return "", errBadUTF8 - } - s = s[n:] - if r != '\\' { - if r < utf8.RuneSelf { - buf = append(buf, byte(r)) - } else { - buf = append(buf, string(r)...) - } - continue - } - - ch, tail, err := unescape(s) - if err != nil { - return "", err - } - buf = append(buf, ch...) - s = tail - } - return string(buf), nil -} - -func unescape(s string) (ch string, tail string, err error) { - r, n := utf8.DecodeRuneInString(s) - if r == utf8.RuneError && n == 1 { - return "", "", errBadUTF8 - } - s = s[n:] - switch r { - case 'a': - return "\a", s, nil - case 'b': - return "\b", s, nil - case 'f': - return "\f", s, nil - case 'n': - return "\n", s, nil - case 'r': - return "\r", s, nil - case 't': - return "\t", s, nil - case 'v': - return "\v", s, nil - case '?': - return "?", s, nil // trigraph workaround - case '\'', '"', '\\': - return string(r), s, nil - case '0', '1', '2', '3', '4', '5', '6', '7', 'x', 'X': - if len(s) < 2 { - return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) - } - base := 8 - ss := s[:2] - s = s[2:] - if r == 'x' || r == 'X' { - base = 16 - } else { - ss = string(r) + ss - } - i, err := strconv.ParseUint(ss, base, 8) - if err != nil { - return "", "", err - } - return string([]byte{byte(i)}), s, nil - case 'u', 'U': - n := 4 - if r == 'U' { - n = 8 - } - if len(s) < n { - return "", "", fmt.Errorf(`\%c requires %d digits`, r, n) - } - - bs := make([]byte, n/2) - for i := 0; i < n; i += 2 { - a, ok1 := unhex(s[i]) - b, ok2 := unhex(s[i+1]) - if !ok1 || !ok2 { - return "", "", errBadHex - } - bs[i/2] = a<<4 | b - } - s = s[n:] - return string(bs), s, nil - } - return "", "", fmt.Errorf(`unknown escape \%c`, r) -} - -// Adapted from src/pkg/strconv/quote.go. -func unhex(b byte) (v byte, ok bool) { - switch { - case '0' <= b && b <= '9': - return b - '0', true - case 'a' <= b && b <= 'f': - return b - 'a' + 10, true - case 'A' <= b && b <= 'F': - return b - 'A' + 10, true - } - return 0, false -} - -// Back off the parser by one token. Can only be done between calls to next(). -// It makes the next advance() a no-op. -func (p *textParser) back() { p.backed = true } - -// Advances the parser and returns the new current token. -func (p *textParser) next() *token { - if p.backed || p.done { - p.backed = false - return &p.cur - } - p.advance() - if p.done { - p.cur.value = "" - } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { - // Look for multiple quoted strings separated by whitespace, - // and concatenate them. - cat := p.cur - for { - p.skipWhitespace() - if p.done || !isQuote(p.s[0]) { - break - } - p.advance() - if p.cur.err != nil { - return &p.cur - } - cat.value += " " + p.cur.value - cat.unquoted += p.cur.unquoted - } - p.done = false // parser may have seen EOF, but we want to return cat - p.cur = cat - } - return &p.cur -} - -func (p *textParser) consumeToken(s string) error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != s { - p.back() - return p.errorf("expected %q, found %q", s, tok.value) - } - return nil -} - -// Return a RequiredNotSetError indicating which required field was not set. -func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError { - st := sv.Type() - sprops := GetProperties(st) - for i := 0; i < st.NumField(); i++ { - if !isNil(sv.Field(i)) { - continue - } - - props := sprops.Prop[i] - if props.Required { - return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)} - } - } - return &RequiredNotSetError{fmt.Sprintf("%v.", st)} // should not happen -} - -// Returns the index in the struct for the named field, as well as the parsed tag properties. -func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) { - i, ok := sprops.decoderOrigNames[name] - if ok { - return i, sprops.Prop[i], true - } - return -1, nil, false -} - -// Consume a ':' from the input stream (if the next token is a colon), -// returning an error if a colon is needed but not present. -func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != ":" { - // Colon is optional when the field is a group or message. - needColon := true - switch props.Wire { - case "group": - needColon = false - case "bytes": - // A "bytes" field is either a message, a string, or a repeated field; - // those three become *T, *string and []T respectively, so we can check for - // this field being a pointer to a non-string. - if typ.Kind() == reflect.Ptr { - // *T or *string - if typ.Elem().Kind() == reflect.String { - break - } - } else if typ.Kind() == reflect.Slice { - // []T or []*T - if typ.Elem().Kind() != reflect.Ptr { - break - } - } else if typ.Kind() == reflect.String { - // The proto3 exception is for a string field, - // which requires a colon. - break - } - needColon = false - } - if needColon { - return p.errorf("expected ':', found %q", tok.value) - } - p.back() - } - return nil -} - -func (p *textParser) readStruct(sv reflect.Value, terminator string) error { - st := sv.Type() - sprops := GetProperties(st) - reqCount := sprops.reqCount - var reqFieldErr error - fieldSet := make(map[string]bool) - // A struct is a sequence of "name: value", terminated by one of - // '>' or '}', or the end of the input. A name may also be - // "[extension]" or "[type/url]". - // - // The whole struct can also be an expanded Any message, like: - // [type/url] < ... struct contents ... > - for { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == terminator { - break - } - if tok.value == "[" { - // Looks like an extension or an Any. - // - // TODO: Check whether we need to handle - // namespace rooted names (e.g. ".something.Foo"). - extName, err := p.consumeExtName() - if err != nil { - return err - } - - if s := strings.LastIndex(extName, "/"); s >= 0 { - // If it contains a slash, it's an Any type URL. - messageName := extName[s+1:] - mt := MessageType(messageName) - if mt == nil { - return p.errorf("unrecognized message %q in google.protobuf.Any", messageName) - } - tok = p.next() - if tok.err != nil { - return tok.err - } - // consume an optional colon - if tok.value == ":" { - tok = p.next() - if tok.err != nil { - return tok.err - } - } - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - v := reflect.New(mt.Elem()) - if pe := p.readStruct(v.Elem(), terminator); pe != nil { - return pe - } - b, err := Marshal(v.Interface().(Message)) - if err != nil { - return p.errorf("failed to marshal message of type %q: %v", messageName, err) - } - if fieldSet["type_url"] { - return p.errorf(anyRepeatedlyUnpacked, "type_url") - } - if fieldSet["value"] { - return p.errorf(anyRepeatedlyUnpacked, "value") - } - sv.FieldByName("TypeUrl").SetString(extName) - sv.FieldByName("Value").SetBytes(b) - fieldSet["type_url"] = true - fieldSet["value"] = true - continue - } - - var desc *ExtensionDesc - // This could be faster, but it's functional. - // TODO: Do something smarter than a linear scan. - for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) { - if d.Name == extName { - desc = d - break - } - } - if desc == nil { - return p.errorf("unrecognized extension %q", extName) - } - - props := &Properties{} - props.Parse(desc.Tag) - - typ := reflect.TypeOf(desc.ExtensionType) - if err := p.checkForColon(props, typ); err != nil { - return err - } - - rep := desc.repeated() - - // Read the extension structure, and set it in - // the value we're constructing. - var ext reflect.Value - if !rep { - ext = reflect.New(typ).Elem() - } else { - ext = reflect.New(typ.Elem()).Elem() - } - if err := p.readAny(ext, props); err != nil { - if _, ok := err.(*RequiredNotSetError); !ok { - return err - } - reqFieldErr = err - } - ep := sv.Addr().Interface().(Message) - if !rep { - SetExtension(ep, desc, ext.Interface()) - } else { - old, err := GetExtension(ep, desc) - var sl reflect.Value - if err == nil { - sl = reflect.ValueOf(old) // existing slice - } else { - sl = reflect.MakeSlice(typ, 0, 1) - } - sl = reflect.Append(sl, ext) - SetExtension(ep, desc, sl.Interface()) - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - continue - } - - // This is a normal, non-extension field. - name := tok.value - var dst reflect.Value - fi, props, ok := structFieldByName(sprops, name) - if ok { - dst = sv.Field(fi) - } else if oop, ok := sprops.OneofTypes[name]; ok { - // It is a oneof. - props = oop.Prop - nv := reflect.New(oop.Type.Elem()) - dst = nv.Elem().Field(0) - field := sv.Field(oop.Field) - if !field.IsNil() { - return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name) - } - field.Set(nv) - } - if !dst.IsValid() { - return p.errorf("unknown field name %q in %v", name, st) - } - - if dst.Kind() == reflect.Map { - // Consume any colon. - if err := p.checkForColon(props, dst.Type()); err != nil { - return err - } - - // Construct the map if it doesn't already exist. - if dst.IsNil() { - dst.Set(reflect.MakeMap(dst.Type())) - } - key := reflect.New(dst.Type().Key()).Elem() - val := reflect.New(dst.Type().Elem()).Elem() - - // The map entry should be this sequence of tokens: - // < key : KEY value : VALUE > - // However, implementations may omit key or value, and technically - // we should support them in any order. See b/28924776 for a time - // this went wrong. - - tok := p.next() - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - for { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == terminator { - break - } - switch tok.value { - case "key": - if err := p.consumeToken(":"); err != nil { - return err - } - if err := p.readAny(key, props.mkeyprop); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - case "value": - if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { - return err - } - if err := p.readAny(val, props.mvalprop); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - default: - p.back() - return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value) - } - } - - dst.SetMapIndex(key, val) - continue - } - - // Check that it's not already set if it's not a repeated field. - if !props.Repeated && fieldSet[name] { - return p.errorf("non-repeated field %q was repeated", name) - } - - if err := p.checkForColon(props, dst.Type()); err != nil { - return err - } - - // Parse into the field. - fieldSet[name] = true - if err := p.readAny(dst, props); err != nil { - if _, ok := err.(*RequiredNotSetError); !ok { - return err - } - reqFieldErr = err - } - if props.Required { - reqCount-- - } - - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - - } - - if reqCount > 0 { - return p.missingRequiredFieldError(sv) - } - return reqFieldErr -} - -// consumeExtName consumes extension name or expanded Any type URL and the -// following ']'. It returns the name or URL consumed. -func (p *textParser) consumeExtName() (string, error) { - tok := p.next() - if tok.err != nil { - return "", tok.err - } - - // If extension name or type url is quoted, it's a single token. - if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] { - name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0])) - if err != nil { - return "", err - } - return name, p.consumeToken("]") - } - - // Consume everything up to "]" - var parts []string - for tok.value != "]" { - parts = append(parts, tok.value) - tok = p.next() - if tok.err != nil { - return "", p.errorf("unrecognized type_url or extension name: %s", tok.err) - } - } - return strings.Join(parts, ""), nil -} - -// consumeOptionalSeparator consumes an optional semicolon or comma. -// It is used in readStruct to provide backward compatibility. -func (p *textParser) consumeOptionalSeparator() error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != ";" && tok.value != "," { - p.back() - } - return nil -} - -func (p *textParser) readAny(v reflect.Value, props *Properties) error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == "" { - return p.errorf("unexpected EOF") - } - if len(props.CustomType) > 0 { - if props.Repeated { - t := reflect.TypeOf(v.Interface()) - if t.Kind() == reflect.Slice { - tc := reflect.TypeOf(new(Marshaler)) - ok := t.Elem().Implements(tc.Elem()) - if ok { - fv := v - flen := fv.Len() - if flen == fv.Cap() { - nav := reflect.MakeSlice(v.Type(), flen, 2*flen+1) - reflect.Copy(nav, fv) - fv.Set(nav) - } - fv.SetLen(flen + 1) - - // Read one. - p.back() - return p.readAny(fv.Index(flen), props) - } - } - } - if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { - custom := reflect.New(props.ctype.Elem()).Interface().(Unmarshaler) - err := custom.Unmarshal([]byte(tok.unquoted)) - if err != nil { - return p.errorf("%v %v: %v", err, v.Type(), tok.value) - } - v.Set(reflect.ValueOf(custom)) - } else { - custom := reflect.New(reflect.TypeOf(v.Interface())).Interface().(Unmarshaler) - err := custom.Unmarshal([]byte(tok.unquoted)) - if err != nil { - return p.errorf("%v %v: %v", err, v.Type(), tok.value) - } - v.Set(reflect.Indirect(reflect.ValueOf(custom))) - } - return nil - } - if props.StdTime { - fv := v - p.back() - props.StdTime = false - tproto := ×tamp{} - err := p.readAny(reflect.ValueOf(tproto).Elem(), props) - props.StdTime = true - if err != nil { - return err - } - tim, err := timestampFromProto(tproto) - if err != nil { - return err - } - if props.Repeated { - t := reflect.TypeOf(v.Interface()) - if t.Kind() == reflect.Slice { - if t.Elem().Kind() == reflect.Ptr { - ts := fv.Interface().([]*time.Time) - ts = append(ts, &tim) - fv.Set(reflect.ValueOf(ts)) - return nil - } else { - ts := fv.Interface().([]time.Time) - ts = append(ts, tim) - fv.Set(reflect.ValueOf(ts)) - return nil - } - } - } - if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { - v.Set(reflect.ValueOf(&tim)) - } else { - v.Set(reflect.Indirect(reflect.ValueOf(&tim))) - } - return nil - } - if props.StdDuration { - fv := v - p.back() - props.StdDuration = false - dproto := &duration{} - err := p.readAny(reflect.ValueOf(dproto).Elem(), props) - props.StdDuration = true - if err != nil { - return err - } - dur, err := durationFromProto(dproto) - if err != nil { - return err - } - if props.Repeated { - t := reflect.TypeOf(v.Interface()) - if t.Kind() == reflect.Slice { - if t.Elem().Kind() == reflect.Ptr { - ds := fv.Interface().([]*time.Duration) - ds = append(ds, &dur) - fv.Set(reflect.ValueOf(ds)) - return nil - } else { - ds := fv.Interface().([]time.Duration) - ds = append(ds, dur) - fv.Set(reflect.ValueOf(ds)) - return nil - } - } - } - if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { - v.Set(reflect.ValueOf(&dur)) - } else { - v.Set(reflect.Indirect(reflect.ValueOf(&dur))) - } - return nil - } - switch fv := v; fv.Kind() { - case reflect.Slice: - at := v.Type() - if at.Elem().Kind() == reflect.Uint8 { - // Special case for []byte - if tok.value[0] != '"' && tok.value[0] != '\'' { - // Deliberately written out here, as the error after - // this switch statement would write "invalid []byte: ...", - // which is not as user-friendly. - return p.errorf("invalid string: %v", tok.value) - } - bytes := []byte(tok.unquoted) - fv.Set(reflect.ValueOf(bytes)) - return nil - } - // Repeated field. - if tok.value == "[" { - // Repeated field with list notation, like [1,2,3]. - for { - fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) - err := p.readAny(fv.Index(fv.Len()-1), props) - if err != nil { - return err - } - ntok := p.next() - if ntok.err != nil { - return ntok.err - } - if ntok.value == "]" { - break - } - if ntok.value != "," { - return p.errorf("Expected ']' or ',' found %q", ntok.value) - } - } - return nil - } - // One value of the repeated field. - p.back() - fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) - return p.readAny(fv.Index(fv.Len()-1), props) - case reflect.Bool: - // true/1/t/True or false/f/0/False. - switch tok.value { - case "true", "1", "t", "True": - fv.SetBool(true) - return nil - case "false", "0", "f", "False": - fv.SetBool(false) - return nil - } - case reflect.Float32, reflect.Float64: - v := tok.value - // Ignore 'f' for compatibility with output generated by C++, but don't - // remove 'f' when the value is "-inf" or "inf". - if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" { - v = v[:len(v)-1] - } - if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil { - fv.SetFloat(f) - return nil - } - case reflect.Int32: - if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { - fv.SetInt(x) - return nil - } - - if len(props.Enum) == 0 { - break - } - m, ok := enumValueMaps[props.Enum] - if !ok { - break - } - x, ok := m[tok.value] - if !ok { - break - } - fv.SetInt(int64(x)) - return nil - case reflect.Int64: - if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { - fv.SetInt(x) - return nil - } - - case reflect.Ptr: - // A basic field (indirected through pointer), or a repeated message/group - p.back() - fv.Set(reflect.New(fv.Type().Elem())) - return p.readAny(fv.Elem(), props) - case reflect.String: - if tok.value[0] == '"' || tok.value[0] == '\'' { - fv.SetString(tok.unquoted) - return nil - } - case reflect.Struct: - var terminator string - switch tok.value { - case "{": - terminator = "}" - case "<": - terminator = ">" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - // TODO: Handle nested messages which implement encoding.TextUnmarshaler. - return p.readStruct(fv, terminator) - case reflect.Uint32: - if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { - fv.SetUint(x) - return nil - } - case reflect.Uint64: - if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { - fv.SetUint(x) - return nil - } - } - return p.errorf("invalid %v: %v", v.Type(), tok.value) -} - -// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb -// before starting to unmarshal, so any existing data in pb is always removed. -// If a required field is not set and no other error occurs, -// UnmarshalText returns *RequiredNotSetError. -func UnmarshalText(s string, pb Message) error { - if um, ok := pb.(encoding.TextUnmarshaler); ok { - err := um.UnmarshalText([]byte(s)) - return err - } - pb.Reset() - v := reflect.ValueOf(pb) - if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil { - return pe - } - return nil -} diff --git a/vendor/github.com/gogo/protobuf/proto/timestamp.go b/vendor/github.com/gogo/protobuf/proto/timestamp.go deleted file mode 100644 index 9324f6542..000000000 --- a/vendor/github.com/gogo/protobuf/proto/timestamp.go +++ /dev/null @@ -1,113 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// This file implements operations on google.protobuf.Timestamp. - -import ( - "errors" - "fmt" - "time" -) - -const ( - // Seconds field of the earliest valid Timestamp. - // This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). - minValidSeconds = -62135596800 - // Seconds field just after the latest valid Timestamp. - // This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). - maxValidSeconds = 253402300800 -) - -// validateTimestamp determines whether a Timestamp is valid. -// A valid timestamp represents a time in the range -// [0001-01-01, 10000-01-01) and has a Nanos field -// in the range [0, 1e9). -// -// If the Timestamp is valid, validateTimestamp returns nil. -// Otherwise, it returns an error that describes -// the problem. -// -// Every valid Timestamp can be represented by a time.Time, but the converse is not true. -func validateTimestamp(ts *timestamp) error { - if ts == nil { - return errors.New("timestamp: nil Timestamp") - } - if ts.Seconds < minValidSeconds { - return fmt.Errorf("timestamp: %#v before 0001-01-01", ts) - } - if ts.Seconds >= maxValidSeconds { - return fmt.Errorf("timestamp: %#v after 10000-01-01", ts) - } - if ts.Nanos < 0 || ts.Nanos >= 1e9 { - return fmt.Errorf("timestamp: %#v: nanos not in range [0, 1e9)", ts) - } - return nil -} - -// TimestampFromProto converts a google.protobuf.Timestamp proto to a time.Time. -// It returns an error if the argument is invalid. -// -// Unlike most Go functions, if Timestamp returns an error, the first return value -// is not the zero time.Time. Instead, it is the value obtained from the -// time.Unix function when passed the contents of the Timestamp, in the UTC -// locale. This may or may not be a meaningful time; many invalid Timestamps -// do map to valid time.Times. -// -// A nil Timestamp returns an error. The first return value in that case is -// undefined. -func timestampFromProto(ts *timestamp) (time.Time, error) { - // Don't return the zero value on error, because corresponds to a valid - // timestamp. Instead return whatever time.Unix gives us. - var t time.Time - if ts == nil { - t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp - } else { - t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() - } - return t, validateTimestamp(ts) -} - -// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. -// It returns an error if the resulting Timestamp is invalid. -func timestampProto(t time.Time) (*timestamp, error) { - seconds := t.Unix() - nanos := int32(t.Sub(time.Unix(seconds, 0))) - ts := ×tamp{ - Seconds: seconds, - Nanos: nanos, - } - if err := validateTimestamp(ts); err != nil { - return nil, err - } - return ts, nil -} diff --git a/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go b/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go deleted file mode 100644 index d42764743..000000000 --- a/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go +++ /dev/null @@ -1,229 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2016, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "reflect" - "time" -) - -var timeType = reflect.TypeOf((*time.Time)(nil)).Elem() - -type timestamp struct { - Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` - Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` -} - -func (m *timestamp) Reset() { *m = timestamp{} } -func (*timestamp) ProtoMessage() {} -func (*timestamp) String() string { return "timestamp" } - -func init() { - RegisterType((*timestamp)(nil), "gogo.protobuf.proto.timestamp") -} - -func (o *Buffer) decTimestamp() (time.Time, error) { - b, err := o.DecodeRawBytes(true) - if err != nil { - return time.Time{}, err - } - tproto := ×tamp{} - if err := Unmarshal(b, tproto); err != nil { - return time.Time{}, err - } - return timestampFromProto(tproto) -} - -func (o *Buffer) dec_time(p *Properties, base structPointer) error { - t, err := o.decTimestamp() - if err != nil { - return err - } - setPtrCustomType(base, p.field, &t) - return nil -} - -func (o *Buffer) dec_ref_time(p *Properties, base structPointer) error { - t, err := o.decTimestamp() - if err != nil { - return err - } - setCustomType(base, p.field, &t) - return nil -} - -func (o *Buffer) dec_slice_time(p *Properties, base structPointer) error { - t, err := o.decTimestamp() - if err != nil { - return err - } - newBas := appendStructPointer(base, p.field, reflect.SliceOf(reflect.PtrTo(timeType))) - var zero field - setPtrCustomType(newBas, zero, &t) - return nil -} - -func (o *Buffer) dec_slice_ref_time(p *Properties, base structPointer) error { - t, err := o.decTimestamp() - if err != nil { - return err - } - newBas := appendStructPointer(base, p.field, reflect.SliceOf(timeType)) - var zero field - setCustomType(newBas, zero, &t) - return nil -} - -func size_time(p *Properties, base structPointer) (n int) { - structp := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(structp) { - return 0 - } - tim := structPointer_Interface(structp, timeType).(*time.Time) - t, err := timestampProto(*tim) - if err != nil { - return 0 - } - size := Size(t) - return size + sizeVarint(uint64(size)) + len(p.tagcode) -} - -func (o *Buffer) enc_time(p *Properties, base structPointer) error { - structp := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(structp) { - return ErrNil - } - tim := structPointer_Interface(structp, timeType).(*time.Time) - t, err := timestampProto(*tim) - if err != nil { - return err - } - data, err := Marshal(t) - if err != nil { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - return nil -} - -func size_ref_time(p *Properties, base structPointer) (n int) { - tim := structPointer_InterfaceAt(base, p.field, timeType).(*time.Time) - t, err := timestampProto(*tim) - if err != nil { - return 0 - } - size := Size(t) - return size + sizeVarint(uint64(size)) + len(p.tagcode) -} - -func (o *Buffer) enc_ref_time(p *Properties, base structPointer) error { - tim := structPointer_InterfaceAt(base, p.field, timeType).(*time.Time) - t, err := timestampProto(*tim) - if err != nil { - return err - } - data, err := Marshal(t) - if err != nil { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - return nil -} - -func size_slice_time(p *Properties, base structPointer) (n int) { - ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(timeType))).(*[]*time.Time) - tims := *ptims - for i := 0; i < len(tims); i++ { - if tims[i] == nil { - return 0 - } - tproto, err := timestampProto(*tims[i]) - if err != nil { - return 0 - } - size := Size(tproto) - n += len(p.tagcode) + size + sizeVarint(uint64(size)) - } - return n -} - -func (o *Buffer) enc_slice_time(p *Properties, base structPointer) error { - ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(timeType))).(*[]*time.Time) - tims := *ptims - for i := 0; i < len(tims); i++ { - if tims[i] == nil { - return errRepeatedHasNil - } - tproto, err := timestampProto(*tims[i]) - if err != nil { - return err - } - data, err := Marshal(tproto) - if err != nil { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - } - return nil -} - -func size_slice_ref_time(p *Properties, base structPointer) (n int) { - ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(timeType)).(*[]time.Time) - tims := *ptims - for i := 0; i < len(tims); i++ { - tproto, err := timestampProto(tims[i]) - if err != nil { - return 0 - } - size := Size(tproto) - n += len(p.tagcode) + size + sizeVarint(uint64(size)) - } - return n -} - -func (o *Buffer) enc_slice_ref_time(p *Properties, base structPointer) error { - ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(timeType)).(*[]time.Time) - tims := *ptims - for i := 0; i < len(tims); i++ { - tproto, err := timestampProto(tims[i]) - if err != nil { - return err - } - data, err := Marshal(tproto) - if err != nil { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - } - return nil -} diff --git a/vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go b/vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go deleted file mode 100644 index ceadde6a5..000000000 --- a/vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go +++ /dev/null @@ -1,101 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package sortkeys - -import ( - "sort" -) - -func Strings(l []string) { - sort.Strings(l) -} - -func Float64s(l []float64) { - sort.Float64s(l) -} - -func Float32s(l []float32) { - sort.Sort(Float32Slice(l)) -} - -func Int64s(l []int64) { - sort.Sort(Int64Slice(l)) -} - -func Int32s(l []int32) { - sort.Sort(Int32Slice(l)) -} - -func Uint64s(l []uint64) { - sort.Sort(Uint64Slice(l)) -} - -func Uint32s(l []uint32) { - sort.Sort(Uint32Slice(l)) -} - -func Bools(l []bool) { - sort.Sort(BoolSlice(l)) -} - -type BoolSlice []bool - -func (p BoolSlice) Len() int { return len(p) } -func (p BoolSlice) Less(i, j int) bool { return p[j] } -func (p BoolSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -type Int64Slice []int64 - -func (p Int64Slice) Len() int { return len(p) } -func (p Int64Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p Int64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -type Int32Slice []int32 - -func (p Int32Slice) Len() int { return len(p) } -func (p Int32Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p Int32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -type Uint64Slice []uint64 - -func (p Uint64Slice) Len() int { return len(p) } -func (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p Uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -type Uint32Slice []uint32 - -func (p Uint32Slice) Len() int { return len(p) } -func (p Uint32Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p Uint32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -type Float32Slice []float32 - -func (p Float32Slice) Len() int { return len(p) } -func (p Float32Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p Float32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } diff --git a/vendor/github.com/golang/glog/LICENSE b/vendor/github.com/golang/glog/LICENSE deleted file mode 100644 index 37ec93a14..000000000 --- a/vendor/github.com/golang/glog/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/golang/glog/glog.go b/vendor/github.com/golang/glog/glog.go deleted file mode 100644 index 54bd7afdc..000000000 --- a/vendor/github.com/golang/glog/glog.go +++ /dev/null @@ -1,1180 +0,0 @@ -// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/ -// -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package glog implements logging analogous to the Google-internal C++ INFO/ERROR/V setup. -// It provides functions Info, Warning, Error, Fatal, plus formatting variants such as -// Infof. It also provides V-style logging controlled by the -v and -vmodule=file=2 flags. -// -// Basic examples: -// -// glog.Info("Prepare to repel boarders") -// -// glog.Fatalf("Initialization failed: %s", err) -// -// See the documentation for the V function for an explanation of these examples: -// -// if glog.V(2) { -// glog.Info("Starting transaction...") -// } -// -// glog.V(2).Infoln("Processed", nItems, "elements") -// -// Log output is buffered and written periodically using Flush. Programs -// should call Flush before exiting to guarantee all log output is written. -// -// By default, all log statements write to files in a temporary directory. -// This package provides several flags that modify this behavior. -// As a result, flag.Parse must be called before any logging is done. -// -// -logtostderr=false -// Logs are written to standard error instead of to files. -// -alsologtostderr=false -// Logs are written to standard error as well as to files. -// -stderrthreshold=ERROR -// Log events at or above this severity are logged to standard -// error as well as to files. -// -log_dir="" -// Log files will be written to this directory instead of the -// default temporary directory. -// -// Other flags provide aids to debugging. -// -// -log_backtrace_at="" -// When set to a file and line number holding a logging statement, -// such as -// -log_backtrace_at=gopherflakes.go:234 -// a stack trace will be written to the Info log whenever execution -// hits that statement. (Unlike with -vmodule, the ".go" must be -// present.) -// -v=0 -// Enable V-leveled logging at the specified level. -// -vmodule="" -// The syntax of the argument is a comma-separated list of pattern=N, -// where pattern is a literal file name (minus the ".go" suffix) or -// "glob" pattern and N is a V level. For instance, -// -vmodule=gopher*=3 -// sets the V level to 3 in all Go files whose names begin "gopher". -// -package glog - -import ( - "bufio" - "bytes" - "errors" - "flag" - "fmt" - "io" - stdLog "log" - "os" - "path/filepath" - "runtime" - "strconv" - "strings" - "sync" - "sync/atomic" - "time" -) - -// severity identifies the sort of log: info, warning etc. It also implements -// the flag.Value interface. The -stderrthreshold flag is of type severity and -// should be modified only through the flag.Value interface. The values match -// the corresponding constants in C++. -type severity int32 // sync/atomic int32 - -// These constants identify the log levels in order of increasing severity. -// A message written to a high-severity log file is also written to each -// lower-severity log file. -const ( - infoLog severity = iota - warningLog - errorLog - fatalLog - numSeverity = 4 -) - -const severityChar = "IWEF" - -var severityName = []string{ - infoLog: "INFO", - warningLog: "WARNING", - errorLog: "ERROR", - fatalLog: "FATAL", -} - -// get returns the value of the severity. -func (s *severity) get() severity { - return severity(atomic.LoadInt32((*int32)(s))) -} - -// set sets the value of the severity. -func (s *severity) set(val severity) { - atomic.StoreInt32((*int32)(s), int32(val)) -} - -// String is part of the flag.Value interface. -func (s *severity) String() string { - return strconv.FormatInt(int64(*s), 10) -} - -// Get is part of the flag.Value interface. -func (s *severity) Get() interface{} { - return *s -} - -// Set is part of the flag.Value interface. -func (s *severity) Set(value string) error { - var threshold severity - // Is it a known name? - if v, ok := severityByName(value); ok { - threshold = v - } else { - v, err := strconv.Atoi(value) - if err != nil { - return err - } - threshold = severity(v) - } - logging.stderrThreshold.set(threshold) - return nil -} - -func severityByName(s string) (severity, bool) { - s = strings.ToUpper(s) - for i, name := range severityName { - if name == s { - return severity(i), true - } - } - return 0, false -} - -// OutputStats tracks the number of output lines and bytes written. -type OutputStats struct { - lines int64 - bytes int64 -} - -// Lines returns the number of lines written. -func (s *OutputStats) Lines() int64 { - return atomic.LoadInt64(&s.lines) -} - -// Bytes returns the number of bytes written. -func (s *OutputStats) Bytes() int64 { - return atomic.LoadInt64(&s.bytes) -} - -// Stats tracks the number of lines of output and number of bytes -// per severity level. Values must be read with atomic.LoadInt64. -var Stats struct { - Info, Warning, Error OutputStats -} - -var severityStats = [numSeverity]*OutputStats{ - infoLog: &Stats.Info, - warningLog: &Stats.Warning, - errorLog: &Stats.Error, -} - -// Level is exported because it appears in the arguments to V and is -// the type of the v flag, which can be set programmatically. -// It's a distinct type because we want to discriminate it from logType. -// Variables of type level are only changed under logging.mu. -// The -v flag is read only with atomic ops, so the state of the logging -// module is consistent. - -// Level is treated as a sync/atomic int32. - -// Level specifies a level of verbosity for V logs. *Level implements -// flag.Value; the -v flag is of type Level and should be modified -// only through the flag.Value interface. -type Level int32 - -// get returns the value of the Level. -func (l *Level) get() Level { - return Level(atomic.LoadInt32((*int32)(l))) -} - -// set sets the value of the Level. -func (l *Level) set(val Level) { - atomic.StoreInt32((*int32)(l), int32(val)) -} - -// String is part of the flag.Value interface. -func (l *Level) String() string { - return strconv.FormatInt(int64(*l), 10) -} - -// Get is part of the flag.Value interface. -func (l *Level) Get() interface{} { - return *l -} - -// Set is part of the flag.Value interface. -func (l *Level) Set(value string) error { - v, err := strconv.Atoi(value) - if err != nil { - return err - } - logging.mu.Lock() - defer logging.mu.Unlock() - logging.setVState(Level(v), logging.vmodule.filter, false) - return nil -} - -// moduleSpec represents the setting of the -vmodule flag. -type moduleSpec struct { - filter []modulePat -} - -// modulePat contains a filter for the -vmodule flag. -// It holds a verbosity level and a file pattern to match. -type modulePat struct { - pattern string - literal bool // The pattern is a literal string - level Level -} - -// match reports whether the file matches the pattern. It uses a string -// comparison if the pattern contains no metacharacters. -func (m *modulePat) match(file string) bool { - if m.literal { - return file == m.pattern - } - match, _ := filepath.Match(m.pattern, file) - return match -} - -func (m *moduleSpec) String() string { - // Lock because the type is not atomic. TODO: clean this up. - logging.mu.Lock() - defer logging.mu.Unlock() - var b bytes.Buffer - for i, f := range m.filter { - if i > 0 { - b.WriteRune(',') - } - fmt.Fprintf(&b, "%s=%d", f.pattern, f.level) - } - return b.String() -} - -// Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the -// struct is not exported. -func (m *moduleSpec) Get() interface{} { - return nil -} - -var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N") - -// Syntax: -vmodule=recordio=2,file=1,gfs*=3 -func (m *moduleSpec) Set(value string) error { - var filter []modulePat - for _, pat := range strings.Split(value, ",") { - if len(pat) == 0 { - // Empty strings such as from a trailing comma can be ignored. - continue - } - patLev := strings.Split(pat, "=") - if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 { - return errVmoduleSyntax - } - pattern := patLev[0] - v, err := strconv.Atoi(patLev[1]) - if err != nil { - return errors.New("syntax error: expect comma-separated list of filename=N") - } - if v < 0 { - return errors.New("negative value for vmodule level") - } - if v == 0 { - continue // Ignore. It's harmless but no point in paying the overhead. - } - // TODO: check syntax of filter? - filter = append(filter, modulePat{pattern, isLiteral(pattern), Level(v)}) - } - logging.mu.Lock() - defer logging.mu.Unlock() - logging.setVState(logging.verbosity, filter, true) - return nil -} - -// isLiteral reports whether the pattern is a literal string, that is, has no metacharacters -// that require filepath.Match to be called to match the pattern. -func isLiteral(pattern string) bool { - return !strings.ContainsAny(pattern, `\*?[]`) -} - -// traceLocation represents the setting of the -log_backtrace_at flag. -type traceLocation struct { - file string - line int -} - -// isSet reports whether the trace location has been specified. -// logging.mu is held. -func (t *traceLocation) isSet() bool { - return t.line > 0 -} - -// match reports whether the specified file and line matches the trace location. -// The argument file name is the full path, not the basename specified in the flag. -// logging.mu is held. -func (t *traceLocation) match(file string, line int) bool { - if t.line != line { - return false - } - if i := strings.LastIndex(file, "/"); i >= 0 { - file = file[i+1:] - } - return t.file == file -} - -func (t *traceLocation) String() string { - // Lock because the type is not atomic. TODO: clean this up. - logging.mu.Lock() - defer logging.mu.Unlock() - return fmt.Sprintf("%s:%d", t.file, t.line) -} - -// Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the -// struct is not exported -func (t *traceLocation) Get() interface{} { - return nil -} - -var errTraceSyntax = errors.New("syntax error: expect file.go:234") - -// Syntax: -log_backtrace_at=gopherflakes.go:234 -// Note that unlike vmodule the file extension is included here. -func (t *traceLocation) Set(value string) error { - if value == "" { - // Unset. - t.line = 0 - t.file = "" - } - fields := strings.Split(value, ":") - if len(fields) != 2 { - return errTraceSyntax - } - file, line := fields[0], fields[1] - if !strings.Contains(file, ".") { - return errTraceSyntax - } - v, err := strconv.Atoi(line) - if err != nil { - return errTraceSyntax - } - if v <= 0 { - return errors.New("negative or zero value for level") - } - logging.mu.Lock() - defer logging.mu.Unlock() - t.line = v - t.file = file - return nil -} - -// flushSyncWriter is the interface satisfied by logging destinations. -type flushSyncWriter interface { - Flush() error - Sync() error - io.Writer -} - -func init() { - flag.BoolVar(&logging.toStderr, "logtostderr", false, "log to standard error instead of files") - flag.BoolVar(&logging.alsoToStderr, "alsologtostderr", false, "log to standard error as well as files") - flag.Var(&logging.verbosity, "v", "log level for V logs") - flag.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr") - flag.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging") - flag.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace") - - // Default stderrThreshold is ERROR. - logging.stderrThreshold = errorLog - - logging.setVState(0, nil, false) - go logging.flushDaemon() -} - -// Flush flushes all pending log I/O. -func Flush() { - logging.lockAndFlushAll() -} - -// loggingT collects all the global state of the logging setup. -type loggingT struct { - // Boolean flags. Not handled atomically because the flag.Value interface - // does not let us avoid the =true, and that shorthand is necessary for - // compatibility. TODO: does this matter enough to fix? Seems unlikely. - toStderr bool // The -logtostderr flag. - alsoToStderr bool // The -alsologtostderr flag. - - // Level flag. Handled atomically. - stderrThreshold severity // The -stderrthreshold flag. - - // freeList is a list of byte buffers, maintained under freeListMu. - freeList *buffer - // freeListMu maintains the free list. It is separate from the main mutex - // so buffers can be grabbed and printed to without holding the main lock, - // for better parallelization. - freeListMu sync.Mutex - - // mu protects the remaining elements of this structure and is - // used to synchronize logging. - mu sync.Mutex - // file holds writer for each of the log types. - file [numSeverity]flushSyncWriter - // pcs is used in V to avoid an allocation when computing the caller's PC. - pcs [1]uintptr - // vmap is a cache of the V Level for each V() call site, identified by PC. - // It is wiped whenever the vmodule flag changes state. - vmap map[uintptr]Level - // filterLength stores the length of the vmodule filter chain. If greater - // than zero, it means vmodule is enabled. It may be read safely - // using sync.LoadInt32, but is only modified under mu. - filterLength int32 - // traceLocation is the state of the -log_backtrace_at flag. - traceLocation traceLocation - // These flags are modified only under lock, although verbosity may be fetched - // safely using atomic.LoadInt32. - vmodule moduleSpec // The state of the -vmodule flag. - verbosity Level // V logging level, the value of the -v flag/ -} - -// buffer holds a byte Buffer for reuse. The zero value is ready for use. -type buffer struct { - bytes.Buffer - tmp [64]byte // temporary byte array for creating headers. - next *buffer -} - -var logging loggingT - -// setVState sets a consistent state for V logging. -// l.mu is held. -func (l *loggingT) setVState(verbosity Level, filter []modulePat, setFilter bool) { - // Turn verbosity off so V will not fire while we are in transition. - logging.verbosity.set(0) - // Ditto for filter length. - atomic.StoreInt32(&logging.filterLength, 0) - - // Set the new filters and wipe the pc->Level map if the filter has changed. - if setFilter { - logging.vmodule.filter = filter - logging.vmap = make(map[uintptr]Level) - } - - // Things are consistent now, so enable filtering and verbosity. - // They are enabled in order opposite to that in V. - atomic.StoreInt32(&logging.filterLength, int32(len(filter))) - logging.verbosity.set(verbosity) -} - -// getBuffer returns a new, ready-to-use buffer. -func (l *loggingT) getBuffer() *buffer { - l.freeListMu.Lock() - b := l.freeList - if b != nil { - l.freeList = b.next - } - l.freeListMu.Unlock() - if b == nil { - b = new(buffer) - } else { - b.next = nil - b.Reset() - } - return b -} - -// putBuffer returns a buffer to the free list. -func (l *loggingT) putBuffer(b *buffer) { - if b.Len() >= 256 { - // Let big buffers die a natural death. - return - } - l.freeListMu.Lock() - b.next = l.freeList - l.freeList = b - l.freeListMu.Unlock() -} - -var timeNow = time.Now // Stubbed out for testing. - -/* -header formats a log header as defined by the C++ implementation. -It returns a buffer containing the formatted header and the user's file and line number. -The depth specifies how many stack frames above lives the source line to be identified in the log message. - -Log lines have this form: - Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg... -where the fields are defined as follows: - L A single character, representing the log level (eg 'I' for INFO) - mm The month (zero padded; ie May is '05') - dd The day (zero padded) - hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds - threadid The space-padded thread ID as returned by GetTID() - file The file name - line The line number - msg The user-supplied message -*/ -func (l *loggingT) header(s severity, depth int) (*buffer, string, int) { - _, file, line, ok := runtime.Caller(3 + depth) - if !ok { - file = "???" - line = 1 - } else { - slash := strings.LastIndex(file, "/") - if slash >= 0 { - file = file[slash+1:] - } - } - return l.formatHeader(s, file, line), file, line -} - -// formatHeader formats a log header using the provided file name and line number. -func (l *loggingT) formatHeader(s severity, file string, line int) *buffer { - now := timeNow() - if line < 0 { - line = 0 // not a real line number, but acceptable to someDigits - } - if s > fatalLog { - s = infoLog // for safety. - } - buf := l.getBuffer() - - // Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand. - // It's worth about 3X. Fprintf is hard. - _, month, day := now.Date() - hour, minute, second := now.Clock() - // Lmmdd hh:mm:ss.uuuuuu threadid file:line] - buf.tmp[0] = severityChar[s] - buf.twoDigits(1, int(month)) - buf.twoDigits(3, day) - buf.tmp[5] = ' ' - buf.twoDigits(6, hour) - buf.tmp[8] = ':' - buf.twoDigits(9, minute) - buf.tmp[11] = ':' - buf.twoDigits(12, second) - buf.tmp[14] = '.' - buf.nDigits(6, 15, now.Nanosecond()/1000, '0') - buf.tmp[21] = ' ' - buf.nDigits(7, 22, pid, ' ') // TODO: should be TID - buf.tmp[29] = ' ' - buf.Write(buf.tmp[:30]) - buf.WriteString(file) - buf.tmp[0] = ':' - n := buf.someDigits(1, line) - buf.tmp[n+1] = ']' - buf.tmp[n+2] = ' ' - buf.Write(buf.tmp[:n+3]) - return buf -} - -// Some custom tiny helper functions to print the log header efficiently. - -const digits = "0123456789" - -// twoDigits formats a zero-prefixed two-digit integer at buf.tmp[i]. -func (buf *buffer) twoDigits(i, d int) { - buf.tmp[i+1] = digits[d%10] - d /= 10 - buf.tmp[i] = digits[d%10] -} - -// nDigits formats an n-digit integer at buf.tmp[i], -// padding with pad on the left. -// It assumes d >= 0. -func (buf *buffer) nDigits(n, i, d int, pad byte) { - j := n - 1 - for ; j >= 0 && d > 0; j-- { - buf.tmp[i+j] = digits[d%10] - d /= 10 - } - for ; j >= 0; j-- { - buf.tmp[i+j] = pad - } -} - -// someDigits formats a zero-prefixed variable-width integer at buf.tmp[i]. -func (buf *buffer) someDigits(i, d int) int { - // Print into the top, then copy down. We know there's space for at least - // a 10-digit number. - j := len(buf.tmp) - for { - j-- - buf.tmp[j] = digits[d%10] - d /= 10 - if d == 0 { - break - } - } - return copy(buf.tmp[i:], buf.tmp[j:]) -} - -func (l *loggingT) println(s severity, args ...interface{}) { - buf, file, line := l.header(s, 0) - fmt.Fprintln(buf, args...) - l.output(s, buf, file, line, false) -} - -func (l *loggingT) print(s severity, args ...interface{}) { - l.printDepth(s, 1, args...) -} - -func (l *loggingT) printDepth(s severity, depth int, args ...interface{}) { - buf, file, line := l.header(s, depth) - fmt.Fprint(buf, args...) - if buf.Bytes()[buf.Len()-1] != '\n' { - buf.WriteByte('\n') - } - l.output(s, buf, file, line, false) -} - -func (l *loggingT) printf(s severity, format string, args ...interface{}) { - buf, file, line := l.header(s, 0) - fmt.Fprintf(buf, format, args...) - if buf.Bytes()[buf.Len()-1] != '\n' { - buf.WriteByte('\n') - } - l.output(s, buf, file, line, false) -} - -// printWithFileLine behaves like print but uses the provided file and line number. If -// alsoLogToStderr is true, the log message always appears on standard error; it -// will also appear in the log file unless --logtostderr is set. -func (l *loggingT) printWithFileLine(s severity, file string, line int, alsoToStderr bool, args ...interface{}) { - buf := l.formatHeader(s, file, line) - fmt.Fprint(buf, args...) - if buf.Bytes()[buf.Len()-1] != '\n' { - buf.WriteByte('\n') - } - l.output(s, buf, file, line, alsoToStderr) -} - -// output writes the data to the log files and releases the buffer. -func (l *loggingT) output(s severity, buf *buffer, file string, line int, alsoToStderr bool) { - l.mu.Lock() - if l.traceLocation.isSet() { - if l.traceLocation.match(file, line) { - buf.Write(stacks(false)) - } - } - data := buf.Bytes() - if !flag.Parsed() { - os.Stderr.Write([]byte("ERROR: logging before flag.Parse: ")) - os.Stderr.Write(data) - } else if l.toStderr { - os.Stderr.Write(data) - } else { - if alsoToStderr || l.alsoToStderr || s >= l.stderrThreshold.get() { - os.Stderr.Write(data) - } - if l.file[s] == nil { - if err := l.createFiles(s); err != nil { - os.Stderr.Write(data) // Make sure the message appears somewhere. - l.exit(err) - } - } - switch s { - case fatalLog: - l.file[fatalLog].Write(data) - fallthrough - case errorLog: - l.file[errorLog].Write(data) - fallthrough - case warningLog: - l.file[warningLog].Write(data) - fallthrough - case infoLog: - l.file[infoLog].Write(data) - } - } - if s == fatalLog { - // If we got here via Exit rather than Fatal, print no stacks. - if atomic.LoadUint32(&fatalNoStacks) > 0 { - l.mu.Unlock() - timeoutFlush(10 * time.Second) - os.Exit(1) - } - // Dump all goroutine stacks before exiting. - // First, make sure we see the trace for the current goroutine on standard error. - // If -logtostderr has been specified, the loop below will do that anyway - // as the first stack in the full dump. - if !l.toStderr { - os.Stderr.Write(stacks(false)) - } - // Write the stack trace for all goroutines to the files. - trace := stacks(true) - logExitFunc = func(error) {} // If we get a write error, we'll still exit below. - for log := fatalLog; log >= infoLog; log-- { - if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set. - f.Write(trace) - } - } - l.mu.Unlock() - timeoutFlush(10 * time.Second) - os.Exit(255) // C++ uses -1, which is silly because it's anded with 255 anyway. - } - l.putBuffer(buf) - l.mu.Unlock() - if stats := severityStats[s]; stats != nil { - atomic.AddInt64(&stats.lines, 1) - atomic.AddInt64(&stats.bytes, int64(len(data))) - } -} - -// timeoutFlush calls Flush and returns when it completes or after timeout -// elapses, whichever happens first. This is needed because the hooks invoked -// by Flush may deadlock when glog.Fatal is called from a hook that holds -// a lock. -func timeoutFlush(timeout time.Duration) { - done := make(chan bool, 1) - go func() { - Flush() // calls logging.lockAndFlushAll() - done <- true - }() - select { - case <-done: - case <-time.After(timeout): - fmt.Fprintln(os.Stderr, "glog: Flush took longer than", timeout) - } -} - -// stacks is a wrapper for runtime.Stack that attempts to recover the data for all goroutines. -func stacks(all bool) []byte { - // We don't know how big the traces are, so grow a few times if they don't fit. Start large, though. - n := 10000 - if all { - n = 100000 - } - var trace []byte - for i := 0; i < 5; i++ { - trace = make([]byte, n) - nbytes := runtime.Stack(trace, all) - if nbytes < len(trace) { - return trace[:nbytes] - } - n *= 2 - } - return trace -} - -// logExitFunc provides a simple mechanism to override the default behavior -// of exiting on error. Used in testing and to guarantee we reach a required exit -// for fatal logs. Instead, exit could be a function rather than a method but that -// would make its use clumsier. -var logExitFunc func(error) - -// exit is called if there is trouble creating or writing log files. -// It flushes the logs and exits the program; there's no point in hanging around. -// l.mu is held. -func (l *loggingT) exit(err error) { - fmt.Fprintf(os.Stderr, "log: exiting because of error: %s\n", err) - // If logExitFunc is set, we do that instead of exiting. - if logExitFunc != nil { - logExitFunc(err) - return - } - l.flushAll() - os.Exit(2) -} - -// syncBuffer joins a bufio.Writer to its underlying file, providing access to the -// file's Sync method and providing a wrapper for the Write method that provides log -// file rotation. There are conflicting methods, so the file cannot be embedded. -// l.mu is held for all its methods. -type syncBuffer struct { - logger *loggingT - *bufio.Writer - file *os.File - sev severity - nbytes uint64 // The number of bytes written to this file -} - -func (sb *syncBuffer) Sync() error { - return sb.file.Sync() -} - -func (sb *syncBuffer) Write(p []byte) (n int, err error) { - if sb.nbytes+uint64(len(p)) >= MaxSize { - if err := sb.rotateFile(time.Now()); err != nil { - sb.logger.exit(err) - } - } - n, err = sb.Writer.Write(p) - sb.nbytes += uint64(n) - if err != nil { - sb.logger.exit(err) - } - return -} - -// rotateFile closes the syncBuffer's file and starts a new one. -func (sb *syncBuffer) rotateFile(now time.Time) error { - if sb.file != nil { - sb.Flush() - sb.file.Close() - } - var err error - sb.file, _, err = create(severityName[sb.sev], now) - sb.nbytes = 0 - if err != nil { - return err - } - - sb.Writer = bufio.NewWriterSize(sb.file, bufferSize) - - // Write header. - var buf bytes.Buffer - fmt.Fprintf(&buf, "Log file created at: %s\n", now.Format("2006/01/02 15:04:05")) - fmt.Fprintf(&buf, "Running on machine: %s\n", host) - fmt.Fprintf(&buf, "Binary: Built with %s %s for %s/%s\n", runtime.Compiler, runtime.Version(), runtime.GOOS, runtime.GOARCH) - fmt.Fprintf(&buf, "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg\n") - n, err := sb.file.Write(buf.Bytes()) - sb.nbytes += uint64(n) - return err -} - -// bufferSize sizes the buffer associated with each log file. It's large -// so that log records can accumulate without the logging thread blocking -// on disk I/O. The flushDaemon will block instead. -const bufferSize = 256 * 1024 - -// createFiles creates all the log files for severity from sev down to infoLog. -// l.mu is held. -func (l *loggingT) createFiles(sev severity) error { - now := time.Now() - // Files are created in decreasing severity order, so as soon as we find one - // has already been created, we can stop. - for s := sev; s >= infoLog && l.file[s] == nil; s-- { - sb := &syncBuffer{ - logger: l, - sev: s, - } - if err := sb.rotateFile(now); err != nil { - return err - } - l.file[s] = sb - } - return nil -} - -const flushInterval = 30 * time.Second - -// flushDaemon periodically flushes the log file buffers. -func (l *loggingT) flushDaemon() { - for _ = range time.NewTicker(flushInterval).C { - l.lockAndFlushAll() - } -} - -// lockAndFlushAll is like flushAll but locks l.mu first. -func (l *loggingT) lockAndFlushAll() { - l.mu.Lock() - l.flushAll() - l.mu.Unlock() -} - -// flushAll flushes all the logs and attempts to "sync" their data to disk. -// l.mu is held. -func (l *loggingT) flushAll() { - // Flush from fatal down, in case there's trouble flushing. - for s := fatalLog; s >= infoLog; s-- { - file := l.file[s] - if file != nil { - file.Flush() // ignore error - file.Sync() // ignore error - } - } -} - -// CopyStandardLogTo arranges for messages written to the Go "log" package's -// default logs to also appear in the Google logs for the named and lower -// severities. Subsequent changes to the standard log's default output location -// or format may break this behavior. -// -// Valid names are "INFO", "WARNING", "ERROR", and "FATAL". If the name is not -// recognized, CopyStandardLogTo panics. -func CopyStandardLogTo(name string) { - sev, ok := severityByName(name) - if !ok { - panic(fmt.Sprintf("log.CopyStandardLogTo(%q): unrecognized severity name", name)) - } - // Set a log format that captures the user's file and line: - // d.go:23: message - stdLog.SetFlags(stdLog.Lshortfile) - stdLog.SetOutput(logBridge(sev)) -} - -// logBridge provides the Write method that enables CopyStandardLogTo to connect -// Go's standard logs to the logs provided by this package. -type logBridge severity - -// Write parses the standard logging line and passes its components to the -// logger for severity(lb). -func (lb logBridge) Write(b []byte) (n int, err error) { - var ( - file = "???" - line = 1 - text string - ) - // Split "d.go:23: message" into "d.go", "23", and "message". - if parts := bytes.SplitN(b, []byte{':'}, 3); len(parts) != 3 || len(parts[0]) < 1 || len(parts[2]) < 1 { - text = fmt.Sprintf("bad log format: %s", b) - } else { - file = string(parts[0]) - text = string(parts[2][1:]) // skip leading space - line, err = strconv.Atoi(string(parts[1])) - if err != nil { - text = fmt.Sprintf("bad line number: %s", b) - line = 1 - } - } - // printWithFileLine with alsoToStderr=true, so standard log messages - // always appear on standard error. - logging.printWithFileLine(severity(lb), file, line, true, text) - return len(b), nil -} - -// setV computes and remembers the V level for a given PC -// when vmodule is enabled. -// File pattern matching takes the basename of the file, stripped -// of its .go suffix, and uses filepath.Match, which is a little more -// general than the *? matching used in C++. -// l.mu is held. -func (l *loggingT) setV(pc uintptr) Level { - fn := runtime.FuncForPC(pc) - file, _ := fn.FileLine(pc) - // The file is something like /a/b/c/d.go. We want just the d. - if strings.HasSuffix(file, ".go") { - file = file[:len(file)-3] - } - if slash := strings.LastIndex(file, "/"); slash >= 0 { - file = file[slash+1:] - } - for _, filter := range l.vmodule.filter { - if filter.match(file) { - l.vmap[pc] = filter.level - return filter.level - } - } - l.vmap[pc] = 0 - return 0 -} - -// Verbose is a boolean type that implements Infof (like Printf) etc. -// See the documentation of V for more information. -type Verbose bool - -// V reports whether verbosity at the call site is at least the requested level. -// The returned value is a boolean of type Verbose, which implements Info, Infoln -// and Infof. These methods will write to the Info log if called. -// Thus, one may write either -// if glog.V(2) { glog.Info("log this") } -// or -// glog.V(2).Info("log this") -// The second form is shorter but the first is cheaper if logging is off because it does -// not evaluate its arguments. -// -// Whether an individual call to V generates a log record depends on the setting of -// the -v and --vmodule flags; both are off by default. If the level in the call to -// V is at least the value of -v, or of -vmodule for the source file containing the -// call, the V call will log. -func V(level Level) Verbose { - // This function tries hard to be cheap unless there's work to do. - // The fast path is two atomic loads and compares. - - // Here is a cheap but safe test to see if V logging is enabled globally. - if logging.verbosity.get() >= level { - return Verbose(true) - } - - // It's off globally but it vmodule may still be set. - // Here is another cheap but safe test to see if vmodule is enabled. - if atomic.LoadInt32(&logging.filterLength) > 0 { - // Now we need a proper lock to use the logging structure. The pcs field - // is shared so we must lock before accessing it. This is fairly expensive, - // but if V logging is enabled we're slow anyway. - logging.mu.Lock() - defer logging.mu.Unlock() - if runtime.Callers(2, logging.pcs[:]) == 0 { - return Verbose(false) - } - v, ok := logging.vmap[logging.pcs[0]] - if !ok { - v = logging.setV(logging.pcs[0]) - } - return Verbose(v >= level) - } - return Verbose(false) -} - -// Info is equivalent to the global Info function, guarded by the value of v. -// See the documentation of V for usage. -func (v Verbose) Info(args ...interface{}) { - if v { - logging.print(infoLog, args...) - } -} - -// Infoln is equivalent to the global Infoln function, guarded by the value of v. -// See the documentation of V for usage. -func (v Verbose) Infoln(args ...interface{}) { - if v { - logging.println(infoLog, args...) - } -} - -// Infof is equivalent to the global Infof function, guarded by the value of v. -// See the documentation of V for usage. -func (v Verbose) Infof(format string, args ...interface{}) { - if v { - logging.printf(infoLog, format, args...) - } -} - -// Info logs to the INFO log. -// Arguments are handled in the manner of fmt.Print; a newline is appended if missing. -func Info(args ...interface{}) { - logging.print(infoLog, args...) -} - -// InfoDepth acts as Info but uses depth to determine which call frame to log. -// InfoDepth(0, "msg") is the same as Info("msg"). -func InfoDepth(depth int, args ...interface{}) { - logging.printDepth(infoLog, depth, args...) -} - -// Infoln logs to the INFO log. -// Arguments are handled in the manner of fmt.Println; a newline is appended if missing. -func Infoln(args ...interface{}) { - logging.println(infoLog, args...) -} - -// Infof logs to the INFO log. -// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. -func Infof(format string, args ...interface{}) { - logging.printf(infoLog, format, args...) -} - -// Warning logs to the WARNING and INFO logs. -// Arguments are handled in the manner of fmt.Print; a newline is appended if missing. -func Warning(args ...interface{}) { - logging.print(warningLog, args...) -} - -// WarningDepth acts as Warning but uses depth to determine which call frame to log. -// WarningDepth(0, "msg") is the same as Warning("msg"). -func WarningDepth(depth int, args ...interface{}) { - logging.printDepth(warningLog, depth, args...) -} - -// Warningln logs to the WARNING and INFO logs. -// Arguments are handled in the manner of fmt.Println; a newline is appended if missing. -func Warningln(args ...interface{}) { - logging.println(warningLog, args...) -} - -// Warningf logs to the WARNING and INFO logs. -// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. -func Warningf(format string, args ...interface{}) { - logging.printf(warningLog, format, args...) -} - -// Error logs to the ERROR, WARNING, and INFO logs. -// Arguments are handled in the manner of fmt.Print; a newline is appended if missing. -func Error(args ...interface{}) { - logging.print(errorLog, args...) -} - -// ErrorDepth acts as Error but uses depth to determine which call frame to log. -// ErrorDepth(0, "msg") is the same as Error("msg"). -func ErrorDepth(depth int, args ...interface{}) { - logging.printDepth(errorLog, depth, args...) -} - -// Errorln logs to the ERROR, WARNING, and INFO logs. -// Arguments are handled in the manner of fmt.Println; a newline is appended if missing. -func Errorln(args ...interface{}) { - logging.println(errorLog, args...) -} - -// Errorf logs to the ERROR, WARNING, and INFO logs. -// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. -func Errorf(format string, args ...interface{}) { - logging.printf(errorLog, format, args...) -} - -// Fatal logs to the FATAL, ERROR, WARNING, and INFO logs, -// including a stack trace of all running goroutines, then calls os.Exit(255). -// Arguments are handled in the manner of fmt.Print; a newline is appended if missing. -func Fatal(args ...interface{}) { - logging.print(fatalLog, args...) -} - -// FatalDepth acts as Fatal but uses depth to determine which call frame to log. -// FatalDepth(0, "msg") is the same as Fatal("msg"). -func FatalDepth(depth int, args ...interface{}) { - logging.printDepth(fatalLog, depth, args...) -} - -// Fatalln logs to the FATAL, ERROR, WARNING, and INFO logs, -// including a stack trace of all running goroutines, then calls os.Exit(255). -// Arguments are handled in the manner of fmt.Println; a newline is appended if missing. -func Fatalln(args ...interface{}) { - logging.println(fatalLog, args...) -} - -// Fatalf logs to the FATAL, ERROR, WARNING, and INFO logs, -// including a stack trace of all running goroutines, then calls os.Exit(255). -// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. -func Fatalf(format string, args ...interface{}) { - logging.printf(fatalLog, format, args...) -} - -// fatalNoStacks is non-zero if we are to exit without dumping goroutine stacks. -// It allows Exit and relatives to use the Fatal logs. -var fatalNoStacks uint32 - -// Exit logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1). -// Arguments are handled in the manner of fmt.Print; a newline is appended if missing. -func Exit(args ...interface{}) { - atomic.StoreUint32(&fatalNoStacks, 1) - logging.print(fatalLog, args...) -} - -// ExitDepth acts as Exit but uses depth to determine which call frame to log. -// ExitDepth(0, "msg") is the same as Exit("msg"). -func ExitDepth(depth int, args ...interface{}) { - atomic.StoreUint32(&fatalNoStacks, 1) - logging.printDepth(fatalLog, depth, args...) -} - -// Exitln logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1). -func Exitln(args ...interface{}) { - atomic.StoreUint32(&fatalNoStacks, 1) - logging.println(fatalLog, args...) -} - -// Exitf logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1). -// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. -func Exitf(format string, args ...interface{}) { - atomic.StoreUint32(&fatalNoStacks, 1) - logging.printf(fatalLog, format, args...) -} diff --git a/vendor/github.com/golang/glog/glog_file.go b/vendor/github.com/golang/glog/glog_file.go deleted file mode 100644 index 65075d281..000000000 --- a/vendor/github.com/golang/glog/glog_file.go +++ /dev/null @@ -1,124 +0,0 @@ -// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/ -// -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// File I/O for logs. - -package glog - -import ( - "errors" - "flag" - "fmt" - "os" - "os/user" - "path/filepath" - "strings" - "sync" - "time" -) - -// MaxSize is the maximum size of a log file in bytes. -var MaxSize uint64 = 1024 * 1024 * 1800 - -// logDirs lists the candidate directories for new log files. -var logDirs []string - -// If non-empty, overrides the choice of directory in which to write logs. -// See createLogDirs for the full list of possible destinations. -var logDir = flag.String("log_dir", "", "If non-empty, write log files in this directory") - -func createLogDirs() { - if *logDir != "" { - logDirs = append(logDirs, *logDir) - } - logDirs = append(logDirs, os.TempDir()) -} - -var ( - pid = os.Getpid() - program = filepath.Base(os.Args[0]) - host = "unknownhost" - userName = "unknownuser" -) - -func init() { - h, err := os.Hostname() - if err == nil { - host = shortHostname(h) - } - - current, err := user.Current() - if err == nil { - userName = current.Username - } - - // Sanitize userName since it may contain filepath separators on Windows. - userName = strings.Replace(userName, `\`, "_", -1) -} - -// shortHostname returns its argument, truncating at the first period. -// For instance, given "www.google.com" it returns "www". -func shortHostname(hostname string) string { - if i := strings.Index(hostname, "."); i >= 0 { - return hostname[:i] - } - return hostname -} - -// logName returns a new log file name containing tag, with start time t, and -// the name for the symlink for tag. -func logName(tag string, t time.Time) (name, link string) { - name = fmt.Sprintf("%s.%s.%s.log.%s.%04d%02d%02d-%02d%02d%02d.%d", - program, - host, - userName, - tag, - t.Year(), - t.Month(), - t.Day(), - t.Hour(), - t.Minute(), - t.Second(), - pid) - return name, program + "." + tag -} - -var onceLogDirs sync.Once - -// create creates a new log file and returns the file and its filename, which -// contains tag ("INFO", "FATAL", etc.) and t. If the file is created -// successfully, create also attempts to update the symlink for that tag, ignoring -// errors. -func create(tag string, t time.Time) (f *os.File, filename string, err error) { - onceLogDirs.Do(createLogDirs) - if len(logDirs) == 0 { - return nil, "", errors.New("log: no log dirs") - } - name, link := logName(tag, t) - var lastErr error - for _, dir := range logDirs { - fname := filepath.Join(dir, name) - f, err := os.Create(fname) - if err == nil { - symlink := filepath.Join(dir, link) - os.Remove(symlink) // ignore err - os.Symlink(name, symlink) // ignore err - return f, fname, nil - } - lastErr = err - } - return nil, "", fmt.Errorf("log: cannot create log: %v", lastErr) -} diff --git a/vendor/github.com/golang/protobuf/AUTHORS b/vendor/github.com/golang/protobuf/AUTHORS deleted file mode 100644 index 15167cd74..000000000 --- a/vendor/github.com/golang/protobuf/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/github.com/golang/protobuf/CONTRIBUTORS b/vendor/github.com/golang/protobuf/CONTRIBUTORS deleted file mode 100644 index 1c4577e96..000000000 --- a/vendor/github.com/golang/protobuf/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/github.com/golang/protobuf/LICENSE b/vendor/github.com/golang/protobuf/LICENSE deleted file mode 100644 index 1b1b1921e..000000000 --- a/vendor/github.com/golang/protobuf/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ -Go support for Protocol Buffers - Google's data interchange format - -Copyright 2010 The Go Authors. All rights reserved. -https://github.com/golang/protobuf - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/vendor/github.com/golang/protobuf/proto/clone.go b/vendor/github.com/golang/protobuf/proto/clone.go deleted file mode 100644 index 3cd3249f7..000000000 --- a/vendor/github.com/golang/protobuf/proto/clone.go +++ /dev/null @@ -1,253 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2011 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Protocol buffer deep copy and merge. -// TODO: RawMessage. - -package proto - -import ( - "fmt" - "log" - "reflect" - "strings" -) - -// Clone returns a deep copy of a protocol buffer. -func Clone(src Message) Message { - in := reflect.ValueOf(src) - if in.IsNil() { - return src - } - out := reflect.New(in.Type().Elem()) - dst := out.Interface().(Message) - Merge(dst, src) - return dst -} - -// Merger is the interface representing objects that can merge messages of the same type. -type Merger interface { - // Merge merges src into this message. - // Required and optional fields that are set in src will be set to that value in dst. - // Elements of repeated fields will be appended. - // - // Merge may panic if called with a different argument type than the receiver. - Merge(src Message) -} - -// generatedMerger is the custom merge method that generated protos will have. -// We must add this method since a generate Merge method will conflict with -// many existing protos that have a Merge data field already defined. -type generatedMerger interface { - XXX_Merge(src Message) -} - -// Merge merges src into dst. -// Required and optional fields that are set in src will be set to that value in dst. -// Elements of repeated fields will be appended. -// Merge panics if src and dst are not the same type, or if dst is nil. -func Merge(dst, src Message) { - if m, ok := dst.(Merger); ok { - m.Merge(src) - return - } - - in := reflect.ValueOf(src) - out := reflect.ValueOf(dst) - if out.IsNil() { - panic("proto: nil destination") - } - if in.Type() != out.Type() { - panic(fmt.Sprintf("proto.Merge(%T, %T) type mismatch", dst, src)) - } - if in.IsNil() { - return // Merge from nil src is a noop - } - if m, ok := dst.(generatedMerger); ok { - m.XXX_Merge(src) - return - } - mergeStruct(out.Elem(), in.Elem()) -} - -func mergeStruct(out, in reflect.Value) { - sprop := GetProperties(in.Type()) - for i := 0; i < in.NumField(); i++ { - f := in.Type().Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) - } - - if emIn, err := extendable(in.Addr().Interface()); err == nil { - emOut, _ := extendable(out.Addr().Interface()) - mIn, muIn := emIn.extensionsRead() - if mIn != nil { - mOut := emOut.extensionsWrite() - muIn.Lock() - mergeExtension(mOut, mIn) - muIn.Unlock() - } - } - - uf := in.FieldByName("XXX_unrecognized") - if !uf.IsValid() { - return - } - uin := uf.Bytes() - if len(uin) > 0 { - out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...)) - } -} - -// mergeAny performs a merge between two values of the same type. -// viaPtr indicates whether the values were indirected through a pointer (implying proto2). -// prop is set if this is a struct field (it may be nil). -func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) { - if in.Type() == protoMessageType { - if !in.IsNil() { - if out.IsNil() { - out.Set(reflect.ValueOf(Clone(in.Interface().(Message)))) - } else { - Merge(out.Interface().(Message), in.Interface().(Message)) - } - } - return - } - switch in.Kind() { - case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, - reflect.String, reflect.Uint32, reflect.Uint64: - if !viaPtr && isProto3Zero(in) { - return - } - out.Set(in) - case reflect.Interface: - // Probably a oneof field; copy non-nil values. - if in.IsNil() { - return - } - // Allocate destination if it is not set, or set to a different type. - // Otherwise we will merge as normal. - if out.IsNil() || out.Elem().Type() != in.Elem().Type() { - out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T) - } - mergeAny(out.Elem(), in.Elem(), false, nil) - case reflect.Map: - if in.Len() == 0 { - return - } - if out.IsNil() { - out.Set(reflect.MakeMap(in.Type())) - } - // For maps with value types of *T or []byte we need to deep copy each value. - elemKind := in.Type().Elem().Kind() - for _, key := range in.MapKeys() { - var val reflect.Value - switch elemKind { - case reflect.Ptr: - val = reflect.New(in.Type().Elem().Elem()) - mergeAny(val, in.MapIndex(key), false, nil) - case reflect.Slice: - val = in.MapIndex(key) - val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) - default: - val = in.MapIndex(key) - } - out.SetMapIndex(key, val) - } - case reflect.Ptr: - if in.IsNil() { - return - } - if out.IsNil() { - out.Set(reflect.New(in.Elem().Type())) - } - mergeAny(out.Elem(), in.Elem(), true, nil) - case reflect.Slice: - if in.IsNil() { - return - } - if in.Type().Elem().Kind() == reflect.Uint8 { - // []byte is a scalar bytes field, not a repeated field. - - // Edge case: if this is in a proto3 message, a zero length - // bytes field is considered the zero value, and should not - // be merged. - if prop != nil && prop.proto3 && in.Len() == 0 { - return - } - - // Make a deep copy. - // Append to []byte{} instead of []byte(nil) so that we never end up - // with a nil result. - out.SetBytes(append([]byte{}, in.Bytes()...)) - return - } - n := in.Len() - if out.IsNil() { - out.Set(reflect.MakeSlice(in.Type(), 0, n)) - } - switch in.Type().Elem().Kind() { - case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, - reflect.String, reflect.Uint32, reflect.Uint64: - out.Set(reflect.AppendSlice(out, in)) - default: - for i := 0; i < n; i++ { - x := reflect.Indirect(reflect.New(in.Type().Elem())) - mergeAny(x, in.Index(i), false, nil) - out.Set(reflect.Append(out, x)) - } - } - case reflect.Struct: - mergeStruct(out, in) - default: - // unknown type, so not a protocol buffer - log.Printf("proto: don't know how to copy %v", in) - } -} - -func mergeExtension(out, in map[int32]Extension) { - for extNum, eIn := range in { - eOut := Extension{desc: eIn.desc} - if eIn.value != nil { - v := reflect.New(reflect.TypeOf(eIn.value)).Elem() - mergeAny(v, reflect.ValueOf(eIn.value), false, nil) - eOut.value = v.Interface() - } - if eIn.enc != nil { - eOut.enc = make([]byte, len(eIn.enc)) - copy(eOut.enc, eIn.enc) - } - - out[extNum] = eOut - } -} diff --git a/vendor/github.com/golang/protobuf/proto/decode.go b/vendor/github.com/golang/protobuf/proto/decode.go deleted file mode 100644 index d9aa3c42d..000000000 --- a/vendor/github.com/golang/protobuf/proto/decode.go +++ /dev/null @@ -1,428 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Routines for decoding protocol buffer data to construct in-memory representations. - */ - -import ( - "errors" - "fmt" - "io" -) - -// errOverflow is returned when an integer is too large to be represented. -var errOverflow = errors.New("proto: integer overflow") - -// ErrInternalBadWireType is returned by generated code when an incorrect -// wire type is encountered. It does not get returned to user code. -var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") - -// DecodeVarint reads a varint-encoded integer from the slice. -// It returns the integer and the number of bytes consumed, or -// zero if there is not enough. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func DecodeVarint(buf []byte) (x uint64, n int) { - for shift := uint(0); shift < 64; shift += 7 { - if n >= len(buf) { - return 0, 0 - } - b := uint64(buf[n]) - n++ - x |= (b & 0x7F) << shift - if (b & 0x80) == 0 { - return x, n - } - } - - // The number is too large to represent in a 64-bit value. - return 0, 0 -} - -func (p *Buffer) decodeVarintSlow() (x uint64, err error) { - i := p.index - l := len(p.buf) - - for shift := uint(0); shift < 64; shift += 7 { - if i >= l { - err = io.ErrUnexpectedEOF - return - } - b := p.buf[i] - i++ - x |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - p.index = i - return - } - } - - // The number is too large to represent in a 64-bit value. - err = errOverflow - return -} - -// DecodeVarint reads a varint-encoded integer from the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (p *Buffer) DecodeVarint() (x uint64, err error) { - i := p.index - buf := p.buf - - if i >= len(buf) { - return 0, io.ErrUnexpectedEOF - } else if buf[i] < 0x80 { - p.index++ - return uint64(buf[i]), nil - } else if len(buf)-i < 10 { - return p.decodeVarintSlow() - } - - var b uint64 - // we already checked the first byte - x = uint64(buf[i]) - 0x80 - i++ - - b = uint64(buf[i]) - i++ - x += b << 7 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 7 - - b = uint64(buf[i]) - i++ - x += b << 14 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 14 - - b = uint64(buf[i]) - i++ - x += b << 21 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 21 - - b = uint64(buf[i]) - i++ - x += b << 28 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 28 - - b = uint64(buf[i]) - i++ - x += b << 35 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 35 - - b = uint64(buf[i]) - i++ - x += b << 42 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 42 - - b = uint64(buf[i]) - i++ - x += b << 49 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 49 - - b = uint64(buf[i]) - i++ - x += b << 56 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 56 - - b = uint64(buf[i]) - i++ - x += b << 63 - if b&0x80 == 0 { - goto done - } - // x -= 0x80 << 63 // Always zero. - - return 0, errOverflow - -done: - p.index = i - return x, nil -} - -// DecodeFixed64 reads a 64-bit integer from the Buffer. -// This is the format for the -// fixed64, sfixed64, and double protocol buffer types. -func (p *Buffer) DecodeFixed64() (x uint64, err error) { - // x, err already 0 - i := p.index + 8 - if i < 0 || i > len(p.buf) { - err = io.ErrUnexpectedEOF - return - } - p.index = i - - x = uint64(p.buf[i-8]) - x |= uint64(p.buf[i-7]) << 8 - x |= uint64(p.buf[i-6]) << 16 - x |= uint64(p.buf[i-5]) << 24 - x |= uint64(p.buf[i-4]) << 32 - x |= uint64(p.buf[i-3]) << 40 - x |= uint64(p.buf[i-2]) << 48 - x |= uint64(p.buf[i-1]) << 56 - return -} - -// DecodeFixed32 reads a 32-bit integer from the Buffer. -// This is the format for the -// fixed32, sfixed32, and float protocol buffer types. -func (p *Buffer) DecodeFixed32() (x uint64, err error) { - // x, err already 0 - i := p.index + 4 - if i < 0 || i > len(p.buf) { - err = io.ErrUnexpectedEOF - return - } - p.index = i - - x = uint64(p.buf[i-4]) - x |= uint64(p.buf[i-3]) << 8 - x |= uint64(p.buf[i-2]) << 16 - x |= uint64(p.buf[i-1]) << 24 - return -} - -// DecodeZigzag64 reads a zigzag-encoded 64-bit integer -// from the Buffer. -// This is the format used for the sint64 protocol buffer type. -func (p *Buffer) DecodeZigzag64() (x uint64, err error) { - x, err = p.DecodeVarint() - if err != nil { - return - } - x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63) - return -} - -// DecodeZigzag32 reads a zigzag-encoded 32-bit integer -// from the Buffer. -// This is the format used for the sint32 protocol buffer type. -func (p *Buffer) DecodeZigzag32() (x uint64, err error) { - x, err = p.DecodeVarint() - if err != nil { - return - } - x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31)) - return -} - -// DecodeRawBytes reads a count-delimited byte buffer from the Buffer. -// This is the format used for the bytes protocol buffer -// type and for embedded messages. -func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { - n, err := p.DecodeVarint() - if err != nil { - return nil, err - } - - nb := int(n) - if nb < 0 { - return nil, fmt.Errorf("proto: bad byte length %d", nb) - } - end := p.index + nb - if end < p.index || end > len(p.buf) { - return nil, io.ErrUnexpectedEOF - } - - if !alloc { - // todo: check if can get more uses of alloc=false - buf = p.buf[p.index:end] - p.index += nb - return - } - - buf = make([]byte, nb) - copy(buf, p.buf[p.index:]) - p.index += nb - return -} - -// DecodeStringBytes reads an encoded string from the Buffer. -// This is the format used for the proto2 string type. -func (p *Buffer) DecodeStringBytes() (s string, err error) { - buf, err := p.DecodeRawBytes(false) - if err != nil { - return - } - return string(buf), nil -} - -// Unmarshaler is the interface representing objects that can -// unmarshal themselves. The argument points to data that may be -// overwritten, so implementations should not keep references to the -// buffer. -// Unmarshal implementations should not clear the receiver. -// Any unmarshaled data should be merged into the receiver. -// Callers of Unmarshal that do not want to retain existing data -// should Reset the receiver before calling Unmarshal. -type Unmarshaler interface { - Unmarshal([]byte) error -} - -// newUnmarshaler is the interface representing objects that can -// unmarshal themselves. The semantics are identical to Unmarshaler. -// -// This exists to support protoc-gen-go generated messages. -// The proto package will stop type-asserting to this interface in the future. -// -// DO NOT DEPEND ON THIS. -type newUnmarshaler interface { - XXX_Unmarshal([]byte) error -} - -// Unmarshal parses the protocol buffer representation in buf and places the -// decoded result in pb. If the struct underlying pb does not match -// the data in buf, the results can be unpredictable. -// -// Unmarshal resets pb before starting to unmarshal, so any -// existing data in pb is always removed. Use UnmarshalMerge -// to preserve and append to existing data. -func Unmarshal(buf []byte, pb Message) error { - pb.Reset() - if u, ok := pb.(newUnmarshaler); ok { - return u.XXX_Unmarshal(buf) - } - if u, ok := pb.(Unmarshaler); ok { - return u.Unmarshal(buf) - } - return NewBuffer(buf).Unmarshal(pb) -} - -// UnmarshalMerge parses the protocol buffer representation in buf and -// writes the decoded result to pb. If the struct underlying pb does not match -// the data in buf, the results can be unpredictable. -// -// UnmarshalMerge merges into existing data in pb. -// Most code should use Unmarshal instead. -func UnmarshalMerge(buf []byte, pb Message) error { - if u, ok := pb.(newUnmarshaler); ok { - return u.XXX_Unmarshal(buf) - } - if u, ok := pb.(Unmarshaler); ok { - // NOTE: The history of proto have unfortunately been inconsistent - // whether Unmarshaler should or should not implicitly clear itself. - // Some implementations do, most do not. - // Thus, calling this here may or may not do what people want. - // - // See https://github.com/golang/protobuf/issues/424 - return u.Unmarshal(buf) - } - return NewBuffer(buf).Unmarshal(pb) -} - -// DecodeMessage reads a count-delimited message from the Buffer. -func (p *Buffer) DecodeMessage(pb Message) error { - enc, err := p.DecodeRawBytes(false) - if err != nil { - return err - } - return NewBuffer(enc).Unmarshal(pb) -} - -// DecodeGroup reads a tag-delimited group from the Buffer. -// StartGroup tag is already consumed. This function consumes -// EndGroup tag. -func (p *Buffer) DecodeGroup(pb Message) error { - b := p.buf[p.index:] - x, y := findEndGroup(b) - if x < 0 { - return io.ErrUnexpectedEOF - } - err := Unmarshal(b[:x], pb) - p.index += y - return err -} - -// Unmarshal parses the protocol buffer representation in the -// Buffer and places the decoded result in pb. If the struct -// underlying pb does not match the data in the buffer, the results can be -// unpredictable. -// -// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal. -func (p *Buffer) Unmarshal(pb Message) error { - // If the object can unmarshal itself, let it. - if u, ok := pb.(newUnmarshaler); ok { - err := u.XXX_Unmarshal(p.buf[p.index:]) - p.index = len(p.buf) - return err - } - if u, ok := pb.(Unmarshaler); ok { - // NOTE: The history of proto have unfortunately been inconsistent - // whether Unmarshaler should or should not implicitly clear itself. - // Some implementations do, most do not. - // Thus, calling this here may or may not do what people want. - // - // See https://github.com/golang/protobuf/issues/424 - err := u.Unmarshal(p.buf[p.index:]) - p.index = len(p.buf) - return err - } - - // Slow workaround for messages that aren't Unmarshalers. - // This includes some hand-coded .pb.go files and - // bootstrap protos. - // TODO: fix all of those and then add Unmarshal to - // the Message interface. Then: - // The cast above and code below can be deleted. - // The old unmarshaler can be deleted. - // Clients can call Unmarshal directly (can already do that, actually). - var info InternalMessageInfo - err := info.Unmarshal(pb, p.buf[p.index:]) - p.index = len(p.buf) - return err -} diff --git a/vendor/github.com/golang/protobuf/proto/discard.go b/vendor/github.com/golang/protobuf/proto/discard.go deleted file mode 100644 index dea2617ce..000000000 --- a/vendor/github.com/golang/protobuf/proto/discard.go +++ /dev/null @@ -1,350 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2017 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "reflect" - "strings" - "sync" - "sync/atomic" -) - -type generatedDiscarder interface { - XXX_DiscardUnknown() -} - -// DiscardUnknown recursively discards all unknown fields from this message -// and all embedded messages. -// -// When unmarshaling a message with unrecognized fields, the tags and values -// of such fields are preserved in the Message. This allows a later call to -// marshal to be able to produce a message that continues to have those -// unrecognized fields. To avoid this, DiscardUnknown is used to -// explicitly clear the unknown fields after unmarshaling. -// -// For proto2 messages, the unknown fields of message extensions are only -// discarded from messages that have been accessed via GetExtension. -func DiscardUnknown(m Message) { - if m, ok := m.(generatedDiscarder); ok { - m.XXX_DiscardUnknown() - return - } - // TODO: Dynamically populate a InternalMessageInfo for legacy messages, - // but the master branch has no implementation for InternalMessageInfo, - // so it would be more work to replicate that approach. - discardLegacy(m) -} - -// DiscardUnknown recursively discards all unknown fields. -func (a *InternalMessageInfo) DiscardUnknown(m Message) { - di := atomicLoadDiscardInfo(&a.discard) - if di == nil { - di = getDiscardInfo(reflect.TypeOf(m).Elem()) - atomicStoreDiscardInfo(&a.discard, di) - } - di.discard(toPointer(&m)) -} - -type discardInfo struct { - typ reflect.Type - - initialized int32 // 0: only typ is valid, 1: everything is valid - lock sync.Mutex - - fields []discardFieldInfo - unrecognized field -} - -type discardFieldInfo struct { - field field // Offset of field, guaranteed to be valid - discard func(src pointer) -} - -var ( - discardInfoMap = map[reflect.Type]*discardInfo{} - discardInfoLock sync.Mutex -) - -func getDiscardInfo(t reflect.Type) *discardInfo { - discardInfoLock.Lock() - defer discardInfoLock.Unlock() - di := discardInfoMap[t] - if di == nil { - di = &discardInfo{typ: t} - discardInfoMap[t] = di - } - return di -} - -func (di *discardInfo) discard(src pointer) { - if src.isNil() { - return // Nothing to do. - } - - if atomic.LoadInt32(&di.initialized) == 0 { - di.computeDiscardInfo() - } - - for _, fi := range di.fields { - sfp := src.offset(fi.field) - fi.discard(sfp) - } - - // For proto2 messages, only discard unknown fields in message extensions - // that have been accessed via GetExtension. - if em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil { - // Ignore lock since DiscardUnknown is not concurrency safe. - emm, _ := em.extensionsRead() - for _, mx := range emm { - if m, ok := mx.value.(Message); ok { - DiscardUnknown(m) - } - } - } - - if di.unrecognized.IsValid() { - *src.offset(di.unrecognized).toBytes() = nil - } -} - -func (di *discardInfo) computeDiscardInfo() { - di.lock.Lock() - defer di.lock.Unlock() - if di.initialized != 0 { - return - } - t := di.typ - n := t.NumField() - - for i := 0; i < n; i++ { - f := t.Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - - dfi := discardFieldInfo{field: toField(&f)} - tf := f.Type - - // Unwrap tf to get its most basic type. - var isPointer, isSlice bool - if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { - isSlice = true - tf = tf.Elem() - } - if tf.Kind() == reflect.Ptr { - isPointer = true - tf = tf.Elem() - } - if isPointer && isSlice && tf.Kind() != reflect.Struct { - panic(fmt.Sprintf("%v.%s cannot be a slice of pointers to primitive types", t, f.Name)) - } - - switch tf.Kind() { - case reflect.Struct: - switch { - case !isPointer: - panic(fmt.Sprintf("%v.%s cannot be a direct struct value", t, f.Name)) - case isSlice: // E.g., []*pb.T - di := getDiscardInfo(tf) - dfi.discard = func(src pointer) { - sps := src.getPointerSlice() - for _, sp := range sps { - if !sp.isNil() { - di.discard(sp) - } - } - } - default: // E.g., *pb.T - di := getDiscardInfo(tf) - dfi.discard = func(src pointer) { - sp := src.getPointer() - if !sp.isNil() { - di.discard(sp) - } - } - } - case reflect.Map: - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%v.%s cannot be a pointer to a map or a slice of map values", t, f.Name)) - default: // E.g., map[K]V - if tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T) - dfi.discard = func(src pointer) { - sm := src.asPointerTo(tf).Elem() - if sm.Len() == 0 { - return - } - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - DiscardUnknown(val.Interface().(Message)) - } - } - } else { - dfi.discard = func(pointer) {} // Noop - } - } - case reflect.Interface: - // Must be oneof field. - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%v.%s cannot be a pointer to a interface or a slice of interface values", t, f.Name)) - default: // E.g., interface{} - // TODO: Make this faster? - dfi.discard = func(src pointer) { - su := src.asPointerTo(tf).Elem() - if !su.IsNil() { - sv := su.Elem().Elem().Field(0) - if sv.Kind() == reflect.Ptr && sv.IsNil() { - return - } - switch sv.Type().Kind() { - case reflect.Ptr: // Proto struct (e.g., *T) - DiscardUnknown(sv.Interface().(Message)) - } - } - } - } - default: - continue - } - di.fields = append(di.fields, dfi) - } - - di.unrecognized = invalidField - if f, ok := t.FieldByName("XXX_unrecognized"); ok { - if f.Type != reflect.TypeOf([]byte{}) { - panic("expected XXX_unrecognized to be of type []byte") - } - di.unrecognized = toField(&f) - } - - atomic.StoreInt32(&di.initialized, 1) -} - -func discardLegacy(m Message) { - v := reflect.ValueOf(m) - if v.Kind() != reflect.Ptr || v.IsNil() { - return - } - v = v.Elem() - if v.Kind() != reflect.Struct { - return - } - t := v.Type() - - for i := 0; i < v.NumField(); i++ { - f := t.Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - vf := v.Field(i) - tf := f.Type - - // Unwrap tf to get its most basic type. - var isPointer, isSlice bool - if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { - isSlice = true - tf = tf.Elem() - } - if tf.Kind() == reflect.Ptr { - isPointer = true - tf = tf.Elem() - } - if isPointer && isSlice && tf.Kind() != reflect.Struct { - panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name)) - } - - switch tf.Kind() { - case reflect.Struct: - switch { - case !isPointer: - panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name)) - case isSlice: // E.g., []*pb.T - for j := 0; j < vf.Len(); j++ { - discardLegacy(vf.Index(j).Interface().(Message)) - } - default: // E.g., *pb.T - discardLegacy(vf.Interface().(Message)) - } - case reflect.Map: - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name)) - default: // E.g., map[K]V - tv := vf.Type().Elem() - if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T) - for _, key := range vf.MapKeys() { - val := vf.MapIndex(key) - discardLegacy(val.Interface().(Message)) - } - } - } - case reflect.Interface: - // Must be oneof field. - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name)) - default: // E.g., test_proto.isCommunique_Union interface - if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" { - vf = vf.Elem() // E.g., *test_proto.Communique_Msg - if !vf.IsNil() { - vf = vf.Elem() // E.g., test_proto.Communique_Msg - vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value - if vf.Kind() == reflect.Ptr { - discardLegacy(vf.Interface().(Message)) - } - } - } - } - } - } - - if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() { - if vf.Type() != reflect.TypeOf([]byte{}) { - panic("expected XXX_unrecognized to be of type []byte") - } - vf.Set(reflect.ValueOf([]byte(nil))) - } - - // For proto2 messages, only discard unknown fields in message extensions - // that have been accessed via GetExtension. - if em, err := extendable(m); err == nil { - // Ignore lock since discardLegacy is not concurrency safe. - emm, _ := em.extensionsRead() - for _, mx := range emm { - if m, ok := mx.value.(Message); ok { - discardLegacy(m) - } - } - } -} diff --git a/vendor/github.com/golang/protobuf/proto/encode.go b/vendor/github.com/golang/protobuf/proto/encode.go deleted file mode 100644 index c27d35f86..000000000 --- a/vendor/github.com/golang/protobuf/proto/encode.go +++ /dev/null @@ -1,221 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Routines for encoding data into the wire format for protocol buffers. - */ - -import ( - "errors" - "fmt" - "reflect" -) - -// RequiredNotSetError is the error returned if Marshal is called with -// a protocol buffer struct whose required fields have not -// all been initialized. It is also the error returned if Unmarshal is -// called with an encoded protocol buffer that does not include all the -// required fields. -// -// When printed, RequiredNotSetError reports the first unset required field in a -// message. If the field cannot be precisely determined, it is reported as -// "{Unknown}". -type RequiredNotSetError struct { - field string -} - -func (e *RequiredNotSetError) Error() string { - return fmt.Sprintf("proto: required field %q not set", e.field) -} - -var ( - // errRepeatedHasNil is the error returned if Marshal is called with - // a struct with a repeated field containing a nil element. - errRepeatedHasNil = errors.New("proto: repeated field has nil element") - - // errOneofHasNil is the error returned if Marshal is called with - // a struct with a oneof field containing a nil element. - errOneofHasNil = errors.New("proto: oneof field has nil value") - - // ErrNil is the error returned if Marshal is called with nil. - ErrNil = errors.New("proto: Marshal called with nil") - - // ErrTooLarge is the error returned if Marshal is called with a - // message that encodes to >2GB. - ErrTooLarge = errors.New("proto: message encodes to over 2 GB") -) - -// The fundamental encoders that put bytes on the wire. -// Those that take integer types all accept uint64 and are -// therefore of type valueEncoder. - -const maxVarintBytes = 10 // maximum length of a varint - -// EncodeVarint returns the varint encoding of x. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -// Not used by the package itself, but helpful to clients -// wishing to use the same encoding. -func EncodeVarint(x uint64) []byte { - var buf [maxVarintBytes]byte - var n int - for n = 0; x > 127; n++ { - buf[n] = 0x80 | uint8(x&0x7F) - x >>= 7 - } - buf[n] = uint8(x) - n++ - return buf[0:n] -} - -// EncodeVarint writes a varint-encoded integer to the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (p *Buffer) EncodeVarint(x uint64) error { - for x >= 1<<7 { - p.buf = append(p.buf, uint8(x&0x7f|0x80)) - x >>= 7 - } - p.buf = append(p.buf, uint8(x)) - return nil -} - -// SizeVarint returns the varint encoding size of an integer. -func SizeVarint(x uint64) int { - switch { - case x < 1<<7: - return 1 - case x < 1<<14: - return 2 - case x < 1<<21: - return 3 - case x < 1<<28: - return 4 - case x < 1<<35: - return 5 - case x < 1<<42: - return 6 - case x < 1<<49: - return 7 - case x < 1<<56: - return 8 - case x < 1<<63: - return 9 - } - return 10 -} - -// EncodeFixed64 writes a 64-bit integer to the Buffer. -// This is the format for the -// fixed64, sfixed64, and double protocol buffer types. -func (p *Buffer) EncodeFixed64(x uint64) error { - p.buf = append(p.buf, - uint8(x), - uint8(x>>8), - uint8(x>>16), - uint8(x>>24), - uint8(x>>32), - uint8(x>>40), - uint8(x>>48), - uint8(x>>56)) - return nil -} - -// EncodeFixed32 writes a 32-bit integer to the Buffer. -// This is the format for the -// fixed32, sfixed32, and float protocol buffer types. -func (p *Buffer) EncodeFixed32(x uint64) error { - p.buf = append(p.buf, - uint8(x), - uint8(x>>8), - uint8(x>>16), - uint8(x>>24)) - return nil -} - -// EncodeZigzag64 writes a zigzag-encoded 64-bit integer -// to the Buffer. -// This is the format used for the sint64 protocol buffer type. -func (p *Buffer) EncodeZigzag64(x uint64) error { - // use signed number to get arithmetic right shift. - return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} - -// EncodeZigzag32 writes a zigzag-encoded 32-bit integer -// to the Buffer. -// This is the format used for the sint32 protocol buffer type. -func (p *Buffer) EncodeZigzag32(x uint64) error { - // use signed number to get arithmetic right shift. - return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) -} - -// EncodeRawBytes writes a count-delimited byte buffer to the Buffer. -// This is the format used for the bytes protocol buffer -// type and for embedded messages. -func (p *Buffer) EncodeRawBytes(b []byte) error { - p.EncodeVarint(uint64(len(b))) - p.buf = append(p.buf, b...) - return nil -} - -// EncodeStringBytes writes an encoded string to the Buffer. -// This is the format used for the proto2 string type. -func (p *Buffer) EncodeStringBytes(s string) error { - p.EncodeVarint(uint64(len(s))) - p.buf = append(p.buf, s...) - return nil -} - -// Marshaler is the interface representing objects that can marshal themselves. -type Marshaler interface { - Marshal() ([]byte, error) -} - -// EncodeMessage writes the protocol buffer to the Buffer, -// prefixed by a varint-encoded length. -func (p *Buffer) EncodeMessage(pb Message) error { - siz := Size(pb) - p.EncodeVarint(uint64(siz)) - return p.Marshal(pb) -} - -// All protocol buffer fields are nillable, but be careful. -func isNil(v reflect.Value) bool { - switch v.Kind() { - case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return v.IsNil() - } - return false -} diff --git a/vendor/github.com/golang/protobuf/proto/equal.go b/vendor/github.com/golang/protobuf/proto/equal.go deleted file mode 100644 index d4db5a1c1..000000000 --- a/vendor/github.com/golang/protobuf/proto/equal.go +++ /dev/null @@ -1,300 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2011 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Protocol buffer comparison. - -package proto - -import ( - "bytes" - "log" - "reflect" - "strings" -) - -/* -Equal returns true iff protocol buffers a and b are equal. -The arguments must both be pointers to protocol buffer structs. - -Equality is defined in this way: - - Two messages are equal iff they are the same type, - corresponding fields are equal, unknown field sets - are equal, and extensions sets are equal. - - Two set scalar fields are equal iff their values are equal. - If the fields are of a floating-point type, remember that - NaN != x for all x, including NaN. If the message is defined - in a proto3 .proto file, fields are not "set"; specifically, - zero length proto3 "bytes" fields are equal (nil == {}). - - Two repeated fields are equal iff their lengths are the same, - and their corresponding elements are equal. Note a "bytes" field, - although represented by []byte, is not a repeated field and the - rule for the scalar fields described above applies. - - Two unset fields are equal. - - Two unknown field sets are equal if their current - encoded state is equal. - - Two extension sets are equal iff they have corresponding - elements that are pairwise equal. - - Two map fields are equal iff their lengths are the same, - and they contain the same set of elements. Zero-length map - fields are equal. - - Every other combination of things are not equal. - -The return value is undefined if a and b are not protocol buffers. -*/ -func Equal(a, b Message) bool { - if a == nil || b == nil { - return a == b - } - v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b) - if v1.Type() != v2.Type() { - return false - } - if v1.Kind() == reflect.Ptr { - if v1.IsNil() { - return v2.IsNil() - } - if v2.IsNil() { - return false - } - v1, v2 = v1.Elem(), v2.Elem() - } - if v1.Kind() != reflect.Struct { - return false - } - return equalStruct(v1, v2) -} - -// v1 and v2 are known to have the same type. -func equalStruct(v1, v2 reflect.Value) bool { - sprop := GetProperties(v1.Type()) - for i := 0; i < v1.NumField(); i++ { - f := v1.Type().Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - f1, f2 := v1.Field(i), v2.Field(i) - if f.Type.Kind() == reflect.Ptr { - if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 { - // both unset - continue - } else if n1 != n2 { - // set/unset mismatch - return false - } - f1, f2 = f1.Elem(), f2.Elem() - } - if !equalAny(f1, f2, sprop.Prop[i]) { - return false - } - } - - if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() { - em2 := v2.FieldByName("XXX_InternalExtensions") - if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) { - return false - } - } - - if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { - em2 := v2.FieldByName("XXX_extensions") - if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) { - return false - } - } - - uf := v1.FieldByName("XXX_unrecognized") - if !uf.IsValid() { - return true - } - - u1 := uf.Bytes() - u2 := v2.FieldByName("XXX_unrecognized").Bytes() - return bytes.Equal(u1, u2) -} - -// v1 and v2 are known to have the same type. -// prop may be nil. -func equalAny(v1, v2 reflect.Value, prop *Properties) bool { - if v1.Type() == protoMessageType { - m1, _ := v1.Interface().(Message) - m2, _ := v2.Interface().(Message) - return Equal(m1, m2) - } - switch v1.Kind() { - case reflect.Bool: - return v1.Bool() == v2.Bool() - case reflect.Float32, reflect.Float64: - return v1.Float() == v2.Float() - case reflect.Int32, reflect.Int64: - return v1.Int() == v2.Int() - case reflect.Interface: - // Probably a oneof field; compare the inner values. - n1, n2 := v1.IsNil(), v2.IsNil() - if n1 || n2 { - return n1 == n2 - } - e1, e2 := v1.Elem(), v2.Elem() - if e1.Type() != e2.Type() { - return false - } - return equalAny(e1, e2, nil) - case reflect.Map: - if v1.Len() != v2.Len() { - return false - } - for _, key := range v1.MapKeys() { - val2 := v2.MapIndex(key) - if !val2.IsValid() { - // This key was not found in the second map. - return false - } - if !equalAny(v1.MapIndex(key), val2, nil) { - return false - } - } - return true - case reflect.Ptr: - // Maps may have nil values in them, so check for nil. - if v1.IsNil() && v2.IsNil() { - return true - } - if v1.IsNil() != v2.IsNil() { - return false - } - return equalAny(v1.Elem(), v2.Elem(), prop) - case reflect.Slice: - if v1.Type().Elem().Kind() == reflect.Uint8 { - // short circuit: []byte - - // Edge case: if this is in a proto3 message, a zero length - // bytes field is considered the zero value. - if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 { - return true - } - if v1.IsNil() != v2.IsNil() { - return false - } - return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte)) - } - - if v1.Len() != v2.Len() { - return false - } - for i := 0; i < v1.Len(); i++ { - if !equalAny(v1.Index(i), v2.Index(i), prop) { - return false - } - } - return true - case reflect.String: - return v1.Interface().(string) == v2.Interface().(string) - case reflect.Struct: - return equalStruct(v1, v2) - case reflect.Uint32, reflect.Uint64: - return v1.Uint() == v2.Uint() - } - - // unknown type, so not a protocol buffer - log.Printf("proto: don't know how to compare %v", v1) - return false -} - -// base is the struct type that the extensions are based on. -// x1 and x2 are InternalExtensions. -func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool { - em1, _ := x1.extensionsRead() - em2, _ := x2.extensionsRead() - return equalExtMap(base, em1, em2) -} - -func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool { - if len(em1) != len(em2) { - return false - } - - for extNum, e1 := range em1 { - e2, ok := em2[extNum] - if !ok { - return false - } - - m1, m2 := e1.value, e2.value - - if m1 == nil && m2 == nil { - // Both have only encoded form. - if bytes.Equal(e1.enc, e2.enc) { - continue - } - // The bytes are different, but the extensions might still be - // equal. We need to decode them to compare. - } - - if m1 != nil && m2 != nil { - // Both are unencoded. - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { - return false - } - continue - } - - // At least one is encoded. To do a semantically correct comparison - // we need to unmarshal them first. - var desc *ExtensionDesc - if m := extensionMaps[base]; m != nil { - desc = m[extNum] - } - if desc == nil { - // If both have only encoded form and the bytes are the same, - // it is handled above. We get here when the bytes are different. - // We don't know how to decode it, so just compare them as byte - // slices. - log.Printf("proto: don't know how to compare extension %d of %v", extNum, base) - return false - } - var err error - if m1 == nil { - m1, err = decodeExtension(e1.enc, desc) - } - if m2 == nil && err == nil { - m2, err = decodeExtension(e2.enc, desc) - } - if err != nil { - // The encoded form is invalid. - log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err) - return false - } - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { - return false - } - } - - return true -} diff --git a/vendor/github.com/golang/protobuf/proto/extensions.go b/vendor/github.com/golang/protobuf/proto/extensions.go deleted file mode 100644 index 816a3b9d6..000000000 --- a/vendor/github.com/golang/protobuf/proto/extensions.go +++ /dev/null @@ -1,543 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Types and routines for supporting protocol buffer extensions. - */ - -import ( - "errors" - "fmt" - "io" - "reflect" - "strconv" - "sync" -) - -// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message. -var ErrMissingExtension = errors.New("proto: missing extension") - -// ExtensionRange represents a range of message extensions for a protocol buffer. -// Used in code generated by the protocol compiler. -type ExtensionRange struct { - Start, End int32 // both inclusive -} - -// extendableProto is an interface implemented by any protocol buffer generated by the current -// proto compiler that may be extended. -type extendableProto interface { - Message - ExtensionRangeArray() []ExtensionRange - extensionsWrite() map[int32]Extension - extensionsRead() (map[int32]Extension, sync.Locker) -} - -// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous -// version of the proto compiler that may be extended. -type extendableProtoV1 interface { - Message - ExtensionRangeArray() []ExtensionRange - ExtensionMap() map[int32]Extension -} - -// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto. -type extensionAdapter struct { - extendableProtoV1 -} - -func (e extensionAdapter) extensionsWrite() map[int32]Extension { - return e.ExtensionMap() -} - -func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) { - return e.ExtensionMap(), notLocker{} -} - -// notLocker is a sync.Locker whose Lock and Unlock methods are nops. -type notLocker struct{} - -func (n notLocker) Lock() {} -func (n notLocker) Unlock() {} - -// extendable returns the extendableProto interface for the given generated proto message. -// If the proto message has the old extension format, it returns a wrapper that implements -// the extendableProto interface. -func extendable(p interface{}) (extendableProto, error) { - switch p := p.(type) { - case extendableProto: - if isNilPtr(p) { - return nil, fmt.Errorf("proto: nil %T is not extendable", p) - } - return p, nil - case extendableProtoV1: - if isNilPtr(p) { - return nil, fmt.Errorf("proto: nil %T is not extendable", p) - } - return extensionAdapter{p}, nil - } - // Don't allocate a specific error containing %T: - // this is the hot path for Clone and MarshalText. - return nil, errNotExtendable -} - -var errNotExtendable = errors.New("proto: not an extendable proto.Message") - -func isNilPtr(x interface{}) bool { - v := reflect.ValueOf(x) - return v.Kind() == reflect.Ptr && v.IsNil() -} - -// XXX_InternalExtensions is an internal representation of proto extensions. -// -// Each generated message struct type embeds an anonymous XXX_InternalExtensions field, -// thus gaining the unexported 'extensions' method, which can be called only from the proto package. -// -// The methods of XXX_InternalExtensions are not concurrency safe in general, -// but calls to logically read-only methods such as has and get may be executed concurrently. -type XXX_InternalExtensions struct { - // The struct must be indirect so that if a user inadvertently copies a - // generated message and its embedded XXX_InternalExtensions, they - // avoid the mayhem of a copied mutex. - // - // The mutex serializes all logically read-only operations to p.extensionMap. - // It is up to the client to ensure that write operations to p.extensionMap are - // mutually exclusive with other accesses. - p *struct { - mu sync.Mutex - extensionMap map[int32]Extension - } -} - -// extensionsWrite returns the extension map, creating it on first use. -func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension { - if e.p == nil { - e.p = new(struct { - mu sync.Mutex - extensionMap map[int32]Extension - }) - e.p.extensionMap = make(map[int32]Extension) - } - return e.p.extensionMap -} - -// extensionsRead returns the extensions map for read-only use. It may be nil. -// The caller must hold the returned mutex's lock when accessing Elements within the map. -func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) { - if e.p == nil { - return nil, nil - } - return e.p.extensionMap, &e.p.mu -} - -// ExtensionDesc represents an extension specification. -// Used in generated code from the protocol compiler. -type ExtensionDesc struct { - ExtendedType Message // nil pointer to the type that is being extended - ExtensionType interface{} // nil pointer to the extension type - Field int32 // field number - Name string // fully-qualified name of extension, for text formatting - Tag string // protobuf tag style - Filename string // name of the file in which the extension is defined -} - -func (ed *ExtensionDesc) repeated() bool { - t := reflect.TypeOf(ed.ExtensionType) - return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 -} - -// Extension represents an extension in a message. -type Extension struct { - // When an extension is stored in a message using SetExtension - // only desc and value are set. When the message is marshaled - // enc will be set to the encoded form of the message. - // - // When a message is unmarshaled and contains extensions, each - // extension will have only enc set. When such an extension is - // accessed using GetExtension (or GetExtensions) desc and value - // will be set. - desc *ExtensionDesc - value interface{} - enc []byte -} - -// SetRawExtension is for testing only. -func SetRawExtension(base Message, id int32, b []byte) { - epb, err := extendable(base) - if err != nil { - return - } - extmap := epb.extensionsWrite() - extmap[id] = Extension{enc: b} -} - -// isExtensionField returns true iff the given field number is in an extension range. -func isExtensionField(pb extendableProto, field int32) bool { - for _, er := range pb.ExtensionRangeArray() { - if er.Start <= field && field <= er.End { - return true - } - } - return false -} - -// checkExtensionTypes checks that the given extension is valid for pb. -func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error { - var pbi interface{} = pb - // Check the extended type. - if ea, ok := pbi.(extensionAdapter); ok { - pbi = ea.extendableProtoV1 - } - if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b { - return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a) - } - // Check the range. - if !isExtensionField(pb, extension.Field) { - return errors.New("proto: bad extension number; not in declared ranges") - } - return nil -} - -// extPropKey is sufficient to uniquely identify an extension. -type extPropKey struct { - base reflect.Type - field int32 -} - -var extProp = struct { - sync.RWMutex - m map[extPropKey]*Properties -}{ - m: make(map[extPropKey]*Properties), -} - -func extensionProperties(ed *ExtensionDesc) *Properties { - key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field} - - extProp.RLock() - if prop, ok := extProp.m[key]; ok { - extProp.RUnlock() - return prop - } - extProp.RUnlock() - - extProp.Lock() - defer extProp.Unlock() - // Check again. - if prop, ok := extProp.m[key]; ok { - return prop - } - - prop := new(Properties) - prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil) - extProp.m[key] = prop - return prop -} - -// HasExtension returns whether the given extension is present in pb. -func HasExtension(pb Message, extension *ExtensionDesc) bool { - // TODO: Check types, field numbers, etc.? - epb, err := extendable(pb) - if err != nil { - return false - } - extmap, mu := epb.extensionsRead() - if extmap == nil { - return false - } - mu.Lock() - _, ok := extmap[extension.Field] - mu.Unlock() - return ok -} - -// ClearExtension removes the given extension from pb. -func ClearExtension(pb Message, extension *ExtensionDesc) { - epb, err := extendable(pb) - if err != nil { - return - } - // TODO: Check types, field numbers, etc.? - extmap := epb.extensionsWrite() - delete(extmap, extension.Field) -} - -// GetExtension retrieves a proto2 extended field from pb. -// -// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil), -// then GetExtension parses the encoded field and returns a Go value of the specified type. -// If the field is not present, then the default value is returned (if one is specified), -// otherwise ErrMissingExtension is reported. -// -// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil), -// then GetExtension returns the raw encoded bytes of the field extension. -func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { - epb, err := extendable(pb) - if err != nil { - return nil, err - } - - if extension.ExtendedType != nil { - // can only check type if this is a complete descriptor - if err := checkExtensionTypes(epb, extension); err != nil { - return nil, err - } - } - - emap, mu := epb.extensionsRead() - if emap == nil { - return defaultExtensionValue(extension) - } - mu.Lock() - defer mu.Unlock() - e, ok := emap[extension.Field] - if !ok { - // defaultExtensionValue returns the default value or - // ErrMissingExtension if there is no default. - return defaultExtensionValue(extension) - } - - if e.value != nil { - // Already decoded. Check the descriptor, though. - if e.desc != extension { - // This shouldn't happen. If it does, it means that - // GetExtension was called twice with two different - // descriptors with the same field number. - return nil, errors.New("proto: descriptor conflict") - } - return e.value, nil - } - - if extension.ExtensionType == nil { - // incomplete descriptor - return e.enc, nil - } - - v, err := decodeExtension(e.enc, extension) - if err != nil { - return nil, err - } - - // Remember the decoded version and drop the encoded version. - // That way it is safe to mutate what we return. - e.value = v - e.desc = extension - e.enc = nil - emap[extension.Field] = e - return e.value, nil -} - -// defaultExtensionValue returns the default value for extension. -// If no default for an extension is defined ErrMissingExtension is returned. -func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { - if extension.ExtensionType == nil { - // incomplete descriptor, so no default - return nil, ErrMissingExtension - } - - t := reflect.TypeOf(extension.ExtensionType) - props := extensionProperties(extension) - - sf, _, err := fieldDefault(t, props) - if err != nil { - return nil, err - } - - if sf == nil || sf.value == nil { - // There is no default value. - return nil, ErrMissingExtension - } - - if t.Kind() != reflect.Ptr { - // We do not need to return a Ptr, we can directly return sf.value. - return sf.value, nil - } - - // We need to return an interface{} that is a pointer to sf.value. - value := reflect.New(t).Elem() - value.Set(reflect.New(value.Type().Elem())) - if sf.kind == reflect.Int32 { - // We may have an int32 or an enum, but the underlying data is int32. - // Since we can't set an int32 into a non int32 reflect.value directly - // set it as a int32. - value.Elem().SetInt(int64(sf.value.(int32))) - } else { - value.Elem().Set(reflect.ValueOf(sf.value)) - } - return value.Interface(), nil -} - -// decodeExtension decodes an extension encoded in b. -func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { - t := reflect.TypeOf(extension.ExtensionType) - unmarshal := typeUnmarshaler(t, extension.Tag) - - // t is a pointer to a struct, pointer to basic type or a slice. - // Allocate space to store the pointer/slice. - value := reflect.New(t).Elem() - - var err error - for { - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - wire := int(x) & 7 - - b, err = unmarshal(b, valToPointer(value.Addr()), wire) - if err != nil { - return nil, err - } - - if len(b) == 0 { - break - } - } - return value.Interface(), nil -} - -// GetExtensions returns a slice of the extensions present in pb that are also listed in es. -// The returned slice has the same length as es; missing extensions will appear as nil elements. -func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) { - epb, err := extendable(pb) - if err != nil { - return nil, err - } - extensions = make([]interface{}, len(es)) - for i, e := range es { - extensions[i], err = GetExtension(epb, e) - if err == ErrMissingExtension { - err = nil - } - if err != nil { - return - } - } - return -} - -// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order. -// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing -// just the Field field, which defines the extension's field number. -func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) { - epb, err := extendable(pb) - if err != nil { - return nil, err - } - registeredExtensions := RegisteredExtensions(pb) - - emap, mu := epb.extensionsRead() - if emap == nil { - return nil, nil - } - mu.Lock() - defer mu.Unlock() - extensions := make([]*ExtensionDesc, 0, len(emap)) - for extid, e := range emap { - desc := e.desc - if desc == nil { - desc = registeredExtensions[extid] - if desc == nil { - desc = &ExtensionDesc{Field: extid} - } - } - - extensions = append(extensions, desc) - } - return extensions, nil -} - -// SetExtension sets the specified extension of pb to the specified value. -func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error { - epb, err := extendable(pb) - if err != nil { - return err - } - if err := checkExtensionTypes(epb, extension); err != nil { - return err - } - typ := reflect.TypeOf(extension.ExtensionType) - if typ != reflect.TypeOf(value) { - return errors.New("proto: bad extension value type") - } - // nil extension values need to be caught early, because the - // encoder can't distinguish an ErrNil due to a nil extension - // from an ErrNil due to a missing field. Extensions are - // always optional, so the encoder would just swallow the error - // and drop all the extensions from the encoded message. - if reflect.ValueOf(value).IsNil() { - return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) - } - - extmap := epb.extensionsWrite() - extmap[extension.Field] = Extension{desc: extension, value: value} - return nil -} - -// ClearAllExtensions clears all extensions from pb. -func ClearAllExtensions(pb Message) { - epb, err := extendable(pb) - if err != nil { - return - } - m := epb.extensionsWrite() - for k := range m { - delete(m, k) - } -} - -// A global registry of extensions. -// The generated code will register the generated descriptors by calling RegisterExtension. - -var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc) - -// RegisterExtension is called from the generated code. -func RegisterExtension(desc *ExtensionDesc) { - st := reflect.TypeOf(desc.ExtendedType).Elem() - m := extensionMaps[st] - if m == nil { - m = make(map[int32]*ExtensionDesc) - extensionMaps[st] = m - } - if _, ok := m[desc.Field]; ok { - panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field))) - } - m[desc.Field] = desc -} - -// RegisteredExtensions returns a map of the registered extensions of a -// protocol buffer struct, indexed by the extension number. -// The argument pb should be a nil pointer to the struct type. -func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { - return extensionMaps[reflect.TypeOf(pb).Elem()] -} diff --git a/vendor/github.com/golang/protobuf/proto/lib.go b/vendor/github.com/golang/protobuf/proto/lib.go deleted file mode 100644 index 0e2191b8a..000000000 --- a/vendor/github.com/golang/protobuf/proto/lib.go +++ /dev/null @@ -1,921 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/* -Package proto converts data structures to and from the wire format of -protocol buffers. It works in concert with the Go source code generated -for .proto files by the protocol compiler. - -A summary of the properties of the protocol buffer interface -for a protocol buffer variable v: - - - Names are turned from camel_case to CamelCase for export. - - There are no methods on v to set fields; just treat - them as structure fields. - - There are getters that return a field's value if set, - and return the field's default value if unset. - The getters work even if the receiver is a nil message. - - The zero value for a struct is its correct initialization state. - All desired fields must be set before marshaling. - - A Reset() method will restore a protobuf struct to its zero state. - - Non-repeated fields are pointers to the values; nil means unset. - That is, optional or required field int32 f becomes F *int32. - - Repeated fields are slices. - - Helper functions are available to aid the setting of fields. - msg.Foo = proto.String("hello") // set field - - Constants are defined to hold the default values of all fields that - have them. They have the form Default_StructName_FieldName. - Because the getter methods handle defaulted values, - direct use of these constants should be rare. - - Enums are given type names and maps from names to values. - Enum values are prefixed by the enclosing message's name, or by the - enum's type name if it is a top-level enum. Enum types have a String - method, and a Enum method to assist in message construction. - - Nested messages, groups and enums have type names prefixed with the name of - the surrounding message type. - - Extensions are given descriptor names that start with E_, - followed by an underscore-delimited list of the nested messages - that contain it (if any) followed by the CamelCased name of the - extension field itself. HasExtension, ClearExtension, GetExtension - and SetExtension are functions for manipulating extensions. - - Oneof field sets are given a single field in their message, - with distinguished wrapper types for each possible field value. - - Marshal and Unmarshal are functions to encode and decode the wire format. - -When the .proto file specifies `syntax="proto3"`, there are some differences: - - - Non-repeated fields of non-message type are values instead of pointers. - - Enum types do not get an Enum method. - -The simplest way to describe this is to see an example. -Given file test.proto, containing - - package example; - - enum FOO { X = 17; } - - message Test { - required string label = 1; - optional int32 type = 2 [default=77]; - repeated int64 reps = 3; - optional group OptionalGroup = 4 { - required string RequiredField = 5; - } - oneof union { - int32 number = 6; - string name = 7; - } - } - -The resulting file, test.pb.go, is: - - package example - - import proto "github.com/golang/protobuf/proto" - import math "math" - - type FOO int32 - const ( - FOO_X FOO = 17 - ) - var FOO_name = map[int32]string{ - 17: "X", - } - var FOO_value = map[string]int32{ - "X": 17, - } - - func (x FOO) Enum() *FOO { - p := new(FOO) - *p = x - return p - } - func (x FOO) String() string { - return proto.EnumName(FOO_name, int32(x)) - } - func (x *FOO) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(FOO_value, data) - if err != nil { - return err - } - *x = FOO(value) - return nil - } - - type Test struct { - Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` - Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` - Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` - Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` - // Types that are valid to be assigned to Union: - // *Test_Number - // *Test_Name - Union isTest_Union `protobuf_oneof:"union"` - XXX_unrecognized []byte `json:"-"` - } - func (m *Test) Reset() { *m = Test{} } - func (m *Test) String() string { return proto.CompactTextString(m) } - func (*Test) ProtoMessage() {} - - type isTest_Union interface { - isTest_Union() - } - - type Test_Number struct { - Number int32 `protobuf:"varint,6,opt,name=number"` - } - type Test_Name struct { - Name string `protobuf:"bytes,7,opt,name=name"` - } - - func (*Test_Number) isTest_Union() {} - func (*Test_Name) isTest_Union() {} - - func (m *Test) GetUnion() isTest_Union { - if m != nil { - return m.Union - } - return nil - } - const Default_Test_Type int32 = 77 - - func (m *Test) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" - } - - func (m *Test) GetType() int32 { - if m != nil && m.Type != nil { - return *m.Type - } - return Default_Test_Type - } - - func (m *Test) GetOptionalgroup() *Test_OptionalGroup { - if m != nil { - return m.Optionalgroup - } - return nil - } - - type Test_OptionalGroup struct { - RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` - } - func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} } - func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) } - - func (m *Test_OptionalGroup) GetRequiredField() string { - if m != nil && m.RequiredField != nil { - return *m.RequiredField - } - return "" - } - - func (m *Test) GetNumber() int32 { - if x, ok := m.GetUnion().(*Test_Number); ok { - return x.Number - } - return 0 - } - - func (m *Test) GetName() string { - if x, ok := m.GetUnion().(*Test_Name); ok { - return x.Name - } - return "" - } - - func init() { - proto.RegisterEnum("example.FOO", FOO_name, FOO_value) - } - -To create and play with a Test object: - - package main - - import ( - "log" - - "github.com/golang/protobuf/proto" - pb "./example.pb" - ) - - func main() { - test := &pb.Test{ - Label: proto.String("hello"), - Type: proto.Int32(17), - Reps: []int64{1, 2, 3}, - Optionalgroup: &pb.Test_OptionalGroup{ - RequiredField: proto.String("good bye"), - }, - Union: &pb.Test_Name{"fred"}, - } - data, err := proto.Marshal(test) - if err != nil { - log.Fatal("marshaling error: ", err) - } - newTest := &pb.Test{} - err = proto.Unmarshal(data, newTest) - if err != nil { - log.Fatal("unmarshaling error: ", err) - } - // Now test and newTest contain the same data. - if test.GetLabel() != newTest.GetLabel() { - log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) - } - // Use a type switch to determine which oneof was set. - switch u := test.Union.(type) { - case *pb.Test_Number: // u.Number contains the number. - case *pb.Test_Name: // u.Name contains the string. - } - // etc. - } -*/ -package proto - -import ( - "encoding/json" - "errors" - "fmt" - "log" - "reflect" - "sort" - "strconv" - "sync" -) - -var errInvalidUTF8 = errors.New("proto: invalid UTF-8 string") - -// Message is implemented by generated protocol buffer messages. -type Message interface { - Reset() - String() string - ProtoMessage() -} - -// Stats records allocation details about the protocol buffer encoders -// and decoders. Useful for tuning the library itself. -type Stats struct { - Emalloc uint64 // mallocs in encode - Dmalloc uint64 // mallocs in decode - Encode uint64 // number of encodes - Decode uint64 // number of decodes - Chit uint64 // number of cache hits - Cmiss uint64 // number of cache misses - Size uint64 // number of sizes -} - -// Set to true to enable stats collection. -const collectStats = false - -var stats Stats - -// GetStats returns a copy of the global Stats structure. -func GetStats() Stats { return stats } - -// A Buffer is a buffer manager for marshaling and unmarshaling -// protocol buffers. It may be reused between invocations to -// reduce memory usage. It is not necessary to use a Buffer; -// the global functions Marshal and Unmarshal create a -// temporary Buffer and are fine for most applications. -type Buffer struct { - buf []byte // encode/decode byte stream - index int // read point - - deterministic bool -} - -// NewBuffer allocates a new Buffer and initializes its internal data to -// the contents of the argument slice. -func NewBuffer(e []byte) *Buffer { - return &Buffer{buf: e} -} - -// Reset resets the Buffer, ready for marshaling a new protocol buffer. -func (p *Buffer) Reset() { - p.buf = p.buf[0:0] // for reading/writing - p.index = 0 // for reading -} - -// SetBuf replaces the internal buffer with the slice, -// ready for unmarshaling the contents of the slice. -func (p *Buffer) SetBuf(s []byte) { - p.buf = s - p.index = 0 -} - -// Bytes returns the contents of the Buffer. -func (p *Buffer) Bytes() []byte { return p.buf } - -// SetDeterministic sets whether to use deterministic serialization. -// -// Deterministic serialization guarantees that for a given binary, equal -// messages will always be serialized to the same bytes. This implies: -// -// - Repeated serialization of a message will return the same bytes. -// - Different processes of the same binary (which may be executing on -// different machines) will serialize equal messages to the same bytes. -// -// Note that the deterministic serialization is NOT canonical across -// languages. It is not guaranteed to remain stable over time. It is unstable -// across different builds with schema changes due to unknown fields. -// Users who need canonical serialization (e.g., persistent storage in a -// canonical form, fingerprinting, etc.) should define their own -// canonicalization specification and implement their own serializer rather -// than relying on this API. -// -// If deterministic serialization is requested, map entries will be sorted -// by keys in lexographical order. This is an implementation detail and -// subject to change. -func (p *Buffer) SetDeterministic(deterministic bool) { - p.deterministic = deterministic -} - -/* - * Helper routines for simplifying the creation of optional fields of basic type. - */ - -// Bool is a helper routine that allocates a new bool value -// to store v and returns a pointer to it. -func Bool(v bool) *bool { - return &v -} - -// Int32 is a helper routine that allocates a new int32 value -// to store v and returns a pointer to it. -func Int32(v int32) *int32 { - return &v -} - -// Int is a helper routine that allocates a new int32 value -// to store v and returns a pointer to it, but unlike Int32 -// its argument value is an int. -func Int(v int) *int32 { - p := new(int32) - *p = int32(v) - return p -} - -// Int64 is a helper routine that allocates a new int64 value -// to store v and returns a pointer to it. -func Int64(v int64) *int64 { - return &v -} - -// Float32 is a helper routine that allocates a new float32 value -// to store v and returns a pointer to it. -func Float32(v float32) *float32 { - return &v -} - -// Float64 is a helper routine that allocates a new float64 value -// to store v and returns a pointer to it. -func Float64(v float64) *float64 { - return &v -} - -// Uint32 is a helper routine that allocates a new uint32 value -// to store v and returns a pointer to it. -func Uint32(v uint32) *uint32 { - return &v -} - -// Uint64 is a helper routine that allocates a new uint64 value -// to store v and returns a pointer to it. -func Uint64(v uint64) *uint64 { - return &v -} - -// String is a helper routine that allocates a new string value -// to store v and returns a pointer to it. -func String(v string) *string { - return &v -} - -// EnumName is a helper function to simplify printing protocol buffer enums -// by name. Given an enum map and a value, it returns a useful string. -func EnumName(m map[int32]string, v int32) string { - s, ok := m[v] - if ok { - return s - } - return strconv.Itoa(int(v)) -} - -// UnmarshalJSONEnum is a helper function to simplify recovering enum int values -// from their JSON-encoded representation. Given a map from the enum's symbolic -// names to its int values, and a byte buffer containing the JSON-encoded -// value, it returns an int32 that can be cast to the enum type by the caller. -// -// The function can deal with both JSON representations, numeric and symbolic. -func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { - if data[0] == '"' { - // New style: enums are strings. - var repr string - if err := json.Unmarshal(data, &repr); err != nil { - return -1, err - } - val, ok := m[repr] - if !ok { - return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) - } - return val, nil - } - // Old style: enums are ints. - var val int32 - if err := json.Unmarshal(data, &val); err != nil { - return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) - } - return val, nil -} - -// DebugPrint dumps the encoded data in b in a debugging format with a header -// including the string s. Used in testing but made available for general debugging. -func (p *Buffer) DebugPrint(s string, b []byte) { - var u uint64 - - obuf := p.buf - index := p.index - p.buf = b - p.index = 0 - depth := 0 - - fmt.Printf("\n--- %s ---\n", s) - -out: - for { - for i := 0; i < depth; i++ { - fmt.Print(" ") - } - - index := p.index - if index == len(p.buf) { - break - } - - op, err := p.DecodeVarint() - if err != nil { - fmt.Printf("%3d: fetching op err %v\n", index, err) - break out - } - tag := op >> 3 - wire := op & 7 - - switch wire { - default: - fmt.Printf("%3d: t=%3d unknown wire=%d\n", - index, tag, wire) - break out - - case WireBytes: - var r []byte - - r, err = p.DecodeRawBytes(false) - if err != nil { - break out - } - fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r)) - if len(r) <= 6 { - for i := 0; i < len(r); i++ { - fmt.Printf(" %.2x", r[i]) - } - } else { - for i := 0; i < 3; i++ { - fmt.Printf(" %.2x", r[i]) - } - fmt.Printf(" ..") - for i := len(r) - 3; i < len(r); i++ { - fmt.Printf(" %.2x", r[i]) - } - } - fmt.Printf("\n") - - case WireFixed32: - u, err = p.DecodeFixed32() - if err != nil { - fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u) - - case WireFixed64: - u, err = p.DecodeFixed64() - if err != nil { - fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u) - - case WireVarint: - u, err = p.DecodeVarint() - if err != nil { - fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u) - - case WireStartGroup: - fmt.Printf("%3d: t=%3d start\n", index, tag) - depth++ - - case WireEndGroup: - depth-- - fmt.Printf("%3d: t=%3d end\n", index, tag) - } - } - - if depth != 0 { - fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth) - } - fmt.Printf("\n") - - p.buf = obuf - p.index = index -} - -// SetDefaults sets unset protocol buffer fields to their default values. -// It only modifies fields that are both unset and have defined defaults. -// It recursively sets default values in any non-nil sub-messages. -func SetDefaults(pb Message) { - setDefaults(reflect.ValueOf(pb), true, false) -} - -// v is a pointer to a struct. -func setDefaults(v reflect.Value, recur, zeros bool) { - v = v.Elem() - - defaultMu.RLock() - dm, ok := defaults[v.Type()] - defaultMu.RUnlock() - if !ok { - dm = buildDefaultMessage(v.Type()) - defaultMu.Lock() - defaults[v.Type()] = dm - defaultMu.Unlock() - } - - for _, sf := range dm.scalars { - f := v.Field(sf.index) - if !f.IsNil() { - // field already set - continue - } - dv := sf.value - if dv == nil && !zeros { - // no explicit default, and don't want to set zeros - continue - } - fptr := f.Addr().Interface() // **T - // TODO: Consider batching the allocations we do here. - switch sf.kind { - case reflect.Bool: - b := new(bool) - if dv != nil { - *b = dv.(bool) - } - *(fptr.(**bool)) = b - case reflect.Float32: - f := new(float32) - if dv != nil { - *f = dv.(float32) - } - *(fptr.(**float32)) = f - case reflect.Float64: - f := new(float64) - if dv != nil { - *f = dv.(float64) - } - *(fptr.(**float64)) = f - case reflect.Int32: - // might be an enum - if ft := f.Type(); ft != int32PtrType { - // enum - f.Set(reflect.New(ft.Elem())) - if dv != nil { - f.Elem().SetInt(int64(dv.(int32))) - } - } else { - // int32 field - i := new(int32) - if dv != nil { - *i = dv.(int32) - } - *(fptr.(**int32)) = i - } - case reflect.Int64: - i := new(int64) - if dv != nil { - *i = dv.(int64) - } - *(fptr.(**int64)) = i - case reflect.String: - s := new(string) - if dv != nil { - *s = dv.(string) - } - *(fptr.(**string)) = s - case reflect.Uint8: - // exceptional case: []byte - var b []byte - if dv != nil { - db := dv.([]byte) - b = make([]byte, len(db)) - copy(b, db) - } else { - b = []byte{} - } - *(fptr.(*[]byte)) = b - case reflect.Uint32: - u := new(uint32) - if dv != nil { - *u = dv.(uint32) - } - *(fptr.(**uint32)) = u - case reflect.Uint64: - u := new(uint64) - if dv != nil { - *u = dv.(uint64) - } - *(fptr.(**uint64)) = u - default: - log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind) - } - } - - for _, ni := range dm.nested { - f := v.Field(ni) - // f is *T or []*T or map[T]*T - switch f.Kind() { - case reflect.Ptr: - if f.IsNil() { - continue - } - setDefaults(f, recur, zeros) - - case reflect.Slice: - for i := 0; i < f.Len(); i++ { - e := f.Index(i) - if e.IsNil() { - continue - } - setDefaults(e, recur, zeros) - } - - case reflect.Map: - for _, k := range f.MapKeys() { - e := f.MapIndex(k) - if e.IsNil() { - continue - } - setDefaults(e, recur, zeros) - } - } - } -} - -var ( - // defaults maps a protocol buffer struct type to a slice of the fields, - // with its scalar fields set to their proto-declared non-zero default values. - defaultMu sync.RWMutex - defaults = make(map[reflect.Type]defaultMessage) - - int32PtrType = reflect.TypeOf((*int32)(nil)) -) - -// defaultMessage represents information about the default values of a message. -type defaultMessage struct { - scalars []scalarField - nested []int // struct field index of nested messages -} - -type scalarField struct { - index int // struct field index - kind reflect.Kind // element type (the T in *T or []T) - value interface{} // the proto-declared default value, or nil -} - -// t is a struct type. -func buildDefaultMessage(t reflect.Type) (dm defaultMessage) { - sprop := GetProperties(t) - for _, prop := range sprop.Prop { - fi, ok := sprop.decoderTags.get(prop.Tag) - if !ok { - // XXX_unrecognized - continue - } - ft := t.Field(fi).Type - - sf, nested, err := fieldDefault(ft, prop) - switch { - case err != nil: - log.Print(err) - case nested: - dm.nested = append(dm.nested, fi) - case sf != nil: - sf.index = fi - dm.scalars = append(dm.scalars, *sf) - } - } - - return dm -} - -// fieldDefault returns the scalarField for field type ft. -// sf will be nil if the field can not have a default. -// nestedMessage will be true if this is a nested message. -// Note that sf.index is not set on return. -func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) { - var canHaveDefault bool - switch ft.Kind() { - case reflect.Ptr: - if ft.Elem().Kind() == reflect.Struct { - nestedMessage = true - } else { - canHaveDefault = true // proto2 scalar field - } - - case reflect.Slice: - switch ft.Elem().Kind() { - case reflect.Ptr: - nestedMessage = true // repeated message - case reflect.Uint8: - canHaveDefault = true // bytes field - } - - case reflect.Map: - if ft.Elem().Kind() == reflect.Ptr { - nestedMessage = true // map with message values - } - } - - if !canHaveDefault { - if nestedMessage { - return nil, true, nil - } - return nil, false, nil - } - - // We now know that ft is a pointer or slice. - sf = &scalarField{kind: ft.Elem().Kind()} - - // scalar fields without defaults - if !prop.HasDefault { - return sf, false, nil - } - - // a scalar field: either *T or []byte - switch ft.Elem().Kind() { - case reflect.Bool: - x, err := strconv.ParseBool(prop.Default) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err) - } - sf.value = x - case reflect.Float32: - x, err := strconv.ParseFloat(prop.Default, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err) - } - sf.value = float32(x) - case reflect.Float64: - x, err := strconv.ParseFloat(prop.Default, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err) - } - sf.value = x - case reflect.Int32: - x, err := strconv.ParseInt(prop.Default, 10, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err) - } - sf.value = int32(x) - case reflect.Int64: - x, err := strconv.ParseInt(prop.Default, 10, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err) - } - sf.value = x - case reflect.String: - sf.value = prop.Default - case reflect.Uint8: - // []byte (not *uint8) - sf.value = []byte(prop.Default) - case reflect.Uint32: - x, err := strconv.ParseUint(prop.Default, 10, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err) - } - sf.value = uint32(x) - case reflect.Uint64: - x, err := strconv.ParseUint(prop.Default, 10, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err) - } - sf.value = x - default: - return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind()) - } - - return sf, false, nil -} - -// mapKeys returns a sort.Interface to be used for sorting the map keys. -// Map fields may have key types of non-float scalars, strings and enums. -func mapKeys(vs []reflect.Value) sort.Interface { - s := mapKeySorter{vs: vs} - - // Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps. - if len(vs) == 0 { - return s - } - switch vs[0].Kind() { - case reflect.Int32, reflect.Int64: - s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() } - case reflect.Uint32, reflect.Uint64: - s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() } - case reflect.Bool: - s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true - case reflect.String: - s.less = func(a, b reflect.Value) bool { return a.String() < b.String() } - default: - panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind())) - } - - return s -} - -type mapKeySorter struct { - vs []reflect.Value - less func(a, b reflect.Value) bool -} - -func (s mapKeySorter) Len() int { return len(s.vs) } -func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] } -func (s mapKeySorter) Less(i, j int) bool { - return s.less(s.vs[i], s.vs[j]) -} - -// isProto3Zero reports whether v is a zero proto3 value. -func isProto3Zero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Bool: - return !v.Bool() - case reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint32, reflect.Uint64: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.String: - return v.String() == "" - } - return false -} - -// ProtoPackageIsVersion2 is referenced from generated protocol buffer files -// to assert that that code is compatible with this version of the proto package. -const ProtoPackageIsVersion2 = true - -// ProtoPackageIsVersion1 is referenced from generated protocol buffer files -// to assert that that code is compatible with this version of the proto package. -const ProtoPackageIsVersion1 = true - -// InternalMessageInfo is a type used internally by generated .pb.go files. -// This type is not intended to be used by non-generated code. -// This type is not subject to any compatibility guarantee. -type InternalMessageInfo struct { - marshal *marshalInfo - unmarshal *unmarshalInfo - merge *mergeInfo - discard *discardInfo -} diff --git a/vendor/github.com/golang/protobuf/proto/message_set.go b/vendor/github.com/golang/protobuf/proto/message_set.go deleted file mode 100644 index 3b6ca41d5..000000000 --- a/vendor/github.com/golang/protobuf/proto/message_set.go +++ /dev/null @@ -1,314 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Support for message sets. - */ - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "reflect" - "sort" - "sync" -) - -// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. -// A message type ID is required for storing a protocol buffer in a message set. -var errNoMessageTypeID = errors.New("proto does not have a message type ID") - -// The first two types (_MessageSet_Item and messageSet) -// model what the protocol compiler produces for the following protocol message: -// message MessageSet { -// repeated group Item = 1 { -// required int32 type_id = 2; -// required string message = 3; -// }; -// } -// That is the MessageSet wire format. We can't use a proto to generate these -// because that would introduce a circular dependency between it and this package. - -type _MessageSet_Item struct { - TypeId *int32 `protobuf:"varint,2,req,name=type_id"` - Message []byte `protobuf:"bytes,3,req,name=message"` -} - -type messageSet struct { - Item []*_MessageSet_Item `protobuf:"group,1,rep"` - XXX_unrecognized []byte - // TODO: caching? -} - -// Make sure messageSet is a Message. -var _ Message = (*messageSet)(nil) - -// messageTypeIder is an interface satisfied by a protocol buffer type -// that may be stored in a MessageSet. -type messageTypeIder interface { - MessageTypeId() int32 -} - -func (ms *messageSet) find(pb Message) *_MessageSet_Item { - mti, ok := pb.(messageTypeIder) - if !ok { - return nil - } - id := mti.MessageTypeId() - for _, item := range ms.Item { - if *item.TypeId == id { - return item - } - } - return nil -} - -func (ms *messageSet) Has(pb Message) bool { - return ms.find(pb) != nil -} - -func (ms *messageSet) Unmarshal(pb Message) error { - if item := ms.find(pb); item != nil { - return Unmarshal(item.Message, pb) - } - if _, ok := pb.(messageTypeIder); !ok { - return errNoMessageTypeID - } - return nil // TODO: return error instead? -} - -func (ms *messageSet) Marshal(pb Message) error { - msg, err := Marshal(pb) - if err != nil { - return err - } - if item := ms.find(pb); item != nil { - // reuse existing item - item.Message = msg - return nil - } - - mti, ok := pb.(messageTypeIder) - if !ok { - return errNoMessageTypeID - } - - mtid := mti.MessageTypeId() - ms.Item = append(ms.Item, &_MessageSet_Item{ - TypeId: &mtid, - Message: msg, - }) - return nil -} - -func (ms *messageSet) Reset() { *ms = messageSet{} } -func (ms *messageSet) String() string { return CompactTextString(ms) } -func (*messageSet) ProtoMessage() {} - -// Support for the message_set_wire_format message option. - -func skipVarint(buf []byte) []byte { - i := 0 - for ; buf[i]&0x80 != 0; i++ { - } - return buf[i+1:] -} - -// MarshalMessageSet encodes the extension map represented by m in the message set wire format. -// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option. -func MarshalMessageSet(exts interface{}) ([]byte, error) { - return marshalMessageSet(exts, false) -} - -// marshaMessageSet implements above function, with the opt to turn on / off deterministic during Marshal. -func marshalMessageSet(exts interface{}, deterministic bool) ([]byte, error) { - switch exts := exts.(type) { - case *XXX_InternalExtensions: - var u marshalInfo - siz := u.sizeMessageSet(exts) - b := make([]byte, 0, siz) - return u.appendMessageSet(b, exts, deterministic) - - case map[int32]Extension: - // This is an old-style extension map. - // Wrap it in a new-style XXX_InternalExtensions. - ie := XXX_InternalExtensions{ - p: &struct { - mu sync.Mutex - extensionMap map[int32]Extension - }{ - extensionMap: exts, - }, - } - - var u marshalInfo - siz := u.sizeMessageSet(&ie) - b := make([]byte, 0, siz) - return u.appendMessageSet(b, &ie, deterministic) - - default: - return nil, errors.New("proto: not an extension map") - } -} - -// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. -// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option. -func UnmarshalMessageSet(buf []byte, exts interface{}) error { - var m map[int32]Extension - switch exts := exts.(type) { - case *XXX_InternalExtensions: - m = exts.extensionsWrite() - case map[int32]Extension: - m = exts - default: - return errors.New("proto: not an extension map") - } - - ms := new(messageSet) - if err := Unmarshal(buf, ms); err != nil { - return err - } - for _, item := range ms.Item { - id := *item.TypeId - msg := item.Message - - // Restore wire type and field number varint, plus length varint. - // Be careful to preserve duplicate items. - b := EncodeVarint(uint64(id)<<3 | WireBytes) - if ext, ok := m[id]; ok { - // Existing data; rip off the tag and length varint - // so we join the new data correctly. - // We can assume that ext.enc is set because we are unmarshaling. - o := ext.enc[len(b):] // skip wire type and field number - _, n := DecodeVarint(o) // calculate length of length varint - o = o[n:] // skip length varint - msg = append(o, msg...) // join old data and new data - } - b = append(b, EncodeVarint(uint64(len(msg)))...) - b = append(b, msg...) - - m[id] = Extension{enc: b} - } - return nil -} - -// MarshalMessageSetJSON encodes the extension map represented by m in JSON format. -// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option. -func MarshalMessageSetJSON(exts interface{}) ([]byte, error) { - var m map[int32]Extension - switch exts := exts.(type) { - case *XXX_InternalExtensions: - var mu sync.Locker - m, mu = exts.extensionsRead() - if m != nil { - // Keep the extensions map locked until we're done marshaling to prevent - // races between marshaling and unmarshaling the lazily-{en,de}coded - // values. - mu.Lock() - defer mu.Unlock() - } - case map[int32]Extension: - m = exts - default: - return nil, errors.New("proto: not an extension map") - } - var b bytes.Buffer - b.WriteByte('{') - - // Process the map in key order for deterministic output. - ids := make([]int32, 0, len(m)) - for id := range m { - ids = append(ids, id) - } - sort.Sort(int32Slice(ids)) // int32Slice defined in text.go - - for i, id := range ids { - ext := m[id] - msd, ok := messageSetMap[id] - if !ok { - // Unknown type; we can't render it, so skip it. - continue - } - - if i > 0 && b.Len() > 1 { - b.WriteByte(',') - } - - fmt.Fprintf(&b, `"[%s]":`, msd.name) - - x := ext.value - if x == nil { - x = reflect.New(msd.t.Elem()).Interface() - if err := Unmarshal(ext.enc, x.(Message)); err != nil { - return nil, err - } - } - d, err := json.Marshal(x) - if err != nil { - return nil, err - } - b.Write(d) - } - b.WriteByte('}') - return b.Bytes(), nil -} - -// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format. -// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option. -func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error { - // Common-case fast path. - if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) { - return nil - } - - // This is fairly tricky, and it's not clear that it is needed. - return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented") -} - -// A global registry of types that can be used in a MessageSet. - -var messageSetMap = make(map[int32]messageSetDesc) - -type messageSetDesc struct { - t reflect.Type // pointer to struct - name string -} - -// RegisterMessageSetType is called from the generated code. -func RegisterMessageSetType(m Message, fieldNum int32, name string) { - messageSetMap[fieldNum] = messageSetDesc{ - t: reflect.TypeOf(m), - name: name, - } -} diff --git a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go deleted file mode 100644 index b6cad9083..000000000 --- a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go +++ /dev/null @@ -1,357 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2012 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build purego appengine js - -// This file contains an implementation of proto field accesses using package reflect. -// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can -// be used on App Engine. - -package proto - -import ( - "reflect" - "sync" -) - -const unsafeAllowed = false - -// A field identifies a field in a struct, accessible from a pointer. -// In this implementation, a field is identified by the sequence of field indices -// passed to reflect's FieldByIndex. -type field []int - -// toField returns a field equivalent to the given reflect field. -func toField(f *reflect.StructField) field { - return f.Index -} - -// invalidField is an invalid field identifier. -var invalidField = field(nil) - -// zeroField is a noop when calling pointer.offset. -var zeroField = field([]int{}) - -// IsValid reports whether the field identifier is valid. -func (f field) IsValid() bool { return f != nil } - -// The pointer type is for the table-driven decoder. -// The implementation here uses a reflect.Value of pointer type to -// create a generic pointer. In pointer_unsafe.go we use unsafe -// instead of reflect to implement the same (but faster) interface. -type pointer struct { - v reflect.Value -} - -// toPointer converts an interface of pointer type to a pointer -// that points to the same target. -func toPointer(i *Message) pointer { - return pointer{v: reflect.ValueOf(*i)} -} - -// toAddrPointer converts an interface to a pointer that points to -// the interface data. -func toAddrPointer(i *interface{}, isptr bool) pointer { - v := reflect.ValueOf(*i) - u := reflect.New(v.Type()) - u.Elem().Set(v) - return pointer{v: u} -} - -// valToPointer converts v to a pointer. v must be of pointer type. -func valToPointer(v reflect.Value) pointer { - return pointer{v: v} -} - -// offset converts from a pointer to a structure to a pointer to -// one of its fields. -func (p pointer) offset(f field) pointer { - return pointer{v: p.v.Elem().FieldByIndex(f).Addr()} -} - -func (p pointer) isNil() bool { - return p.v.IsNil() -} - -// grow updates the slice s in place to make it one element longer. -// s must be addressable. -// Returns the (addressable) new element. -func grow(s reflect.Value) reflect.Value { - n, m := s.Len(), s.Cap() - if n < m { - s.SetLen(n + 1) - } else { - s.Set(reflect.Append(s, reflect.Zero(s.Type().Elem()))) - } - return s.Index(n) -} - -func (p pointer) toInt64() *int64 { - return p.v.Interface().(*int64) -} -func (p pointer) toInt64Ptr() **int64 { - return p.v.Interface().(**int64) -} -func (p pointer) toInt64Slice() *[]int64 { - return p.v.Interface().(*[]int64) -} - -var int32ptr = reflect.TypeOf((*int32)(nil)) - -func (p pointer) toInt32() *int32 { - return p.v.Convert(int32ptr).Interface().(*int32) -} - -// The toInt32Ptr/Slice methods don't work because of enums. -// Instead, we must use set/get methods for the int32ptr/slice case. -/* - func (p pointer) toInt32Ptr() **int32 { - return p.v.Interface().(**int32) -} - func (p pointer) toInt32Slice() *[]int32 { - return p.v.Interface().(*[]int32) -} -*/ -func (p pointer) getInt32Ptr() *int32 { - if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { - // raw int32 type - return p.v.Elem().Interface().(*int32) - } - // an enum - return p.v.Elem().Convert(int32PtrType).Interface().(*int32) -} -func (p pointer) setInt32Ptr(v int32) { - // Allocate value in a *int32. Possibly convert that to a *enum. - // Then assign it to a **int32 or **enum. - // Note: we can convert *int32 to *enum, but we can't convert - // **int32 to **enum! - p.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem())) -} - -// getInt32Slice copies []int32 from p as a new slice. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) getInt32Slice() []int32 { - if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { - // raw int32 type - return p.v.Elem().Interface().([]int32) - } - // an enum - // Allocate a []int32, then assign []enum's values into it. - // Note: we can't convert []enum to []int32. - slice := p.v.Elem() - s := make([]int32, slice.Len()) - for i := 0; i < slice.Len(); i++ { - s[i] = int32(slice.Index(i).Int()) - } - return s -} - -// setInt32Slice copies []int32 into p as a new slice. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) setInt32Slice(v []int32) { - if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { - // raw int32 type - p.v.Elem().Set(reflect.ValueOf(v)) - return - } - // an enum - // Allocate a []enum, then assign []int32's values into it. - // Note: we can't convert []enum to []int32. - slice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v)) - for i, x := range v { - slice.Index(i).SetInt(int64(x)) - } - p.v.Elem().Set(slice) -} -func (p pointer) appendInt32Slice(v int32) { - grow(p.v.Elem()).SetInt(int64(v)) -} - -func (p pointer) toUint64() *uint64 { - return p.v.Interface().(*uint64) -} -func (p pointer) toUint64Ptr() **uint64 { - return p.v.Interface().(**uint64) -} -func (p pointer) toUint64Slice() *[]uint64 { - return p.v.Interface().(*[]uint64) -} -func (p pointer) toUint32() *uint32 { - return p.v.Interface().(*uint32) -} -func (p pointer) toUint32Ptr() **uint32 { - return p.v.Interface().(**uint32) -} -func (p pointer) toUint32Slice() *[]uint32 { - return p.v.Interface().(*[]uint32) -} -func (p pointer) toBool() *bool { - return p.v.Interface().(*bool) -} -func (p pointer) toBoolPtr() **bool { - return p.v.Interface().(**bool) -} -func (p pointer) toBoolSlice() *[]bool { - return p.v.Interface().(*[]bool) -} -func (p pointer) toFloat64() *float64 { - return p.v.Interface().(*float64) -} -func (p pointer) toFloat64Ptr() **float64 { - return p.v.Interface().(**float64) -} -func (p pointer) toFloat64Slice() *[]float64 { - return p.v.Interface().(*[]float64) -} -func (p pointer) toFloat32() *float32 { - return p.v.Interface().(*float32) -} -func (p pointer) toFloat32Ptr() **float32 { - return p.v.Interface().(**float32) -} -func (p pointer) toFloat32Slice() *[]float32 { - return p.v.Interface().(*[]float32) -} -func (p pointer) toString() *string { - return p.v.Interface().(*string) -} -func (p pointer) toStringPtr() **string { - return p.v.Interface().(**string) -} -func (p pointer) toStringSlice() *[]string { - return p.v.Interface().(*[]string) -} -func (p pointer) toBytes() *[]byte { - return p.v.Interface().(*[]byte) -} -func (p pointer) toBytesSlice() *[][]byte { - return p.v.Interface().(*[][]byte) -} -func (p pointer) toExtensions() *XXX_InternalExtensions { - return p.v.Interface().(*XXX_InternalExtensions) -} -func (p pointer) toOldExtensions() *map[int32]Extension { - return p.v.Interface().(*map[int32]Extension) -} -func (p pointer) getPointer() pointer { - return pointer{v: p.v.Elem()} -} -func (p pointer) setPointer(q pointer) { - p.v.Elem().Set(q.v) -} -func (p pointer) appendPointer(q pointer) { - grow(p.v.Elem()).Set(q.v) -} - -// getPointerSlice copies []*T from p as a new []pointer. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) getPointerSlice() []pointer { - if p.v.IsNil() { - return nil - } - n := p.v.Elem().Len() - s := make([]pointer, n) - for i := 0; i < n; i++ { - s[i] = pointer{v: p.v.Elem().Index(i)} - } - return s -} - -// setPointerSlice copies []pointer into p as a new []*T. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) setPointerSlice(v []pointer) { - if v == nil { - p.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem()) - return - } - s := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v)) - for _, p := range v { - s = reflect.Append(s, p.v) - } - p.v.Elem().Set(s) -} - -// getInterfacePointer returns a pointer that points to the -// interface data of the interface pointed by p. -func (p pointer) getInterfacePointer() pointer { - if p.v.Elem().IsNil() { - return pointer{v: p.v.Elem()} - } - return pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct -} - -func (p pointer) asPointerTo(t reflect.Type) reflect.Value { - // TODO: check that p.v.Type().Elem() == t? - return p.v -} - -func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} -func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} -func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} -func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} - -var atomicLock sync.Mutex diff --git a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go deleted file mode 100644 index d55a335d9..000000000 --- a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go +++ /dev/null @@ -1,308 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2012 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build !purego,!appengine,!js - -// This file contains the implementation of the proto field accesses using package unsafe. - -package proto - -import ( - "reflect" - "sync/atomic" - "unsafe" -) - -const unsafeAllowed = true - -// A field identifies a field in a struct, accessible from a pointer. -// In this implementation, a field is identified by its byte offset from the start of the struct. -type field uintptr - -// toField returns a field equivalent to the given reflect field. -func toField(f *reflect.StructField) field { - return field(f.Offset) -} - -// invalidField is an invalid field identifier. -const invalidField = ^field(0) - -// zeroField is a noop when calling pointer.offset. -const zeroField = field(0) - -// IsValid reports whether the field identifier is valid. -func (f field) IsValid() bool { - return f != invalidField -} - -// The pointer type below is for the new table-driven encoder/decoder. -// The implementation here uses unsafe.Pointer to create a generic pointer. -// In pointer_reflect.go we use reflect instead of unsafe to implement -// the same (but slower) interface. -type pointer struct { - p unsafe.Pointer -} - -// size of pointer -var ptrSize = unsafe.Sizeof(uintptr(0)) - -// toPointer converts an interface of pointer type to a pointer -// that points to the same target. -func toPointer(i *Message) pointer { - // Super-tricky - read pointer out of data word of interface value. - // Saves ~25ns over the equivalent: - // return valToPointer(reflect.ValueOf(*i)) - return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} -} - -// toAddrPointer converts an interface to a pointer that points to -// the interface data. -func toAddrPointer(i *interface{}, isptr bool) pointer { - // Super-tricky - read or get the address of data word of interface value. - if isptr { - // The interface is of pointer type, thus it is a direct interface. - // The data word is the pointer data itself. We take its address. - return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)} - } - // The interface is not of pointer type. The data word is the pointer - // to the data. - return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} -} - -// valToPointer converts v to a pointer. v must be of pointer type. -func valToPointer(v reflect.Value) pointer { - return pointer{p: unsafe.Pointer(v.Pointer())} -} - -// offset converts from a pointer to a structure to a pointer to -// one of its fields. -func (p pointer) offset(f field) pointer { - // For safety, we should panic if !f.IsValid, however calling panic causes - // this to no longer be inlineable, which is a serious performance cost. - /* - if !f.IsValid() { - panic("invalid field") - } - */ - return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))} -} - -func (p pointer) isNil() bool { - return p.p == nil -} - -func (p pointer) toInt64() *int64 { - return (*int64)(p.p) -} -func (p pointer) toInt64Ptr() **int64 { - return (**int64)(p.p) -} -func (p pointer) toInt64Slice() *[]int64 { - return (*[]int64)(p.p) -} -func (p pointer) toInt32() *int32 { - return (*int32)(p.p) -} - -// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist. -/* - func (p pointer) toInt32Ptr() **int32 { - return (**int32)(p.p) - } - func (p pointer) toInt32Slice() *[]int32 { - return (*[]int32)(p.p) - } -*/ -func (p pointer) getInt32Ptr() *int32 { - return *(**int32)(p.p) -} -func (p pointer) setInt32Ptr(v int32) { - *(**int32)(p.p) = &v -} - -// getInt32Slice loads a []int32 from p. -// The value returned is aliased with the original slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) getInt32Slice() []int32 { - return *(*[]int32)(p.p) -} - -// setInt32Slice stores a []int32 to p. -// The value set is aliased with the input slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) setInt32Slice(v []int32) { - *(*[]int32)(p.p) = v -} - -// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead? -func (p pointer) appendInt32Slice(v int32) { - s := (*[]int32)(p.p) - *s = append(*s, v) -} - -func (p pointer) toUint64() *uint64 { - return (*uint64)(p.p) -} -func (p pointer) toUint64Ptr() **uint64 { - return (**uint64)(p.p) -} -func (p pointer) toUint64Slice() *[]uint64 { - return (*[]uint64)(p.p) -} -func (p pointer) toUint32() *uint32 { - return (*uint32)(p.p) -} -func (p pointer) toUint32Ptr() **uint32 { - return (**uint32)(p.p) -} -func (p pointer) toUint32Slice() *[]uint32 { - return (*[]uint32)(p.p) -} -func (p pointer) toBool() *bool { - return (*bool)(p.p) -} -func (p pointer) toBoolPtr() **bool { - return (**bool)(p.p) -} -func (p pointer) toBoolSlice() *[]bool { - return (*[]bool)(p.p) -} -func (p pointer) toFloat64() *float64 { - return (*float64)(p.p) -} -func (p pointer) toFloat64Ptr() **float64 { - return (**float64)(p.p) -} -func (p pointer) toFloat64Slice() *[]float64 { - return (*[]float64)(p.p) -} -func (p pointer) toFloat32() *float32 { - return (*float32)(p.p) -} -func (p pointer) toFloat32Ptr() **float32 { - return (**float32)(p.p) -} -func (p pointer) toFloat32Slice() *[]float32 { - return (*[]float32)(p.p) -} -func (p pointer) toString() *string { - return (*string)(p.p) -} -func (p pointer) toStringPtr() **string { - return (**string)(p.p) -} -func (p pointer) toStringSlice() *[]string { - return (*[]string)(p.p) -} -func (p pointer) toBytes() *[]byte { - return (*[]byte)(p.p) -} -func (p pointer) toBytesSlice() *[][]byte { - return (*[][]byte)(p.p) -} -func (p pointer) toExtensions() *XXX_InternalExtensions { - return (*XXX_InternalExtensions)(p.p) -} -func (p pointer) toOldExtensions() *map[int32]Extension { - return (*map[int32]Extension)(p.p) -} - -// getPointerSlice loads []*T from p as a []pointer. -// The value returned is aliased with the original slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) getPointerSlice() []pointer { - // Super-tricky - p should point to a []*T where T is a - // message type. We load it as []pointer. - return *(*[]pointer)(p.p) -} - -// setPointerSlice stores []pointer into p as a []*T. -// The value set is aliased with the input slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) setPointerSlice(v []pointer) { - // Super-tricky - p should point to a []*T where T is a - // message type. We store it as []pointer. - *(*[]pointer)(p.p) = v -} - -// getPointer loads the pointer at p and returns it. -func (p pointer) getPointer() pointer { - return pointer{p: *(*unsafe.Pointer)(p.p)} -} - -// setPointer stores the pointer q at p. -func (p pointer) setPointer(q pointer) { - *(*unsafe.Pointer)(p.p) = q.p -} - -// append q to the slice pointed to by p. -func (p pointer) appendPointer(q pointer) { - s := (*[]unsafe.Pointer)(p.p) - *s = append(*s, q.p) -} - -// getInterfacePointer returns a pointer that points to the -// interface data of the interface pointed by p. -func (p pointer) getInterfacePointer() pointer { - // Super-tricky - read pointer out of data word of interface value. - return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]} -} - -// asPointerTo returns a reflect.Value that is a pointer to an -// object of type t stored at p. -func (p pointer) asPointerTo(t reflect.Type) reflect.Value { - return reflect.NewAt(t, p.p) -} - -func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { - return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} -func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { - return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} -func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { - return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} -func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { - return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} diff --git a/vendor/github.com/golang/protobuf/proto/properties.go b/vendor/github.com/golang/protobuf/proto/properties.go deleted file mode 100644 index f710adab0..000000000 --- a/vendor/github.com/golang/protobuf/proto/properties.go +++ /dev/null @@ -1,544 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Routines for encoding data into the wire format for protocol buffers. - */ - -import ( - "fmt" - "log" - "os" - "reflect" - "sort" - "strconv" - "strings" - "sync" -) - -const debug bool = false - -// Constants that identify the encoding of a value on the wire. -const ( - WireVarint = 0 - WireFixed64 = 1 - WireBytes = 2 - WireStartGroup = 3 - WireEndGroup = 4 - WireFixed32 = 5 -) - -// tagMap is an optimization over map[int]int for typical protocol buffer -// use-cases. Encoded protocol buffers are often in tag order with small tag -// numbers. -type tagMap struct { - fastTags []int - slowTags map[int]int -} - -// tagMapFastLimit is the upper bound on the tag number that will be stored in -// the tagMap slice rather than its map. -const tagMapFastLimit = 1024 - -func (p *tagMap) get(t int) (int, bool) { - if t > 0 && t < tagMapFastLimit { - if t >= len(p.fastTags) { - return 0, false - } - fi := p.fastTags[t] - return fi, fi >= 0 - } - fi, ok := p.slowTags[t] - return fi, ok -} - -func (p *tagMap) put(t int, fi int) { - if t > 0 && t < tagMapFastLimit { - for len(p.fastTags) < t+1 { - p.fastTags = append(p.fastTags, -1) - } - p.fastTags[t] = fi - return - } - if p.slowTags == nil { - p.slowTags = make(map[int]int) - } - p.slowTags[t] = fi -} - -// StructProperties represents properties for all the fields of a struct. -// decoderTags and decoderOrigNames should only be used by the decoder. -type StructProperties struct { - Prop []*Properties // properties for each field - reqCount int // required count - decoderTags tagMap // map from proto tag to struct field number - decoderOrigNames map[string]int // map from original name to struct field number - order []int // list of struct field numbers in tag order - - // OneofTypes contains information about the oneof fields in this message. - // It is keyed by the original name of a field. - OneofTypes map[string]*OneofProperties -} - -// OneofProperties represents information about a specific field in a oneof. -type OneofProperties struct { - Type reflect.Type // pointer to generated struct type for this oneof field - Field int // struct field number of the containing oneof in the message - Prop *Properties -} - -// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. -// See encode.go, (*Buffer).enc_struct. - -func (sp *StructProperties) Len() int { return len(sp.order) } -func (sp *StructProperties) Less(i, j int) bool { - return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag -} -func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] } - -// Properties represents the protocol-specific behavior of a single struct field. -type Properties struct { - Name string // name of the field, for error messages - OrigName string // original name before protocol compiler (always set) - JSONName string // name to use for JSON; determined by protoc - Wire string - WireType int - Tag int - Required bool - Optional bool - Repeated bool - Packed bool // relevant for repeated primitives only - Enum string // set for enum types only - proto3 bool // whether this is known to be a proto3 field; set for []byte only - oneof bool // whether this is a oneof field - - Default string // default value - HasDefault bool // whether an explicit default was provided - - stype reflect.Type // set for struct types only - sprop *StructProperties // set for struct types only - - mtype reflect.Type // set for map types only - mkeyprop *Properties // set for map types only - mvalprop *Properties // set for map types only -} - -// String formats the properties in the protobuf struct field tag style. -func (p *Properties) String() string { - s := p.Wire - s += "," - s += strconv.Itoa(p.Tag) - if p.Required { - s += ",req" - } - if p.Optional { - s += ",opt" - } - if p.Repeated { - s += ",rep" - } - if p.Packed { - s += ",packed" - } - s += ",name=" + p.OrigName - if p.JSONName != p.OrigName { - s += ",json=" + p.JSONName - } - if p.proto3 { - s += ",proto3" - } - if p.oneof { - s += ",oneof" - } - if len(p.Enum) > 0 { - s += ",enum=" + p.Enum - } - if p.HasDefault { - s += ",def=" + p.Default - } - return s -} - -// Parse populates p by parsing a string in the protobuf struct field tag style. -func (p *Properties) Parse(s string) { - // "bytes,49,opt,name=foo,def=hello!" - fields := strings.Split(s, ",") // breaks def=, but handled below. - if len(fields) < 2 { - fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s) - return - } - - p.Wire = fields[0] - switch p.Wire { - case "varint": - p.WireType = WireVarint - case "fixed32": - p.WireType = WireFixed32 - case "fixed64": - p.WireType = WireFixed64 - case "zigzag32": - p.WireType = WireVarint - case "zigzag64": - p.WireType = WireVarint - case "bytes", "group": - p.WireType = WireBytes - // no numeric converter for non-numeric types - default: - fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s) - return - } - - var err error - p.Tag, err = strconv.Atoi(fields[1]) - if err != nil { - return - } - -outer: - for i := 2; i < len(fields); i++ { - f := fields[i] - switch { - case f == "req": - p.Required = true - case f == "opt": - p.Optional = true - case f == "rep": - p.Repeated = true - case f == "packed": - p.Packed = true - case strings.HasPrefix(f, "name="): - p.OrigName = f[5:] - case strings.HasPrefix(f, "json="): - p.JSONName = f[5:] - case strings.HasPrefix(f, "enum="): - p.Enum = f[5:] - case f == "proto3": - p.proto3 = true - case f == "oneof": - p.oneof = true - case strings.HasPrefix(f, "def="): - p.HasDefault = true - p.Default = f[4:] // rest of string - if i+1 < len(fields) { - // Commas aren't escaped, and def is always last. - p.Default += "," + strings.Join(fields[i+1:], ",") - break outer - } - } - } -} - -var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() - -// setFieldProps initializes the field properties for submessages and maps. -func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { - switch t1 := typ; t1.Kind() { - case reflect.Ptr: - if t1.Elem().Kind() == reflect.Struct { - p.stype = t1.Elem() - } - - case reflect.Slice: - if t2 := t1.Elem(); t2.Kind() == reflect.Ptr && t2.Elem().Kind() == reflect.Struct { - p.stype = t2.Elem() - } - - case reflect.Map: - p.mtype = t1 - p.mkeyprop = &Properties{} - p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) - p.mvalprop = &Properties{} - vtype := p.mtype.Elem() - if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { - // The value type is not a message (*T) or bytes ([]byte), - // so we need encoders for the pointer to this type. - vtype = reflect.PtrTo(vtype) - } - p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) - } - - if p.stype != nil { - if lockGetProp { - p.sprop = GetProperties(p.stype) - } else { - p.sprop = getPropertiesLocked(p.stype) - } - } -} - -var ( - marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() -) - -// Init populates the properties from a protocol buffer struct tag. -func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { - p.init(typ, name, tag, f, true) -} - -func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) { - // "bytes,49,opt,def=hello!" - p.Name = name - p.OrigName = name - if tag == "" { - return - } - p.Parse(tag) - p.setFieldProps(typ, f, lockGetProp) -} - -var ( - propertiesMu sync.RWMutex - propertiesMap = make(map[reflect.Type]*StructProperties) -) - -// GetProperties returns the list of properties for the type represented by t. -// t must represent a generated struct type of a protocol message. -func GetProperties(t reflect.Type) *StructProperties { - if t.Kind() != reflect.Struct { - panic("proto: type must have kind struct") - } - - // Most calls to GetProperties in a long-running program will be - // retrieving details for types we have seen before. - propertiesMu.RLock() - sprop, ok := propertiesMap[t] - propertiesMu.RUnlock() - if ok { - if collectStats { - stats.Chit++ - } - return sprop - } - - propertiesMu.Lock() - sprop = getPropertiesLocked(t) - propertiesMu.Unlock() - return sprop -} - -// getPropertiesLocked requires that propertiesMu is held. -func getPropertiesLocked(t reflect.Type) *StructProperties { - if prop, ok := propertiesMap[t]; ok { - if collectStats { - stats.Chit++ - } - return prop - } - if collectStats { - stats.Cmiss++ - } - - prop := new(StructProperties) - // in case of recursive protos, fill this in now. - propertiesMap[t] = prop - - // build properties - prop.Prop = make([]*Properties, t.NumField()) - prop.order = make([]int, t.NumField()) - - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - p := new(Properties) - name := f.Name - p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false) - - oneof := f.Tag.Get("protobuf_oneof") // special case - if oneof != "" { - // Oneof fields don't use the traditional protobuf tag. - p.OrigName = oneof - } - prop.Prop[i] = p - prop.order[i] = i - if debug { - print(i, " ", f.Name, " ", t.String(), " ") - if p.Tag > 0 { - print(p.String()) - } - print("\n") - } - } - - // Re-order prop.order. - sort.Sort(prop) - - type oneofMessage interface { - XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) - } - if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { - var oots []interface{} - _, _, _, oots = om.XXX_OneofFuncs() - - // Interpret oneof metadata. - prop.OneofTypes = make(map[string]*OneofProperties) - for _, oot := range oots { - oop := &OneofProperties{ - Type: reflect.ValueOf(oot).Type(), // *T - Prop: new(Properties), - } - sft := oop.Type.Elem().Field(0) - oop.Prop.Name = sft.Name - oop.Prop.Parse(sft.Tag.Get("protobuf")) - // There will be exactly one interface field that - // this new value is assignable to. - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - if f.Type.Kind() != reflect.Interface { - continue - } - if !oop.Type.AssignableTo(f.Type) { - continue - } - oop.Field = i - break - } - prop.OneofTypes[oop.Prop.OrigName] = oop - } - } - - // build required counts - // build tags - reqCount := 0 - prop.decoderOrigNames = make(map[string]int) - for i, p := range prop.Prop { - if strings.HasPrefix(p.Name, "XXX_") { - // Internal fields should not appear in tags/origNames maps. - // They are handled specially when encoding and decoding. - continue - } - if p.Required { - reqCount++ - } - prop.decoderTags.put(p.Tag, i) - prop.decoderOrigNames[p.OrigName] = i - } - prop.reqCount = reqCount - - return prop -} - -// A global registry of enum types. -// The generated code will register the generated maps by calling RegisterEnum. - -var enumValueMaps = make(map[string]map[string]int32) - -// RegisterEnum is called from the generated code to install the enum descriptor -// maps into the global table to aid parsing text format protocol buffers. -func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) { - if _, ok := enumValueMaps[typeName]; ok { - panic("proto: duplicate enum registered: " + typeName) - } - enumValueMaps[typeName] = valueMap -} - -// EnumValueMap returns the mapping from names to integers of the -// enum type enumType, or a nil if not found. -func EnumValueMap(enumType string) map[string]int32 { - return enumValueMaps[enumType] -} - -// A registry of all linked message types. -// The string is a fully-qualified proto name ("pkg.Message"). -var ( - protoTypedNils = make(map[string]Message) // a map from proto names to typed nil pointers - protoMapTypes = make(map[string]reflect.Type) // a map from proto names to map types - revProtoTypes = make(map[reflect.Type]string) -) - -// RegisterType is called from generated code and maps from the fully qualified -// proto name to the type (pointer to struct) of the protocol buffer. -func RegisterType(x Message, name string) { - if _, ok := protoTypedNils[name]; ok { - // TODO: Some day, make this a panic. - log.Printf("proto: duplicate proto type registered: %s", name) - return - } - t := reflect.TypeOf(x) - if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 { - // Generated code always calls RegisterType with nil x. - // This check is just for extra safety. - protoTypedNils[name] = x - } else { - protoTypedNils[name] = reflect.Zero(t).Interface().(Message) - } - revProtoTypes[t] = name -} - -// RegisterMapType is called from generated code and maps from the fully qualified -// proto name to the native map type of the proto map definition. -func RegisterMapType(x interface{}, name string) { - if reflect.TypeOf(x).Kind() != reflect.Map { - panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name)) - } - if _, ok := protoMapTypes[name]; ok { - log.Printf("proto: duplicate proto type registered: %s", name) - return - } - t := reflect.TypeOf(x) - protoMapTypes[name] = t - revProtoTypes[t] = name -} - -// MessageName returns the fully-qualified proto name for the given message type. -func MessageName(x Message) string { - type xname interface { - XXX_MessageName() string - } - if m, ok := x.(xname); ok { - return m.XXX_MessageName() - } - return revProtoTypes[reflect.TypeOf(x)] -} - -// MessageType returns the message type (pointer to struct) for a named message. -// The type is not guaranteed to implement proto.Message if the name refers to a -// map entry. -func MessageType(name string) reflect.Type { - if t, ok := protoTypedNils[name]; ok { - return reflect.TypeOf(t) - } - return protoMapTypes[name] -} - -// A registry of all linked proto files. -var ( - protoFiles = make(map[string][]byte) // file name => fileDescriptor -) - -// RegisterFile is called from generated code and maps from the -// full file name of a .proto file to its compressed FileDescriptorProto. -func RegisterFile(filename string, fileDescriptor []byte) { - protoFiles[filename] = fileDescriptor -} - -// FileDescriptor returns the compressed FileDescriptorProto for a .proto file. -func FileDescriptor(filename string) []byte { return protoFiles[filename] } diff --git a/vendor/github.com/golang/protobuf/proto/table_marshal.go b/vendor/github.com/golang/protobuf/proto/table_marshal.go deleted file mode 100644 index 0f212b302..000000000 --- a/vendor/github.com/golang/protobuf/proto/table_marshal.go +++ /dev/null @@ -1,2681 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "errors" - "fmt" - "math" - "reflect" - "sort" - "strconv" - "strings" - "sync" - "sync/atomic" - "unicode/utf8" -) - -// a sizer takes a pointer to a field and the size of its tag, computes the size of -// the encoded data. -type sizer func(pointer, int) int - -// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format), -// marshals the field to the end of the slice, returns the slice and error (if any). -type marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) - -// marshalInfo is the information used for marshaling a message. -type marshalInfo struct { - typ reflect.Type - fields []*marshalFieldInfo - unrecognized field // offset of XXX_unrecognized - extensions field // offset of XXX_InternalExtensions - v1extensions field // offset of XXX_extensions - sizecache field // offset of XXX_sizecache - initialized int32 // 0 -- only typ is set, 1 -- fully initialized - messageset bool // uses message set wire format - hasmarshaler bool // has custom marshaler - sync.RWMutex // protect extElems map, also for initialization - extElems map[int32]*marshalElemInfo // info of extension elements -} - -// marshalFieldInfo is the information used for marshaling a field of a message. -type marshalFieldInfo struct { - field field - wiretag uint64 // tag in wire format - tagsize int // size of tag in wire format - sizer sizer - marshaler marshaler - isPointer bool - required bool // field is required - name string // name of the field, for error reporting - oneofElems map[reflect.Type]*marshalElemInfo // info of oneof elements -} - -// marshalElemInfo is the information used for marshaling an extension or oneof element. -type marshalElemInfo struct { - wiretag uint64 // tag in wire format - tagsize int // size of tag in wire format - sizer sizer - marshaler marshaler - isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only) -} - -var ( - marshalInfoMap = map[reflect.Type]*marshalInfo{} - marshalInfoLock sync.Mutex -) - -// getMarshalInfo returns the information to marshal a given type of message. -// The info it returns may not necessarily initialized. -// t is the type of the message (NOT the pointer to it). -func getMarshalInfo(t reflect.Type) *marshalInfo { - marshalInfoLock.Lock() - u, ok := marshalInfoMap[t] - if !ok { - u = &marshalInfo{typ: t} - marshalInfoMap[t] = u - } - marshalInfoLock.Unlock() - return u -} - -// Size is the entry point from generated code, -// and should be ONLY called by generated code. -// It computes the size of encoded data of msg. -// a is a pointer to a place to store cached marshal info. -func (a *InternalMessageInfo) Size(msg Message) int { - u := getMessageMarshalInfo(msg, a) - ptr := toPointer(&msg) - if ptr.isNil() { - // We get here if msg is a typed nil ((*SomeMessage)(nil)), - // so it satisfies the interface, and msg == nil wouldn't - // catch it. We don't want crash in this case. - return 0 - } - return u.size(ptr) -} - -// Marshal is the entry point from generated code, -// and should be ONLY called by generated code. -// It marshals msg to the end of b. -// a is a pointer to a place to store cached marshal info. -func (a *InternalMessageInfo) Marshal(b []byte, msg Message, deterministic bool) ([]byte, error) { - u := getMessageMarshalInfo(msg, a) - ptr := toPointer(&msg) - if ptr.isNil() { - // We get here if msg is a typed nil ((*SomeMessage)(nil)), - // so it satisfies the interface, and msg == nil wouldn't - // catch it. We don't want crash in this case. - return b, ErrNil - } - return u.marshal(b, ptr, deterministic) -} - -func getMessageMarshalInfo(msg interface{}, a *InternalMessageInfo) *marshalInfo { - // u := a.marshal, but atomically. - // We use an atomic here to ensure memory consistency. - u := atomicLoadMarshalInfo(&a.marshal) - if u == nil { - // Get marshal information from type of message. - t := reflect.ValueOf(msg).Type() - if t.Kind() != reflect.Ptr { - panic(fmt.Sprintf("cannot handle non-pointer message type %v", t)) - } - u = getMarshalInfo(t.Elem()) - // Store it in the cache for later users. - // a.marshal = u, but atomically. - atomicStoreMarshalInfo(&a.marshal, u) - } - return u -} - -// size is the main function to compute the size of the encoded data of a message. -// ptr is the pointer to the message. -func (u *marshalInfo) size(ptr pointer) int { - if atomic.LoadInt32(&u.initialized) == 0 { - u.computeMarshalInfo() - } - - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - if u.hasmarshaler { - m := ptr.asPointerTo(u.typ).Interface().(Marshaler) - b, _ := m.Marshal() - return len(b) - } - - n := 0 - for _, f := range u.fields { - if f.isPointer && ptr.offset(f.field).getPointer().isNil() { - // nil pointer always marshals to nothing - continue - } - n += f.sizer(ptr.offset(f.field), f.tagsize) - } - if u.extensions.IsValid() { - e := ptr.offset(u.extensions).toExtensions() - if u.messageset { - n += u.sizeMessageSet(e) - } else { - n += u.sizeExtensions(e) - } - } - if u.v1extensions.IsValid() { - m := *ptr.offset(u.v1extensions).toOldExtensions() - n += u.sizeV1Extensions(m) - } - if u.unrecognized.IsValid() { - s := *ptr.offset(u.unrecognized).toBytes() - n += len(s) - } - // cache the result for use in marshal - if u.sizecache.IsValid() { - atomic.StoreInt32(ptr.offset(u.sizecache).toInt32(), int32(n)) - } - return n -} - -// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated), -// fall back to compute the size. -func (u *marshalInfo) cachedsize(ptr pointer) int { - if u.sizecache.IsValid() { - return int(atomic.LoadInt32(ptr.offset(u.sizecache).toInt32())) - } - return u.size(ptr) -} - -// marshal is the main function to marshal a message. It takes a byte slice and appends -// the encoded data to the end of the slice, returns the slice and error (if any). -// ptr is the pointer to the message. -// If deterministic is true, map is marshaled in deterministic order. -func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte, error) { - if atomic.LoadInt32(&u.initialized) == 0 { - u.computeMarshalInfo() - } - - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - if u.hasmarshaler { - m := ptr.asPointerTo(u.typ).Interface().(Marshaler) - b1, err := m.Marshal() - b = append(b, b1...) - return b, err - } - - var err, errreq error - // The old marshaler encodes extensions at beginning. - if u.extensions.IsValid() { - e := ptr.offset(u.extensions).toExtensions() - if u.messageset { - b, err = u.appendMessageSet(b, e, deterministic) - } else { - b, err = u.appendExtensions(b, e, deterministic) - } - if err != nil { - return b, err - } - } - if u.v1extensions.IsValid() { - m := *ptr.offset(u.v1extensions).toOldExtensions() - b, err = u.appendV1Extensions(b, m, deterministic) - if err != nil { - return b, err - } - } - for _, f := range u.fields { - if f.required && errreq == nil { - if ptr.offset(f.field).getPointer().isNil() { - // Required field is not set. - // We record the error but keep going, to give a complete marshaling. - errreq = &RequiredNotSetError{f.name} - continue - } - } - if f.isPointer && ptr.offset(f.field).getPointer().isNil() { - // nil pointer always marshals to nothing - continue - } - b, err = f.marshaler(b, ptr.offset(f.field), f.wiretag, deterministic) - if err != nil { - if err1, ok := err.(*RequiredNotSetError); ok { - // Required field in submessage is not set. - // We record the error but keep going, to give a complete marshaling. - if errreq == nil { - errreq = &RequiredNotSetError{f.name + "." + err1.field} - } - continue - } - if err == errRepeatedHasNil { - err = errors.New("proto: repeated field " + f.name + " has nil element") - } - return b, err - } - } - if u.unrecognized.IsValid() { - s := *ptr.offset(u.unrecognized).toBytes() - b = append(b, s...) - } - return b, errreq -} - -// computeMarshalInfo initializes the marshal info. -func (u *marshalInfo) computeMarshalInfo() { - u.Lock() - defer u.Unlock() - if u.initialized != 0 { // non-atomic read is ok as it is protected by the lock - return - } - - t := u.typ - u.unrecognized = invalidField - u.extensions = invalidField - u.v1extensions = invalidField - u.sizecache = invalidField - - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - if reflect.PtrTo(t).Implements(marshalerType) { - u.hasmarshaler = true - atomic.StoreInt32(&u.initialized, 1) - return - } - - // get oneof implementers - var oneofImplementers []interface{} - if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { - _, _, _, oneofImplementers = m.XXX_OneofFuncs() - } - - n := t.NumField() - - // deal with XXX fields first - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - if !strings.HasPrefix(f.Name, "XXX_") { - continue - } - switch f.Name { - case "XXX_sizecache": - u.sizecache = toField(&f) - case "XXX_unrecognized": - u.unrecognized = toField(&f) - case "XXX_InternalExtensions": - u.extensions = toField(&f) - u.messageset = f.Tag.Get("protobuf_messageset") == "1" - case "XXX_extensions": - u.v1extensions = toField(&f) - case "XXX_NoUnkeyedLiteral": - // nothing to do - default: - panic("unknown XXX field: " + f.Name) - } - n-- - } - - // normal fields - fields := make([]marshalFieldInfo, n) // batch allocation - u.fields = make([]*marshalFieldInfo, 0, n) - for i, j := 0, 0; i < t.NumField(); i++ { - f := t.Field(i) - - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - field := &fields[j] - j++ - field.name = f.Name - u.fields = append(u.fields, field) - if f.Tag.Get("protobuf_oneof") != "" { - field.computeOneofFieldInfo(&f, oneofImplementers) - continue - } - if f.Tag.Get("protobuf") == "" { - // field has no tag (not in generated message), ignore it - u.fields = u.fields[:len(u.fields)-1] - j-- - continue - } - field.computeMarshalFieldInfo(&f) - } - - // fields are marshaled in tag order on the wire. - sort.Sort(byTag(u.fields)) - - atomic.StoreInt32(&u.initialized, 1) -} - -// helper for sorting fields by tag -type byTag []*marshalFieldInfo - -func (a byTag) Len() int { return len(a) } -func (a byTag) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a byTag) Less(i, j int) bool { return a[i].wiretag < a[j].wiretag } - -// getExtElemInfo returns the information to marshal an extension element. -// The info it returns is initialized. -func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo { - // get from cache first - u.RLock() - e, ok := u.extElems[desc.Field] - u.RUnlock() - if ok { - return e - } - - t := reflect.TypeOf(desc.ExtensionType) // pointer or slice to basic type or struct - tags := strings.Split(desc.Tag, ",") - tag, err := strconv.Atoi(tags[1]) - if err != nil { - panic("tag is not an integer") - } - wt := wiretype(tags[0]) - sizer, marshaler := typeMarshaler(t, tags, false, false) - e = &marshalElemInfo{ - wiretag: uint64(tag)<<3 | wt, - tagsize: SizeVarint(uint64(tag) << 3), - sizer: sizer, - marshaler: marshaler, - isptr: t.Kind() == reflect.Ptr, - } - - // update cache - u.Lock() - if u.extElems == nil { - u.extElems = make(map[int32]*marshalElemInfo) - } - u.extElems[desc.Field] = e - u.Unlock() - return e -} - -// computeMarshalFieldInfo fills up the information to marshal a field. -func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) { - // parse protobuf tag of the field. - // tag has format of "bytes,49,opt,name=foo,def=hello!" - tags := strings.Split(f.Tag.Get("protobuf"), ",") - if tags[0] == "" { - return - } - tag, err := strconv.Atoi(tags[1]) - if err != nil { - panic("tag is not an integer") - } - wt := wiretype(tags[0]) - if tags[2] == "req" { - fi.required = true - } - fi.setTag(f, tag, wt) - fi.setMarshaler(f, tags) -} - -func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) { - fi.field = toField(f) - fi.wiretag = 1<<31 - 1 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire. - fi.isPointer = true - fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f) - fi.oneofElems = make(map[reflect.Type]*marshalElemInfo) - - ityp := f.Type // interface type - for _, o := range oneofImplementers { - t := reflect.TypeOf(o) - if !t.Implements(ityp) { - continue - } - sf := t.Elem().Field(0) // oneof implementer is a struct with a single field - tags := strings.Split(sf.Tag.Get("protobuf"), ",") - tag, err := strconv.Atoi(tags[1]) - if err != nil { - panic("tag is not an integer") - } - wt := wiretype(tags[0]) - sizer, marshaler := typeMarshaler(sf.Type, tags, false, true) // oneof should not omit any zero value - fi.oneofElems[t.Elem()] = &marshalElemInfo{ - wiretag: uint64(tag)<<3 | wt, - tagsize: SizeVarint(uint64(tag) << 3), - sizer: sizer, - marshaler: marshaler, - } - } -} - -type oneofMessage interface { - XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) -} - -// wiretype returns the wire encoding of the type. -func wiretype(encoding string) uint64 { - switch encoding { - case "fixed32": - return WireFixed32 - case "fixed64": - return WireFixed64 - case "varint", "zigzag32", "zigzag64": - return WireVarint - case "bytes": - return WireBytes - case "group": - return WireStartGroup - } - panic("unknown wire type " + encoding) -} - -// setTag fills up the tag (in wire format) and its size in the info of a field. -func (fi *marshalFieldInfo) setTag(f *reflect.StructField, tag int, wt uint64) { - fi.field = toField(f) - fi.wiretag = uint64(tag)<<3 | wt - fi.tagsize = SizeVarint(uint64(tag) << 3) -} - -// setMarshaler fills up the sizer and marshaler in the info of a field. -func (fi *marshalFieldInfo) setMarshaler(f *reflect.StructField, tags []string) { - switch f.Type.Kind() { - case reflect.Map: - // map field - fi.isPointer = true - fi.sizer, fi.marshaler = makeMapMarshaler(f) - return - case reflect.Ptr, reflect.Slice: - fi.isPointer = true - } - fi.sizer, fi.marshaler = typeMarshaler(f.Type, tags, true, false) -} - -// typeMarshaler returns the sizer and marshaler of a given field. -// t is the type of the field. -// tags is the generated "protobuf" tag of the field. -// If nozero is true, zero value is not marshaled to the wire. -// If oneof is true, it is a oneof field. -func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, marshaler) { - encoding := tags[0] - - pointer := false - slice := false - if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { - slice = true - t = t.Elem() - } - if t.Kind() == reflect.Ptr { - pointer = true - t = t.Elem() - } - - packed := false - proto3 := false - for i := 2; i < len(tags); i++ { - if tags[i] == "packed" { - packed = true - } - if tags[i] == "proto3" { - proto3 = true - } - } - - switch t.Kind() { - case reflect.Bool: - if pointer { - return sizeBoolPtr, appendBoolPtr - } - if slice { - if packed { - return sizeBoolPackedSlice, appendBoolPackedSlice - } - return sizeBoolSlice, appendBoolSlice - } - if nozero { - return sizeBoolValueNoZero, appendBoolValueNoZero - } - return sizeBoolValue, appendBoolValue - case reflect.Uint32: - switch encoding { - case "fixed32": - if pointer { - return sizeFixed32Ptr, appendFixed32Ptr - } - if slice { - if packed { - return sizeFixed32PackedSlice, appendFixed32PackedSlice - } - return sizeFixed32Slice, appendFixed32Slice - } - if nozero { - return sizeFixed32ValueNoZero, appendFixed32ValueNoZero - } - return sizeFixed32Value, appendFixed32Value - case "varint": - if pointer { - return sizeVarint32Ptr, appendVarint32Ptr - } - if slice { - if packed { - return sizeVarint32PackedSlice, appendVarint32PackedSlice - } - return sizeVarint32Slice, appendVarint32Slice - } - if nozero { - return sizeVarint32ValueNoZero, appendVarint32ValueNoZero - } - return sizeVarint32Value, appendVarint32Value - } - case reflect.Int32: - switch encoding { - case "fixed32": - if pointer { - return sizeFixedS32Ptr, appendFixedS32Ptr - } - if slice { - if packed { - return sizeFixedS32PackedSlice, appendFixedS32PackedSlice - } - return sizeFixedS32Slice, appendFixedS32Slice - } - if nozero { - return sizeFixedS32ValueNoZero, appendFixedS32ValueNoZero - } - return sizeFixedS32Value, appendFixedS32Value - case "varint": - if pointer { - return sizeVarintS32Ptr, appendVarintS32Ptr - } - if slice { - if packed { - return sizeVarintS32PackedSlice, appendVarintS32PackedSlice - } - return sizeVarintS32Slice, appendVarintS32Slice - } - if nozero { - return sizeVarintS32ValueNoZero, appendVarintS32ValueNoZero - } - return sizeVarintS32Value, appendVarintS32Value - case "zigzag32": - if pointer { - return sizeZigzag32Ptr, appendZigzag32Ptr - } - if slice { - if packed { - return sizeZigzag32PackedSlice, appendZigzag32PackedSlice - } - return sizeZigzag32Slice, appendZigzag32Slice - } - if nozero { - return sizeZigzag32ValueNoZero, appendZigzag32ValueNoZero - } - return sizeZigzag32Value, appendZigzag32Value - } - case reflect.Uint64: - switch encoding { - case "fixed64": - if pointer { - return sizeFixed64Ptr, appendFixed64Ptr - } - if slice { - if packed { - return sizeFixed64PackedSlice, appendFixed64PackedSlice - } - return sizeFixed64Slice, appendFixed64Slice - } - if nozero { - return sizeFixed64ValueNoZero, appendFixed64ValueNoZero - } - return sizeFixed64Value, appendFixed64Value - case "varint": - if pointer { - return sizeVarint64Ptr, appendVarint64Ptr - } - if slice { - if packed { - return sizeVarint64PackedSlice, appendVarint64PackedSlice - } - return sizeVarint64Slice, appendVarint64Slice - } - if nozero { - return sizeVarint64ValueNoZero, appendVarint64ValueNoZero - } - return sizeVarint64Value, appendVarint64Value - } - case reflect.Int64: - switch encoding { - case "fixed64": - if pointer { - return sizeFixedS64Ptr, appendFixedS64Ptr - } - if slice { - if packed { - return sizeFixedS64PackedSlice, appendFixedS64PackedSlice - } - return sizeFixedS64Slice, appendFixedS64Slice - } - if nozero { - return sizeFixedS64ValueNoZero, appendFixedS64ValueNoZero - } - return sizeFixedS64Value, appendFixedS64Value - case "varint": - if pointer { - return sizeVarintS64Ptr, appendVarintS64Ptr - } - if slice { - if packed { - return sizeVarintS64PackedSlice, appendVarintS64PackedSlice - } - return sizeVarintS64Slice, appendVarintS64Slice - } - if nozero { - return sizeVarintS64ValueNoZero, appendVarintS64ValueNoZero - } - return sizeVarintS64Value, appendVarintS64Value - case "zigzag64": - if pointer { - return sizeZigzag64Ptr, appendZigzag64Ptr - } - if slice { - if packed { - return sizeZigzag64PackedSlice, appendZigzag64PackedSlice - } - return sizeZigzag64Slice, appendZigzag64Slice - } - if nozero { - return sizeZigzag64ValueNoZero, appendZigzag64ValueNoZero - } - return sizeZigzag64Value, appendZigzag64Value - } - case reflect.Float32: - if pointer { - return sizeFloat32Ptr, appendFloat32Ptr - } - if slice { - if packed { - return sizeFloat32PackedSlice, appendFloat32PackedSlice - } - return sizeFloat32Slice, appendFloat32Slice - } - if nozero { - return sizeFloat32ValueNoZero, appendFloat32ValueNoZero - } - return sizeFloat32Value, appendFloat32Value - case reflect.Float64: - if pointer { - return sizeFloat64Ptr, appendFloat64Ptr - } - if slice { - if packed { - return sizeFloat64PackedSlice, appendFloat64PackedSlice - } - return sizeFloat64Slice, appendFloat64Slice - } - if nozero { - return sizeFloat64ValueNoZero, appendFloat64ValueNoZero - } - return sizeFloat64Value, appendFloat64Value - case reflect.String: - if pointer { - return sizeStringPtr, appendStringPtr - } - if slice { - return sizeStringSlice, appendStringSlice - } - if nozero { - return sizeStringValueNoZero, appendStringValueNoZero - } - return sizeStringValue, appendStringValue - case reflect.Slice: - if slice { - return sizeBytesSlice, appendBytesSlice - } - if oneof { - // Oneof bytes field may also have "proto3" tag. - // We want to marshal it as a oneof field. Do this - // check before the proto3 check. - return sizeBytesOneof, appendBytesOneof - } - if proto3 { - return sizeBytes3, appendBytes3 - } - return sizeBytes, appendBytes - case reflect.Struct: - switch encoding { - case "group": - if slice { - return makeGroupSliceMarshaler(getMarshalInfo(t)) - } - return makeGroupMarshaler(getMarshalInfo(t)) - case "bytes": - if slice { - return makeMessageSliceMarshaler(getMarshalInfo(t)) - } - return makeMessageMarshaler(getMarshalInfo(t)) - } - } - panic(fmt.Sprintf("unknown or mismatched type: type: %v, wire type: %v", t, encoding)) -} - -// Below are functions to size/marshal a specific type of a field. -// They are stored in the field's info, and called by function pointers. -// They have type sizer or marshaler. - -func sizeFixed32Value(_ pointer, tagsize int) int { - return 4 + tagsize -} -func sizeFixed32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint32() - if v == 0 { - return 0 - } - return 4 + tagsize -} -func sizeFixed32Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint32Ptr() - if p == nil { - return 0 - } - return 4 + tagsize -} -func sizeFixed32Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - return (4 + tagsize) * len(s) -} -func sizeFixed32PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return 0 - } - return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize -} -func sizeFixedS32Value(_ pointer, tagsize int) int { - return 4 + tagsize -} -func sizeFixedS32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - if v == 0 { - return 0 - } - return 4 + tagsize -} -func sizeFixedS32Ptr(ptr pointer, tagsize int) int { - p := ptr.getInt32Ptr() - if p == nil { - return 0 - } - return 4 + tagsize -} -func sizeFixedS32Slice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - return (4 + tagsize) * len(s) -} -func sizeFixedS32PackedSlice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - if len(s) == 0 { - return 0 - } - return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize -} -func sizeFloat32Value(_ pointer, tagsize int) int { - return 4 + tagsize -} -func sizeFloat32ValueNoZero(ptr pointer, tagsize int) int { - v := math.Float32bits(*ptr.toFloat32()) - if v == 0 { - return 0 - } - return 4 + tagsize -} -func sizeFloat32Ptr(ptr pointer, tagsize int) int { - p := *ptr.toFloat32Ptr() - if p == nil { - return 0 - } - return 4 + tagsize -} -func sizeFloat32Slice(ptr pointer, tagsize int) int { - s := *ptr.toFloat32Slice() - return (4 + tagsize) * len(s) -} -func sizeFloat32PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toFloat32Slice() - if len(s) == 0 { - return 0 - } - return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize -} -func sizeFixed64Value(_ pointer, tagsize int) int { - return 8 + tagsize -} -func sizeFixed64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint64() - if v == 0 { - return 0 - } - return 8 + tagsize -} -func sizeFixed64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint64Ptr() - if p == nil { - return 0 - } - return 8 + tagsize -} -func sizeFixed64Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - return (8 + tagsize) * len(s) -} -func sizeFixed64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return 0 - } - return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize -} -func sizeFixedS64Value(_ pointer, tagsize int) int { - return 8 + tagsize -} -func sizeFixedS64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - if v == 0 { - return 0 - } - return 8 + tagsize -} -func sizeFixedS64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toInt64Ptr() - if p == nil { - return 0 - } - return 8 + tagsize -} -func sizeFixedS64Slice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - return (8 + tagsize) * len(s) -} -func sizeFixedS64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return 0 - } - return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize -} -func sizeFloat64Value(_ pointer, tagsize int) int { - return 8 + tagsize -} -func sizeFloat64ValueNoZero(ptr pointer, tagsize int) int { - v := math.Float64bits(*ptr.toFloat64()) - if v == 0 { - return 0 - } - return 8 + tagsize -} -func sizeFloat64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toFloat64Ptr() - if p == nil { - return 0 - } - return 8 + tagsize -} -func sizeFloat64Slice(ptr pointer, tagsize int) int { - s := *ptr.toFloat64Slice() - return (8 + tagsize) * len(s) -} -func sizeFloat64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toFloat64Slice() - if len(s) == 0 { - return 0 - } - return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize -} -func sizeVarint32Value(ptr pointer, tagsize int) int { - v := *ptr.toUint32() - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarint32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint32() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarint32Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint32Ptr() - if p == nil { - return 0 - } - return SizeVarint(uint64(*p)) + tagsize -} -func sizeVarint32Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) + tagsize - } - return n -} -func sizeVarint32PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeVarintS32Value(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS32Ptr(ptr pointer, tagsize int) int { - p := ptr.getInt32Ptr() - if p == nil { - return 0 - } - return SizeVarint(uint64(*p)) + tagsize -} -func sizeVarintS32Slice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) + tagsize - } - return n -} -func sizeVarintS32PackedSlice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeVarint64Value(ptr pointer, tagsize int) int { - v := *ptr.toUint64() - return SizeVarint(v) + tagsize -} -func sizeVarint64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint64() - if v == 0 { - return 0 - } - return SizeVarint(v) + tagsize -} -func sizeVarint64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint64Ptr() - if p == nil { - return 0 - } - return SizeVarint(*p) + tagsize -} -func sizeVarint64Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - n := 0 - for _, v := range s { - n += SizeVarint(v) + tagsize - } - return n -} -func sizeVarint64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(v) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeVarintS64Value(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toInt64Ptr() - if p == nil { - return 0 - } - return SizeVarint(uint64(*p)) + tagsize -} -func sizeVarintS64Slice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) + tagsize - } - return n -} -func sizeVarintS64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeZigzag32Value(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize -} -func sizeZigzag32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - if v == 0 { - return 0 - } - return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize -} -func sizeZigzag32Ptr(ptr pointer, tagsize int) int { - p := ptr.getInt32Ptr() - if p == nil { - return 0 - } - v := *p - return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize -} -func sizeZigzag32Slice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize - } - return n -} -func sizeZigzag32PackedSlice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeZigzag64Value(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize -} -func sizeZigzag64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize -} -func sizeZigzag64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toInt64Ptr() - if p == nil { - return 0 - } - v := *p - return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize -} -func sizeZigzag64Slice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize - } - return n -} -func sizeZigzag64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63))) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeBoolValue(_ pointer, tagsize int) int { - return 1 + tagsize -} -func sizeBoolValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toBool() - if !v { - return 0 - } - return 1 + tagsize -} -func sizeBoolPtr(ptr pointer, tagsize int) int { - p := *ptr.toBoolPtr() - if p == nil { - return 0 - } - return 1 + tagsize -} -func sizeBoolSlice(ptr pointer, tagsize int) int { - s := *ptr.toBoolSlice() - return (1 + tagsize) * len(s) -} -func sizeBoolPackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toBoolSlice() - if len(s) == 0 { - return 0 - } - return len(s) + SizeVarint(uint64(len(s))) + tagsize -} -func sizeStringValue(ptr pointer, tagsize int) int { - v := *ptr.toString() - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeStringValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toString() - if v == "" { - return 0 - } - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeStringPtr(ptr pointer, tagsize int) int { - p := *ptr.toStringPtr() - if p == nil { - return 0 - } - v := *p - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeStringSlice(ptr pointer, tagsize int) int { - s := *ptr.toStringSlice() - n := 0 - for _, v := range s { - n += len(v) + SizeVarint(uint64(len(v))) + tagsize - } - return n -} -func sizeBytes(ptr pointer, tagsize int) int { - v := *ptr.toBytes() - if v == nil { - return 0 - } - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeBytes3(ptr pointer, tagsize int) int { - v := *ptr.toBytes() - if len(v) == 0 { - return 0 - } - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeBytesOneof(ptr pointer, tagsize int) int { - v := *ptr.toBytes() - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeBytesSlice(ptr pointer, tagsize int) int { - s := *ptr.toBytesSlice() - n := 0 - for _, v := range s { - n += len(v) + SizeVarint(uint64(len(v))) + tagsize - } - return n -} - -// appendFixed32 appends an encoded fixed32 to b. -func appendFixed32(b []byte, v uint32) []byte { - b = append(b, - byte(v), - byte(v>>8), - byte(v>>16), - byte(v>>24)) - return b -} - -// appendFixed64 appends an encoded fixed64 to b. -func appendFixed64(b []byte, v uint64) []byte { - b = append(b, - byte(v), - byte(v>>8), - byte(v>>16), - byte(v>>24), - byte(v>>32), - byte(v>>40), - byte(v>>48), - byte(v>>56)) - return b -} - -// appendVarint appends an encoded varint to b. -func appendVarint(b []byte, v uint64) []byte { - // TODO: make 1-byte (maybe 2-byte) case inline-able, once we - // have non-leaf inliner. - switch { - case v < 1<<7: - b = append(b, byte(v)) - case v < 1<<14: - b = append(b, - byte(v&0x7f|0x80), - byte(v>>7)) - case v < 1<<21: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte(v>>14)) - case v < 1<<28: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte(v>>21)) - case v < 1<<35: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte(v>>28)) - case v < 1<<42: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte(v>>35)) - case v < 1<<49: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte(v>>42)) - case v < 1<<56: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte((v>>42)&0x7f|0x80), - byte(v>>49)) - case v < 1<<63: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte((v>>42)&0x7f|0x80), - byte((v>>49)&0x7f|0x80), - byte(v>>56)) - default: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte((v>>42)&0x7f|0x80), - byte((v>>49)&0x7f|0x80), - byte((v>>56)&0x7f|0x80), - 1) - } - return b -} - -func appendFixed32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFixed32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFixed32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, *p) - return b, nil -} -func appendFixed32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - } - return b, nil -} -func appendFixed32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(4*len(s))) - for _, v := range s { - b = appendFixed32(b, v) - } - return b, nil -} -func appendFixedS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(v)) - return b, nil -} -func appendFixedS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(v)) - return b, nil -} -func appendFixedS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := ptr.getInt32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(*p)) - return b, nil -} -func appendFixedS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(v)) - } - return b, nil -} -func appendFixedS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(4*len(s))) - for _, v := range s { - b = appendFixed32(b, uint32(v)) - } - return b, nil -} -func appendFloat32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float32bits(*ptr.toFloat32()) - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFloat32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float32bits(*ptr.toFloat32()) - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFloat32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toFloat32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, math.Float32bits(*p)) - return b, nil -} -func appendFloat32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed32(b, math.Float32bits(v)) - } - return b, nil -} -func appendFloat32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(4*len(s))) - for _, v := range s { - b = appendFixed32(b, math.Float32bits(v)) - } - return b, nil -} -func appendFixed64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFixed64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFixed64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, *p) - return b, nil -} -func appendFixed64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - } - return b, nil -} -func appendFixed64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(8*len(s))) - for _, v := range s { - b = appendFixed64(b, v) - } - return b, nil -} -func appendFixedS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(v)) - return b, nil -} -func appendFixedS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(v)) - return b, nil -} -func appendFixedS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toInt64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(*p)) - return b, nil -} -func appendFixedS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(v)) - } - return b, nil -} -func appendFixedS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(8*len(s))) - for _, v := range s { - b = appendFixed64(b, uint64(v)) - } - return b, nil -} -func appendFloat64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float64bits(*ptr.toFloat64()) - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFloat64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float64bits(*ptr.toFloat64()) - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFloat64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toFloat64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, math.Float64bits(*p)) - return b, nil -} -func appendFloat64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed64(b, math.Float64bits(v)) - } - return b, nil -} -func appendFloat64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(8*len(s))) - for _, v := range s { - b = appendFixed64(b, math.Float64bits(v)) - } - return b, nil -} -func appendVarint32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarint32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarint32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(*p)) - return b, nil -} -func appendVarint32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarint32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarintS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := ptr.getInt32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(*p)) - return b, nil -} -func appendVarintS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarintS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarint64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - b = appendVarint(b, wiretag) - b = appendVarint(b, v) - return b, nil -} -func appendVarint64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, v) - return b, nil -} -func appendVarint64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, *p) - return b, nil -} -func appendVarint64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, v) - } - return b, nil -} -func appendVarint64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(v) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, v) - } - return b, nil -} -func appendVarintS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toInt64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(*p)) - return b, nil -} -func appendVarintS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarintS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendZigzag32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - return b, nil -} -func appendZigzag32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - return b, nil -} -func appendZigzag32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := ptr.getInt32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - v := *p - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - return b, nil -} -func appendZigzag32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - } - return b, nil -} -func appendZigzag32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - } - return b, nil -} -func appendZigzag64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - return b, nil -} -func appendZigzag64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - return b, nil -} -func appendZigzag64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toInt64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - v := *p - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - return b, nil -} -func appendZigzag64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - } - return b, nil -} -func appendZigzag64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63))) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - } - return b, nil -} -func appendBoolValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBool() - b = appendVarint(b, wiretag) - if v { - b = append(b, 1) - } else { - b = append(b, 0) - } - return b, nil -} -func appendBoolValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBool() - if !v { - return b, nil - } - b = appendVarint(b, wiretag) - b = append(b, 1) - return b, nil -} - -func appendBoolPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toBoolPtr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - if *p { - b = append(b, 1) - } else { - b = append(b, 0) - } - return b, nil -} -func appendBoolSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toBoolSlice() - for _, v := range s { - b = appendVarint(b, wiretag) - if v { - b = append(b, 1) - } else { - b = append(b, 0) - } - } - return b, nil -} -func appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toBoolSlice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(len(s))) - for _, v := range s { - if v { - b = append(b, 1) - } else { - b = append(b, 0) - } - } - return b, nil -} -func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toString() - if !utf8.ValidString(v) { - return nil, errInvalidUTF8 - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toString() - if v == "" { - return b, nil - } - if !utf8.ValidString(v) { - return nil, errInvalidUTF8 - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toStringPtr() - if p == nil { - return b, nil - } - v := *p - if !utf8.ValidString(v) { - return nil, errInvalidUTF8 - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toStringSlice() - for _, v := range s { - if !utf8.ValidString(v) { - return nil, errInvalidUTF8 - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - } - return b, nil -} -func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBytes() - if v == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendBytes3(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBytes() - if len(v) == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendBytesOneof(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBytes() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendBytesSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toBytesSlice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - } - return b, nil -} - -// makeGroupMarshaler returns the sizer and marshaler for a group. -// u is the marshal info of the underlying message. -func makeGroupMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - p := ptr.getPointer() - if p.isNil() { - return 0 - } - return u.size(p) + 2*tagsize - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - p := ptr.getPointer() - if p.isNil() { - return b, nil - } - var err error - b = appendVarint(b, wiretag) // start group - b, err = u.marshal(b, p, deterministic) - b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group - return b, err - } -} - -// makeGroupSliceMarshaler returns the sizer and marshaler for a group slice. -// u is the marshal info of the underlying message. -func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getPointerSlice() - n := 0 - for _, v := range s { - if v.isNil() { - continue - } - n += u.size(v) + 2*tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getPointerSlice() - var err, errreq error - for _, v := range s { - if v.isNil() { - return b, errRepeatedHasNil - } - b = appendVarint(b, wiretag) // start group - b, err = u.marshal(b, v, deterministic) - b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group - if err != nil { - if _, ok := err.(*RequiredNotSetError); ok { - // Required field in submessage is not set. - // We record the error but keep going, to give a complete marshaling. - if errreq == nil { - errreq = err - } - continue - } - if err == ErrNil { - err = errRepeatedHasNil - } - return b, err - } - } - return b, errreq - } -} - -// makeMessageMarshaler returns the sizer and marshaler for a message field. -// u is the marshal info of the message. -func makeMessageMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - p := ptr.getPointer() - if p.isNil() { - return 0 - } - siz := u.size(p) - return siz + SizeVarint(uint64(siz)) + tagsize - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - p := ptr.getPointer() - if p.isNil() { - return b, nil - } - b = appendVarint(b, wiretag) - siz := u.cachedsize(p) - b = appendVarint(b, uint64(siz)) - return u.marshal(b, p, deterministic) - } -} - -// makeMessageSliceMarshaler returns the sizer and marshaler for a message slice. -// u is the marshal info of the message. -func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getPointerSlice() - n := 0 - for _, v := range s { - if v.isNil() { - continue - } - siz := u.size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getPointerSlice() - var err, errreq error - for _, v := range s { - if v.isNil() { - return b, errRepeatedHasNil - } - b = appendVarint(b, wiretag) - siz := u.cachedsize(v) - b = appendVarint(b, uint64(siz)) - b, err = u.marshal(b, v, deterministic) - - if err != nil { - if _, ok := err.(*RequiredNotSetError); ok { - // Required field in submessage is not set. - // We record the error but keep going, to give a complete marshaling. - if errreq == nil { - errreq = err - } - continue - } - if err == ErrNil { - err = errRepeatedHasNil - } - return b, err - } - } - return b, errreq - } -} - -// makeMapMarshaler returns the sizer and marshaler for a map field. -// f is the pointer to the reflect data structure of the field. -func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) { - // figure out key and value type - t := f.Type - keyType := t.Key() - valType := t.Elem() - keyTags := strings.Split(f.Tag.Get("protobuf_key"), ",") - valTags := strings.Split(f.Tag.Get("protobuf_val"), ",") - keySizer, keyMarshaler := typeMarshaler(keyType, keyTags, false, false) // don't omit zero value in map - valSizer, valMarshaler := typeMarshaler(valType, valTags, false, false) // don't omit zero value in map - keyWireTag := 1<<3 | wiretype(keyTags[0]) - valWireTag := 2<<3 | wiretype(valTags[0]) - - // We create an interface to get the addresses of the map key and value. - // If value is pointer-typed, the interface is a direct interface, the - // idata itself is the value. Otherwise, the idata is the pointer to the - // value. - // Key cannot be pointer-typed. - valIsPtr := valType.Kind() == reflect.Ptr - return func(ptr pointer, tagsize int) int { - m := ptr.asPointerTo(t).Elem() // the map - n := 0 - for _, k := range m.MapKeys() { - ki := k.Interface() - vi := m.MapIndex(k).Interface() - kaddr := toAddrPointer(&ki, false) // pointer to key - vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value - siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, tag uint64, deterministic bool) ([]byte, error) { - m := ptr.asPointerTo(t).Elem() // the map - var err error - keys := m.MapKeys() - if len(keys) > 1 && deterministic { - sort.Sort(mapKeys(keys)) - } - for _, k := range keys { - ki := k.Interface() - vi := m.MapIndex(k).Interface() - kaddr := toAddrPointer(&ki, false) // pointer to key - vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value - b = appendVarint(b, tag) - siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) - b = appendVarint(b, uint64(siz)) - b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic) - if err != nil { - return b, err - } - b, err = valMarshaler(b, vaddr, valWireTag, deterministic) - if err != nil && err != ErrNil { // allow nil value in map - return b, err - } - } - return b, nil - } -} - -// makeOneOfMarshaler returns the sizer and marshaler for a oneof field. -// fi is the marshal info of the field. -// f is the pointer to the reflect data structure of the field. -func makeOneOfMarshaler(fi *marshalFieldInfo, f *reflect.StructField) (sizer, marshaler) { - // Oneof field is an interface. We need to get the actual data type on the fly. - t := f.Type - return func(ptr pointer, _ int) int { - p := ptr.getInterfacePointer() - if p.isNil() { - return 0 - } - v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct - telem := v.Type() - e := fi.oneofElems[telem] - return e.sizer(p, e.tagsize) - }, - func(b []byte, ptr pointer, _ uint64, deterministic bool) ([]byte, error) { - p := ptr.getInterfacePointer() - if p.isNil() { - return b, nil - } - v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct - telem := v.Type() - if telem.Field(0).Type.Kind() == reflect.Ptr && p.getPointer().isNil() { - return b, errOneofHasNil - } - e := fi.oneofElems[telem] - return e.marshaler(b, p, e.wiretag, deterministic) - } -} - -// sizeExtensions computes the size of encoded data for a XXX_InternalExtensions field. -func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int { - m, mu := ext.extensionsRead() - if m == nil { - return 0 - } - mu.Lock() - - n := 0 - for _, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - n += len(e.enc) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - n += ei.sizer(p, ei.tagsize) - } - mu.Unlock() - return n -} - -// appendExtensions marshals a XXX_InternalExtensions field to the end of byte slice b. -func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) { - m, mu := ext.extensionsRead() - if m == nil { - return b, nil - } - mu.Lock() - defer mu.Unlock() - - var err error - - // Fast-path for common cases: zero or one extensions. - // Don't bother sorting the keys. - if len(m) <= 1 { - for _, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - b = append(b, e.enc...) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if err != nil { - return b, err - } - } - return b, nil - } - - // Sort the keys to provide a deterministic encoding. - // Not sure this is required, but the old code does it. - keys := make([]int, 0, len(m)) - for k := range m { - keys = append(keys, int(k)) - } - sort.Ints(keys) - - for _, k := range keys { - e := m[int32(k)] - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - b = append(b, e.enc...) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if err != nil { - return b, err - } - } - return b, nil -} - -// message set format is: -// message MessageSet { -// repeated group Item = 1 { -// required int32 type_id = 2; -// required string message = 3; -// }; -// } - -// sizeMessageSet computes the size of encoded data for a XXX_InternalExtensions field -// in message set format (above). -func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int { - m, mu := ext.extensionsRead() - if m == nil { - return 0 - } - mu.Lock() - - n := 0 - for id, e := range m { - n += 2 // start group, end group. tag = 1 (size=1) - n += SizeVarint(uint64(id)) + 1 // type_id, tag = 2 (size=1) - - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint - siz := len(msgWithLen) - n += siz + 1 // message, tag = 3 (size=1) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - n += ei.sizer(p, 1) // message, tag = 3 (size=1) - } - mu.Unlock() - return n -} - -// appendMessageSet marshals a XXX_InternalExtensions field in message set format (above) -// to the end of byte slice b. -func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) { - m, mu := ext.extensionsRead() - if m == nil { - return b, nil - } - mu.Lock() - defer mu.Unlock() - - var err error - - // Fast-path for common cases: zero or one extensions. - // Don't bother sorting the keys. - if len(m) <= 1 { - for id, e := range m { - b = append(b, 1<<3|WireStartGroup) - b = append(b, 2<<3|WireVarint) - b = appendVarint(b, uint64(id)) - - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint - b = append(b, 3<<3|WireBytes) - b = append(b, msgWithLen...) - b = append(b, 1<<3|WireEndGroup) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) - if err != nil { - return b, err - } - b = append(b, 1<<3|WireEndGroup) - } - return b, nil - } - - // Sort the keys to provide a deterministic encoding. - keys := make([]int, 0, len(m)) - for k := range m { - keys = append(keys, int(k)) - } - sort.Ints(keys) - - for _, id := range keys { - e := m[int32(id)] - b = append(b, 1<<3|WireStartGroup) - b = append(b, 2<<3|WireVarint) - b = appendVarint(b, uint64(id)) - - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint - b = append(b, 3<<3|WireBytes) - b = append(b, msgWithLen...) - b = append(b, 1<<3|WireEndGroup) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) - b = append(b, 1<<3|WireEndGroup) - if err != nil { - return b, err - } - } - return b, nil -} - -// sizeV1Extensions computes the size of encoded data for a V1-API extension field. -func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int { - if m == nil { - return 0 - } - - n := 0 - for _, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - n += len(e.enc) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - n += ei.sizer(p, ei.tagsize) - } - return n -} - -// appendV1Extensions marshals a V1-API extension field to the end of byte slice b. -func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, deterministic bool) ([]byte, error) { - if m == nil { - return b, nil - } - - // Sort the keys to provide a deterministic encoding. - keys := make([]int, 0, len(m)) - for k := range m { - keys = append(keys, int(k)) - } - sort.Ints(keys) - - var err error - for _, k := range keys { - e := m[int32(k)] - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - b = append(b, e.enc...) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if err != nil { - return b, err - } - } - return b, nil -} - -// newMarshaler is the interface representing objects that can marshal themselves. -// -// This exists to support protoc-gen-go generated messages. -// The proto package will stop type-asserting to this interface in the future. -// -// DO NOT DEPEND ON THIS. -type newMarshaler interface { - XXX_Size() int - XXX_Marshal(b []byte, deterministic bool) ([]byte, error) -} - -// Size returns the encoded size of a protocol buffer message. -// This is the main entry point. -func Size(pb Message) int { - if m, ok := pb.(newMarshaler); ok { - return m.XXX_Size() - } - if m, ok := pb.(Marshaler); ok { - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - b, _ := m.Marshal() - return len(b) - } - // in case somehow we didn't generate the wrapper - if pb == nil { - return 0 - } - var info InternalMessageInfo - return info.Size(pb) -} - -// Marshal takes a protocol buffer message -// and encodes it into the wire format, returning the data. -// This is the main entry point. -func Marshal(pb Message) ([]byte, error) { - if m, ok := pb.(newMarshaler); ok { - siz := m.XXX_Size() - b := make([]byte, 0, siz) - return m.XXX_Marshal(b, false) - } - if m, ok := pb.(Marshaler); ok { - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - return m.Marshal() - } - // in case somehow we didn't generate the wrapper - if pb == nil { - return nil, ErrNil - } - var info InternalMessageInfo - siz := info.Size(pb) - b := make([]byte, 0, siz) - return info.Marshal(b, pb, false) -} - -// Marshal takes a protocol buffer message -// and encodes it into the wire format, writing the result to the -// Buffer. -// This is an alternative entry point. It is not necessary to use -// a Buffer for most applications. -func (p *Buffer) Marshal(pb Message) error { - var err error - if m, ok := pb.(newMarshaler); ok { - siz := m.XXX_Size() - p.grow(siz) // make sure buf has enough capacity - p.buf, err = m.XXX_Marshal(p.buf, p.deterministic) - return err - } - if m, ok := pb.(Marshaler); ok { - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - b, err := m.Marshal() - p.buf = append(p.buf, b...) - return err - } - // in case somehow we didn't generate the wrapper - if pb == nil { - return ErrNil - } - var info InternalMessageInfo - siz := info.Size(pb) - p.grow(siz) // make sure buf has enough capacity - p.buf, err = info.Marshal(p.buf, pb, p.deterministic) - return err -} - -// grow grows the buffer's capacity, if necessary, to guarantee space for -// another n bytes. After grow(n), at least n bytes can be written to the -// buffer without another allocation. -func (p *Buffer) grow(n int) { - need := len(p.buf) + n - if need <= cap(p.buf) { - return - } - newCap := len(p.buf) * 2 - if newCap < need { - newCap = need - } - p.buf = append(make([]byte, 0, newCap), p.buf...) -} diff --git a/vendor/github.com/golang/protobuf/proto/table_merge.go b/vendor/github.com/golang/protobuf/proto/table_merge.go deleted file mode 100644 index 5525def6a..000000000 --- a/vendor/github.com/golang/protobuf/proto/table_merge.go +++ /dev/null @@ -1,654 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "reflect" - "strings" - "sync" - "sync/atomic" -) - -// Merge merges the src message into dst. -// This assumes that dst and src of the same type and are non-nil. -func (a *InternalMessageInfo) Merge(dst, src Message) { - mi := atomicLoadMergeInfo(&a.merge) - if mi == nil { - mi = getMergeInfo(reflect.TypeOf(dst).Elem()) - atomicStoreMergeInfo(&a.merge, mi) - } - mi.merge(toPointer(&dst), toPointer(&src)) -} - -type mergeInfo struct { - typ reflect.Type - - initialized int32 // 0: only typ is valid, 1: everything is valid - lock sync.Mutex - - fields []mergeFieldInfo - unrecognized field // Offset of XXX_unrecognized -} - -type mergeFieldInfo struct { - field field // Offset of field, guaranteed to be valid - - // isPointer reports whether the value in the field is a pointer. - // This is true for the following situations: - // * Pointer to struct - // * Pointer to basic type (proto2 only) - // * Slice (first value in slice header is a pointer) - // * String (first value in string header is a pointer) - isPointer bool - - // basicWidth reports the width of the field assuming that it is directly - // embedded in the struct (as is the case for basic types in proto3). - // The possible values are: - // 0: invalid - // 1: bool - // 4: int32, uint32, float32 - // 8: int64, uint64, float64 - basicWidth int - - // Where dst and src are pointers to the types being merged. - merge func(dst, src pointer) -} - -var ( - mergeInfoMap = map[reflect.Type]*mergeInfo{} - mergeInfoLock sync.Mutex -) - -func getMergeInfo(t reflect.Type) *mergeInfo { - mergeInfoLock.Lock() - defer mergeInfoLock.Unlock() - mi := mergeInfoMap[t] - if mi == nil { - mi = &mergeInfo{typ: t} - mergeInfoMap[t] = mi - } - return mi -} - -// merge merges src into dst assuming they are both of type *mi.typ. -func (mi *mergeInfo) merge(dst, src pointer) { - if dst.isNil() { - panic("proto: nil destination") - } - if src.isNil() { - return // Nothing to do. - } - - if atomic.LoadInt32(&mi.initialized) == 0 { - mi.computeMergeInfo() - } - - for _, fi := range mi.fields { - sfp := src.offset(fi.field) - - // As an optimization, we can avoid the merge function call cost - // if we know for sure that the source will have no effect - // by checking if it is the zero value. - if unsafeAllowed { - if fi.isPointer && sfp.getPointer().isNil() { // Could be slice or string - continue - } - if fi.basicWidth > 0 { - switch { - case fi.basicWidth == 1 && !*sfp.toBool(): - continue - case fi.basicWidth == 4 && *sfp.toUint32() == 0: - continue - case fi.basicWidth == 8 && *sfp.toUint64() == 0: - continue - } - } - } - - dfp := dst.offset(fi.field) - fi.merge(dfp, sfp) - } - - // TODO: Make this faster? - out := dst.asPointerTo(mi.typ).Elem() - in := src.asPointerTo(mi.typ).Elem() - if emIn, err := extendable(in.Addr().Interface()); err == nil { - emOut, _ := extendable(out.Addr().Interface()) - mIn, muIn := emIn.extensionsRead() - if mIn != nil { - mOut := emOut.extensionsWrite() - muIn.Lock() - mergeExtension(mOut, mIn) - muIn.Unlock() - } - } - - if mi.unrecognized.IsValid() { - if b := *src.offset(mi.unrecognized).toBytes(); len(b) > 0 { - *dst.offset(mi.unrecognized).toBytes() = append([]byte(nil), b...) - } - } -} - -func (mi *mergeInfo) computeMergeInfo() { - mi.lock.Lock() - defer mi.lock.Unlock() - if mi.initialized != 0 { - return - } - t := mi.typ - n := t.NumField() - - props := GetProperties(t) - for i := 0; i < n; i++ { - f := t.Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - - mfi := mergeFieldInfo{field: toField(&f)} - tf := f.Type - - // As an optimization, we can avoid the merge function call cost - // if we know for sure that the source will have no effect - // by checking if it is the zero value. - if unsafeAllowed { - switch tf.Kind() { - case reflect.Ptr, reflect.Slice, reflect.String: - // As a special case, we assume slices and strings are pointers - // since we know that the first field in the SliceSlice or - // StringHeader is a data pointer. - mfi.isPointer = true - case reflect.Bool: - mfi.basicWidth = 1 - case reflect.Int32, reflect.Uint32, reflect.Float32: - mfi.basicWidth = 4 - case reflect.Int64, reflect.Uint64, reflect.Float64: - mfi.basicWidth = 8 - } - } - - // Unwrap tf to get at its most basic type. - var isPointer, isSlice bool - if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { - isSlice = true - tf = tf.Elem() - } - if tf.Kind() == reflect.Ptr { - isPointer = true - tf = tf.Elem() - } - if isPointer && isSlice && tf.Kind() != reflect.Struct { - panic("both pointer and slice for basic type in " + tf.Name()) - } - - switch tf.Kind() { - case reflect.Int32: - switch { - case isSlice: // E.g., []int32 - mfi.merge = func(dst, src pointer) { - // NOTE: toInt32Slice is not defined (see pointer_reflect.go). - /* - sfsp := src.toInt32Slice() - if *sfsp != nil { - dfsp := dst.toInt32Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []int64{} - } - } - */ - sfs := src.getInt32Slice() - if sfs != nil { - dfs := dst.getInt32Slice() - dfs = append(dfs, sfs...) - if dfs == nil { - dfs = []int32{} - } - dst.setInt32Slice(dfs) - } - } - case isPointer: // E.g., *int32 - mfi.merge = func(dst, src pointer) { - // NOTE: toInt32Ptr is not defined (see pointer_reflect.go). - /* - sfpp := src.toInt32Ptr() - if *sfpp != nil { - dfpp := dst.toInt32Ptr() - if *dfpp == nil { - *dfpp = Int32(**sfpp) - } else { - **dfpp = **sfpp - } - } - */ - sfp := src.getInt32Ptr() - if sfp != nil { - dfp := dst.getInt32Ptr() - if dfp == nil { - dst.setInt32Ptr(*sfp) - } else { - *dfp = *sfp - } - } - } - default: // E.g., int32 - mfi.merge = func(dst, src pointer) { - if v := *src.toInt32(); v != 0 { - *dst.toInt32() = v - } - } - } - case reflect.Int64: - switch { - case isSlice: // E.g., []int64 - mfi.merge = func(dst, src pointer) { - sfsp := src.toInt64Slice() - if *sfsp != nil { - dfsp := dst.toInt64Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []int64{} - } - } - } - case isPointer: // E.g., *int64 - mfi.merge = func(dst, src pointer) { - sfpp := src.toInt64Ptr() - if *sfpp != nil { - dfpp := dst.toInt64Ptr() - if *dfpp == nil { - *dfpp = Int64(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., int64 - mfi.merge = func(dst, src pointer) { - if v := *src.toInt64(); v != 0 { - *dst.toInt64() = v - } - } - } - case reflect.Uint32: - switch { - case isSlice: // E.g., []uint32 - mfi.merge = func(dst, src pointer) { - sfsp := src.toUint32Slice() - if *sfsp != nil { - dfsp := dst.toUint32Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []uint32{} - } - } - } - case isPointer: // E.g., *uint32 - mfi.merge = func(dst, src pointer) { - sfpp := src.toUint32Ptr() - if *sfpp != nil { - dfpp := dst.toUint32Ptr() - if *dfpp == nil { - *dfpp = Uint32(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., uint32 - mfi.merge = func(dst, src pointer) { - if v := *src.toUint32(); v != 0 { - *dst.toUint32() = v - } - } - } - case reflect.Uint64: - switch { - case isSlice: // E.g., []uint64 - mfi.merge = func(dst, src pointer) { - sfsp := src.toUint64Slice() - if *sfsp != nil { - dfsp := dst.toUint64Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []uint64{} - } - } - } - case isPointer: // E.g., *uint64 - mfi.merge = func(dst, src pointer) { - sfpp := src.toUint64Ptr() - if *sfpp != nil { - dfpp := dst.toUint64Ptr() - if *dfpp == nil { - *dfpp = Uint64(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., uint64 - mfi.merge = func(dst, src pointer) { - if v := *src.toUint64(); v != 0 { - *dst.toUint64() = v - } - } - } - case reflect.Float32: - switch { - case isSlice: // E.g., []float32 - mfi.merge = func(dst, src pointer) { - sfsp := src.toFloat32Slice() - if *sfsp != nil { - dfsp := dst.toFloat32Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []float32{} - } - } - } - case isPointer: // E.g., *float32 - mfi.merge = func(dst, src pointer) { - sfpp := src.toFloat32Ptr() - if *sfpp != nil { - dfpp := dst.toFloat32Ptr() - if *dfpp == nil { - *dfpp = Float32(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., float32 - mfi.merge = func(dst, src pointer) { - if v := *src.toFloat32(); v != 0 { - *dst.toFloat32() = v - } - } - } - case reflect.Float64: - switch { - case isSlice: // E.g., []float64 - mfi.merge = func(dst, src pointer) { - sfsp := src.toFloat64Slice() - if *sfsp != nil { - dfsp := dst.toFloat64Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []float64{} - } - } - } - case isPointer: // E.g., *float64 - mfi.merge = func(dst, src pointer) { - sfpp := src.toFloat64Ptr() - if *sfpp != nil { - dfpp := dst.toFloat64Ptr() - if *dfpp == nil { - *dfpp = Float64(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., float64 - mfi.merge = func(dst, src pointer) { - if v := *src.toFloat64(); v != 0 { - *dst.toFloat64() = v - } - } - } - case reflect.Bool: - switch { - case isSlice: // E.g., []bool - mfi.merge = func(dst, src pointer) { - sfsp := src.toBoolSlice() - if *sfsp != nil { - dfsp := dst.toBoolSlice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []bool{} - } - } - } - case isPointer: // E.g., *bool - mfi.merge = func(dst, src pointer) { - sfpp := src.toBoolPtr() - if *sfpp != nil { - dfpp := dst.toBoolPtr() - if *dfpp == nil { - *dfpp = Bool(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., bool - mfi.merge = func(dst, src pointer) { - if v := *src.toBool(); v { - *dst.toBool() = v - } - } - } - case reflect.String: - switch { - case isSlice: // E.g., []string - mfi.merge = func(dst, src pointer) { - sfsp := src.toStringSlice() - if *sfsp != nil { - dfsp := dst.toStringSlice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []string{} - } - } - } - case isPointer: // E.g., *string - mfi.merge = func(dst, src pointer) { - sfpp := src.toStringPtr() - if *sfpp != nil { - dfpp := dst.toStringPtr() - if *dfpp == nil { - *dfpp = String(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., string - mfi.merge = func(dst, src pointer) { - if v := *src.toString(); v != "" { - *dst.toString() = v - } - } - } - case reflect.Slice: - isProto3 := props.Prop[i].proto3 - switch { - case isPointer: - panic("bad pointer in byte slice case in " + tf.Name()) - case tf.Elem().Kind() != reflect.Uint8: - panic("bad element kind in byte slice case in " + tf.Name()) - case isSlice: // E.g., [][]byte - mfi.merge = func(dst, src pointer) { - sbsp := src.toBytesSlice() - if *sbsp != nil { - dbsp := dst.toBytesSlice() - for _, sb := range *sbsp { - if sb == nil { - *dbsp = append(*dbsp, nil) - } else { - *dbsp = append(*dbsp, append([]byte{}, sb...)) - } - } - if *dbsp == nil { - *dbsp = [][]byte{} - } - } - } - default: // E.g., []byte - mfi.merge = func(dst, src pointer) { - sbp := src.toBytes() - if *sbp != nil { - dbp := dst.toBytes() - if !isProto3 || len(*sbp) > 0 { - *dbp = append([]byte{}, *sbp...) - } - } - } - } - case reflect.Struct: - switch { - case !isPointer: - panic(fmt.Sprintf("message field %s without pointer", tf)) - case isSlice: // E.g., []*pb.T - mi := getMergeInfo(tf) - mfi.merge = func(dst, src pointer) { - sps := src.getPointerSlice() - if sps != nil { - dps := dst.getPointerSlice() - for _, sp := range sps { - var dp pointer - if !sp.isNil() { - dp = valToPointer(reflect.New(tf)) - mi.merge(dp, sp) - } - dps = append(dps, dp) - } - if dps == nil { - dps = []pointer{} - } - dst.setPointerSlice(dps) - } - } - default: // E.g., *pb.T - mi := getMergeInfo(tf) - mfi.merge = func(dst, src pointer) { - sp := src.getPointer() - if !sp.isNil() { - dp := dst.getPointer() - if dp.isNil() { - dp = valToPointer(reflect.New(tf)) - dst.setPointer(dp) - } - mi.merge(dp, sp) - } - } - } - case reflect.Map: - switch { - case isPointer || isSlice: - panic("bad pointer or slice in map case in " + tf.Name()) - default: // E.g., map[K]V - mfi.merge = func(dst, src pointer) { - sm := src.asPointerTo(tf).Elem() - if sm.Len() == 0 { - return - } - dm := dst.asPointerTo(tf).Elem() - if dm.IsNil() { - dm.Set(reflect.MakeMap(tf)) - } - - switch tf.Elem().Kind() { - case reflect.Ptr: // Proto struct (e.g., *T) - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - val = reflect.ValueOf(Clone(val.Interface().(Message))) - dm.SetMapIndex(key, val) - } - case reflect.Slice: // E.g. Bytes type (e.g., []byte) - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) - dm.SetMapIndex(key, val) - } - default: // Basic type (e.g., string) - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - dm.SetMapIndex(key, val) - } - } - } - } - case reflect.Interface: - // Must be oneof field. - switch { - case isPointer || isSlice: - panic("bad pointer or slice in interface case in " + tf.Name()) - default: // E.g., interface{} - // TODO: Make this faster? - mfi.merge = func(dst, src pointer) { - su := src.asPointerTo(tf).Elem() - if !su.IsNil() { - du := dst.asPointerTo(tf).Elem() - typ := su.Elem().Type() - if du.IsNil() || du.Elem().Type() != typ { - du.Set(reflect.New(typ.Elem())) // Initialize interface if empty - } - sv := su.Elem().Elem().Field(0) - if sv.Kind() == reflect.Ptr && sv.IsNil() { - return - } - dv := du.Elem().Elem().Field(0) - if dv.Kind() == reflect.Ptr && dv.IsNil() { - dv.Set(reflect.New(sv.Type().Elem())) // Initialize proto message if empty - } - switch sv.Type().Kind() { - case reflect.Ptr: // Proto struct (e.g., *T) - Merge(dv.Interface().(Message), sv.Interface().(Message)) - case reflect.Slice: // E.g. Bytes type (e.g., []byte) - dv.Set(reflect.ValueOf(append([]byte{}, sv.Bytes()...))) - default: // Basic type (e.g., string) - dv.Set(sv) - } - } - } - } - default: - panic(fmt.Sprintf("merger not found for type:%s", tf)) - } - mi.fields = append(mi.fields, mfi) - } - - mi.unrecognized = invalidField - if f, ok := t.FieldByName("XXX_unrecognized"); ok { - if f.Type != reflect.TypeOf([]byte{}) { - panic("expected XXX_unrecognized to be of type []byte") - } - mi.unrecognized = toField(&f) - } - - atomic.StoreInt32(&mi.initialized, 1) -} diff --git a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go deleted file mode 100644 index 55f0340a3..000000000 --- a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go +++ /dev/null @@ -1,1967 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "errors" - "fmt" - "io" - "math" - "reflect" - "strconv" - "strings" - "sync" - "sync/atomic" - "unicode/utf8" -) - -// Unmarshal is the entry point from the generated .pb.go files. -// This function is not intended to be used by non-generated code. -// This function is not subject to any compatibility guarantee. -// msg contains a pointer to a protocol buffer struct. -// b is the data to be unmarshaled into the protocol buffer. -// a is a pointer to a place to store cached unmarshal information. -func (a *InternalMessageInfo) Unmarshal(msg Message, b []byte) error { - // Load the unmarshal information for this message type. - // The atomic load ensures memory consistency. - u := atomicLoadUnmarshalInfo(&a.unmarshal) - if u == nil { - // Slow path: find unmarshal info for msg, update a with it. - u = getUnmarshalInfo(reflect.TypeOf(msg).Elem()) - atomicStoreUnmarshalInfo(&a.unmarshal, u) - } - // Then do the unmarshaling. - err := u.unmarshal(toPointer(&msg), b) - return err -} - -type unmarshalInfo struct { - typ reflect.Type // type of the protobuf struct - - // 0 = only typ field is initialized - // 1 = completely initialized - initialized int32 - lock sync.Mutex // prevents double initialization - dense []unmarshalFieldInfo // fields indexed by tag # - sparse map[uint64]unmarshalFieldInfo // fields indexed by tag # - reqFields []string // names of required fields - reqMask uint64 // 1< 0 { - // Read tag and wire type. - // Special case 1 and 2 byte varints. - var x uint64 - if b[0] < 128 { - x = uint64(b[0]) - b = b[1:] - } else if len(b) >= 2 && b[1] < 128 { - x = uint64(b[0]&0x7f) + uint64(b[1])<<7 - b = b[2:] - } else { - var n int - x, n = decodeVarint(b) - if n == 0 { - return io.ErrUnexpectedEOF - } - b = b[n:] - } - tag := x >> 3 - wire := int(x) & 7 - - // Dispatch on the tag to one of the unmarshal* functions below. - var f unmarshalFieldInfo - if tag < uint64(len(u.dense)) { - f = u.dense[tag] - } else { - f = u.sparse[tag] - } - if fn := f.unmarshal; fn != nil { - var err error - b, err = fn(b, m.offset(f.field), wire) - if err == nil { - reqMask |= f.reqMask - continue - } - if r, ok := err.(*RequiredNotSetError); ok { - // Remember this error, but keep parsing. We need to produce - // a full parse even if a required field is missing. - rnse = r - reqMask |= f.reqMask - continue - } - if err != errInternalBadWireType { - return err - } - // Fragments with bad wire type are treated as unknown fields. - } - - // Unknown tag. - if !u.unrecognized.IsValid() { - // Don't keep unrecognized data; just skip it. - var err error - b, err = skipField(b, wire) - if err != nil { - return err - } - continue - } - // Keep unrecognized data around. - // maybe in extensions, maybe in the unrecognized field. - z := m.offset(u.unrecognized).toBytes() - var emap map[int32]Extension - var e Extension - for _, r := range u.extensionRanges { - if uint64(r.Start) <= tag && tag <= uint64(r.End) { - if u.extensions.IsValid() { - mp := m.offset(u.extensions).toExtensions() - emap = mp.extensionsWrite() - e = emap[int32(tag)] - z = &e.enc - break - } - if u.oldExtensions.IsValid() { - p := m.offset(u.oldExtensions).toOldExtensions() - emap = *p - if emap == nil { - emap = map[int32]Extension{} - *p = emap - } - e = emap[int32(tag)] - z = &e.enc - break - } - panic("no extensions field available") - } - } - - // Use wire type to skip data. - var err error - b0 := b - b, err = skipField(b, wire) - if err != nil { - return err - } - *z = encodeVarint(*z, tag<<3|uint64(wire)) - *z = append(*z, b0[:len(b0)-len(b)]...) - - if emap != nil { - emap[int32(tag)] = e - } - } - if rnse != nil { - // A required field of a submessage/group is missing. Return that error. - return rnse - } - if reqMask != u.reqMask { - // A required field of this message is missing. - for _, n := range u.reqFields { - if reqMask&1 == 0 { - return &RequiredNotSetError{n} - } - reqMask >>= 1 - } - } - return nil -} - -// computeUnmarshalInfo fills in u with information for use -// in unmarshaling protocol buffers of type u.typ. -func (u *unmarshalInfo) computeUnmarshalInfo() { - u.lock.Lock() - defer u.lock.Unlock() - if u.initialized != 0 { - return - } - t := u.typ - n := t.NumField() - - // Set up the "not found" value for the unrecognized byte buffer. - // This is the default for proto3. - u.unrecognized = invalidField - u.extensions = invalidField - u.oldExtensions = invalidField - - // List of the generated type and offset for each oneof field. - type oneofField struct { - ityp reflect.Type // interface type of oneof field - field field // offset in containing message - } - var oneofFields []oneofField - - for i := 0; i < n; i++ { - f := t.Field(i) - if f.Name == "XXX_unrecognized" { - // The byte slice used to hold unrecognized input is special. - if f.Type != reflect.TypeOf(([]byte)(nil)) { - panic("bad type for XXX_unrecognized field: " + f.Type.Name()) - } - u.unrecognized = toField(&f) - continue - } - if f.Name == "XXX_InternalExtensions" { - // Ditto here. - if f.Type != reflect.TypeOf(XXX_InternalExtensions{}) { - panic("bad type for XXX_InternalExtensions field: " + f.Type.Name()) - } - u.extensions = toField(&f) - if f.Tag.Get("protobuf_messageset") == "1" { - u.isMessageSet = true - } - continue - } - if f.Name == "XXX_extensions" { - // An older form of the extensions field. - if f.Type != reflect.TypeOf((map[int32]Extension)(nil)) { - panic("bad type for XXX_extensions field: " + f.Type.Name()) - } - u.oldExtensions = toField(&f) - continue - } - if f.Name == "XXX_NoUnkeyedLiteral" || f.Name == "XXX_sizecache" { - continue - } - - oneof := f.Tag.Get("protobuf_oneof") - if oneof != "" { - oneofFields = append(oneofFields, oneofField{f.Type, toField(&f)}) - // The rest of oneof processing happens below. - continue - } - - tags := f.Tag.Get("protobuf") - tagArray := strings.Split(tags, ",") - if len(tagArray) < 2 { - panic("protobuf tag not enough fields in " + t.Name() + "." + f.Name + ": " + tags) - } - tag, err := strconv.Atoi(tagArray[1]) - if err != nil { - panic("protobuf tag field not an integer: " + tagArray[1]) - } - - name := "" - for _, tag := range tagArray[3:] { - if strings.HasPrefix(tag, "name=") { - name = tag[5:] - } - } - - // Extract unmarshaling function from the field (its type and tags). - unmarshal := fieldUnmarshaler(&f) - - // Required field? - var reqMask uint64 - if tagArray[2] == "req" { - bit := len(u.reqFields) - u.reqFields = append(u.reqFields, name) - reqMask = uint64(1) << uint(bit) - // TODO: if we have more than 64 required fields, we end up - // not verifying that all required fields are present. - // Fix this, perhaps using a count of required fields? - } - - // Store the info in the correct slot in the message. - u.setTag(tag, toField(&f), unmarshal, reqMask) - } - - // Find any types associated with oneof fields. - // TODO: XXX_OneofFuncs returns more info than we need. Get rid of some of it? - fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("XXX_OneofFuncs") - if fn.IsValid() { - res := fn.Call(nil)[3] // last return value from XXX_OneofFuncs: []interface{} - for i := res.Len() - 1; i >= 0; i-- { - v := res.Index(i) // interface{} - tptr := reflect.ValueOf(v.Interface()).Type() // *Msg_X - typ := tptr.Elem() // Msg_X - - f := typ.Field(0) // oneof implementers have one field - baseUnmarshal := fieldUnmarshaler(&f) - tagstr := strings.Split(f.Tag.Get("protobuf"), ",")[1] - tag, err := strconv.Atoi(tagstr) - if err != nil { - panic("protobuf tag field not an integer: " + tagstr) - } - - // Find the oneof field that this struct implements. - // Might take O(n^2) to process all of the oneofs, but who cares. - for _, of := range oneofFields { - if tptr.Implements(of.ityp) { - // We have found the corresponding interface for this struct. - // That lets us know where this struct should be stored - // when we encounter it during unmarshaling. - unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal) - u.setTag(tag, of.field, unmarshal, 0) - } - } - } - } - - // Get extension ranges, if any. - fn = reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray") - if fn.IsValid() { - if !u.extensions.IsValid() && !u.oldExtensions.IsValid() { - panic("a message with extensions, but no extensions field in " + t.Name()) - } - u.extensionRanges = fn.Call(nil)[0].Interface().([]ExtensionRange) - } - - // Explicitly disallow tag 0. This will ensure we flag an error - // when decoding a buffer of all zeros. Without this code, we - // would decode and skip an all-zero buffer of even length. - // [0 0] is [tag=0/wiretype=varint varint-encoded-0]. - u.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) { - return nil, fmt.Errorf("proto: %s: illegal tag 0 (wire type %d)", t, w) - }, 0) - - // Set mask for required field check. - u.reqMask = uint64(1)<= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here? - for len(u.dense) <= tag { - u.dense = append(u.dense, unmarshalFieldInfo{}) - } - u.dense[tag] = i - return - } - if u.sparse == nil { - u.sparse = map[uint64]unmarshalFieldInfo{} - } - u.sparse[uint64(tag)] = i -} - -// fieldUnmarshaler returns an unmarshaler for the given field. -func fieldUnmarshaler(f *reflect.StructField) unmarshaler { - if f.Type.Kind() == reflect.Map { - return makeUnmarshalMap(f) - } - return typeUnmarshaler(f.Type, f.Tag.Get("protobuf")) -} - -// typeUnmarshaler returns an unmarshaler for the given field type / field tag pair. -func typeUnmarshaler(t reflect.Type, tags string) unmarshaler { - tagArray := strings.Split(tags, ",") - encoding := tagArray[0] - name := "unknown" - for _, tag := range tagArray[3:] { - if strings.HasPrefix(tag, "name=") { - name = tag[5:] - } - } - - // Figure out packaging (pointer, slice, or both) - slice := false - pointer := false - if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { - slice = true - t = t.Elem() - } - if t.Kind() == reflect.Ptr { - pointer = true - t = t.Elem() - } - - // We'll never have both pointer and slice for basic types. - if pointer && slice && t.Kind() != reflect.Struct { - panic("both pointer and slice for basic type in " + t.Name()) - } - - switch t.Kind() { - case reflect.Bool: - if pointer { - return unmarshalBoolPtr - } - if slice { - return unmarshalBoolSlice - } - return unmarshalBoolValue - case reflect.Int32: - switch encoding { - case "fixed32": - if pointer { - return unmarshalFixedS32Ptr - } - if slice { - return unmarshalFixedS32Slice - } - return unmarshalFixedS32Value - case "varint": - // this could be int32 or enum - if pointer { - return unmarshalInt32Ptr - } - if slice { - return unmarshalInt32Slice - } - return unmarshalInt32Value - case "zigzag32": - if pointer { - return unmarshalSint32Ptr - } - if slice { - return unmarshalSint32Slice - } - return unmarshalSint32Value - } - case reflect.Int64: - switch encoding { - case "fixed64": - if pointer { - return unmarshalFixedS64Ptr - } - if slice { - return unmarshalFixedS64Slice - } - return unmarshalFixedS64Value - case "varint": - if pointer { - return unmarshalInt64Ptr - } - if slice { - return unmarshalInt64Slice - } - return unmarshalInt64Value - case "zigzag64": - if pointer { - return unmarshalSint64Ptr - } - if slice { - return unmarshalSint64Slice - } - return unmarshalSint64Value - } - case reflect.Uint32: - switch encoding { - case "fixed32": - if pointer { - return unmarshalFixed32Ptr - } - if slice { - return unmarshalFixed32Slice - } - return unmarshalFixed32Value - case "varint": - if pointer { - return unmarshalUint32Ptr - } - if slice { - return unmarshalUint32Slice - } - return unmarshalUint32Value - } - case reflect.Uint64: - switch encoding { - case "fixed64": - if pointer { - return unmarshalFixed64Ptr - } - if slice { - return unmarshalFixed64Slice - } - return unmarshalFixed64Value - case "varint": - if pointer { - return unmarshalUint64Ptr - } - if slice { - return unmarshalUint64Slice - } - return unmarshalUint64Value - } - case reflect.Float32: - if pointer { - return unmarshalFloat32Ptr - } - if slice { - return unmarshalFloat32Slice - } - return unmarshalFloat32Value - case reflect.Float64: - if pointer { - return unmarshalFloat64Ptr - } - if slice { - return unmarshalFloat64Slice - } - return unmarshalFloat64Value - case reflect.Map: - panic("map type in typeUnmarshaler in " + t.Name()) - case reflect.Slice: - if pointer { - panic("bad pointer in slice case in " + t.Name()) - } - if slice { - return unmarshalBytesSlice - } - return unmarshalBytesValue - case reflect.String: - if pointer { - return unmarshalStringPtr - } - if slice { - return unmarshalStringSlice - } - return unmarshalStringValue - case reflect.Struct: - // message or group field - if !pointer { - panic(fmt.Sprintf("message/group field %s:%s without pointer", t, encoding)) - } - switch encoding { - case "bytes": - if slice { - return makeUnmarshalMessageSlicePtr(getUnmarshalInfo(t), name) - } - return makeUnmarshalMessagePtr(getUnmarshalInfo(t), name) - case "group": - if slice { - return makeUnmarshalGroupSlicePtr(getUnmarshalInfo(t), name) - } - return makeUnmarshalGroupPtr(getUnmarshalInfo(t), name) - } - } - panic(fmt.Sprintf("unmarshaler not found type:%s encoding:%s", t, encoding)) -} - -// Below are all the unmarshalers for individual fields of various types. - -func unmarshalInt64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - *f.toInt64() = v - return b, nil -} - -func unmarshalInt64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - *f.toInt64Ptr() = &v - return b, nil -} - -func unmarshalInt64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - s := f.toInt64Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - s := f.toInt64Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalSint64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - *f.toInt64() = v - return b, nil -} - -func unmarshalSint64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - *f.toInt64Ptr() = &v - return b, nil -} - -func unmarshalSint64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - s := f.toInt64Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - s := f.toInt64Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalUint64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - *f.toUint64() = v - return b, nil -} - -func unmarshalUint64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - *f.toUint64Ptr() = &v - return b, nil -} - -func unmarshalUint64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - s := f.toUint64Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - s := f.toUint64Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalInt32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - *f.toInt32() = v - return b, nil -} - -func unmarshalInt32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - f.setInt32Ptr(v) - return b, nil -} - -func unmarshalInt32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - f.appendInt32Slice(v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - f.appendInt32Slice(v) - return b, nil -} - -func unmarshalSint32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - *f.toInt32() = v - return b, nil -} - -func unmarshalSint32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - f.setInt32Ptr(v) - return b, nil -} - -func unmarshalSint32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - f.appendInt32Slice(v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - f.appendInt32Slice(v) - return b, nil -} - -func unmarshalUint32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - *f.toUint32() = v - return b, nil -} - -func unmarshalUint32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - *f.toUint32Ptr() = &v - return b, nil -} - -func unmarshalUint32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - s := f.toUint32Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - s := f.toUint32Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalFixed64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - *f.toUint64() = v - return b[8:], nil -} - -func unmarshalFixed64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - *f.toUint64Ptr() = &v - return b[8:], nil -} - -func unmarshalFixed64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - s := f.toUint64Slice() - *s = append(*s, v) - b = b[8:] - } - return res, nil - } - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - s := f.toUint64Slice() - *s = append(*s, v) - return b[8:], nil -} - -func unmarshalFixedS64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - *f.toInt64() = v - return b[8:], nil -} - -func unmarshalFixedS64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - *f.toInt64Ptr() = &v - return b[8:], nil -} - -func unmarshalFixedS64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - s := f.toInt64Slice() - *s = append(*s, v) - b = b[8:] - } - return res, nil - } - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - s := f.toInt64Slice() - *s = append(*s, v) - return b[8:], nil -} - -func unmarshalFixed32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - *f.toUint32() = v - return b[4:], nil -} - -func unmarshalFixed32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - *f.toUint32Ptr() = &v - return b[4:], nil -} - -func unmarshalFixed32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - s := f.toUint32Slice() - *s = append(*s, v) - b = b[4:] - } - return res, nil - } - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - s := f.toUint32Slice() - *s = append(*s, v) - return b[4:], nil -} - -func unmarshalFixedS32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - *f.toInt32() = v - return b[4:], nil -} - -func unmarshalFixedS32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - f.setInt32Ptr(v) - return b[4:], nil -} - -func unmarshalFixedS32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - f.appendInt32Slice(v) - b = b[4:] - } - return res, nil - } - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - f.appendInt32Slice(v) - return b[4:], nil -} - -func unmarshalBoolValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - // Note: any length varint is allowed, even though any sane - // encoder will use one byte. - // See https://github.com/golang/protobuf/issues/76 - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - // TODO: check if x>1? Tests seem to indicate no. - v := x != 0 - *f.toBool() = v - return b[n:], nil -} - -func unmarshalBoolPtr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - v := x != 0 - *f.toBoolPtr() = &v - return b[n:], nil -} - -func unmarshalBoolSlice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - v := x != 0 - s := f.toBoolSlice() - *s = append(*s, v) - b = b[n:] - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - v := x != 0 - s := f.toBoolSlice() - *s = append(*s, v) - return b[n:], nil -} - -func unmarshalFloat64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - *f.toFloat64() = v - return b[8:], nil -} - -func unmarshalFloat64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - *f.toFloat64Ptr() = &v - return b[8:], nil -} - -func unmarshalFloat64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - s := f.toFloat64Slice() - *s = append(*s, v) - b = b[8:] - } - return res, nil - } - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - s := f.toFloat64Slice() - *s = append(*s, v) - return b[8:], nil -} - -func unmarshalFloat32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - *f.toFloat32() = v - return b[4:], nil -} - -func unmarshalFloat32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - *f.toFloat32Ptr() = &v - return b[4:], nil -} - -func unmarshalFloat32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - s := f.toFloat32Slice() - *s = append(*s, v) - b = b[4:] - } - return res, nil - } - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - s := f.toFloat32Slice() - *s = append(*s, v) - return b[4:], nil -} - -func unmarshalStringValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - if !utf8.ValidString(v) { - return nil, errInvalidUTF8 - } - *f.toString() = v - return b[x:], nil -} - -func unmarshalStringPtr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - if !utf8.ValidString(v) { - return nil, errInvalidUTF8 - } - *f.toStringPtr() = &v - return b[x:], nil -} - -func unmarshalStringSlice(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - if !utf8.ValidString(v) { - return nil, errInvalidUTF8 - } - s := f.toStringSlice() - *s = append(*s, v) - return b[x:], nil -} - -var emptyBuf [0]byte - -func unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - // The use of append here is a trick which avoids the zeroing - // that would be required if we used a make/copy pair. - // We append to emptyBuf instead of nil because we want - // a non-nil result even when the length is 0. - v := append(emptyBuf[:], b[:x]...) - *f.toBytes() = v - return b[x:], nil -} - -func unmarshalBytesSlice(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := append(emptyBuf[:], b[:x]...) - s := f.toBytesSlice() - *s = append(*s, v) - return b[x:], nil -} - -func makeUnmarshalMessagePtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - // First read the message field to see if something is there. - // The semantics of multiple submessages are weird. Instead of - // the last one winning (as it is for all other fields), multiple - // submessages are merged. - v := f.getPointer() - if v.isNil() { - v = valToPointer(reflect.New(sub.typ)) - f.setPointer(v) - } - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - return b[x:], err - } -} - -func makeUnmarshalMessageSlicePtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := valToPointer(reflect.New(sub.typ)) - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - f.appendPointer(v) - return b[x:], err - } -} - -func makeUnmarshalGroupPtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireStartGroup { - return b, errInternalBadWireType - } - x, y := findEndGroup(b) - if x < 0 { - return nil, io.ErrUnexpectedEOF - } - v := f.getPointer() - if v.isNil() { - v = valToPointer(reflect.New(sub.typ)) - f.setPointer(v) - } - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - return b[y:], err - } -} - -func makeUnmarshalGroupSlicePtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireStartGroup { - return b, errInternalBadWireType - } - x, y := findEndGroup(b) - if x < 0 { - return nil, io.ErrUnexpectedEOF - } - v := valToPointer(reflect.New(sub.typ)) - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - f.appendPointer(v) - return b[y:], err - } -} - -func makeUnmarshalMap(f *reflect.StructField) unmarshaler { - t := f.Type - kt := t.Key() - vt := t.Elem() - unmarshalKey := typeUnmarshaler(kt, f.Tag.Get("protobuf_key")) - unmarshalVal := typeUnmarshaler(vt, f.Tag.Get("protobuf_val")) - return func(b []byte, f pointer, w int) ([]byte, error) { - // The map entry is a submessage. Figure out how big it is. - if w != WireBytes { - return nil, fmt.Errorf("proto: bad wiretype for map field: got %d want %d", w, WireBytes) - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - r := b[x:] // unused data to return - b = b[:x] // data for map entry - - // Note: we could use #keys * #values ~= 200 functions - // to do map decoding without reflection. Probably not worth it. - // Maps will be somewhat slow. Oh well. - - // Read key and value from data. - k := reflect.New(kt) - v := reflect.New(vt) - for len(b) > 0 { - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - wire := int(x) & 7 - b = b[n:] - - var err error - switch x >> 3 { - case 1: - b, err = unmarshalKey(b, valToPointer(k), wire) - case 2: - b, err = unmarshalVal(b, valToPointer(v), wire) - default: - err = errInternalBadWireType // skip unknown tag - } - - if err == nil { - continue - } - if err != errInternalBadWireType { - return nil, err - } - - // Skip past unknown fields. - b, err = skipField(b, wire) - if err != nil { - return nil, err - } - } - - // Get map, allocate if needed. - m := f.asPointerTo(t).Elem() // an addressable map[K]T - if m.IsNil() { - m.Set(reflect.MakeMap(t)) - } - - // Insert into map. - m.SetMapIndex(k.Elem(), v.Elem()) - - return r, nil - } -} - -// makeUnmarshalOneof makes an unmarshaler for oneof fields. -// for: -// message Msg { -// oneof F { -// int64 X = 1; -// float64 Y = 2; -// } -// } -// typ is the type of the concrete entry for a oneof case (e.g. Msg_X). -// ityp is the interface type of the oneof field (e.g. isMsg_F). -// unmarshal is the unmarshaler for the base type of the oneof case (e.g. int64). -// Note that this function will be called once for each case in the oneof. -func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshaler { - sf := typ.Field(0) - field0 := toField(&sf) - return func(b []byte, f pointer, w int) ([]byte, error) { - // Allocate holder for value. - v := reflect.New(typ) - - // Unmarshal data into holder. - // We unmarshal into the first field of the holder object. - var err error - b, err = unmarshal(b, valToPointer(v).offset(field0), w) - if err != nil { - return nil, err - } - - // Write pointer to holder into target field. - f.asPointerTo(ityp).Elem().Set(v) - - return b, nil - } -} - -// Error used by decode internally. -var errInternalBadWireType = errors.New("proto: internal error: bad wiretype") - -// skipField skips past a field of type wire and returns the remaining bytes. -func skipField(b []byte, wire int) ([]byte, error) { - switch wire { - case WireVarint: - _, k := decodeVarint(b) - if k == 0 { - return b, io.ErrUnexpectedEOF - } - b = b[k:] - case WireFixed32: - if len(b) < 4 { - return b, io.ErrUnexpectedEOF - } - b = b[4:] - case WireFixed64: - if len(b) < 8 { - return b, io.ErrUnexpectedEOF - } - b = b[8:] - case WireBytes: - m, k := decodeVarint(b) - if k == 0 || uint64(len(b)-k) < m { - return b, io.ErrUnexpectedEOF - } - b = b[uint64(k)+m:] - case WireStartGroup: - _, i := findEndGroup(b) - if i == -1 { - return b, io.ErrUnexpectedEOF - } - b = b[i:] - default: - return b, fmt.Errorf("proto: can't skip unknown wire type %d", wire) - } - return b, nil -} - -// findEndGroup finds the index of the next EndGroup tag. -// Groups may be nested, so the "next" EndGroup tag is the first -// unpaired EndGroup. -// findEndGroup returns the indexes of the start and end of the EndGroup tag. -// Returns (-1,-1) if it can't find one. -func findEndGroup(b []byte) (int, int) { - depth := 1 - i := 0 - for { - x, n := decodeVarint(b[i:]) - if n == 0 { - return -1, -1 - } - j := i - i += n - switch x & 7 { - case WireVarint: - _, k := decodeVarint(b[i:]) - if k == 0 { - return -1, -1 - } - i += k - case WireFixed32: - if len(b)-4 < i { - return -1, -1 - } - i += 4 - case WireFixed64: - if len(b)-8 < i { - return -1, -1 - } - i += 8 - case WireBytes: - m, k := decodeVarint(b[i:]) - if k == 0 { - return -1, -1 - } - i += k - if uint64(len(b)-i) < m { - return -1, -1 - } - i += int(m) - case WireStartGroup: - depth++ - case WireEndGroup: - depth-- - if depth == 0 { - return j, i - } - default: - return -1, -1 - } - } -} - -// encodeVarint appends a varint-encoded integer to b and returns the result. -func encodeVarint(b []byte, x uint64) []byte { - for x >= 1<<7 { - b = append(b, byte(x&0x7f|0x80)) - x >>= 7 - } - return append(b, byte(x)) -} - -// decodeVarint reads a varint-encoded integer from b. -// Returns the decoded integer and the number of bytes read. -// If there is an error, it returns 0,0. -func decodeVarint(b []byte) (uint64, int) { - var x, y uint64 - if len(b) <= 0 { - goto bad - } - x = uint64(b[0]) - if x < 0x80 { - return x, 1 - } - x -= 0x80 - - if len(b) <= 1 { - goto bad - } - y = uint64(b[1]) - x += y << 7 - if y < 0x80 { - return x, 2 - } - x -= 0x80 << 7 - - if len(b) <= 2 { - goto bad - } - y = uint64(b[2]) - x += y << 14 - if y < 0x80 { - return x, 3 - } - x -= 0x80 << 14 - - if len(b) <= 3 { - goto bad - } - y = uint64(b[3]) - x += y << 21 - if y < 0x80 { - return x, 4 - } - x -= 0x80 << 21 - - if len(b) <= 4 { - goto bad - } - y = uint64(b[4]) - x += y << 28 - if y < 0x80 { - return x, 5 - } - x -= 0x80 << 28 - - if len(b) <= 5 { - goto bad - } - y = uint64(b[5]) - x += y << 35 - if y < 0x80 { - return x, 6 - } - x -= 0x80 << 35 - - if len(b) <= 6 { - goto bad - } - y = uint64(b[6]) - x += y << 42 - if y < 0x80 { - return x, 7 - } - x -= 0x80 << 42 - - if len(b) <= 7 { - goto bad - } - y = uint64(b[7]) - x += y << 49 - if y < 0x80 { - return x, 8 - } - x -= 0x80 << 49 - - if len(b) <= 8 { - goto bad - } - y = uint64(b[8]) - x += y << 56 - if y < 0x80 { - return x, 9 - } - x -= 0x80 << 56 - - if len(b) <= 9 { - goto bad - } - y = uint64(b[9]) - x += y << 63 - if y < 2 { - return x, 10 - } - -bad: - return 0, 0 -} diff --git a/vendor/github.com/golang/protobuf/proto/text.go b/vendor/github.com/golang/protobuf/proto/text.go deleted file mode 100644 index 2205fdaad..000000000 --- a/vendor/github.com/golang/protobuf/proto/text.go +++ /dev/null @@ -1,843 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// Functions for writing the text protocol buffer format. - -import ( - "bufio" - "bytes" - "encoding" - "errors" - "fmt" - "io" - "log" - "math" - "reflect" - "sort" - "strings" -) - -var ( - newline = []byte("\n") - spaces = []byte(" ") - endBraceNewline = []byte("}\n") - backslashN = []byte{'\\', 'n'} - backslashR = []byte{'\\', 'r'} - backslashT = []byte{'\\', 't'} - backslashDQ = []byte{'\\', '"'} - backslashBS = []byte{'\\', '\\'} - posInf = []byte("inf") - negInf = []byte("-inf") - nan = []byte("nan") -) - -type writer interface { - io.Writer - WriteByte(byte) error -} - -// textWriter is an io.Writer that tracks its indentation level. -type textWriter struct { - ind int - complete bool // if the current position is a complete line - compact bool // whether to write out as a one-liner - w writer -} - -func (w *textWriter) WriteString(s string) (n int, err error) { - if !strings.Contains(s, "\n") { - if !w.compact && w.complete { - w.writeIndent() - } - w.complete = false - return io.WriteString(w.w, s) - } - // WriteString is typically called without newlines, so this - // codepath and its copy are rare. We copy to avoid - // duplicating all of Write's logic here. - return w.Write([]byte(s)) -} - -func (w *textWriter) Write(p []byte) (n int, err error) { - newlines := bytes.Count(p, newline) - if newlines == 0 { - if !w.compact && w.complete { - w.writeIndent() - } - n, err = w.w.Write(p) - w.complete = false - return n, err - } - - frags := bytes.SplitN(p, newline, newlines+1) - if w.compact { - for i, frag := range frags { - if i > 0 { - if err := w.w.WriteByte(' '); err != nil { - return n, err - } - n++ - } - nn, err := w.w.Write(frag) - n += nn - if err != nil { - return n, err - } - } - return n, nil - } - - for i, frag := range frags { - if w.complete { - w.writeIndent() - } - nn, err := w.w.Write(frag) - n += nn - if err != nil { - return n, err - } - if i+1 < len(frags) { - if err := w.w.WriteByte('\n'); err != nil { - return n, err - } - n++ - } - } - w.complete = len(frags[len(frags)-1]) == 0 - return n, nil -} - -func (w *textWriter) WriteByte(c byte) error { - if w.compact && c == '\n' { - c = ' ' - } - if !w.compact && w.complete { - w.writeIndent() - } - err := w.w.WriteByte(c) - w.complete = c == '\n' - return err -} - -func (w *textWriter) indent() { w.ind++ } - -func (w *textWriter) unindent() { - if w.ind == 0 { - log.Print("proto: textWriter unindented too far") - return - } - w.ind-- -} - -func writeName(w *textWriter, props *Properties) error { - if _, err := w.WriteString(props.OrigName); err != nil { - return err - } - if props.Wire != "group" { - return w.WriteByte(':') - } - return nil -} - -func requiresQuotes(u string) bool { - // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted. - for _, ch := range u { - switch { - case ch == '.' || ch == '/' || ch == '_': - continue - case '0' <= ch && ch <= '9': - continue - case 'A' <= ch && ch <= 'Z': - continue - case 'a' <= ch && ch <= 'z': - continue - default: - return true - } - } - return false -} - -// isAny reports whether sv is a google.protobuf.Any message -func isAny(sv reflect.Value) bool { - type wkt interface { - XXX_WellKnownType() string - } - t, ok := sv.Addr().Interface().(wkt) - return ok && t.XXX_WellKnownType() == "Any" -} - -// writeProto3Any writes an expanded google.protobuf.Any message. -// -// It returns (false, nil) if sv value can't be unmarshaled (e.g. because -// required messages are not linked in). -// -// It returns (true, error) when sv was written in expanded format or an error -// was encountered. -func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) { - turl := sv.FieldByName("TypeUrl") - val := sv.FieldByName("Value") - if !turl.IsValid() || !val.IsValid() { - return true, errors.New("proto: invalid google.protobuf.Any message") - } - - b, ok := val.Interface().([]byte) - if !ok { - return true, errors.New("proto: invalid google.protobuf.Any message") - } - - parts := strings.Split(turl.String(), "/") - mt := MessageType(parts[len(parts)-1]) - if mt == nil { - return false, nil - } - m := reflect.New(mt.Elem()) - if err := Unmarshal(b, m.Interface().(Message)); err != nil { - return false, nil - } - w.Write([]byte("[")) - u := turl.String() - if requiresQuotes(u) { - writeString(w, u) - } else { - w.Write([]byte(u)) - } - if w.compact { - w.Write([]byte("]:<")) - } else { - w.Write([]byte("]: <\n")) - w.ind++ - } - if err := tm.writeStruct(w, m.Elem()); err != nil { - return true, err - } - if w.compact { - w.Write([]byte("> ")) - } else { - w.ind-- - w.Write([]byte(">\n")) - } - return true, nil -} - -func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error { - if tm.ExpandAny && isAny(sv) { - if canExpand, err := tm.writeProto3Any(w, sv); canExpand { - return err - } - } - st := sv.Type() - sprops := GetProperties(st) - for i := 0; i < sv.NumField(); i++ { - fv := sv.Field(i) - props := sprops.Prop[i] - name := st.Field(i).Name - - if name == "XXX_NoUnkeyedLiteral" { - continue - } - - if strings.HasPrefix(name, "XXX_") { - // There are two XXX_ fields: - // XXX_unrecognized []byte - // XXX_extensions map[int32]proto.Extension - // The first is handled here; - // the second is handled at the bottom of this function. - if name == "XXX_unrecognized" && !fv.IsNil() { - if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil { - return err - } - } - continue - } - if fv.Kind() == reflect.Ptr && fv.IsNil() { - // Field not filled in. This could be an optional field or - // a required field that wasn't filled in. Either way, there - // isn't anything we can show for it. - continue - } - if fv.Kind() == reflect.Slice && fv.IsNil() { - // Repeated field that is empty, or a bytes field that is unused. - continue - } - - if props.Repeated && fv.Kind() == reflect.Slice { - // Repeated field. - for j := 0; j < fv.Len(); j++ { - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - v := fv.Index(j) - if v.Kind() == reflect.Ptr && v.IsNil() { - // A nil message in a repeated field is not valid, - // but we can handle that more gracefully than panicking. - if _, err := w.Write([]byte("\n")); err != nil { - return err - } - continue - } - if err := tm.writeAny(w, v, props); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - continue - } - if fv.Kind() == reflect.Map { - // Map fields are rendered as a repeated struct with key/value fields. - keys := fv.MapKeys() - sort.Sort(mapKeys(keys)) - for _, key := range keys { - val := fv.MapIndex(key) - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - // open struct - if err := w.WriteByte('<'); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte('\n'); err != nil { - return err - } - } - w.indent() - // key - if _, err := w.WriteString("key:"); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, key, props.mkeyprop); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - // nil values aren't legal, but we can avoid panicking because of them. - if val.Kind() != reflect.Ptr || !val.IsNil() { - // value - if _, err := w.WriteString("value:"); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, val, props.mvalprop); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - // close struct - w.unindent() - if err := w.WriteByte('>'); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - continue - } - if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 { - // empty bytes field - continue - } - if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice { - // proto3 non-repeated scalar field; skip if zero value - if isProto3Zero(fv) { - continue - } - } - - if fv.Kind() == reflect.Interface { - // Check if it is a oneof. - if st.Field(i).Tag.Get("protobuf_oneof") != "" { - // fv is nil, or holds a pointer to generated struct. - // That generated struct has exactly one field, - // which has a protobuf struct tag. - if fv.IsNil() { - continue - } - inner := fv.Elem().Elem() // interface -> *T -> T - tag := inner.Type().Field(0).Tag.Get("protobuf") - props = new(Properties) // Overwrite the outer props var, but not its pointee. - props.Parse(tag) - // Write the value in the oneof, not the oneof itself. - fv = inner.Field(0) - - // Special case to cope with malformed messages gracefully: - // If the value in the oneof is a nil pointer, don't panic - // in writeAny. - if fv.Kind() == reflect.Ptr && fv.IsNil() { - // Use errors.New so writeAny won't render quotes. - msg := errors.New("/* nil */") - fv = reflect.ValueOf(&msg).Elem() - } - } - } - - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - - // Enums have a String method, so writeAny will work fine. - if err := tm.writeAny(w, fv, props); err != nil { - return err - } - - if err := w.WriteByte('\n'); err != nil { - return err - } - } - - // Extensions (the XXX_extensions field). - pv := sv.Addr() - if _, err := extendable(pv.Interface()); err == nil { - if err := tm.writeExtensions(w, pv); err != nil { - return err - } - } - - return nil -} - -// writeAny writes an arbitrary field. -func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error { - v = reflect.Indirect(v) - - // Floats have special cases. - if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { - x := v.Float() - var b []byte - switch { - case math.IsInf(x, 1): - b = posInf - case math.IsInf(x, -1): - b = negInf - case math.IsNaN(x): - b = nan - } - if b != nil { - _, err := w.Write(b) - return err - } - // Other values are handled below. - } - - // We don't attempt to serialise every possible value type; only those - // that can occur in protocol buffers. - switch v.Kind() { - case reflect.Slice: - // Should only be a []byte; repeated fields are handled in writeStruct. - if err := writeString(w, string(v.Bytes())); err != nil { - return err - } - case reflect.String: - if err := writeString(w, v.String()); err != nil { - return err - } - case reflect.Struct: - // Required/optional group/message. - var bra, ket byte = '<', '>' - if props != nil && props.Wire == "group" { - bra, ket = '{', '}' - } - if err := w.WriteByte(bra); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte('\n'); err != nil { - return err - } - } - w.indent() - if v.CanAddr() { - // Calling v.Interface on a struct causes the reflect package to - // copy the entire struct. This is racy with the new Marshaler - // since we atomically update the XXX_sizecache. - // - // Thus, we retrieve a pointer to the struct if possible to avoid - // a race since v.Interface on the pointer doesn't copy the struct. - // - // If v is not addressable, then we are not worried about a race - // since it implies that the binary Marshaler cannot possibly be - // mutating this value. - v = v.Addr() - } - if etm, ok := v.Interface().(encoding.TextMarshaler); ok { - text, err := etm.MarshalText() - if err != nil { - return err - } - if _, err = w.Write(text); err != nil { - return err - } - } else { - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - if err := tm.writeStruct(w, v); err != nil { - return err - } - } - w.unindent() - if err := w.WriteByte(ket); err != nil { - return err - } - default: - _, err := fmt.Fprint(w, v.Interface()) - return err - } - return nil -} - -// equivalent to C's isprint. -func isprint(c byte) bool { - return c >= 0x20 && c < 0x7f -} - -// writeString writes a string in the protocol buffer text format. -// It is similar to strconv.Quote except we don't use Go escape sequences, -// we treat the string as a byte sequence, and we use octal escapes. -// These differences are to maintain interoperability with the other -// languages' implementations of the text format. -func writeString(w *textWriter, s string) error { - // use WriteByte here to get any needed indent - if err := w.WriteByte('"'); err != nil { - return err - } - // Loop over the bytes, not the runes. - for i := 0; i < len(s); i++ { - var err error - // Divergence from C++: we don't escape apostrophes. - // There's no need to escape them, and the C++ parser - // copes with a naked apostrophe. - switch c := s[i]; c { - case '\n': - _, err = w.w.Write(backslashN) - case '\r': - _, err = w.w.Write(backslashR) - case '\t': - _, err = w.w.Write(backslashT) - case '"': - _, err = w.w.Write(backslashDQ) - case '\\': - _, err = w.w.Write(backslashBS) - default: - if isprint(c) { - err = w.w.WriteByte(c) - } else { - _, err = fmt.Fprintf(w.w, "\\%03o", c) - } - } - if err != nil { - return err - } - } - return w.WriteByte('"') -} - -func writeUnknownStruct(w *textWriter, data []byte) (err error) { - if !w.compact { - if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil { - return err - } - } - b := NewBuffer(data) - for b.index < len(b.buf) { - x, err := b.DecodeVarint() - if err != nil { - _, err := fmt.Fprintf(w, "/* %v */\n", err) - return err - } - wire, tag := x&7, x>>3 - if wire == WireEndGroup { - w.unindent() - if _, err := w.Write(endBraceNewline); err != nil { - return err - } - continue - } - if _, err := fmt.Fprint(w, tag); err != nil { - return err - } - if wire != WireStartGroup { - if err := w.WriteByte(':'); err != nil { - return err - } - } - if !w.compact || wire == WireStartGroup { - if err := w.WriteByte(' '); err != nil { - return err - } - } - switch wire { - case WireBytes: - buf, e := b.DecodeRawBytes(false) - if e == nil { - _, err = fmt.Fprintf(w, "%q", buf) - } else { - _, err = fmt.Fprintf(w, "/* %v */", e) - } - case WireFixed32: - x, err = b.DecodeFixed32() - err = writeUnknownInt(w, x, err) - case WireFixed64: - x, err = b.DecodeFixed64() - err = writeUnknownInt(w, x, err) - case WireStartGroup: - err = w.WriteByte('{') - w.indent() - case WireVarint: - x, err = b.DecodeVarint() - err = writeUnknownInt(w, x, err) - default: - _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire) - } - if err != nil { - return err - } - if err = w.WriteByte('\n'); err != nil { - return err - } - } - return nil -} - -func writeUnknownInt(w *textWriter, x uint64, err error) error { - if err == nil { - _, err = fmt.Fprint(w, x) - } else { - _, err = fmt.Fprintf(w, "/* %v */", err) - } - return err -} - -type int32Slice []int32 - -func (s int32Slice) Len() int { return len(s) } -func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } -func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// writeExtensions writes all the extensions in pv. -// pv is assumed to be a pointer to a protocol message struct that is extendable. -func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error { - emap := extensionMaps[pv.Type().Elem()] - ep, _ := extendable(pv.Interface()) - - // Order the extensions by ID. - // This isn't strictly necessary, but it will give us - // canonical output, which will also make testing easier. - m, mu := ep.extensionsRead() - if m == nil { - return nil - } - mu.Lock() - ids := make([]int32, 0, len(m)) - for id := range m { - ids = append(ids, id) - } - sort.Sort(int32Slice(ids)) - mu.Unlock() - - for _, extNum := range ids { - ext := m[extNum] - var desc *ExtensionDesc - if emap != nil { - desc = emap[extNum] - } - if desc == nil { - // Unknown extension. - if err := writeUnknownStruct(w, ext.enc); err != nil { - return err - } - continue - } - - pb, err := GetExtension(ep, desc) - if err != nil { - return fmt.Errorf("failed getting extension: %v", err) - } - - // Repeated extensions will appear as a slice. - if !desc.repeated() { - if err := tm.writeExtension(w, desc.Name, pb); err != nil { - return err - } - } else { - v := reflect.ValueOf(pb) - for i := 0; i < v.Len(); i++ { - if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { - return err - } - } - } - } - return nil -} - -func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error { - if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - return nil -} - -func (w *textWriter) writeIndent() { - if !w.complete { - return - } - remain := w.ind * 2 - for remain > 0 { - n := remain - if n > len(spaces) { - n = len(spaces) - } - w.w.Write(spaces[:n]) - remain -= n - } - w.complete = false -} - -// TextMarshaler is a configurable text format marshaler. -type TextMarshaler struct { - Compact bool // use compact text format (one line). - ExpandAny bool // expand google.protobuf.Any messages of known types -} - -// Marshal writes a given protocol buffer in text format. -// The only errors returned are from w. -func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error { - val := reflect.ValueOf(pb) - if pb == nil || val.IsNil() { - w.Write([]byte("")) - return nil - } - var bw *bufio.Writer - ww, ok := w.(writer) - if !ok { - bw = bufio.NewWriter(w) - ww = bw - } - aw := &textWriter{ - w: ww, - complete: true, - compact: tm.Compact, - } - - if etm, ok := pb.(encoding.TextMarshaler); ok { - text, err := etm.MarshalText() - if err != nil { - return err - } - if _, err = aw.Write(text); err != nil { - return err - } - if bw != nil { - return bw.Flush() - } - return nil - } - // Dereference the received pointer so we don't have outer < and >. - v := reflect.Indirect(val) - if err := tm.writeStruct(aw, v); err != nil { - return err - } - if bw != nil { - return bw.Flush() - } - return nil -} - -// Text is the same as Marshal, but returns the string directly. -func (tm *TextMarshaler) Text(pb Message) string { - var buf bytes.Buffer - tm.Marshal(&buf, pb) - return buf.String() -} - -var ( - defaultTextMarshaler = TextMarshaler{} - compactTextMarshaler = TextMarshaler{Compact: true} -) - -// TODO: consider removing some of the Marshal functions below. - -// MarshalText writes a given protocol buffer in text format. -// The only errors returned are from w. -func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) } - -// MarshalTextString is the same as MarshalText, but returns the string directly. -func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) } - -// CompactText writes a given protocol buffer in compact text format (one line). -func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) } - -// CompactTextString is the same as CompactText, but returns the string directly. -func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) } diff --git a/vendor/github.com/golang/protobuf/proto/text_parser.go b/vendor/github.com/golang/protobuf/proto/text_parser.go deleted file mode 100644 index 0685bae36..000000000 --- a/vendor/github.com/golang/protobuf/proto/text_parser.go +++ /dev/null @@ -1,880 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// Functions for parsing the Text protocol buffer format. -// TODO: message sets. - -import ( - "encoding" - "errors" - "fmt" - "reflect" - "strconv" - "strings" - "unicode/utf8" -) - -// Error string emitted when deserializing Any and fields are already set -const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set" - -type ParseError struct { - Message string - Line int // 1-based line number - Offset int // 0-based byte offset from start of input -} - -func (p *ParseError) Error() string { - if p.Line == 1 { - // show offset only for first line - return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message) - } - return fmt.Sprintf("line %d: %v", p.Line, p.Message) -} - -type token struct { - value string - err *ParseError - line int // line number - offset int // byte number from start of input, not start of line - unquoted string // the unquoted version of value, if it was a quoted string -} - -func (t *token) String() string { - if t.err == nil { - return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset) - } - return fmt.Sprintf("parse error: %v", t.err) -} - -type textParser struct { - s string // remaining input - done bool // whether the parsing is finished (success or error) - backed bool // whether back() was called - offset, line int - cur token -} - -func newTextParser(s string) *textParser { - p := new(textParser) - p.s = s - p.line = 1 - p.cur.line = 1 - return p -} - -func (p *textParser) errorf(format string, a ...interface{}) *ParseError { - pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset} - p.cur.err = pe - p.done = true - return pe -} - -// Numbers and identifiers are matched by [-+._A-Za-z0-9] -func isIdentOrNumberChar(c byte) bool { - switch { - case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z': - return true - case '0' <= c && c <= '9': - return true - } - switch c { - case '-', '+', '.', '_': - return true - } - return false -} - -func isWhitespace(c byte) bool { - switch c { - case ' ', '\t', '\n', '\r': - return true - } - return false -} - -func isQuote(c byte) bool { - switch c { - case '"', '\'': - return true - } - return false -} - -func (p *textParser) skipWhitespace() { - i := 0 - for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { - if p.s[i] == '#' { - // comment; skip to end of line or input - for i < len(p.s) && p.s[i] != '\n' { - i++ - } - if i == len(p.s) { - break - } - } - if p.s[i] == '\n' { - p.line++ - } - i++ - } - p.offset += i - p.s = p.s[i:len(p.s)] - if len(p.s) == 0 { - p.done = true - } -} - -func (p *textParser) advance() { - // Skip whitespace - p.skipWhitespace() - if p.done { - return - } - - // Start of non-whitespace - p.cur.err = nil - p.cur.offset, p.cur.line = p.offset, p.line - p.cur.unquoted = "" - switch p.s[0] { - case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/': - // Single symbol - p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] - case '"', '\'': - // Quoted string - i := 1 - for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { - if p.s[i] == '\\' && i+1 < len(p.s) { - // skip escaped char - i++ - } - i++ - } - if i >= len(p.s) || p.s[i] != p.s[0] { - p.errorf("unmatched quote") - return - } - unq, err := unquoteC(p.s[1:i], rune(p.s[0])) - if err != nil { - p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) - return - } - p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] - p.cur.unquoted = unq - default: - i := 0 - for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { - i++ - } - if i == 0 { - p.errorf("unexpected byte %#x", p.s[0]) - return - } - p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] - } - p.offset += len(p.cur.value) -} - -var ( - errBadUTF8 = errors.New("proto: bad UTF-8") -) - -func unquoteC(s string, quote rune) (string, error) { - // This is based on C++'s tokenizer.cc. - // Despite its name, this is *not* parsing C syntax. - // For instance, "\0" is an invalid quoted string. - - // Avoid allocation in trivial cases. - simple := true - for _, r := range s { - if r == '\\' || r == quote { - simple = false - break - } - } - if simple { - return s, nil - } - - buf := make([]byte, 0, 3*len(s)/2) - for len(s) > 0 { - r, n := utf8.DecodeRuneInString(s) - if r == utf8.RuneError && n == 1 { - return "", errBadUTF8 - } - s = s[n:] - if r != '\\' { - if r < utf8.RuneSelf { - buf = append(buf, byte(r)) - } else { - buf = append(buf, string(r)...) - } - continue - } - - ch, tail, err := unescape(s) - if err != nil { - return "", err - } - buf = append(buf, ch...) - s = tail - } - return string(buf), nil -} - -func unescape(s string) (ch string, tail string, err error) { - r, n := utf8.DecodeRuneInString(s) - if r == utf8.RuneError && n == 1 { - return "", "", errBadUTF8 - } - s = s[n:] - switch r { - case 'a': - return "\a", s, nil - case 'b': - return "\b", s, nil - case 'f': - return "\f", s, nil - case 'n': - return "\n", s, nil - case 'r': - return "\r", s, nil - case 't': - return "\t", s, nil - case 'v': - return "\v", s, nil - case '?': - return "?", s, nil // trigraph workaround - case '\'', '"', '\\': - return string(r), s, nil - case '0', '1', '2', '3', '4', '5', '6', '7': - if len(s) < 2 { - return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) - } - ss := string(r) + s[:2] - s = s[2:] - i, err := strconv.ParseUint(ss, 8, 8) - if err != nil { - return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss) - } - return string([]byte{byte(i)}), s, nil - case 'x', 'X', 'u', 'U': - var n int - switch r { - case 'x', 'X': - n = 2 - case 'u': - n = 4 - case 'U': - n = 8 - } - if len(s) < n { - return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n) - } - ss := s[:n] - s = s[n:] - i, err := strconv.ParseUint(ss, 16, 64) - if err != nil { - return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss) - } - if r == 'x' || r == 'X' { - return string([]byte{byte(i)}), s, nil - } - if i > utf8.MaxRune { - return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss) - } - return string(i), s, nil - } - return "", "", fmt.Errorf(`unknown escape \%c`, r) -} - -// Back off the parser by one token. Can only be done between calls to next(). -// It makes the next advance() a no-op. -func (p *textParser) back() { p.backed = true } - -// Advances the parser and returns the new current token. -func (p *textParser) next() *token { - if p.backed || p.done { - p.backed = false - return &p.cur - } - p.advance() - if p.done { - p.cur.value = "" - } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { - // Look for multiple quoted strings separated by whitespace, - // and concatenate them. - cat := p.cur - for { - p.skipWhitespace() - if p.done || !isQuote(p.s[0]) { - break - } - p.advance() - if p.cur.err != nil { - return &p.cur - } - cat.value += " " + p.cur.value - cat.unquoted += p.cur.unquoted - } - p.done = false // parser may have seen EOF, but we want to return cat - p.cur = cat - } - return &p.cur -} - -func (p *textParser) consumeToken(s string) error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != s { - p.back() - return p.errorf("expected %q, found %q", s, tok.value) - } - return nil -} - -// Return a RequiredNotSetError indicating which required field was not set. -func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError { - st := sv.Type() - sprops := GetProperties(st) - for i := 0; i < st.NumField(); i++ { - if !isNil(sv.Field(i)) { - continue - } - - props := sprops.Prop[i] - if props.Required { - return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)} - } - } - return &RequiredNotSetError{fmt.Sprintf("%v.", st)} // should not happen -} - -// Returns the index in the struct for the named field, as well as the parsed tag properties. -func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) { - i, ok := sprops.decoderOrigNames[name] - if ok { - return i, sprops.Prop[i], true - } - return -1, nil, false -} - -// Consume a ':' from the input stream (if the next token is a colon), -// returning an error if a colon is needed but not present. -func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != ":" { - // Colon is optional when the field is a group or message. - needColon := true - switch props.Wire { - case "group": - needColon = false - case "bytes": - // A "bytes" field is either a message, a string, or a repeated field; - // those three become *T, *string and []T respectively, so we can check for - // this field being a pointer to a non-string. - if typ.Kind() == reflect.Ptr { - // *T or *string - if typ.Elem().Kind() == reflect.String { - break - } - } else if typ.Kind() == reflect.Slice { - // []T or []*T - if typ.Elem().Kind() != reflect.Ptr { - break - } - } else if typ.Kind() == reflect.String { - // The proto3 exception is for a string field, - // which requires a colon. - break - } - needColon = false - } - if needColon { - return p.errorf("expected ':', found %q", tok.value) - } - p.back() - } - return nil -} - -func (p *textParser) readStruct(sv reflect.Value, terminator string) error { - st := sv.Type() - sprops := GetProperties(st) - reqCount := sprops.reqCount - var reqFieldErr error - fieldSet := make(map[string]bool) - // A struct is a sequence of "name: value", terminated by one of - // '>' or '}', or the end of the input. A name may also be - // "[extension]" or "[type/url]". - // - // The whole struct can also be an expanded Any message, like: - // [type/url] < ... struct contents ... > - for { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == terminator { - break - } - if tok.value == "[" { - // Looks like an extension or an Any. - // - // TODO: Check whether we need to handle - // namespace rooted names (e.g. ".something.Foo"). - extName, err := p.consumeExtName() - if err != nil { - return err - } - - if s := strings.LastIndex(extName, "/"); s >= 0 { - // If it contains a slash, it's an Any type URL. - messageName := extName[s+1:] - mt := MessageType(messageName) - if mt == nil { - return p.errorf("unrecognized message %q in google.protobuf.Any", messageName) - } - tok = p.next() - if tok.err != nil { - return tok.err - } - // consume an optional colon - if tok.value == ":" { - tok = p.next() - if tok.err != nil { - return tok.err - } - } - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - v := reflect.New(mt.Elem()) - if pe := p.readStruct(v.Elem(), terminator); pe != nil { - return pe - } - b, err := Marshal(v.Interface().(Message)) - if err != nil { - return p.errorf("failed to marshal message of type %q: %v", messageName, err) - } - if fieldSet["type_url"] { - return p.errorf(anyRepeatedlyUnpacked, "type_url") - } - if fieldSet["value"] { - return p.errorf(anyRepeatedlyUnpacked, "value") - } - sv.FieldByName("TypeUrl").SetString(extName) - sv.FieldByName("Value").SetBytes(b) - fieldSet["type_url"] = true - fieldSet["value"] = true - continue - } - - var desc *ExtensionDesc - // This could be faster, but it's functional. - // TODO: Do something smarter than a linear scan. - for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) { - if d.Name == extName { - desc = d - break - } - } - if desc == nil { - return p.errorf("unrecognized extension %q", extName) - } - - props := &Properties{} - props.Parse(desc.Tag) - - typ := reflect.TypeOf(desc.ExtensionType) - if err := p.checkForColon(props, typ); err != nil { - return err - } - - rep := desc.repeated() - - // Read the extension structure, and set it in - // the value we're constructing. - var ext reflect.Value - if !rep { - ext = reflect.New(typ).Elem() - } else { - ext = reflect.New(typ.Elem()).Elem() - } - if err := p.readAny(ext, props); err != nil { - if _, ok := err.(*RequiredNotSetError); !ok { - return err - } - reqFieldErr = err - } - ep := sv.Addr().Interface().(Message) - if !rep { - SetExtension(ep, desc, ext.Interface()) - } else { - old, err := GetExtension(ep, desc) - var sl reflect.Value - if err == nil { - sl = reflect.ValueOf(old) // existing slice - } else { - sl = reflect.MakeSlice(typ, 0, 1) - } - sl = reflect.Append(sl, ext) - SetExtension(ep, desc, sl.Interface()) - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - continue - } - - // This is a normal, non-extension field. - name := tok.value - var dst reflect.Value - fi, props, ok := structFieldByName(sprops, name) - if ok { - dst = sv.Field(fi) - } else if oop, ok := sprops.OneofTypes[name]; ok { - // It is a oneof. - props = oop.Prop - nv := reflect.New(oop.Type.Elem()) - dst = nv.Elem().Field(0) - field := sv.Field(oop.Field) - if !field.IsNil() { - return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name) - } - field.Set(nv) - } - if !dst.IsValid() { - return p.errorf("unknown field name %q in %v", name, st) - } - - if dst.Kind() == reflect.Map { - // Consume any colon. - if err := p.checkForColon(props, dst.Type()); err != nil { - return err - } - - // Construct the map if it doesn't already exist. - if dst.IsNil() { - dst.Set(reflect.MakeMap(dst.Type())) - } - key := reflect.New(dst.Type().Key()).Elem() - val := reflect.New(dst.Type().Elem()).Elem() - - // The map entry should be this sequence of tokens: - // < key : KEY value : VALUE > - // However, implementations may omit key or value, and technically - // we should support them in any order. See b/28924776 for a time - // this went wrong. - - tok := p.next() - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - for { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == terminator { - break - } - switch tok.value { - case "key": - if err := p.consumeToken(":"); err != nil { - return err - } - if err := p.readAny(key, props.mkeyprop); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - case "value": - if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { - return err - } - if err := p.readAny(val, props.mvalprop); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - default: - p.back() - return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value) - } - } - - dst.SetMapIndex(key, val) - continue - } - - // Check that it's not already set if it's not a repeated field. - if !props.Repeated && fieldSet[name] { - return p.errorf("non-repeated field %q was repeated", name) - } - - if err := p.checkForColon(props, dst.Type()); err != nil { - return err - } - - // Parse into the field. - fieldSet[name] = true - if err := p.readAny(dst, props); err != nil { - if _, ok := err.(*RequiredNotSetError); !ok { - return err - } - reqFieldErr = err - } - if props.Required { - reqCount-- - } - - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - - } - - if reqCount > 0 { - return p.missingRequiredFieldError(sv) - } - return reqFieldErr -} - -// consumeExtName consumes extension name or expanded Any type URL and the -// following ']'. It returns the name or URL consumed. -func (p *textParser) consumeExtName() (string, error) { - tok := p.next() - if tok.err != nil { - return "", tok.err - } - - // If extension name or type url is quoted, it's a single token. - if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] { - name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0])) - if err != nil { - return "", err - } - return name, p.consumeToken("]") - } - - // Consume everything up to "]" - var parts []string - for tok.value != "]" { - parts = append(parts, tok.value) - tok = p.next() - if tok.err != nil { - return "", p.errorf("unrecognized type_url or extension name: %s", tok.err) - } - if p.done && tok.value != "]" { - return "", p.errorf("unclosed type_url or extension name") - } - } - return strings.Join(parts, ""), nil -} - -// consumeOptionalSeparator consumes an optional semicolon or comma. -// It is used in readStruct to provide backward compatibility. -func (p *textParser) consumeOptionalSeparator() error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != ";" && tok.value != "," { - p.back() - } - return nil -} - -func (p *textParser) readAny(v reflect.Value, props *Properties) error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == "" { - return p.errorf("unexpected EOF") - } - - switch fv := v; fv.Kind() { - case reflect.Slice: - at := v.Type() - if at.Elem().Kind() == reflect.Uint8 { - // Special case for []byte - if tok.value[0] != '"' && tok.value[0] != '\'' { - // Deliberately written out here, as the error after - // this switch statement would write "invalid []byte: ...", - // which is not as user-friendly. - return p.errorf("invalid string: %v", tok.value) - } - bytes := []byte(tok.unquoted) - fv.Set(reflect.ValueOf(bytes)) - return nil - } - // Repeated field. - if tok.value == "[" { - // Repeated field with list notation, like [1,2,3]. - for { - fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) - err := p.readAny(fv.Index(fv.Len()-1), props) - if err != nil { - return err - } - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == "]" { - break - } - if tok.value != "," { - return p.errorf("Expected ']' or ',' found %q", tok.value) - } - } - return nil - } - // One value of the repeated field. - p.back() - fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) - return p.readAny(fv.Index(fv.Len()-1), props) - case reflect.Bool: - // true/1/t/True or false/f/0/False. - switch tok.value { - case "true", "1", "t", "True": - fv.SetBool(true) - return nil - case "false", "0", "f", "False": - fv.SetBool(false) - return nil - } - case reflect.Float32, reflect.Float64: - v := tok.value - // Ignore 'f' for compatibility with output generated by C++, but don't - // remove 'f' when the value is "-inf" or "inf". - if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" { - v = v[:len(v)-1] - } - if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil { - fv.SetFloat(f) - return nil - } - case reflect.Int32: - if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { - fv.SetInt(x) - return nil - } - - if len(props.Enum) == 0 { - break - } - m, ok := enumValueMaps[props.Enum] - if !ok { - break - } - x, ok := m[tok.value] - if !ok { - break - } - fv.SetInt(int64(x)) - return nil - case reflect.Int64: - if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { - fv.SetInt(x) - return nil - } - - case reflect.Ptr: - // A basic field (indirected through pointer), or a repeated message/group - p.back() - fv.Set(reflect.New(fv.Type().Elem())) - return p.readAny(fv.Elem(), props) - case reflect.String: - if tok.value[0] == '"' || tok.value[0] == '\'' { - fv.SetString(tok.unquoted) - return nil - } - case reflect.Struct: - var terminator string - switch tok.value { - case "{": - terminator = "}" - case "<": - terminator = ">" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - // TODO: Handle nested messages which implement encoding.TextUnmarshaler. - return p.readStruct(fv, terminator) - case reflect.Uint32: - if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { - fv.SetUint(uint64(x)) - return nil - } - case reflect.Uint64: - if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { - fv.SetUint(x) - return nil - } - } - return p.errorf("invalid %v: %v", v.Type(), tok.value) -} - -// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb -// before starting to unmarshal, so any existing data in pb is always removed. -// If a required field is not set and no other error occurs, -// UnmarshalText returns *RequiredNotSetError. -func UnmarshalText(s string, pb Message) error { - if um, ok := pb.(encoding.TextUnmarshaler); ok { - return um.UnmarshalText([]byte(s)) - } - pb.Reset() - v := reflect.ValueOf(pb) - return newTextParser(s).readStruct(v.Elem(), "") -} diff --git a/vendor/github.com/golang/protobuf/ptypes/any.go b/vendor/github.com/golang/protobuf/ptypes/any.go deleted file mode 100644 index b2af97f4a..000000000 --- a/vendor/github.com/golang/protobuf/ptypes/any.go +++ /dev/null @@ -1,139 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package ptypes - -// This file implements functions to marshal proto.Message to/from -// google.protobuf.Any message. - -import ( - "fmt" - "reflect" - "strings" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes/any" -) - -const googleApis = "type.googleapis.com/" - -// AnyMessageName returns the name of the message contained in a google.protobuf.Any message. -// -// Note that regular type assertions should be done using the Is -// function. AnyMessageName is provided for less common use cases like filtering a -// sequence of Any messages based on a set of allowed message type names. -func AnyMessageName(any *any.Any) (string, error) { - if any == nil { - return "", fmt.Errorf("message is nil") - } - slash := strings.LastIndex(any.TypeUrl, "/") - if slash < 0 { - return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl) - } - return any.TypeUrl[slash+1:], nil -} - -// MarshalAny takes the protocol buffer and encodes it into google.protobuf.Any. -func MarshalAny(pb proto.Message) (*any.Any, error) { - value, err := proto.Marshal(pb) - if err != nil { - return nil, err - } - return &any.Any{TypeUrl: googleApis + proto.MessageName(pb), Value: value}, nil -} - -// DynamicAny is a value that can be passed to UnmarshalAny to automatically -// allocate a proto.Message for the type specified in a google.protobuf.Any -// message. The allocated message is stored in the embedded proto.Message. -// -// Example: -// -// var x ptypes.DynamicAny -// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... } -// fmt.Printf("unmarshaled message: %v", x.Message) -type DynamicAny struct { - proto.Message -} - -// Empty returns a new proto.Message of the type specified in a -// google.protobuf.Any message. It returns an error if corresponding message -// type isn't linked in. -func Empty(any *any.Any) (proto.Message, error) { - aname, err := AnyMessageName(any) - if err != nil { - return nil, err - } - - t := proto.MessageType(aname) - if t == nil { - return nil, fmt.Errorf("any: message type %q isn't linked in", aname) - } - return reflect.New(t.Elem()).Interface().(proto.Message), nil -} - -// UnmarshalAny parses the protocol buffer representation in a google.protobuf.Any -// message and places the decoded result in pb. It returns an error if type of -// contents of Any message does not match type of pb message. -// -// pb can be a proto.Message, or a *DynamicAny. -func UnmarshalAny(any *any.Any, pb proto.Message) error { - if d, ok := pb.(*DynamicAny); ok { - if d.Message == nil { - var err error - d.Message, err = Empty(any) - if err != nil { - return err - } - } - return UnmarshalAny(any, d.Message) - } - - aname, err := AnyMessageName(any) - if err != nil { - return err - } - - mname := proto.MessageName(pb) - if aname != mname { - return fmt.Errorf("mismatched message type: got %q want %q", aname, mname) - } - return proto.Unmarshal(any.Value, pb) -} - -// Is returns true if any value contains a given message type. -func Is(any *any.Any, pb proto.Message) bool { - aname, err := AnyMessageName(any) - if err != nil { - return false - } - - return aname == proto.MessageName(pb) -} diff --git a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go deleted file mode 100644 index f67edc7dc..000000000 --- a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go +++ /dev/null @@ -1,191 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: google/protobuf/any.proto - -package any // import "github.com/golang/protobuf/ptypes/any" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -// `Any` contains an arbitrary serialized protocol buffer message along with a -// URL that describes the type of the serialized message. -// -// Protobuf library provides support to pack/unpack Any values in the form -// of utility functions or additional generated methods of the Any type. -// -// Example 1: Pack and unpack a message in C++. -// -// Foo foo = ...; -// Any any; -// any.PackFrom(foo); -// ... -// if (any.UnpackTo(&foo)) { -// ... -// } -// -// Example 2: Pack and unpack a message in Java. -// -// Foo foo = ...; -// Any any = Any.pack(foo); -// ... -// if (any.is(Foo.class)) { -// foo = any.unpack(Foo.class); -// } -// -// Example 3: Pack and unpack a message in Python. -// -// foo = Foo(...) -// any = Any() -// any.Pack(foo) -// ... -// if any.Is(Foo.DESCRIPTOR): -// any.Unpack(foo) -// ... -// -// Example 4: Pack and unpack a message in Go -// -// foo := &pb.Foo{...} -// any, err := ptypes.MarshalAny(foo) -// ... -// foo := &pb.Foo{} -// if err := ptypes.UnmarshalAny(any, foo); err != nil { -// ... -// } -// -// The pack methods provided by protobuf library will by default use -// 'type.googleapis.com/full.type.name' as the type URL and the unpack -// methods only use the fully qualified type name after the last '/' -// in the type URL, for example "foo.bar.com/x/y.z" will yield type -// name "y.z". -// -// -// JSON -// ==== -// The JSON representation of an `Any` value uses the regular -// representation of the deserialized, embedded message, with an -// additional field `@type` which contains the type URL. Example: -// -// package google.profile; -// message Person { -// string first_name = 1; -// string last_name = 2; -// } -// -// { -// "@type": "type.googleapis.com/google.profile.Person", -// "firstName": , -// "lastName": -// } -// -// If the embedded message type is well-known and has a custom JSON -// representation, that representation will be embedded adding a field -// `value` which holds the custom JSON in addition to the `@type` -// field. Example (for message [google.protobuf.Duration][]): -// -// { -// "@type": "type.googleapis.com/google.protobuf.Duration", -// "value": "1.212s" -// } -// -type Any struct { - // A URL/resource name whose content describes the type of the - // serialized protocol buffer message. - // - // For URLs which use the scheme `http`, `https`, or no scheme, the - // following restrictions and interpretations apply: - // - // * If no scheme is provided, `https` is assumed. - // * The last segment of the URL's path must represent the fully - // qualified name of the type (as in `path/google.protobuf.Duration`). - // The name should be in a canonical form (e.g., leading "." is - // not accepted). - // * An HTTP GET on the URL must yield a [google.protobuf.Type][] - // value in binary format, or produce an error. - // * Applications are allowed to cache lookup results based on the - // URL, or have them precompiled into a binary to avoid any - // lookup. Therefore, binary compatibility needs to be preserved - // on changes to types. (Use versioned type names to manage - // breaking changes.) - // - // Schemes other than `http`, `https` (or the empty scheme) might be - // used with implementation specific semantics. - // - TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl" json:"type_url,omitempty"` - // Must be a valid serialized protocol buffer of the above specified type. - Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Any) Reset() { *m = Any{} } -func (m *Any) String() string { return proto.CompactTextString(m) } -func (*Any) ProtoMessage() {} -func (*Any) Descriptor() ([]byte, []int) { - return fileDescriptor_any_744b9ca530f228db, []int{0} -} -func (*Any) XXX_WellKnownType() string { return "Any" } -func (m *Any) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Any.Unmarshal(m, b) -} -func (m *Any) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Any.Marshal(b, m, deterministic) -} -func (dst *Any) XXX_Merge(src proto.Message) { - xxx_messageInfo_Any.Merge(dst, src) -} -func (m *Any) XXX_Size() int { - return xxx_messageInfo_Any.Size(m) -} -func (m *Any) XXX_DiscardUnknown() { - xxx_messageInfo_Any.DiscardUnknown(m) -} - -var xxx_messageInfo_Any proto.InternalMessageInfo - -func (m *Any) GetTypeUrl() string { - if m != nil { - return m.TypeUrl - } - return "" -} - -func (m *Any) GetValue() []byte { - if m != nil { - return m.Value - } - return nil -} - -func init() { - proto.RegisterType((*Any)(nil), "google.protobuf.Any") -} - -func init() { proto.RegisterFile("google/protobuf/any.proto", fileDescriptor_any_744b9ca530f228db) } - -var fileDescriptor_any_744b9ca530f228db = []byte{ - // 185 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4c, 0xcf, 0xcf, 0x4f, - 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0xcc, 0xab, 0xd4, - 0x03, 0x73, 0x84, 0xf8, 0x21, 0x52, 0x7a, 0x30, 0x29, 0x25, 0x33, 0x2e, 0x66, 0xc7, 0xbc, 0x4a, - 0x21, 0x49, 0x2e, 0x8e, 0x92, 0xca, 0x82, 0xd4, 0xf8, 0xd2, 0xa2, 0x1c, 0x09, 0x46, 0x05, 0x46, - 0x0d, 0xce, 0x20, 0x76, 0x10, 0x3f, 0xb4, 0x28, 0x47, 0x48, 0x84, 0x8b, 0xb5, 0x2c, 0x31, 0xa7, - 0x34, 0x55, 0x82, 0x49, 0x81, 0x51, 0x83, 0x27, 0x08, 0xc2, 0x71, 0xca, 0xe7, 0x12, 0x4e, 0xce, - 0xcf, 0xd5, 0x43, 0x33, 0xce, 0x89, 0xc3, 0x31, 0xaf, 0x32, 0x00, 0xc4, 0x09, 0x60, 0x8c, 0x52, - 0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, - 0x4b, 0x47, 0xb8, 0xa8, 0x00, 0x64, 0x7a, 0x31, 0xc8, 0x61, 0x8b, 0x98, 0x98, 0xdd, 0x03, 0x9c, - 0x56, 0x31, 0xc9, 0xb9, 0x43, 0x8c, 0x0a, 0x80, 0x2a, 0xd1, 0x0b, 0x4f, 0xcd, 0xc9, 0xf1, 0xce, - 0xcb, 0x2f, 0xcf, 0x0b, 0x01, 0x29, 0x4d, 0x62, 0x03, 0xeb, 0x35, 0x06, 0x04, 0x00, 0x00, 0xff, - 0xff, 0x13, 0xf8, 0xe8, 0x42, 0xdd, 0x00, 0x00, 0x00, -} diff --git a/vendor/github.com/golang/protobuf/ptypes/doc.go b/vendor/github.com/golang/protobuf/ptypes/doc.go deleted file mode 100644 index c0d595da7..000000000 --- a/vendor/github.com/golang/protobuf/ptypes/doc.go +++ /dev/null @@ -1,35 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/* -Package ptypes contains code for interacting with well-known types. -*/ -package ptypes diff --git a/vendor/github.com/golang/protobuf/ptypes/duration.go b/vendor/github.com/golang/protobuf/ptypes/duration.go deleted file mode 100644 index 65cb0f8eb..000000000 --- a/vendor/github.com/golang/protobuf/ptypes/duration.go +++ /dev/null @@ -1,102 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package ptypes - -// This file implements conversions between google.protobuf.Duration -// and time.Duration. - -import ( - "errors" - "fmt" - "time" - - durpb "github.com/golang/protobuf/ptypes/duration" -) - -const ( - // Range of a durpb.Duration in seconds, as specified in - // google/protobuf/duration.proto. This is about 10,000 years in seconds. - maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) - minSeconds = -maxSeconds -) - -// validateDuration determines whether the durpb.Duration is valid according to the -// definition in google/protobuf/duration.proto. A valid durpb.Duration -// may still be too large to fit into a time.Duration (the range of durpb.Duration -// is about 10,000 years, and the range of time.Duration is about 290). -func validateDuration(d *durpb.Duration) error { - if d == nil { - return errors.New("duration: nil Duration") - } - if d.Seconds < minSeconds || d.Seconds > maxSeconds { - return fmt.Errorf("duration: %v: seconds out of range", d) - } - if d.Nanos <= -1e9 || d.Nanos >= 1e9 { - return fmt.Errorf("duration: %v: nanos out of range", d) - } - // Seconds and Nanos must have the same sign, unless d.Nanos is zero. - if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) { - return fmt.Errorf("duration: %v: seconds and nanos have different signs", d) - } - return nil -} - -// Duration converts a durpb.Duration to a time.Duration. Duration -// returns an error if the durpb.Duration is invalid or is too large to be -// represented in a time.Duration. -func Duration(p *durpb.Duration) (time.Duration, error) { - if err := validateDuration(p); err != nil { - return 0, err - } - d := time.Duration(p.Seconds) * time.Second - if int64(d/time.Second) != p.Seconds { - return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p) - } - if p.Nanos != 0 { - d += time.Duration(p.Nanos) - if (d < 0) != (p.Nanos < 0) { - return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p) - } - } - return d, nil -} - -// DurationProto converts a time.Duration to a durpb.Duration. -func DurationProto(d time.Duration) *durpb.Duration { - nanos := d.Nanoseconds() - secs := nanos / 1e9 - nanos -= secs * 1e9 - return &durpb.Duration{ - Seconds: secs, - Nanos: int32(nanos), - } -} diff --git a/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go b/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go deleted file mode 100644 index 4d75473b8..000000000 --- a/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go +++ /dev/null @@ -1,159 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: google/protobuf/duration.proto - -package duration // import "github.com/golang/protobuf/ptypes/duration" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -// A Duration represents a signed, fixed-length span of time represented -// as a count of seconds and fractions of seconds at nanosecond -// resolution. It is independent of any calendar and concepts like "day" -// or "month". It is related to Timestamp in that the difference between -// two Timestamp values is a Duration and it can be added or subtracted -// from a Timestamp. Range is approximately +-10,000 years. -// -// # Examples -// -// Example 1: Compute Duration from two Timestamps in pseudo code. -// -// Timestamp start = ...; -// Timestamp end = ...; -// Duration duration = ...; -// -// duration.seconds = end.seconds - start.seconds; -// duration.nanos = end.nanos - start.nanos; -// -// if (duration.seconds < 0 && duration.nanos > 0) { -// duration.seconds += 1; -// duration.nanos -= 1000000000; -// } else if (durations.seconds > 0 && duration.nanos < 0) { -// duration.seconds -= 1; -// duration.nanos += 1000000000; -// } -// -// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. -// -// Timestamp start = ...; -// Duration duration = ...; -// Timestamp end = ...; -// -// end.seconds = start.seconds + duration.seconds; -// end.nanos = start.nanos + duration.nanos; -// -// if (end.nanos < 0) { -// end.seconds -= 1; -// end.nanos += 1000000000; -// } else if (end.nanos >= 1000000000) { -// end.seconds += 1; -// end.nanos -= 1000000000; -// } -// -// Example 3: Compute Duration from datetime.timedelta in Python. -// -// td = datetime.timedelta(days=3, minutes=10) -// duration = Duration() -// duration.FromTimedelta(td) -// -// # JSON Mapping -// -// In JSON format, the Duration type is encoded as a string rather than an -// object, where the string ends in the suffix "s" (indicating seconds) and -// is preceded by the number of seconds, with nanoseconds expressed as -// fractional seconds. For example, 3 seconds with 0 nanoseconds should be -// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should -// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 -// microsecond should be expressed in JSON format as "3.000001s". -// -// -type Duration struct { - // Signed seconds of the span of time. Must be from -315,576,000,000 - // to +315,576,000,000 inclusive. Note: these bounds are computed from: - // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years - Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"` - // Signed fractions of a second at nanosecond resolution of the span - // of time. Durations less than one second are represented with a 0 - // `seconds` field and a positive or negative `nanos` field. For durations - // of one second or more, a non-zero value for the `nanos` field must be - // of the same sign as the `seconds` field. Must be from -999,999,999 - // to +999,999,999 inclusive. - Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Duration) Reset() { *m = Duration{} } -func (m *Duration) String() string { return proto.CompactTextString(m) } -func (*Duration) ProtoMessage() {} -func (*Duration) Descriptor() ([]byte, []int) { - return fileDescriptor_duration_e7d612259e3f0613, []int{0} -} -func (*Duration) XXX_WellKnownType() string { return "Duration" } -func (m *Duration) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Duration.Unmarshal(m, b) -} -func (m *Duration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Duration.Marshal(b, m, deterministic) -} -func (dst *Duration) XXX_Merge(src proto.Message) { - xxx_messageInfo_Duration.Merge(dst, src) -} -func (m *Duration) XXX_Size() int { - return xxx_messageInfo_Duration.Size(m) -} -func (m *Duration) XXX_DiscardUnknown() { - xxx_messageInfo_Duration.DiscardUnknown(m) -} - -var xxx_messageInfo_Duration proto.InternalMessageInfo - -func (m *Duration) GetSeconds() int64 { - if m != nil { - return m.Seconds - } - return 0 -} - -func (m *Duration) GetNanos() int32 { - if m != nil { - return m.Nanos - } - return 0 -} - -func init() { - proto.RegisterType((*Duration)(nil), "google.protobuf.Duration") -} - -func init() { - proto.RegisterFile("google/protobuf/duration.proto", fileDescriptor_duration_e7d612259e3f0613) -} - -var fileDescriptor_duration_e7d612259e3f0613 = []byte{ - // 190 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0xcf, 0xcf, 0x4f, - 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0x29, 0x2d, 0x4a, - 0x2c, 0xc9, 0xcc, 0xcf, 0xd3, 0x03, 0x8b, 0x08, 0xf1, 0x43, 0xe4, 0xf5, 0x60, 0xf2, 0x4a, 0x56, - 0x5c, 0x1c, 0x2e, 0x50, 0x25, 0x42, 0x12, 0x5c, 0xec, 0xc5, 0xa9, 0xc9, 0xf9, 0x79, 0x29, 0xc5, - 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xcc, 0x41, 0x30, 0xae, 0x90, 0x08, 0x17, 0x6b, 0x5e, 0x62, 0x5e, - 0x7e, 0xb1, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x6b, 0x10, 0x84, 0xe3, 0x54, 0xc3, 0x25, 0x9c, 0x9c, - 0x9f, 0xab, 0x87, 0x66, 0xa4, 0x13, 0x2f, 0xcc, 0xc0, 0x00, 0x90, 0x48, 0x00, 0x63, 0x94, 0x56, - 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x7e, 0x7a, 0x7e, 0x4e, 0x62, 0x5e, - 0x3a, 0xc2, 0x7d, 0x05, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x70, 0x67, 0xfe, 0x60, 0x64, 0x5c, 0xc4, - 0xc4, 0xec, 0x1e, 0xe0, 0xb4, 0x8a, 0x49, 0xce, 0x1d, 0x62, 0x6e, 0x00, 0x54, 0xa9, 0x5e, 0x78, - 0x6a, 0x4e, 0x8e, 0x77, 0x5e, 0x7e, 0x79, 0x5e, 0x08, 0x48, 0x4b, 0x12, 0x1b, 0xd8, 0x0c, 0x63, - 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x84, 0x30, 0xff, 0xf3, 0x00, 0x00, 0x00, -} diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp.go b/vendor/github.com/golang/protobuf/ptypes/timestamp.go deleted file mode 100644 index 47f10dbc2..000000000 --- a/vendor/github.com/golang/protobuf/ptypes/timestamp.go +++ /dev/null @@ -1,134 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package ptypes - -// This file implements operations on google.protobuf.Timestamp. - -import ( - "errors" - "fmt" - "time" - - tspb "github.com/golang/protobuf/ptypes/timestamp" -) - -const ( - // Seconds field of the earliest valid Timestamp. - // This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). - minValidSeconds = -62135596800 - // Seconds field just after the latest valid Timestamp. - // This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). - maxValidSeconds = 253402300800 -) - -// validateTimestamp determines whether a Timestamp is valid. -// A valid timestamp represents a time in the range -// [0001-01-01, 10000-01-01) and has a Nanos field -// in the range [0, 1e9). -// -// If the Timestamp is valid, validateTimestamp returns nil. -// Otherwise, it returns an error that describes -// the problem. -// -// Every valid Timestamp can be represented by a time.Time, but the converse is not true. -func validateTimestamp(ts *tspb.Timestamp) error { - if ts == nil { - return errors.New("timestamp: nil Timestamp") - } - if ts.Seconds < minValidSeconds { - return fmt.Errorf("timestamp: %v before 0001-01-01", ts) - } - if ts.Seconds >= maxValidSeconds { - return fmt.Errorf("timestamp: %v after 10000-01-01", ts) - } - if ts.Nanos < 0 || ts.Nanos >= 1e9 { - return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts) - } - return nil -} - -// Timestamp converts a google.protobuf.Timestamp proto to a time.Time. -// It returns an error if the argument is invalid. -// -// Unlike most Go functions, if Timestamp returns an error, the first return value -// is not the zero time.Time. Instead, it is the value obtained from the -// time.Unix function when passed the contents of the Timestamp, in the UTC -// locale. This may or may not be a meaningful time; many invalid Timestamps -// do map to valid time.Times. -// -// A nil Timestamp returns an error. The first return value in that case is -// undefined. -func Timestamp(ts *tspb.Timestamp) (time.Time, error) { - // Don't return the zero value on error, because corresponds to a valid - // timestamp. Instead return whatever time.Unix gives us. - var t time.Time - if ts == nil { - t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp - } else { - t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() - } - return t, validateTimestamp(ts) -} - -// TimestampNow returns a google.protobuf.Timestamp for the current time. -func TimestampNow() *tspb.Timestamp { - ts, err := TimestampProto(time.Now()) - if err != nil { - panic("ptypes: time.Now() out of Timestamp range") - } - return ts -} - -// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. -// It returns an error if the resulting Timestamp is invalid. -func TimestampProto(t time.Time) (*tspb.Timestamp, error) { - seconds := t.Unix() - nanos := int32(t.Sub(time.Unix(seconds, 0))) - ts := &tspb.Timestamp{ - Seconds: seconds, - Nanos: nanos, - } - if err := validateTimestamp(ts); err != nil { - return nil, err - } - return ts, nil -} - -// TimestampString returns the RFC 3339 string for valid Timestamps. For invalid -// Timestamps, it returns an error message in parentheses. -func TimestampString(ts *tspb.Timestamp) string { - t, err := Timestamp(ts) - if err != nil { - return fmt.Sprintf("(%v)", err) - } - return t.Format(time.RFC3339Nano) -} diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go deleted file mode 100644 index e9c222282..000000000 --- a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go +++ /dev/null @@ -1,175 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: google/protobuf/timestamp.proto - -package timestamp // import "github.com/golang/protobuf/ptypes/timestamp" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -// A Timestamp represents a point in time independent of any time zone -// or calendar, represented as seconds and fractions of seconds at -// nanosecond resolution in UTC Epoch time. It is encoded using the -// Proleptic Gregorian Calendar which extends the Gregorian calendar -// backwards to year one. It is encoded assuming all minutes are 60 -// seconds long, i.e. leap seconds are "smeared" so that no leap second -// table is needed for interpretation. Range is from -// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. -// By restricting to that range, we ensure that we can convert to -// and from RFC 3339 date strings. -// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt). -// -// # Examples -// -// Example 1: Compute Timestamp from POSIX `time()`. -// -// Timestamp timestamp; -// timestamp.set_seconds(time(NULL)); -// timestamp.set_nanos(0); -// -// Example 2: Compute Timestamp from POSIX `gettimeofday()`. -// -// struct timeval tv; -// gettimeofday(&tv, NULL); -// -// Timestamp timestamp; -// timestamp.set_seconds(tv.tv_sec); -// timestamp.set_nanos(tv.tv_usec * 1000); -// -// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. -// -// FILETIME ft; -// GetSystemTimeAsFileTime(&ft); -// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; -// -// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z -// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. -// Timestamp timestamp; -// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); -// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); -// -// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. -// -// long millis = System.currentTimeMillis(); -// -// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) -// .setNanos((int) ((millis % 1000) * 1000000)).build(); -// -// -// Example 5: Compute Timestamp from current time in Python. -// -// timestamp = Timestamp() -// timestamp.GetCurrentTime() -// -// # JSON Mapping -// -// In JSON format, the Timestamp type is encoded as a string in the -// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the -// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" -// where {year} is always expressed using four digits while {month}, {day}, -// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional -// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), -// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone -// is required, though only UTC (as indicated by "Z") is presently supported. -// -// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past -// 01:30 UTC on January 15, 2017. -// -// In JavaScript, one can convert a Date object to this format using the -// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString] -// method. In Python, a standard `datetime.datetime` object can be converted -// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) -// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one -// can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( -// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--) -// to obtain a formatter capable of generating timestamps in this format. -// -// -type Timestamp struct { - // Represents seconds of UTC time since Unix epoch - // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to - // 9999-12-31T23:59:59Z inclusive. - Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"` - // Non-negative fractions of a second at nanosecond resolution. Negative - // second values with fractions must still have non-negative nanos values - // that count forward in time. Must be from 0 to 999,999,999 - // inclusive. - Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Timestamp) Reset() { *m = Timestamp{} } -func (m *Timestamp) String() string { return proto.CompactTextString(m) } -func (*Timestamp) ProtoMessage() {} -func (*Timestamp) Descriptor() ([]byte, []int) { - return fileDescriptor_timestamp_b826e8e5fba671a8, []int{0} -} -func (*Timestamp) XXX_WellKnownType() string { return "Timestamp" } -func (m *Timestamp) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Timestamp.Unmarshal(m, b) -} -func (m *Timestamp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Timestamp.Marshal(b, m, deterministic) -} -func (dst *Timestamp) XXX_Merge(src proto.Message) { - xxx_messageInfo_Timestamp.Merge(dst, src) -} -func (m *Timestamp) XXX_Size() int { - return xxx_messageInfo_Timestamp.Size(m) -} -func (m *Timestamp) XXX_DiscardUnknown() { - xxx_messageInfo_Timestamp.DiscardUnknown(m) -} - -var xxx_messageInfo_Timestamp proto.InternalMessageInfo - -func (m *Timestamp) GetSeconds() int64 { - if m != nil { - return m.Seconds - } - return 0 -} - -func (m *Timestamp) GetNanos() int32 { - if m != nil { - return m.Nanos - } - return 0 -} - -func init() { - proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp") -} - -func init() { - proto.RegisterFile("google/protobuf/timestamp.proto", fileDescriptor_timestamp_b826e8e5fba671a8) -} - -var fileDescriptor_timestamp_b826e8e5fba671a8 = []byte{ - // 191 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xcf, 0xcf, 0x4f, - 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0xc9, 0xcc, 0x4d, - 0x2d, 0x2e, 0x49, 0xcc, 0x2d, 0xd0, 0x03, 0x0b, 0x09, 0xf1, 0x43, 0x14, 0xe8, 0xc1, 0x14, 0x28, - 0x59, 0x73, 0x71, 0x86, 0xc0, 0xd4, 0x08, 0x49, 0x70, 0xb1, 0x17, 0xa7, 0x26, 0xe7, 0xe7, 0xa5, - 0x14, 0x4b, 0x30, 0x2a, 0x30, 0x6a, 0x30, 0x07, 0xc1, 0xb8, 0x42, 0x22, 0x5c, 0xac, 0x79, 0x89, - 0x79, 0xf9, 0xc5, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xac, 0x41, 0x10, 0x8e, 0x53, 0x1d, 0x97, 0x70, - 0x72, 0x7e, 0xae, 0x1e, 0x9a, 0x99, 0x4e, 0x7c, 0x70, 0x13, 0x03, 0x40, 0x42, 0x01, 0x8c, 0x51, - 0xda, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xe9, 0xf9, 0x39, 0x89, - 0x79, 0xe9, 0x08, 0x27, 0x16, 0x94, 0x54, 0x16, 0xa4, 0x16, 0x23, 0x5c, 0xfa, 0x83, 0x91, 0x71, - 0x11, 0x13, 0xb3, 0x7b, 0x80, 0xd3, 0x2a, 0x26, 0x39, 0x77, 0x88, 0xc9, 0x01, 0x50, 0xb5, 0x7a, - 0xe1, 0xa9, 0x39, 0x39, 0xde, 0x79, 0xf9, 0xe5, 0x79, 0x21, 0x20, 0x3d, 0x49, 0x6c, 0x60, 0x43, - 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbc, 0x77, 0x4a, 0x07, 0xf7, 0x00, 0x00, 0x00, -} diff --git a/vendor/github.com/google/gofuzz/LICENSE b/vendor/github.com/google/gofuzz/LICENSE deleted file mode 100644 index d64569567..000000000 --- a/vendor/github.com/google/gofuzz/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/google/gofuzz/doc.go b/vendor/github.com/google/gofuzz/doc.go deleted file mode 100644 index 9f9956d4a..000000000 --- a/vendor/github.com/google/gofuzz/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package fuzz is a library for populating go objects with random values. -package fuzz diff --git a/vendor/github.com/google/gofuzz/fuzz.go b/vendor/github.com/google/gofuzz/fuzz.go deleted file mode 100644 index 1dfa80a6f..000000000 --- a/vendor/github.com/google/gofuzz/fuzz.go +++ /dev/null @@ -1,487 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package fuzz - -import ( - "fmt" - "math/rand" - "reflect" - "time" -) - -// fuzzFuncMap is a map from a type to a fuzzFunc that handles that type. -type fuzzFuncMap map[reflect.Type]reflect.Value - -// Fuzzer knows how to fill any object with random fields. -type Fuzzer struct { - fuzzFuncs fuzzFuncMap - defaultFuzzFuncs fuzzFuncMap - r *rand.Rand - nilChance float64 - minElements int - maxElements int - maxDepth int -} - -// New returns a new Fuzzer. Customize your Fuzzer further by calling Funcs, -// RandSource, NilChance, or NumElements in any order. -func New() *Fuzzer { - return NewWithSeed(time.Now().UnixNano()) -} - -func NewWithSeed(seed int64) *Fuzzer { - f := &Fuzzer{ - defaultFuzzFuncs: fuzzFuncMap{ - reflect.TypeOf(&time.Time{}): reflect.ValueOf(fuzzTime), - }, - - fuzzFuncs: fuzzFuncMap{}, - r: rand.New(rand.NewSource(seed)), - nilChance: .2, - minElements: 1, - maxElements: 10, - maxDepth: 100, - } - return f -} - -// Funcs adds each entry in fuzzFuncs as a custom fuzzing function. -// -// Each entry in fuzzFuncs must be a function taking two parameters. -// The first parameter must be a pointer or map. It is the variable that -// function will fill with random data. The second parameter must be a -// fuzz.Continue, which will provide a source of randomness and a way -// to automatically continue fuzzing smaller pieces of the first parameter. -// -// These functions are called sensibly, e.g., if you wanted custom string -// fuzzing, the function `func(s *string, c fuzz.Continue)` would get -// called and passed the address of strings. Maps and pointers will always -// be made/new'd for you, ignoring the NilChange option. For slices, it -// doesn't make much sense to pre-create them--Fuzzer doesn't know how -// long you want your slice--so take a pointer to a slice, and make it -// yourself. (If you don't want your map/pointer type pre-made, take a -// pointer to it, and make it yourself.) See the examples for a range of -// custom functions. -func (f *Fuzzer) Funcs(fuzzFuncs ...interface{}) *Fuzzer { - for i := range fuzzFuncs { - v := reflect.ValueOf(fuzzFuncs[i]) - if v.Kind() != reflect.Func { - panic("Need only funcs!") - } - t := v.Type() - if t.NumIn() != 2 || t.NumOut() != 0 { - panic("Need 2 in and 0 out params!") - } - argT := t.In(0) - switch argT.Kind() { - case reflect.Ptr, reflect.Map: - default: - panic("fuzzFunc must take pointer or map type") - } - if t.In(1) != reflect.TypeOf(Continue{}) { - panic("fuzzFunc's second parameter must be type fuzz.Continue") - } - f.fuzzFuncs[argT] = v - } - return f -} - -// RandSource causes f to get values from the given source of randomness. -// Use if you want deterministic fuzzing. -func (f *Fuzzer) RandSource(s rand.Source) *Fuzzer { - f.r = rand.New(s) - return f -} - -// NilChance sets the probability of creating a nil pointer, map, or slice to -// 'p'. 'p' should be between 0 (no nils) and 1 (all nils), inclusive. -func (f *Fuzzer) NilChance(p float64) *Fuzzer { - if p < 0 || p > 1 { - panic("p should be between 0 and 1, inclusive.") - } - f.nilChance = p - return f -} - -// NumElements sets the minimum and maximum number of elements that will be -// added to a non-nil map or slice. -func (f *Fuzzer) NumElements(atLeast, atMost int) *Fuzzer { - if atLeast > atMost { - panic("atLeast must be <= atMost") - } - if atLeast < 0 { - panic("atLeast must be >= 0") - } - f.minElements = atLeast - f.maxElements = atMost - return f -} - -func (f *Fuzzer) genElementCount() int { - if f.minElements == f.maxElements { - return f.minElements - } - return f.minElements + f.r.Intn(f.maxElements-f.minElements+1) -} - -func (f *Fuzzer) genShouldFill() bool { - return f.r.Float64() > f.nilChance -} - -// MaxDepth sets the maximum number of recursive fuzz calls that will be made -// before stopping. This includes struct members, pointers, and map and slice -// elements. -func (f *Fuzzer) MaxDepth(d int) *Fuzzer { - f.maxDepth = d - return f -} - -// Fuzz recursively fills all of obj's fields with something random. First -// this tries to find a custom fuzz function (see Funcs). If there is no -// custom function this tests whether the object implements fuzz.Interface and, -// if so, calls Fuzz on it to fuzz itself. If that fails, this will see if -// there is a default fuzz function provided by this package. If all of that -// fails, this will generate random values for all primitive fields and then -// recurse for all non-primitives. -// -// This is safe for cyclic or tree-like structs, up to a limit. Use the -// MaxDepth method to adjust how deep you need it to recurse. -// -// obj must be a pointer. Only exported (public) fields can be set (thanks, -// golang :/ ) Intended for tests, so will panic on bad input or unimplemented -// fields. -func (f *Fuzzer) Fuzz(obj interface{}) { - v := reflect.ValueOf(obj) - if v.Kind() != reflect.Ptr { - panic("needed ptr!") - } - v = v.Elem() - f.fuzzWithContext(v, 0) -} - -// FuzzNoCustom is just like Fuzz, except that any custom fuzz function for -// obj's type will not be called and obj will not be tested for fuzz.Interface -// conformance. This applies only to obj and not other instances of obj's -// type. -// Not safe for cyclic or tree-like structs! -// obj must be a pointer. Only exported (public) fields can be set (thanks, golang :/ ) -// Intended for tests, so will panic on bad input or unimplemented fields. -func (f *Fuzzer) FuzzNoCustom(obj interface{}) { - v := reflect.ValueOf(obj) - if v.Kind() != reflect.Ptr { - panic("needed ptr!") - } - v = v.Elem() - f.fuzzWithContext(v, flagNoCustomFuzz) -} - -const ( - // Do not try to find a custom fuzz function. Does not apply recursively. - flagNoCustomFuzz uint64 = 1 << iota -) - -func (f *Fuzzer) fuzzWithContext(v reflect.Value, flags uint64) { - fc := &fuzzerContext{fuzzer: f} - fc.doFuzz(v, flags) -} - -// fuzzerContext carries context about a single fuzzing run, which lets Fuzzer -// be thread-safe. -type fuzzerContext struct { - fuzzer *Fuzzer - curDepth int -} - -func (fc *fuzzerContext) doFuzz(v reflect.Value, flags uint64) { - if fc.curDepth >= fc.fuzzer.maxDepth { - return - } - fc.curDepth++ - defer func() { fc.curDepth-- }() - - if !v.CanSet() { - return - } - - if flags&flagNoCustomFuzz == 0 { - // Check for both pointer and non-pointer custom functions. - if v.CanAddr() && fc.tryCustom(v.Addr()) { - return - } - if fc.tryCustom(v) { - return - } - } - - if fn, ok := fillFuncMap[v.Kind()]; ok { - fn(v, fc.fuzzer.r) - return - } - switch v.Kind() { - case reflect.Map: - if fc.fuzzer.genShouldFill() { - v.Set(reflect.MakeMap(v.Type())) - n := fc.fuzzer.genElementCount() - for i := 0; i < n; i++ { - key := reflect.New(v.Type().Key()).Elem() - fc.doFuzz(key, 0) - val := reflect.New(v.Type().Elem()).Elem() - fc.doFuzz(val, 0) - v.SetMapIndex(key, val) - } - return - } - v.Set(reflect.Zero(v.Type())) - case reflect.Ptr: - if fc.fuzzer.genShouldFill() { - v.Set(reflect.New(v.Type().Elem())) - fc.doFuzz(v.Elem(), 0) - return - } - v.Set(reflect.Zero(v.Type())) - case reflect.Slice: - if fc.fuzzer.genShouldFill() { - n := fc.fuzzer.genElementCount() - v.Set(reflect.MakeSlice(v.Type(), n, n)) - for i := 0; i < n; i++ { - fc.doFuzz(v.Index(i), 0) - } - return - } - v.Set(reflect.Zero(v.Type())) - case reflect.Array: - if fc.fuzzer.genShouldFill() { - n := v.Len() - for i := 0; i < n; i++ { - fc.doFuzz(v.Index(i), 0) - } - return - } - v.Set(reflect.Zero(v.Type())) - case reflect.Struct: - for i := 0; i < v.NumField(); i++ { - fc.doFuzz(v.Field(i), 0) - } - case reflect.Chan: - fallthrough - case reflect.Func: - fallthrough - case reflect.Interface: - fallthrough - default: - panic(fmt.Sprintf("Can't handle %#v", v.Interface())) - } -} - -// tryCustom searches for custom handlers, and returns true iff it finds a match -// and successfully randomizes v. -func (fc *fuzzerContext) tryCustom(v reflect.Value) bool { - // First: see if we have a fuzz function for it. - doCustom, ok := fc.fuzzer.fuzzFuncs[v.Type()] - if !ok { - // Second: see if it can fuzz itself. - if v.CanInterface() { - intf := v.Interface() - if fuzzable, ok := intf.(Interface); ok { - fuzzable.Fuzz(Continue{fc: fc, Rand: fc.fuzzer.r}) - return true - } - } - // Finally: see if there is a default fuzz function. - doCustom, ok = fc.fuzzer.defaultFuzzFuncs[v.Type()] - if !ok { - return false - } - } - - switch v.Kind() { - case reflect.Ptr: - if v.IsNil() { - if !v.CanSet() { - return false - } - v.Set(reflect.New(v.Type().Elem())) - } - case reflect.Map: - if v.IsNil() { - if !v.CanSet() { - return false - } - v.Set(reflect.MakeMap(v.Type())) - } - default: - return false - } - - doCustom.Call([]reflect.Value{v, reflect.ValueOf(Continue{ - fc: fc, - Rand: fc.fuzzer.r, - })}) - return true -} - -// Interface represents an object that knows how to fuzz itself. Any time we -// find a type that implements this interface we will delegate the act of -// fuzzing itself. -type Interface interface { - Fuzz(c Continue) -} - -// Continue can be passed to custom fuzzing functions to allow them to use -// the correct source of randomness and to continue fuzzing their members. -type Continue struct { - fc *fuzzerContext - - // For convenience, Continue implements rand.Rand via embedding. - // Use this for generating any randomness if you want your fuzzing - // to be repeatable for a given seed. - *rand.Rand -} - -// Fuzz continues fuzzing obj. obj must be a pointer. -func (c Continue) Fuzz(obj interface{}) { - v := reflect.ValueOf(obj) - if v.Kind() != reflect.Ptr { - panic("needed ptr!") - } - v = v.Elem() - c.fc.doFuzz(v, 0) -} - -// FuzzNoCustom continues fuzzing obj, except that any custom fuzz function for -// obj's type will not be called and obj will not be tested for fuzz.Interface -// conformance. This applies only to obj and not other instances of obj's -// type. -func (c Continue) FuzzNoCustom(obj interface{}) { - v := reflect.ValueOf(obj) - if v.Kind() != reflect.Ptr { - panic("needed ptr!") - } - v = v.Elem() - c.fc.doFuzz(v, flagNoCustomFuzz) -} - -// RandString makes a random string up to 20 characters long. The returned string -// may include a variety of (valid) UTF-8 encodings. -func (c Continue) RandString() string { - return randString(c.Rand) -} - -// RandUint64 makes random 64 bit numbers. -// Weirdly, rand doesn't have a function that gives you 64 random bits. -func (c Continue) RandUint64() uint64 { - return randUint64(c.Rand) -} - -// RandBool returns true or false randomly. -func (c Continue) RandBool() bool { - return randBool(c.Rand) -} - -func fuzzInt(v reflect.Value, r *rand.Rand) { - v.SetInt(int64(randUint64(r))) -} - -func fuzzUint(v reflect.Value, r *rand.Rand) { - v.SetUint(randUint64(r)) -} - -func fuzzTime(t *time.Time, c Continue) { - var sec, nsec int64 - // Allow for about 1000 years of random time values, which keeps things - // like JSON parsing reasonably happy. - sec = c.Rand.Int63n(1000 * 365 * 24 * 60 * 60) - c.Fuzz(&nsec) - *t = time.Unix(sec, nsec) -} - -var fillFuncMap = map[reflect.Kind]func(reflect.Value, *rand.Rand){ - reflect.Bool: func(v reflect.Value, r *rand.Rand) { - v.SetBool(randBool(r)) - }, - reflect.Int: fuzzInt, - reflect.Int8: fuzzInt, - reflect.Int16: fuzzInt, - reflect.Int32: fuzzInt, - reflect.Int64: fuzzInt, - reflect.Uint: fuzzUint, - reflect.Uint8: fuzzUint, - reflect.Uint16: fuzzUint, - reflect.Uint32: fuzzUint, - reflect.Uint64: fuzzUint, - reflect.Uintptr: fuzzUint, - reflect.Float32: func(v reflect.Value, r *rand.Rand) { - v.SetFloat(float64(r.Float32())) - }, - reflect.Float64: func(v reflect.Value, r *rand.Rand) { - v.SetFloat(r.Float64()) - }, - reflect.Complex64: func(v reflect.Value, r *rand.Rand) { - panic("unimplemented") - }, - reflect.Complex128: func(v reflect.Value, r *rand.Rand) { - panic("unimplemented") - }, - reflect.String: func(v reflect.Value, r *rand.Rand) { - v.SetString(randString(r)) - }, - reflect.UnsafePointer: func(v reflect.Value, r *rand.Rand) { - panic("unimplemented") - }, -} - -// randBool returns true or false randomly. -func randBool(r *rand.Rand) bool { - if r.Int()&1 == 1 { - return true - } - return false -} - -type charRange struct { - first, last rune -} - -// choose returns a random unicode character from the given range, using the -// given randomness source. -func (r *charRange) choose(rand *rand.Rand) rune { - count := int64(r.last - r.first) - return r.first + rune(rand.Int63n(count)) -} - -var unicodeRanges = []charRange{ - {' ', '~'}, // ASCII characters - {'\u00a0', '\u02af'}, // Multi-byte encoded characters - {'\u4e00', '\u9fff'}, // Common CJK (even longer encodings) -} - -// randString makes a random string up to 20 characters long. The returned string -// may include a variety of (valid) UTF-8 encodings. -func randString(r *rand.Rand) string { - n := r.Intn(20) - runes := make([]rune, n) - for i := range runes { - runes[i] = unicodeRanges[r.Intn(len(unicodeRanges))].choose(r) - } - return string(runes) -} - -// randUint64 makes random 64 bit numbers. -// Weirdly, rand doesn't have a function that gives you 64 random bits. -func randUint64(r *rand.Rand) uint64 { - return uint64(r.Uint32())<<32 | uint64(r.Uint32()) -} diff --git a/vendor/github.com/googleapis/gnostic/LICENSE b/vendor/github.com/googleapis/gnostic/LICENSE deleted file mode 100644 index 6b0b1270f..000000000 --- a/vendor/github.com/googleapis/gnostic/LICENSE +++ /dev/null @@ -1,203 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/vendor/github.com/googleapis/gnostic/OpenAPIv2/OpenAPIv2.go b/vendor/github.com/googleapis/gnostic/OpenAPIv2/OpenAPIv2.go deleted file mode 100644 index 0e32451a3..000000000 --- a/vendor/github.com/googleapis/gnostic/OpenAPIv2/OpenAPIv2.go +++ /dev/null @@ -1,8728 +0,0 @@ -// Copyright 2017 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// THIS FILE IS AUTOMATICALLY GENERATED. - -package openapi_v2 - -import ( - "fmt" - "github.com/googleapis/gnostic/compiler" - "gopkg.in/yaml.v2" - "regexp" - "strings" -) - -// Version returns the package name (and OpenAPI version). -func Version() string { - return "openapi_v2" -} - -// NewAdditionalPropertiesItem creates an object of type AdditionalPropertiesItem if possible, returning an error if not. -func NewAdditionalPropertiesItem(in interface{}, context *compiler.Context) (*AdditionalPropertiesItem, error) { - errors := make([]error, 0) - x := &AdditionalPropertiesItem{} - matched := false - // Schema schema = 1; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewSchema(m, compiler.NewContext("schema", context)) - if matchingError == nil { - x.Oneof = &AdditionalPropertiesItem_Schema{Schema: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - // bool boolean = 2; - boolValue, ok := in.(bool) - if ok { - x.Oneof = &AdditionalPropertiesItem_Boolean{Boolean: boolValue} - } - if matched { - // since the oneof matched one of its possibilities, discard any matching errors - errors = make([]error, 0) - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewAny creates an object of type Any if possible, returning an error if not. -func NewAny(in interface{}, context *compiler.Context) (*Any, error) { - errors := make([]error, 0) - x := &Any{} - bytes, _ := yaml.Marshal(in) - x.Yaml = string(bytes) - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewApiKeySecurity creates an object of type ApiKeySecurity if possible, returning an error if not. -func NewApiKeySecurity(in interface{}, context *compiler.Context) (*ApiKeySecurity, error) { - errors := make([]error, 0) - x := &ApiKeySecurity{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"in", "name", "type"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"description", "in", "name", "type"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string type = 1; - v1 := compiler.MapValueForKey(m, "type") - if v1 != nil { - x.Type, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [apiKey] - if ok && !compiler.StringArrayContainsValue([]string{"apiKey"}, x.Type) { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string name = 2; - v2 := compiler.MapValueForKey(m, "name") - if v2 != nil { - x.Name, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string in = 3; - v3 := compiler.MapValueForKey(m, "in") - if v3 != nil { - x.In, ok = v3.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for in: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [header query] - if ok && !compiler.StringArrayContainsValue([]string{"header", "query"}, x.In) { - message := fmt.Sprintf("has unexpected value for in: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 4; - v4 := compiler.MapValueForKey(m, "description") - if v4 != nil { - x.Description, ok = v4.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 5; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewBasicAuthenticationSecurity creates an object of type BasicAuthenticationSecurity if possible, returning an error if not. -func NewBasicAuthenticationSecurity(in interface{}, context *compiler.Context) (*BasicAuthenticationSecurity, error) { - errors := make([]error, 0) - x := &BasicAuthenticationSecurity{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"type"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"description", "type"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string type = 1; - v1 := compiler.MapValueForKey(m, "type") - if v1 != nil { - x.Type, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [basic] - if ok && !compiler.StringArrayContainsValue([]string{"basic"}, x.Type) { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 2; - v2 := compiler.MapValueForKey(m, "description") - if v2 != nil { - x.Description, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 3; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewBodyParameter creates an object of type BodyParameter if possible, returning an error if not. -func NewBodyParameter(in interface{}, context *compiler.Context) (*BodyParameter, error) { - errors := make([]error, 0) - x := &BodyParameter{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"in", "name", "schema"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"description", "in", "name", "required", "schema"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string description = 1; - v1 := compiler.MapValueForKey(m, "description") - if v1 != nil { - x.Description, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string name = 2; - v2 := compiler.MapValueForKey(m, "name") - if v2 != nil { - x.Name, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string in = 3; - v3 := compiler.MapValueForKey(m, "in") - if v3 != nil { - x.In, ok = v3.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for in: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [body] - if ok && !compiler.StringArrayContainsValue([]string{"body"}, x.In) { - message := fmt.Sprintf("has unexpected value for in: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool required = 4; - v4 := compiler.MapValueForKey(m, "required") - if v4 != nil { - x.Required, ok = v4.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for required: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Schema schema = 5; - v5 := compiler.MapValueForKey(m, "schema") - if v5 != nil { - var err error - x.Schema, err = NewSchema(v5, compiler.NewContext("schema", context)) - if err != nil { - errors = append(errors, err) - } - } - // repeated NamedAny vendor_extension = 6; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewContact creates an object of type Contact if possible, returning an error if not. -func NewContact(in interface{}, context *compiler.Context) (*Contact, error) { - errors := make([]error, 0) - x := &Contact{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"email", "name", "url"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string name = 1; - v1 := compiler.MapValueForKey(m, "name") - if v1 != nil { - x.Name, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string url = 2; - v2 := compiler.MapValueForKey(m, "url") - if v2 != nil { - x.Url, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for url: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string email = 3; - v3 := compiler.MapValueForKey(m, "email") - if v3 != nil { - x.Email, ok = v3.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for email: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 4; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewDefault creates an object of type Default if possible, returning an error if not. -func NewDefault(in interface{}, context *compiler.Context) (*Default, error) { - errors := make([]error, 0) - x := &Default{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - // repeated NamedAny additional_properties = 1; - // MAP: Any - x.AdditionalProperties = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.AdditionalProperties = append(x.AdditionalProperties, pair) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewDefinitions creates an object of type Definitions if possible, returning an error if not. -func NewDefinitions(in interface{}, context *compiler.Context) (*Definitions, error) { - errors := make([]error, 0) - x := &Definitions{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - // repeated NamedSchema additional_properties = 1; - // MAP: Schema - x.AdditionalProperties = make([]*NamedSchema, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - pair := &NamedSchema{} - pair.Name = k - var err error - pair.Value, err = NewSchema(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - x.AdditionalProperties = append(x.AdditionalProperties, pair) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewDocument creates an object of type Document if possible, returning an error if not. -func NewDocument(in interface{}, context *compiler.Context) (*Document, error) { - errors := make([]error, 0) - x := &Document{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"info", "paths", "swagger"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"basePath", "consumes", "definitions", "externalDocs", "host", "info", "parameters", "paths", "produces", "responses", "schemes", "security", "securityDefinitions", "swagger", "tags"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string swagger = 1; - v1 := compiler.MapValueForKey(m, "swagger") - if v1 != nil { - x.Swagger, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for swagger: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [2.0] - if ok && !compiler.StringArrayContainsValue([]string{"2.0"}, x.Swagger) { - message := fmt.Sprintf("has unexpected value for swagger: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Info info = 2; - v2 := compiler.MapValueForKey(m, "info") - if v2 != nil { - var err error - x.Info, err = NewInfo(v2, compiler.NewContext("info", context)) - if err != nil { - errors = append(errors, err) - } - } - // string host = 3; - v3 := compiler.MapValueForKey(m, "host") - if v3 != nil { - x.Host, ok = v3.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for host: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string base_path = 4; - v4 := compiler.MapValueForKey(m, "basePath") - if v4 != nil { - x.BasePath, ok = v4.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for basePath: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated string schemes = 5; - v5 := compiler.MapValueForKey(m, "schemes") - if v5 != nil { - v, ok := v5.([]interface{}) - if ok { - x.Schemes = compiler.ConvertInterfaceArrayToStringArray(v) - } else { - message := fmt.Sprintf("has unexpected value for schemes: %+v (%T)", v5, v5) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [http https ws wss] - if ok && !compiler.StringArrayContainsValues([]string{"http", "https", "ws", "wss"}, x.Schemes) { - message := fmt.Sprintf("has unexpected value for schemes: %+v", v5) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated string consumes = 6; - v6 := compiler.MapValueForKey(m, "consumes") - if v6 != nil { - v, ok := v6.([]interface{}) - if ok { - x.Consumes = compiler.ConvertInterfaceArrayToStringArray(v) - } else { - message := fmt.Sprintf("has unexpected value for consumes: %+v (%T)", v6, v6) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated string produces = 7; - v7 := compiler.MapValueForKey(m, "produces") - if v7 != nil { - v, ok := v7.([]interface{}) - if ok { - x.Produces = compiler.ConvertInterfaceArrayToStringArray(v) - } else { - message := fmt.Sprintf("has unexpected value for produces: %+v (%T)", v7, v7) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Paths paths = 8; - v8 := compiler.MapValueForKey(m, "paths") - if v8 != nil { - var err error - x.Paths, err = NewPaths(v8, compiler.NewContext("paths", context)) - if err != nil { - errors = append(errors, err) - } - } - // Definitions definitions = 9; - v9 := compiler.MapValueForKey(m, "definitions") - if v9 != nil { - var err error - x.Definitions, err = NewDefinitions(v9, compiler.NewContext("definitions", context)) - if err != nil { - errors = append(errors, err) - } - } - // ParameterDefinitions parameters = 10; - v10 := compiler.MapValueForKey(m, "parameters") - if v10 != nil { - var err error - x.Parameters, err = NewParameterDefinitions(v10, compiler.NewContext("parameters", context)) - if err != nil { - errors = append(errors, err) - } - } - // ResponseDefinitions responses = 11; - v11 := compiler.MapValueForKey(m, "responses") - if v11 != nil { - var err error - x.Responses, err = NewResponseDefinitions(v11, compiler.NewContext("responses", context)) - if err != nil { - errors = append(errors, err) - } - } - // repeated SecurityRequirement security = 12; - v12 := compiler.MapValueForKey(m, "security") - if v12 != nil { - // repeated SecurityRequirement - x.Security = make([]*SecurityRequirement, 0) - a, ok := v12.([]interface{}) - if ok { - for _, item := range a { - y, err := NewSecurityRequirement(item, compiler.NewContext("security", context)) - if err != nil { - errors = append(errors, err) - } - x.Security = append(x.Security, y) - } - } - } - // SecurityDefinitions security_definitions = 13; - v13 := compiler.MapValueForKey(m, "securityDefinitions") - if v13 != nil { - var err error - x.SecurityDefinitions, err = NewSecurityDefinitions(v13, compiler.NewContext("securityDefinitions", context)) - if err != nil { - errors = append(errors, err) - } - } - // repeated Tag tags = 14; - v14 := compiler.MapValueForKey(m, "tags") - if v14 != nil { - // repeated Tag - x.Tags = make([]*Tag, 0) - a, ok := v14.([]interface{}) - if ok { - for _, item := range a { - y, err := NewTag(item, compiler.NewContext("tags", context)) - if err != nil { - errors = append(errors, err) - } - x.Tags = append(x.Tags, y) - } - } - } - // ExternalDocs external_docs = 15; - v15 := compiler.MapValueForKey(m, "externalDocs") - if v15 != nil { - var err error - x.ExternalDocs, err = NewExternalDocs(v15, compiler.NewContext("externalDocs", context)) - if err != nil { - errors = append(errors, err) - } - } - // repeated NamedAny vendor_extension = 16; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewExamples creates an object of type Examples if possible, returning an error if not. -func NewExamples(in interface{}, context *compiler.Context) (*Examples, error) { - errors := make([]error, 0) - x := &Examples{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - // repeated NamedAny additional_properties = 1; - // MAP: Any - x.AdditionalProperties = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.AdditionalProperties = append(x.AdditionalProperties, pair) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewExternalDocs creates an object of type ExternalDocs if possible, returning an error if not. -func NewExternalDocs(in interface{}, context *compiler.Context) (*ExternalDocs, error) { - errors := make([]error, 0) - x := &ExternalDocs{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"url"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"description", "url"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string description = 1; - v1 := compiler.MapValueForKey(m, "description") - if v1 != nil { - x.Description, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string url = 2; - v2 := compiler.MapValueForKey(m, "url") - if v2 != nil { - x.Url, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for url: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 3; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewFileSchema creates an object of type FileSchema if possible, returning an error if not. -func NewFileSchema(in interface{}, context *compiler.Context) (*FileSchema, error) { - errors := make([]error, 0) - x := &FileSchema{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"type"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"default", "description", "example", "externalDocs", "format", "readOnly", "required", "title", "type"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string format = 1; - v1 := compiler.MapValueForKey(m, "format") - if v1 != nil { - x.Format, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for format: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string title = 2; - v2 := compiler.MapValueForKey(m, "title") - if v2 != nil { - x.Title, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for title: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 3; - v3 := compiler.MapValueForKey(m, "description") - if v3 != nil { - x.Description, ok = v3.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Any default = 4; - v4 := compiler.MapValueForKey(m, "default") - if v4 != nil { - var err error - x.Default, err = NewAny(v4, compiler.NewContext("default", context)) - if err != nil { - errors = append(errors, err) - } - } - // repeated string required = 5; - v5 := compiler.MapValueForKey(m, "required") - if v5 != nil { - v, ok := v5.([]interface{}) - if ok { - x.Required = compiler.ConvertInterfaceArrayToStringArray(v) - } else { - message := fmt.Sprintf("has unexpected value for required: %+v (%T)", v5, v5) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string type = 6; - v6 := compiler.MapValueForKey(m, "type") - if v6 != nil { - x.Type, ok = v6.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v6, v6) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [file] - if ok && !compiler.StringArrayContainsValue([]string{"file"}, x.Type) { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v6, v6) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool read_only = 7; - v7 := compiler.MapValueForKey(m, "readOnly") - if v7 != nil { - x.ReadOnly, ok = v7.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for readOnly: %+v (%T)", v7, v7) - errors = append(errors, compiler.NewError(context, message)) - } - } - // ExternalDocs external_docs = 8; - v8 := compiler.MapValueForKey(m, "externalDocs") - if v8 != nil { - var err error - x.ExternalDocs, err = NewExternalDocs(v8, compiler.NewContext("externalDocs", context)) - if err != nil { - errors = append(errors, err) - } - } - // Any example = 9; - v9 := compiler.MapValueForKey(m, "example") - if v9 != nil { - var err error - x.Example, err = NewAny(v9, compiler.NewContext("example", context)) - if err != nil { - errors = append(errors, err) - } - } - // repeated NamedAny vendor_extension = 10; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewFormDataParameterSubSchema creates an object of type FormDataParameterSubSchema if possible, returning an error if not. -func NewFormDataParameterSubSchema(in interface{}, context *compiler.Context) (*FormDataParameterSubSchema, error) { - errors := make([]error, 0) - x := &FormDataParameterSubSchema{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"allowEmptyValue", "collectionFormat", "default", "description", "enum", "exclusiveMaximum", "exclusiveMinimum", "format", "in", "items", "maxItems", "maxLength", "maximum", "minItems", "minLength", "minimum", "multipleOf", "name", "pattern", "required", "type", "uniqueItems"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // bool required = 1; - v1 := compiler.MapValueForKey(m, "required") - if v1 != nil { - x.Required, ok = v1.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for required: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string in = 2; - v2 := compiler.MapValueForKey(m, "in") - if v2 != nil { - x.In, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for in: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [formData] - if ok && !compiler.StringArrayContainsValue([]string{"formData"}, x.In) { - message := fmt.Sprintf("has unexpected value for in: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 3; - v3 := compiler.MapValueForKey(m, "description") - if v3 != nil { - x.Description, ok = v3.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string name = 4; - v4 := compiler.MapValueForKey(m, "name") - if v4 != nil { - x.Name, ok = v4.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool allow_empty_value = 5; - v5 := compiler.MapValueForKey(m, "allowEmptyValue") - if v5 != nil { - x.AllowEmptyValue, ok = v5.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for allowEmptyValue: %+v (%T)", v5, v5) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string type = 6; - v6 := compiler.MapValueForKey(m, "type") - if v6 != nil { - x.Type, ok = v6.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v6, v6) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [string number boolean integer array file] - if ok && !compiler.StringArrayContainsValue([]string{"string", "number", "boolean", "integer", "array", "file"}, x.Type) { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v6, v6) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string format = 7; - v7 := compiler.MapValueForKey(m, "format") - if v7 != nil { - x.Format, ok = v7.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for format: %+v (%T)", v7, v7) - errors = append(errors, compiler.NewError(context, message)) - } - } - // PrimitivesItems items = 8; - v8 := compiler.MapValueForKey(m, "items") - if v8 != nil { - var err error - x.Items, err = NewPrimitivesItems(v8, compiler.NewContext("items", context)) - if err != nil { - errors = append(errors, err) - } - } - // string collection_format = 9; - v9 := compiler.MapValueForKey(m, "collectionFormat") - if v9 != nil { - x.CollectionFormat, ok = v9.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for collectionFormat: %+v (%T)", v9, v9) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [csv ssv tsv pipes multi] - if ok && !compiler.StringArrayContainsValue([]string{"csv", "ssv", "tsv", "pipes", "multi"}, x.CollectionFormat) { - message := fmt.Sprintf("has unexpected value for collectionFormat: %+v (%T)", v9, v9) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Any default = 10; - v10 := compiler.MapValueForKey(m, "default") - if v10 != nil { - var err error - x.Default, err = NewAny(v10, compiler.NewContext("default", context)) - if err != nil { - errors = append(errors, err) - } - } - // float maximum = 11; - v11 := compiler.MapValueForKey(m, "maximum") - if v11 != nil { - switch v11 := v11.(type) { - case float64: - x.Maximum = v11 - case float32: - x.Maximum = float64(v11) - case uint64: - x.Maximum = float64(v11) - case uint32: - x.Maximum = float64(v11) - case int64: - x.Maximum = float64(v11) - case int32: - x.Maximum = float64(v11) - case int: - x.Maximum = float64(v11) - default: - message := fmt.Sprintf("has unexpected value for maximum: %+v (%T)", v11, v11) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool exclusive_maximum = 12; - v12 := compiler.MapValueForKey(m, "exclusiveMaximum") - if v12 != nil { - x.ExclusiveMaximum, ok = v12.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for exclusiveMaximum: %+v (%T)", v12, v12) - errors = append(errors, compiler.NewError(context, message)) - } - } - // float minimum = 13; - v13 := compiler.MapValueForKey(m, "minimum") - if v13 != nil { - switch v13 := v13.(type) { - case float64: - x.Minimum = v13 - case float32: - x.Minimum = float64(v13) - case uint64: - x.Minimum = float64(v13) - case uint32: - x.Minimum = float64(v13) - case int64: - x.Minimum = float64(v13) - case int32: - x.Minimum = float64(v13) - case int: - x.Minimum = float64(v13) - default: - message := fmt.Sprintf("has unexpected value for minimum: %+v (%T)", v13, v13) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool exclusive_minimum = 14; - v14 := compiler.MapValueForKey(m, "exclusiveMinimum") - if v14 != nil { - x.ExclusiveMinimum, ok = v14.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for exclusiveMinimum: %+v (%T)", v14, v14) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_length = 15; - v15 := compiler.MapValueForKey(m, "maxLength") - if v15 != nil { - t, ok := v15.(int) - if ok { - x.MaxLength = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxLength: %+v (%T)", v15, v15) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_length = 16; - v16 := compiler.MapValueForKey(m, "minLength") - if v16 != nil { - t, ok := v16.(int) - if ok { - x.MinLength = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minLength: %+v (%T)", v16, v16) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string pattern = 17; - v17 := compiler.MapValueForKey(m, "pattern") - if v17 != nil { - x.Pattern, ok = v17.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for pattern: %+v (%T)", v17, v17) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_items = 18; - v18 := compiler.MapValueForKey(m, "maxItems") - if v18 != nil { - t, ok := v18.(int) - if ok { - x.MaxItems = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxItems: %+v (%T)", v18, v18) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_items = 19; - v19 := compiler.MapValueForKey(m, "minItems") - if v19 != nil { - t, ok := v19.(int) - if ok { - x.MinItems = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minItems: %+v (%T)", v19, v19) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool unique_items = 20; - v20 := compiler.MapValueForKey(m, "uniqueItems") - if v20 != nil { - x.UniqueItems, ok = v20.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for uniqueItems: %+v (%T)", v20, v20) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated Any enum = 21; - v21 := compiler.MapValueForKey(m, "enum") - if v21 != nil { - // repeated Any - x.Enum = make([]*Any, 0) - a, ok := v21.([]interface{}) - if ok { - for _, item := range a { - y, err := NewAny(item, compiler.NewContext("enum", context)) - if err != nil { - errors = append(errors, err) - } - x.Enum = append(x.Enum, y) - } - } - } - // float multiple_of = 22; - v22 := compiler.MapValueForKey(m, "multipleOf") - if v22 != nil { - switch v22 := v22.(type) { - case float64: - x.MultipleOf = v22 - case float32: - x.MultipleOf = float64(v22) - case uint64: - x.MultipleOf = float64(v22) - case uint32: - x.MultipleOf = float64(v22) - case int64: - x.MultipleOf = float64(v22) - case int32: - x.MultipleOf = float64(v22) - case int: - x.MultipleOf = float64(v22) - default: - message := fmt.Sprintf("has unexpected value for multipleOf: %+v (%T)", v22, v22) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 23; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewHeader creates an object of type Header if possible, returning an error if not. -func NewHeader(in interface{}, context *compiler.Context) (*Header, error) { - errors := make([]error, 0) - x := &Header{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"type"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"collectionFormat", "default", "description", "enum", "exclusiveMaximum", "exclusiveMinimum", "format", "items", "maxItems", "maxLength", "maximum", "minItems", "minLength", "minimum", "multipleOf", "pattern", "type", "uniqueItems"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string type = 1; - v1 := compiler.MapValueForKey(m, "type") - if v1 != nil { - x.Type, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [string number integer boolean array] - if ok && !compiler.StringArrayContainsValue([]string{"string", "number", "integer", "boolean", "array"}, x.Type) { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string format = 2; - v2 := compiler.MapValueForKey(m, "format") - if v2 != nil { - x.Format, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for format: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // PrimitivesItems items = 3; - v3 := compiler.MapValueForKey(m, "items") - if v3 != nil { - var err error - x.Items, err = NewPrimitivesItems(v3, compiler.NewContext("items", context)) - if err != nil { - errors = append(errors, err) - } - } - // string collection_format = 4; - v4 := compiler.MapValueForKey(m, "collectionFormat") - if v4 != nil { - x.CollectionFormat, ok = v4.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for collectionFormat: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [csv ssv tsv pipes] - if ok && !compiler.StringArrayContainsValue([]string{"csv", "ssv", "tsv", "pipes"}, x.CollectionFormat) { - message := fmt.Sprintf("has unexpected value for collectionFormat: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Any default = 5; - v5 := compiler.MapValueForKey(m, "default") - if v5 != nil { - var err error - x.Default, err = NewAny(v5, compiler.NewContext("default", context)) - if err != nil { - errors = append(errors, err) - } - } - // float maximum = 6; - v6 := compiler.MapValueForKey(m, "maximum") - if v6 != nil { - switch v6 := v6.(type) { - case float64: - x.Maximum = v6 - case float32: - x.Maximum = float64(v6) - case uint64: - x.Maximum = float64(v6) - case uint32: - x.Maximum = float64(v6) - case int64: - x.Maximum = float64(v6) - case int32: - x.Maximum = float64(v6) - case int: - x.Maximum = float64(v6) - default: - message := fmt.Sprintf("has unexpected value for maximum: %+v (%T)", v6, v6) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool exclusive_maximum = 7; - v7 := compiler.MapValueForKey(m, "exclusiveMaximum") - if v7 != nil { - x.ExclusiveMaximum, ok = v7.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for exclusiveMaximum: %+v (%T)", v7, v7) - errors = append(errors, compiler.NewError(context, message)) - } - } - // float minimum = 8; - v8 := compiler.MapValueForKey(m, "minimum") - if v8 != nil { - switch v8 := v8.(type) { - case float64: - x.Minimum = v8 - case float32: - x.Minimum = float64(v8) - case uint64: - x.Minimum = float64(v8) - case uint32: - x.Minimum = float64(v8) - case int64: - x.Minimum = float64(v8) - case int32: - x.Minimum = float64(v8) - case int: - x.Minimum = float64(v8) - default: - message := fmt.Sprintf("has unexpected value for minimum: %+v (%T)", v8, v8) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool exclusive_minimum = 9; - v9 := compiler.MapValueForKey(m, "exclusiveMinimum") - if v9 != nil { - x.ExclusiveMinimum, ok = v9.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for exclusiveMinimum: %+v (%T)", v9, v9) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_length = 10; - v10 := compiler.MapValueForKey(m, "maxLength") - if v10 != nil { - t, ok := v10.(int) - if ok { - x.MaxLength = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxLength: %+v (%T)", v10, v10) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_length = 11; - v11 := compiler.MapValueForKey(m, "minLength") - if v11 != nil { - t, ok := v11.(int) - if ok { - x.MinLength = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minLength: %+v (%T)", v11, v11) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string pattern = 12; - v12 := compiler.MapValueForKey(m, "pattern") - if v12 != nil { - x.Pattern, ok = v12.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for pattern: %+v (%T)", v12, v12) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_items = 13; - v13 := compiler.MapValueForKey(m, "maxItems") - if v13 != nil { - t, ok := v13.(int) - if ok { - x.MaxItems = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxItems: %+v (%T)", v13, v13) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_items = 14; - v14 := compiler.MapValueForKey(m, "minItems") - if v14 != nil { - t, ok := v14.(int) - if ok { - x.MinItems = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minItems: %+v (%T)", v14, v14) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool unique_items = 15; - v15 := compiler.MapValueForKey(m, "uniqueItems") - if v15 != nil { - x.UniqueItems, ok = v15.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for uniqueItems: %+v (%T)", v15, v15) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated Any enum = 16; - v16 := compiler.MapValueForKey(m, "enum") - if v16 != nil { - // repeated Any - x.Enum = make([]*Any, 0) - a, ok := v16.([]interface{}) - if ok { - for _, item := range a { - y, err := NewAny(item, compiler.NewContext("enum", context)) - if err != nil { - errors = append(errors, err) - } - x.Enum = append(x.Enum, y) - } - } - } - // float multiple_of = 17; - v17 := compiler.MapValueForKey(m, "multipleOf") - if v17 != nil { - switch v17 := v17.(type) { - case float64: - x.MultipleOf = v17 - case float32: - x.MultipleOf = float64(v17) - case uint64: - x.MultipleOf = float64(v17) - case uint32: - x.MultipleOf = float64(v17) - case int64: - x.MultipleOf = float64(v17) - case int32: - x.MultipleOf = float64(v17) - case int: - x.MultipleOf = float64(v17) - default: - message := fmt.Sprintf("has unexpected value for multipleOf: %+v (%T)", v17, v17) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 18; - v18 := compiler.MapValueForKey(m, "description") - if v18 != nil { - x.Description, ok = v18.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v18, v18) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 19; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewHeaderParameterSubSchema creates an object of type HeaderParameterSubSchema if possible, returning an error if not. -func NewHeaderParameterSubSchema(in interface{}, context *compiler.Context) (*HeaderParameterSubSchema, error) { - errors := make([]error, 0) - x := &HeaderParameterSubSchema{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"collectionFormat", "default", "description", "enum", "exclusiveMaximum", "exclusiveMinimum", "format", "in", "items", "maxItems", "maxLength", "maximum", "minItems", "minLength", "minimum", "multipleOf", "name", "pattern", "required", "type", "uniqueItems"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // bool required = 1; - v1 := compiler.MapValueForKey(m, "required") - if v1 != nil { - x.Required, ok = v1.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for required: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string in = 2; - v2 := compiler.MapValueForKey(m, "in") - if v2 != nil { - x.In, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for in: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [header] - if ok && !compiler.StringArrayContainsValue([]string{"header"}, x.In) { - message := fmt.Sprintf("has unexpected value for in: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 3; - v3 := compiler.MapValueForKey(m, "description") - if v3 != nil { - x.Description, ok = v3.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string name = 4; - v4 := compiler.MapValueForKey(m, "name") - if v4 != nil { - x.Name, ok = v4.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string type = 5; - v5 := compiler.MapValueForKey(m, "type") - if v5 != nil { - x.Type, ok = v5.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v5, v5) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [string number boolean integer array] - if ok && !compiler.StringArrayContainsValue([]string{"string", "number", "boolean", "integer", "array"}, x.Type) { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v5, v5) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string format = 6; - v6 := compiler.MapValueForKey(m, "format") - if v6 != nil { - x.Format, ok = v6.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for format: %+v (%T)", v6, v6) - errors = append(errors, compiler.NewError(context, message)) - } - } - // PrimitivesItems items = 7; - v7 := compiler.MapValueForKey(m, "items") - if v7 != nil { - var err error - x.Items, err = NewPrimitivesItems(v7, compiler.NewContext("items", context)) - if err != nil { - errors = append(errors, err) - } - } - // string collection_format = 8; - v8 := compiler.MapValueForKey(m, "collectionFormat") - if v8 != nil { - x.CollectionFormat, ok = v8.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for collectionFormat: %+v (%T)", v8, v8) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [csv ssv tsv pipes] - if ok && !compiler.StringArrayContainsValue([]string{"csv", "ssv", "tsv", "pipes"}, x.CollectionFormat) { - message := fmt.Sprintf("has unexpected value for collectionFormat: %+v (%T)", v8, v8) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Any default = 9; - v9 := compiler.MapValueForKey(m, "default") - if v9 != nil { - var err error - x.Default, err = NewAny(v9, compiler.NewContext("default", context)) - if err != nil { - errors = append(errors, err) - } - } - // float maximum = 10; - v10 := compiler.MapValueForKey(m, "maximum") - if v10 != nil { - switch v10 := v10.(type) { - case float64: - x.Maximum = v10 - case float32: - x.Maximum = float64(v10) - case uint64: - x.Maximum = float64(v10) - case uint32: - x.Maximum = float64(v10) - case int64: - x.Maximum = float64(v10) - case int32: - x.Maximum = float64(v10) - case int: - x.Maximum = float64(v10) - default: - message := fmt.Sprintf("has unexpected value for maximum: %+v (%T)", v10, v10) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool exclusive_maximum = 11; - v11 := compiler.MapValueForKey(m, "exclusiveMaximum") - if v11 != nil { - x.ExclusiveMaximum, ok = v11.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for exclusiveMaximum: %+v (%T)", v11, v11) - errors = append(errors, compiler.NewError(context, message)) - } - } - // float minimum = 12; - v12 := compiler.MapValueForKey(m, "minimum") - if v12 != nil { - switch v12 := v12.(type) { - case float64: - x.Minimum = v12 - case float32: - x.Minimum = float64(v12) - case uint64: - x.Minimum = float64(v12) - case uint32: - x.Minimum = float64(v12) - case int64: - x.Minimum = float64(v12) - case int32: - x.Minimum = float64(v12) - case int: - x.Minimum = float64(v12) - default: - message := fmt.Sprintf("has unexpected value for minimum: %+v (%T)", v12, v12) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool exclusive_minimum = 13; - v13 := compiler.MapValueForKey(m, "exclusiveMinimum") - if v13 != nil { - x.ExclusiveMinimum, ok = v13.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for exclusiveMinimum: %+v (%T)", v13, v13) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_length = 14; - v14 := compiler.MapValueForKey(m, "maxLength") - if v14 != nil { - t, ok := v14.(int) - if ok { - x.MaxLength = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxLength: %+v (%T)", v14, v14) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_length = 15; - v15 := compiler.MapValueForKey(m, "minLength") - if v15 != nil { - t, ok := v15.(int) - if ok { - x.MinLength = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minLength: %+v (%T)", v15, v15) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string pattern = 16; - v16 := compiler.MapValueForKey(m, "pattern") - if v16 != nil { - x.Pattern, ok = v16.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for pattern: %+v (%T)", v16, v16) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_items = 17; - v17 := compiler.MapValueForKey(m, "maxItems") - if v17 != nil { - t, ok := v17.(int) - if ok { - x.MaxItems = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxItems: %+v (%T)", v17, v17) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_items = 18; - v18 := compiler.MapValueForKey(m, "minItems") - if v18 != nil { - t, ok := v18.(int) - if ok { - x.MinItems = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minItems: %+v (%T)", v18, v18) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool unique_items = 19; - v19 := compiler.MapValueForKey(m, "uniqueItems") - if v19 != nil { - x.UniqueItems, ok = v19.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for uniqueItems: %+v (%T)", v19, v19) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated Any enum = 20; - v20 := compiler.MapValueForKey(m, "enum") - if v20 != nil { - // repeated Any - x.Enum = make([]*Any, 0) - a, ok := v20.([]interface{}) - if ok { - for _, item := range a { - y, err := NewAny(item, compiler.NewContext("enum", context)) - if err != nil { - errors = append(errors, err) - } - x.Enum = append(x.Enum, y) - } - } - } - // float multiple_of = 21; - v21 := compiler.MapValueForKey(m, "multipleOf") - if v21 != nil { - switch v21 := v21.(type) { - case float64: - x.MultipleOf = v21 - case float32: - x.MultipleOf = float64(v21) - case uint64: - x.MultipleOf = float64(v21) - case uint32: - x.MultipleOf = float64(v21) - case int64: - x.MultipleOf = float64(v21) - case int32: - x.MultipleOf = float64(v21) - case int: - x.MultipleOf = float64(v21) - default: - message := fmt.Sprintf("has unexpected value for multipleOf: %+v (%T)", v21, v21) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 22; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewHeaders creates an object of type Headers if possible, returning an error if not. -func NewHeaders(in interface{}, context *compiler.Context) (*Headers, error) { - errors := make([]error, 0) - x := &Headers{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - // repeated NamedHeader additional_properties = 1; - // MAP: Header - x.AdditionalProperties = make([]*NamedHeader, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - pair := &NamedHeader{} - pair.Name = k - var err error - pair.Value, err = NewHeader(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - x.AdditionalProperties = append(x.AdditionalProperties, pair) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewInfo creates an object of type Info if possible, returning an error if not. -func NewInfo(in interface{}, context *compiler.Context) (*Info, error) { - errors := make([]error, 0) - x := &Info{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"title", "version"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"contact", "description", "license", "termsOfService", "title", "version"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string title = 1; - v1 := compiler.MapValueForKey(m, "title") - if v1 != nil { - x.Title, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for title: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string version = 2; - v2 := compiler.MapValueForKey(m, "version") - if v2 != nil { - x.Version, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for version: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 3; - v3 := compiler.MapValueForKey(m, "description") - if v3 != nil { - x.Description, ok = v3.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string terms_of_service = 4; - v4 := compiler.MapValueForKey(m, "termsOfService") - if v4 != nil { - x.TermsOfService, ok = v4.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for termsOfService: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Contact contact = 5; - v5 := compiler.MapValueForKey(m, "contact") - if v5 != nil { - var err error - x.Contact, err = NewContact(v5, compiler.NewContext("contact", context)) - if err != nil { - errors = append(errors, err) - } - } - // License license = 6; - v6 := compiler.MapValueForKey(m, "license") - if v6 != nil { - var err error - x.License, err = NewLicense(v6, compiler.NewContext("license", context)) - if err != nil { - errors = append(errors, err) - } - } - // repeated NamedAny vendor_extension = 7; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewItemsItem creates an object of type ItemsItem if possible, returning an error if not. -func NewItemsItem(in interface{}, context *compiler.Context) (*ItemsItem, error) { - errors := make([]error, 0) - x := &ItemsItem{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value for item array: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - x.Schema = make([]*Schema, 0) - y, err := NewSchema(m, compiler.NewContext("", context)) - if err != nil { - return nil, err - } - x.Schema = append(x.Schema, y) - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewJsonReference creates an object of type JsonReference if possible, returning an error if not. -func NewJsonReference(in interface{}, context *compiler.Context) (*JsonReference, error) { - errors := make([]error, 0) - x := &JsonReference{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"$ref"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"$ref", "description"} - var allowedPatterns []*regexp.Regexp - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string _ref = 1; - v1 := compiler.MapValueForKey(m, "$ref") - if v1 != nil { - x.XRef, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for $ref: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 2; - v2 := compiler.MapValueForKey(m, "description") - if v2 != nil { - x.Description, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewLicense creates an object of type License if possible, returning an error if not. -func NewLicense(in interface{}, context *compiler.Context) (*License, error) { - errors := make([]error, 0) - x := &License{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"name"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"name", "url"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string name = 1; - v1 := compiler.MapValueForKey(m, "name") - if v1 != nil { - x.Name, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string url = 2; - v2 := compiler.MapValueForKey(m, "url") - if v2 != nil { - x.Url, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for url: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 3; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewNamedAny creates an object of type NamedAny if possible, returning an error if not. -func NewNamedAny(in interface{}, context *compiler.Context) (*NamedAny, error) { - errors := make([]error, 0) - x := &NamedAny{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"name", "value"} - var allowedPatterns []*regexp.Regexp - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string name = 1; - v1 := compiler.MapValueForKey(m, "name") - if v1 != nil { - x.Name, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Any value = 2; - v2 := compiler.MapValueForKey(m, "value") - if v2 != nil { - var err error - x.Value, err = NewAny(v2, compiler.NewContext("value", context)) - if err != nil { - errors = append(errors, err) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewNamedHeader creates an object of type NamedHeader if possible, returning an error if not. -func NewNamedHeader(in interface{}, context *compiler.Context) (*NamedHeader, error) { - errors := make([]error, 0) - x := &NamedHeader{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"name", "value"} - var allowedPatterns []*regexp.Regexp - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string name = 1; - v1 := compiler.MapValueForKey(m, "name") - if v1 != nil { - x.Name, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Header value = 2; - v2 := compiler.MapValueForKey(m, "value") - if v2 != nil { - var err error - x.Value, err = NewHeader(v2, compiler.NewContext("value", context)) - if err != nil { - errors = append(errors, err) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewNamedParameter creates an object of type NamedParameter if possible, returning an error if not. -func NewNamedParameter(in interface{}, context *compiler.Context) (*NamedParameter, error) { - errors := make([]error, 0) - x := &NamedParameter{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"name", "value"} - var allowedPatterns []*regexp.Regexp - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string name = 1; - v1 := compiler.MapValueForKey(m, "name") - if v1 != nil { - x.Name, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Parameter value = 2; - v2 := compiler.MapValueForKey(m, "value") - if v2 != nil { - var err error - x.Value, err = NewParameter(v2, compiler.NewContext("value", context)) - if err != nil { - errors = append(errors, err) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewNamedPathItem creates an object of type NamedPathItem if possible, returning an error if not. -func NewNamedPathItem(in interface{}, context *compiler.Context) (*NamedPathItem, error) { - errors := make([]error, 0) - x := &NamedPathItem{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"name", "value"} - var allowedPatterns []*regexp.Regexp - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string name = 1; - v1 := compiler.MapValueForKey(m, "name") - if v1 != nil { - x.Name, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // PathItem value = 2; - v2 := compiler.MapValueForKey(m, "value") - if v2 != nil { - var err error - x.Value, err = NewPathItem(v2, compiler.NewContext("value", context)) - if err != nil { - errors = append(errors, err) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewNamedResponse creates an object of type NamedResponse if possible, returning an error if not. -func NewNamedResponse(in interface{}, context *compiler.Context) (*NamedResponse, error) { - errors := make([]error, 0) - x := &NamedResponse{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"name", "value"} - var allowedPatterns []*regexp.Regexp - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string name = 1; - v1 := compiler.MapValueForKey(m, "name") - if v1 != nil { - x.Name, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Response value = 2; - v2 := compiler.MapValueForKey(m, "value") - if v2 != nil { - var err error - x.Value, err = NewResponse(v2, compiler.NewContext("value", context)) - if err != nil { - errors = append(errors, err) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewNamedResponseValue creates an object of type NamedResponseValue if possible, returning an error if not. -func NewNamedResponseValue(in interface{}, context *compiler.Context) (*NamedResponseValue, error) { - errors := make([]error, 0) - x := &NamedResponseValue{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"name", "value"} - var allowedPatterns []*regexp.Regexp - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string name = 1; - v1 := compiler.MapValueForKey(m, "name") - if v1 != nil { - x.Name, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // ResponseValue value = 2; - v2 := compiler.MapValueForKey(m, "value") - if v2 != nil { - var err error - x.Value, err = NewResponseValue(v2, compiler.NewContext("value", context)) - if err != nil { - errors = append(errors, err) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewNamedSchema creates an object of type NamedSchema if possible, returning an error if not. -func NewNamedSchema(in interface{}, context *compiler.Context) (*NamedSchema, error) { - errors := make([]error, 0) - x := &NamedSchema{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"name", "value"} - var allowedPatterns []*regexp.Regexp - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string name = 1; - v1 := compiler.MapValueForKey(m, "name") - if v1 != nil { - x.Name, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Schema value = 2; - v2 := compiler.MapValueForKey(m, "value") - if v2 != nil { - var err error - x.Value, err = NewSchema(v2, compiler.NewContext("value", context)) - if err != nil { - errors = append(errors, err) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewNamedSecurityDefinitionsItem creates an object of type NamedSecurityDefinitionsItem if possible, returning an error if not. -func NewNamedSecurityDefinitionsItem(in interface{}, context *compiler.Context) (*NamedSecurityDefinitionsItem, error) { - errors := make([]error, 0) - x := &NamedSecurityDefinitionsItem{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"name", "value"} - var allowedPatterns []*regexp.Regexp - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string name = 1; - v1 := compiler.MapValueForKey(m, "name") - if v1 != nil { - x.Name, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // SecurityDefinitionsItem value = 2; - v2 := compiler.MapValueForKey(m, "value") - if v2 != nil { - var err error - x.Value, err = NewSecurityDefinitionsItem(v2, compiler.NewContext("value", context)) - if err != nil { - errors = append(errors, err) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewNamedString creates an object of type NamedString if possible, returning an error if not. -func NewNamedString(in interface{}, context *compiler.Context) (*NamedString, error) { - errors := make([]error, 0) - x := &NamedString{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"name", "value"} - var allowedPatterns []*regexp.Regexp - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string name = 1; - v1 := compiler.MapValueForKey(m, "name") - if v1 != nil { - x.Name, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string value = 2; - v2 := compiler.MapValueForKey(m, "value") - if v2 != nil { - x.Value, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for value: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewNamedStringArray creates an object of type NamedStringArray if possible, returning an error if not. -func NewNamedStringArray(in interface{}, context *compiler.Context) (*NamedStringArray, error) { - errors := make([]error, 0) - x := &NamedStringArray{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"name", "value"} - var allowedPatterns []*regexp.Regexp - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string name = 1; - v1 := compiler.MapValueForKey(m, "name") - if v1 != nil { - x.Name, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // StringArray value = 2; - v2 := compiler.MapValueForKey(m, "value") - if v2 != nil { - var err error - x.Value, err = NewStringArray(v2, compiler.NewContext("value", context)) - if err != nil { - errors = append(errors, err) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewNonBodyParameter creates an object of type NonBodyParameter if possible, returning an error if not. -func NewNonBodyParameter(in interface{}, context *compiler.Context) (*NonBodyParameter, error) { - errors := make([]error, 0) - x := &NonBodyParameter{} - matched := false - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"in", "name", "type"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // HeaderParameterSubSchema header_parameter_sub_schema = 1; - { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewHeaderParameterSubSchema(m, compiler.NewContext("headerParameterSubSchema", context)) - if matchingError == nil { - x.Oneof = &NonBodyParameter_HeaderParameterSubSchema{HeaderParameterSubSchema: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - // FormDataParameterSubSchema form_data_parameter_sub_schema = 2; - { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewFormDataParameterSubSchema(m, compiler.NewContext("formDataParameterSubSchema", context)) - if matchingError == nil { - x.Oneof = &NonBodyParameter_FormDataParameterSubSchema{FormDataParameterSubSchema: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - // QueryParameterSubSchema query_parameter_sub_schema = 3; - { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewQueryParameterSubSchema(m, compiler.NewContext("queryParameterSubSchema", context)) - if matchingError == nil { - x.Oneof = &NonBodyParameter_QueryParameterSubSchema{QueryParameterSubSchema: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - // PathParameterSubSchema path_parameter_sub_schema = 4; - { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewPathParameterSubSchema(m, compiler.NewContext("pathParameterSubSchema", context)) - if matchingError == nil { - x.Oneof = &NonBodyParameter_PathParameterSubSchema{PathParameterSubSchema: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - if matched { - // since the oneof matched one of its possibilities, discard any matching errors - errors = make([]error, 0) - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewOauth2AccessCodeSecurity creates an object of type Oauth2AccessCodeSecurity if possible, returning an error if not. -func NewOauth2AccessCodeSecurity(in interface{}, context *compiler.Context) (*Oauth2AccessCodeSecurity, error) { - errors := make([]error, 0) - x := &Oauth2AccessCodeSecurity{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"authorizationUrl", "flow", "tokenUrl", "type"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"authorizationUrl", "description", "flow", "scopes", "tokenUrl", "type"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string type = 1; - v1 := compiler.MapValueForKey(m, "type") - if v1 != nil { - x.Type, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [oauth2] - if ok && !compiler.StringArrayContainsValue([]string{"oauth2"}, x.Type) { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string flow = 2; - v2 := compiler.MapValueForKey(m, "flow") - if v2 != nil { - x.Flow, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for flow: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [accessCode] - if ok && !compiler.StringArrayContainsValue([]string{"accessCode"}, x.Flow) { - message := fmt.Sprintf("has unexpected value for flow: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Oauth2Scopes scopes = 3; - v3 := compiler.MapValueForKey(m, "scopes") - if v3 != nil { - var err error - x.Scopes, err = NewOauth2Scopes(v3, compiler.NewContext("scopes", context)) - if err != nil { - errors = append(errors, err) - } - } - // string authorization_url = 4; - v4 := compiler.MapValueForKey(m, "authorizationUrl") - if v4 != nil { - x.AuthorizationUrl, ok = v4.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for authorizationUrl: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string token_url = 5; - v5 := compiler.MapValueForKey(m, "tokenUrl") - if v5 != nil { - x.TokenUrl, ok = v5.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for tokenUrl: %+v (%T)", v5, v5) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 6; - v6 := compiler.MapValueForKey(m, "description") - if v6 != nil { - x.Description, ok = v6.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v6, v6) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 7; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewOauth2ApplicationSecurity creates an object of type Oauth2ApplicationSecurity if possible, returning an error if not. -func NewOauth2ApplicationSecurity(in interface{}, context *compiler.Context) (*Oauth2ApplicationSecurity, error) { - errors := make([]error, 0) - x := &Oauth2ApplicationSecurity{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"flow", "tokenUrl", "type"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"description", "flow", "scopes", "tokenUrl", "type"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string type = 1; - v1 := compiler.MapValueForKey(m, "type") - if v1 != nil { - x.Type, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [oauth2] - if ok && !compiler.StringArrayContainsValue([]string{"oauth2"}, x.Type) { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string flow = 2; - v2 := compiler.MapValueForKey(m, "flow") - if v2 != nil { - x.Flow, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for flow: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [application] - if ok && !compiler.StringArrayContainsValue([]string{"application"}, x.Flow) { - message := fmt.Sprintf("has unexpected value for flow: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Oauth2Scopes scopes = 3; - v3 := compiler.MapValueForKey(m, "scopes") - if v3 != nil { - var err error - x.Scopes, err = NewOauth2Scopes(v3, compiler.NewContext("scopes", context)) - if err != nil { - errors = append(errors, err) - } - } - // string token_url = 4; - v4 := compiler.MapValueForKey(m, "tokenUrl") - if v4 != nil { - x.TokenUrl, ok = v4.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for tokenUrl: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 5; - v5 := compiler.MapValueForKey(m, "description") - if v5 != nil { - x.Description, ok = v5.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v5, v5) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 6; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewOauth2ImplicitSecurity creates an object of type Oauth2ImplicitSecurity if possible, returning an error if not. -func NewOauth2ImplicitSecurity(in interface{}, context *compiler.Context) (*Oauth2ImplicitSecurity, error) { - errors := make([]error, 0) - x := &Oauth2ImplicitSecurity{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"authorizationUrl", "flow", "type"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"authorizationUrl", "description", "flow", "scopes", "type"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string type = 1; - v1 := compiler.MapValueForKey(m, "type") - if v1 != nil { - x.Type, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [oauth2] - if ok && !compiler.StringArrayContainsValue([]string{"oauth2"}, x.Type) { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string flow = 2; - v2 := compiler.MapValueForKey(m, "flow") - if v2 != nil { - x.Flow, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for flow: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [implicit] - if ok && !compiler.StringArrayContainsValue([]string{"implicit"}, x.Flow) { - message := fmt.Sprintf("has unexpected value for flow: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Oauth2Scopes scopes = 3; - v3 := compiler.MapValueForKey(m, "scopes") - if v3 != nil { - var err error - x.Scopes, err = NewOauth2Scopes(v3, compiler.NewContext("scopes", context)) - if err != nil { - errors = append(errors, err) - } - } - // string authorization_url = 4; - v4 := compiler.MapValueForKey(m, "authorizationUrl") - if v4 != nil { - x.AuthorizationUrl, ok = v4.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for authorizationUrl: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 5; - v5 := compiler.MapValueForKey(m, "description") - if v5 != nil { - x.Description, ok = v5.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v5, v5) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 6; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewOauth2PasswordSecurity creates an object of type Oauth2PasswordSecurity if possible, returning an error if not. -func NewOauth2PasswordSecurity(in interface{}, context *compiler.Context) (*Oauth2PasswordSecurity, error) { - errors := make([]error, 0) - x := &Oauth2PasswordSecurity{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"flow", "tokenUrl", "type"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"description", "flow", "scopes", "tokenUrl", "type"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string type = 1; - v1 := compiler.MapValueForKey(m, "type") - if v1 != nil { - x.Type, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [oauth2] - if ok && !compiler.StringArrayContainsValue([]string{"oauth2"}, x.Type) { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string flow = 2; - v2 := compiler.MapValueForKey(m, "flow") - if v2 != nil { - x.Flow, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for flow: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [password] - if ok && !compiler.StringArrayContainsValue([]string{"password"}, x.Flow) { - message := fmt.Sprintf("has unexpected value for flow: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Oauth2Scopes scopes = 3; - v3 := compiler.MapValueForKey(m, "scopes") - if v3 != nil { - var err error - x.Scopes, err = NewOauth2Scopes(v3, compiler.NewContext("scopes", context)) - if err != nil { - errors = append(errors, err) - } - } - // string token_url = 4; - v4 := compiler.MapValueForKey(m, "tokenUrl") - if v4 != nil { - x.TokenUrl, ok = v4.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for tokenUrl: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 5; - v5 := compiler.MapValueForKey(m, "description") - if v5 != nil { - x.Description, ok = v5.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v5, v5) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 6; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewOauth2Scopes creates an object of type Oauth2Scopes if possible, returning an error if not. -func NewOauth2Scopes(in interface{}, context *compiler.Context) (*Oauth2Scopes, error) { - errors := make([]error, 0) - x := &Oauth2Scopes{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - // repeated NamedString additional_properties = 1; - // MAP: string - x.AdditionalProperties = make([]*NamedString, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - pair := &NamedString{} - pair.Name = k - pair.Value = v.(string) - x.AdditionalProperties = append(x.AdditionalProperties, pair) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewOperation creates an object of type Operation if possible, returning an error if not. -func NewOperation(in interface{}, context *compiler.Context) (*Operation, error) { - errors := make([]error, 0) - x := &Operation{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"responses"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"consumes", "deprecated", "description", "externalDocs", "operationId", "parameters", "produces", "responses", "schemes", "security", "summary", "tags"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // repeated string tags = 1; - v1 := compiler.MapValueForKey(m, "tags") - if v1 != nil { - v, ok := v1.([]interface{}) - if ok { - x.Tags = compiler.ConvertInterfaceArrayToStringArray(v) - } else { - message := fmt.Sprintf("has unexpected value for tags: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string summary = 2; - v2 := compiler.MapValueForKey(m, "summary") - if v2 != nil { - x.Summary, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for summary: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 3; - v3 := compiler.MapValueForKey(m, "description") - if v3 != nil { - x.Description, ok = v3.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - } - // ExternalDocs external_docs = 4; - v4 := compiler.MapValueForKey(m, "externalDocs") - if v4 != nil { - var err error - x.ExternalDocs, err = NewExternalDocs(v4, compiler.NewContext("externalDocs", context)) - if err != nil { - errors = append(errors, err) - } - } - // string operation_id = 5; - v5 := compiler.MapValueForKey(m, "operationId") - if v5 != nil { - x.OperationId, ok = v5.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for operationId: %+v (%T)", v5, v5) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated string produces = 6; - v6 := compiler.MapValueForKey(m, "produces") - if v6 != nil { - v, ok := v6.([]interface{}) - if ok { - x.Produces = compiler.ConvertInterfaceArrayToStringArray(v) - } else { - message := fmt.Sprintf("has unexpected value for produces: %+v (%T)", v6, v6) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated string consumes = 7; - v7 := compiler.MapValueForKey(m, "consumes") - if v7 != nil { - v, ok := v7.([]interface{}) - if ok { - x.Consumes = compiler.ConvertInterfaceArrayToStringArray(v) - } else { - message := fmt.Sprintf("has unexpected value for consumes: %+v (%T)", v7, v7) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated ParametersItem parameters = 8; - v8 := compiler.MapValueForKey(m, "parameters") - if v8 != nil { - // repeated ParametersItem - x.Parameters = make([]*ParametersItem, 0) - a, ok := v8.([]interface{}) - if ok { - for _, item := range a { - y, err := NewParametersItem(item, compiler.NewContext("parameters", context)) - if err != nil { - errors = append(errors, err) - } - x.Parameters = append(x.Parameters, y) - } - } - } - // Responses responses = 9; - v9 := compiler.MapValueForKey(m, "responses") - if v9 != nil { - var err error - x.Responses, err = NewResponses(v9, compiler.NewContext("responses", context)) - if err != nil { - errors = append(errors, err) - } - } - // repeated string schemes = 10; - v10 := compiler.MapValueForKey(m, "schemes") - if v10 != nil { - v, ok := v10.([]interface{}) - if ok { - x.Schemes = compiler.ConvertInterfaceArrayToStringArray(v) - } else { - message := fmt.Sprintf("has unexpected value for schemes: %+v (%T)", v10, v10) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [http https ws wss] - if ok && !compiler.StringArrayContainsValues([]string{"http", "https", "ws", "wss"}, x.Schemes) { - message := fmt.Sprintf("has unexpected value for schemes: %+v", v10) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool deprecated = 11; - v11 := compiler.MapValueForKey(m, "deprecated") - if v11 != nil { - x.Deprecated, ok = v11.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for deprecated: %+v (%T)", v11, v11) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated SecurityRequirement security = 12; - v12 := compiler.MapValueForKey(m, "security") - if v12 != nil { - // repeated SecurityRequirement - x.Security = make([]*SecurityRequirement, 0) - a, ok := v12.([]interface{}) - if ok { - for _, item := range a { - y, err := NewSecurityRequirement(item, compiler.NewContext("security", context)) - if err != nil { - errors = append(errors, err) - } - x.Security = append(x.Security, y) - } - } - } - // repeated NamedAny vendor_extension = 13; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewParameter creates an object of type Parameter if possible, returning an error if not. -func NewParameter(in interface{}, context *compiler.Context) (*Parameter, error) { - errors := make([]error, 0) - x := &Parameter{} - matched := false - // BodyParameter body_parameter = 1; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewBodyParameter(m, compiler.NewContext("bodyParameter", context)) - if matchingError == nil { - x.Oneof = &Parameter_BodyParameter{BodyParameter: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - // NonBodyParameter non_body_parameter = 2; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewNonBodyParameter(m, compiler.NewContext("nonBodyParameter", context)) - if matchingError == nil { - x.Oneof = &Parameter_NonBodyParameter{NonBodyParameter: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - if matched { - // since the oneof matched one of its possibilities, discard any matching errors - errors = make([]error, 0) - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewParameterDefinitions creates an object of type ParameterDefinitions if possible, returning an error if not. -func NewParameterDefinitions(in interface{}, context *compiler.Context) (*ParameterDefinitions, error) { - errors := make([]error, 0) - x := &ParameterDefinitions{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - // repeated NamedParameter additional_properties = 1; - // MAP: Parameter - x.AdditionalProperties = make([]*NamedParameter, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - pair := &NamedParameter{} - pair.Name = k - var err error - pair.Value, err = NewParameter(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - x.AdditionalProperties = append(x.AdditionalProperties, pair) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewParametersItem creates an object of type ParametersItem if possible, returning an error if not. -func NewParametersItem(in interface{}, context *compiler.Context) (*ParametersItem, error) { - errors := make([]error, 0) - x := &ParametersItem{} - matched := false - // Parameter parameter = 1; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewParameter(m, compiler.NewContext("parameter", context)) - if matchingError == nil { - x.Oneof = &ParametersItem_Parameter{Parameter: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - // JsonReference json_reference = 2; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewJsonReference(m, compiler.NewContext("jsonReference", context)) - if matchingError == nil { - x.Oneof = &ParametersItem_JsonReference{JsonReference: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - if matched { - // since the oneof matched one of its possibilities, discard any matching errors - errors = make([]error, 0) - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewPathItem creates an object of type PathItem if possible, returning an error if not. -func NewPathItem(in interface{}, context *compiler.Context) (*PathItem, error) { - errors := make([]error, 0) - x := &PathItem{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"$ref", "delete", "get", "head", "options", "parameters", "patch", "post", "put"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string _ref = 1; - v1 := compiler.MapValueForKey(m, "$ref") - if v1 != nil { - x.XRef, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for $ref: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Operation get = 2; - v2 := compiler.MapValueForKey(m, "get") - if v2 != nil { - var err error - x.Get, err = NewOperation(v2, compiler.NewContext("get", context)) - if err != nil { - errors = append(errors, err) - } - } - // Operation put = 3; - v3 := compiler.MapValueForKey(m, "put") - if v3 != nil { - var err error - x.Put, err = NewOperation(v3, compiler.NewContext("put", context)) - if err != nil { - errors = append(errors, err) - } - } - // Operation post = 4; - v4 := compiler.MapValueForKey(m, "post") - if v4 != nil { - var err error - x.Post, err = NewOperation(v4, compiler.NewContext("post", context)) - if err != nil { - errors = append(errors, err) - } - } - // Operation delete = 5; - v5 := compiler.MapValueForKey(m, "delete") - if v5 != nil { - var err error - x.Delete, err = NewOperation(v5, compiler.NewContext("delete", context)) - if err != nil { - errors = append(errors, err) - } - } - // Operation options = 6; - v6 := compiler.MapValueForKey(m, "options") - if v6 != nil { - var err error - x.Options, err = NewOperation(v6, compiler.NewContext("options", context)) - if err != nil { - errors = append(errors, err) - } - } - // Operation head = 7; - v7 := compiler.MapValueForKey(m, "head") - if v7 != nil { - var err error - x.Head, err = NewOperation(v7, compiler.NewContext("head", context)) - if err != nil { - errors = append(errors, err) - } - } - // Operation patch = 8; - v8 := compiler.MapValueForKey(m, "patch") - if v8 != nil { - var err error - x.Patch, err = NewOperation(v8, compiler.NewContext("patch", context)) - if err != nil { - errors = append(errors, err) - } - } - // repeated ParametersItem parameters = 9; - v9 := compiler.MapValueForKey(m, "parameters") - if v9 != nil { - // repeated ParametersItem - x.Parameters = make([]*ParametersItem, 0) - a, ok := v9.([]interface{}) - if ok { - for _, item := range a { - y, err := NewParametersItem(item, compiler.NewContext("parameters", context)) - if err != nil { - errors = append(errors, err) - } - x.Parameters = append(x.Parameters, y) - } - } - } - // repeated NamedAny vendor_extension = 10; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewPathParameterSubSchema creates an object of type PathParameterSubSchema if possible, returning an error if not. -func NewPathParameterSubSchema(in interface{}, context *compiler.Context) (*PathParameterSubSchema, error) { - errors := make([]error, 0) - x := &PathParameterSubSchema{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"required"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"collectionFormat", "default", "description", "enum", "exclusiveMaximum", "exclusiveMinimum", "format", "in", "items", "maxItems", "maxLength", "maximum", "minItems", "minLength", "minimum", "multipleOf", "name", "pattern", "required", "type", "uniqueItems"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // bool required = 1; - v1 := compiler.MapValueForKey(m, "required") - if v1 != nil { - x.Required, ok = v1.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for required: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string in = 2; - v2 := compiler.MapValueForKey(m, "in") - if v2 != nil { - x.In, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for in: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [path] - if ok && !compiler.StringArrayContainsValue([]string{"path"}, x.In) { - message := fmt.Sprintf("has unexpected value for in: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 3; - v3 := compiler.MapValueForKey(m, "description") - if v3 != nil { - x.Description, ok = v3.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string name = 4; - v4 := compiler.MapValueForKey(m, "name") - if v4 != nil { - x.Name, ok = v4.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string type = 5; - v5 := compiler.MapValueForKey(m, "type") - if v5 != nil { - x.Type, ok = v5.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v5, v5) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [string number boolean integer array] - if ok && !compiler.StringArrayContainsValue([]string{"string", "number", "boolean", "integer", "array"}, x.Type) { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v5, v5) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string format = 6; - v6 := compiler.MapValueForKey(m, "format") - if v6 != nil { - x.Format, ok = v6.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for format: %+v (%T)", v6, v6) - errors = append(errors, compiler.NewError(context, message)) - } - } - // PrimitivesItems items = 7; - v7 := compiler.MapValueForKey(m, "items") - if v7 != nil { - var err error - x.Items, err = NewPrimitivesItems(v7, compiler.NewContext("items", context)) - if err != nil { - errors = append(errors, err) - } - } - // string collection_format = 8; - v8 := compiler.MapValueForKey(m, "collectionFormat") - if v8 != nil { - x.CollectionFormat, ok = v8.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for collectionFormat: %+v (%T)", v8, v8) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [csv ssv tsv pipes] - if ok && !compiler.StringArrayContainsValue([]string{"csv", "ssv", "tsv", "pipes"}, x.CollectionFormat) { - message := fmt.Sprintf("has unexpected value for collectionFormat: %+v (%T)", v8, v8) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Any default = 9; - v9 := compiler.MapValueForKey(m, "default") - if v9 != nil { - var err error - x.Default, err = NewAny(v9, compiler.NewContext("default", context)) - if err != nil { - errors = append(errors, err) - } - } - // float maximum = 10; - v10 := compiler.MapValueForKey(m, "maximum") - if v10 != nil { - switch v10 := v10.(type) { - case float64: - x.Maximum = v10 - case float32: - x.Maximum = float64(v10) - case uint64: - x.Maximum = float64(v10) - case uint32: - x.Maximum = float64(v10) - case int64: - x.Maximum = float64(v10) - case int32: - x.Maximum = float64(v10) - case int: - x.Maximum = float64(v10) - default: - message := fmt.Sprintf("has unexpected value for maximum: %+v (%T)", v10, v10) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool exclusive_maximum = 11; - v11 := compiler.MapValueForKey(m, "exclusiveMaximum") - if v11 != nil { - x.ExclusiveMaximum, ok = v11.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for exclusiveMaximum: %+v (%T)", v11, v11) - errors = append(errors, compiler.NewError(context, message)) - } - } - // float minimum = 12; - v12 := compiler.MapValueForKey(m, "minimum") - if v12 != nil { - switch v12 := v12.(type) { - case float64: - x.Minimum = v12 - case float32: - x.Minimum = float64(v12) - case uint64: - x.Minimum = float64(v12) - case uint32: - x.Minimum = float64(v12) - case int64: - x.Minimum = float64(v12) - case int32: - x.Minimum = float64(v12) - case int: - x.Minimum = float64(v12) - default: - message := fmt.Sprintf("has unexpected value for minimum: %+v (%T)", v12, v12) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool exclusive_minimum = 13; - v13 := compiler.MapValueForKey(m, "exclusiveMinimum") - if v13 != nil { - x.ExclusiveMinimum, ok = v13.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for exclusiveMinimum: %+v (%T)", v13, v13) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_length = 14; - v14 := compiler.MapValueForKey(m, "maxLength") - if v14 != nil { - t, ok := v14.(int) - if ok { - x.MaxLength = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxLength: %+v (%T)", v14, v14) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_length = 15; - v15 := compiler.MapValueForKey(m, "minLength") - if v15 != nil { - t, ok := v15.(int) - if ok { - x.MinLength = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minLength: %+v (%T)", v15, v15) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string pattern = 16; - v16 := compiler.MapValueForKey(m, "pattern") - if v16 != nil { - x.Pattern, ok = v16.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for pattern: %+v (%T)", v16, v16) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_items = 17; - v17 := compiler.MapValueForKey(m, "maxItems") - if v17 != nil { - t, ok := v17.(int) - if ok { - x.MaxItems = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxItems: %+v (%T)", v17, v17) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_items = 18; - v18 := compiler.MapValueForKey(m, "minItems") - if v18 != nil { - t, ok := v18.(int) - if ok { - x.MinItems = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minItems: %+v (%T)", v18, v18) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool unique_items = 19; - v19 := compiler.MapValueForKey(m, "uniqueItems") - if v19 != nil { - x.UniqueItems, ok = v19.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for uniqueItems: %+v (%T)", v19, v19) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated Any enum = 20; - v20 := compiler.MapValueForKey(m, "enum") - if v20 != nil { - // repeated Any - x.Enum = make([]*Any, 0) - a, ok := v20.([]interface{}) - if ok { - for _, item := range a { - y, err := NewAny(item, compiler.NewContext("enum", context)) - if err != nil { - errors = append(errors, err) - } - x.Enum = append(x.Enum, y) - } - } - } - // float multiple_of = 21; - v21 := compiler.MapValueForKey(m, "multipleOf") - if v21 != nil { - switch v21 := v21.(type) { - case float64: - x.MultipleOf = v21 - case float32: - x.MultipleOf = float64(v21) - case uint64: - x.MultipleOf = float64(v21) - case uint32: - x.MultipleOf = float64(v21) - case int64: - x.MultipleOf = float64(v21) - case int32: - x.MultipleOf = float64(v21) - case int: - x.MultipleOf = float64(v21) - default: - message := fmt.Sprintf("has unexpected value for multipleOf: %+v (%T)", v21, v21) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 22; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewPaths creates an object of type Paths if possible, returning an error if not. -func NewPaths(in interface{}, context *compiler.Context) (*Paths, error) { - errors := make([]error, 0) - x := &Paths{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{} - allowedPatterns := []*regexp.Regexp{pattern0, pattern1} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // repeated NamedAny vendor_extension = 1; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - // repeated NamedPathItem path = 2; - // MAP: PathItem ^/ - x.Path = make([]*NamedPathItem, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "/") { - pair := &NamedPathItem{} - pair.Name = k - var err error - pair.Value, err = NewPathItem(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - x.Path = append(x.Path, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewPrimitivesItems creates an object of type PrimitivesItems if possible, returning an error if not. -func NewPrimitivesItems(in interface{}, context *compiler.Context) (*PrimitivesItems, error) { - errors := make([]error, 0) - x := &PrimitivesItems{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"collectionFormat", "default", "enum", "exclusiveMaximum", "exclusiveMinimum", "format", "items", "maxItems", "maxLength", "maximum", "minItems", "minLength", "minimum", "multipleOf", "pattern", "type", "uniqueItems"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string type = 1; - v1 := compiler.MapValueForKey(m, "type") - if v1 != nil { - x.Type, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [string number integer boolean array] - if ok && !compiler.StringArrayContainsValue([]string{"string", "number", "integer", "boolean", "array"}, x.Type) { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string format = 2; - v2 := compiler.MapValueForKey(m, "format") - if v2 != nil { - x.Format, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for format: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // PrimitivesItems items = 3; - v3 := compiler.MapValueForKey(m, "items") - if v3 != nil { - var err error - x.Items, err = NewPrimitivesItems(v3, compiler.NewContext("items", context)) - if err != nil { - errors = append(errors, err) - } - } - // string collection_format = 4; - v4 := compiler.MapValueForKey(m, "collectionFormat") - if v4 != nil { - x.CollectionFormat, ok = v4.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for collectionFormat: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [csv ssv tsv pipes] - if ok && !compiler.StringArrayContainsValue([]string{"csv", "ssv", "tsv", "pipes"}, x.CollectionFormat) { - message := fmt.Sprintf("has unexpected value for collectionFormat: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Any default = 5; - v5 := compiler.MapValueForKey(m, "default") - if v5 != nil { - var err error - x.Default, err = NewAny(v5, compiler.NewContext("default", context)) - if err != nil { - errors = append(errors, err) - } - } - // float maximum = 6; - v6 := compiler.MapValueForKey(m, "maximum") - if v6 != nil { - switch v6 := v6.(type) { - case float64: - x.Maximum = v6 - case float32: - x.Maximum = float64(v6) - case uint64: - x.Maximum = float64(v6) - case uint32: - x.Maximum = float64(v6) - case int64: - x.Maximum = float64(v6) - case int32: - x.Maximum = float64(v6) - case int: - x.Maximum = float64(v6) - default: - message := fmt.Sprintf("has unexpected value for maximum: %+v (%T)", v6, v6) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool exclusive_maximum = 7; - v7 := compiler.MapValueForKey(m, "exclusiveMaximum") - if v7 != nil { - x.ExclusiveMaximum, ok = v7.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for exclusiveMaximum: %+v (%T)", v7, v7) - errors = append(errors, compiler.NewError(context, message)) - } - } - // float minimum = 8; - v8 := compiler.MapValueForKey(m, "minimum") - if v8 != nil { - switch v8 := v8.(type) { - case float64: - x.Minimum = v8 - case float32: - x.Minimum = float64(v8) - case uint64: - x.Minimum = float64(v8) - case uint32: - x.Minimum = float64(v8) - case int64: - x.Minimum = float64(v8) - case int32: - x.Minimum = float64(v8) - case int: - x.Minimum = float64(v8) - default: - message := fmt.Sprintf("has unexpected value for minimum: %+v (%T)", v8, v8) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool exclusive_minimum = 9; - v9 := compiler.MapValueForKey(m, "exclusiveMinimum") - if v9 != nil { - x.ExclusiveMinimum, ok = v9.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for exclusiveMinimum: %+v (%T)", v9, v9) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_length = 10; - v10 := compiler.MapValueForKey(m, "maxLength") - if v10 != nil { - t, ok := v10.(int) - if ok { - x.MaxLength = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxLength: %+v (%T)", v10, v10) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_length = 11; - v11 := compiler.MapValueForKey(m, "minLength") - if v11 != nil { - t, ok := v11.(int) - if ok { - x.MinLength = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minLength: %+v (%T)", v11, v11) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string pattern = 12; - v12 := compiler.MapValueForKey(m, "pattern") - if v12 != nil { - x.Pattern, ok = v12.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for pattern: %+v (%T)", v12, v12) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_items = 13; - v13 := compiler.MapValueForKey(m, "maxItems") - if v13 != nil { - t, ok := v13.(int) - if ok { - x.MaxItems = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxItems: %+v (%T)", v13, v13) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_items = 14; - v14 := compiler.MapValueForKey(m, "minItems") - if v14 != nil { - t, ok := v14.(int) - if ok { - x.MinItems = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minItems: %+v (%T)", v14, v14) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool unique_items = 15; - v15 := compiler.MapValueForKey(m, "uniqueItems") - if v15 != nil { - x.UniqueItems, ok = v15.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for uniqueItems: %+v (%T)", v15, v15) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated Any enum = 16; - v16 := compiler.MapValueForKey(m, "enum") - if v16 != nil { - // repeated Any - x.Enum = make([]*Any, 0) - a, ok := v16.([]interface{}) - if ok { - for _, item := range a { - y, err := NewAny(item, compiler.NewContext("enum", context)) - if err != nil { - errors = append(errors, err) - } - x.Enum = append(x.Enum, y) - } - } - } - // float multiple_of = 17; - v17 := compiler.MapValueForKey(m, "multipleOf") - if v17 != nil { - switch v17 := v17.(type) { - case float64: - x.MultipleOf = v17 - case float32: - x.MultipleOf = float64(v17) - case uint64: - x.MultipleOf = float64(v17) - case uint32: - x.MultipleOf = float64(v17) - case int64: - x.MultipleOf = float64(v17) - case int32: - x.MultipleOf = float64(v17) - case int: - x.MultipleOf = float64(v17) - default: - message := fmt.Sprintf("has unexpected value for multipleOf: %+v (%T)", v17, v17) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 18; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewProperties creates an object of type Properties if possible, returning an error if not. -func NewProperties(in interface{}, context *compiler.Context) (*Properties, error) { - errors := make([]error, 0) - x := &Properties{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - // repeated NamedSchema additional_properties = 1; - // MAP: Schema - x.AdditionalProperties = make([]*NamedSchema, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - pair := &NamedSchema{} - pair.Name = k - var err error - pair.Value, err = NewSchema(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - x.AdditionalProperties = append(x.AdditionalProperties, pair) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewQueryParameterSubSchema creates an object of type QueryParameterSubSchema if possible, returning an error if not. -func NewQueryParameterSubSchema(in interface{}, context *compiler.Context) (*QueryParameterSubSchema, error) { - errors := make([]error, 0) - x := &QueryParameterSubSchema{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"allowEmptyValue", "collectionFormat", "default", "description", "enum", "exclusiveMaximum", "exclusiveMinimum", "format", "in", "items", "maxItems", "maxLength", "maximum", "minItems", "minLength", "minimum", "multipleOf", "name", "pattern", "required", "type", "uniqueItems"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // bool required = 1; - v1 := compiler.MapValueForKey(m, "required") - if v1 != nil { - x.Required, ok = v1.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for required: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string in = 2; - v2 := compiler.MapValueForKey(m, "in") - if v2 != nil { - x.In, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for in: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [query] - if ok && !compiler.StringArrayContainsValue([]string{"query"}, x.In) { - message := fmt.Sprintf("has unexpected value for in: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 3; - v3 := compiler.MapValueForKey(m, "description") - if v3 != nil { - x.Description, ok = v3.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string name = 4; - v4 := compiler.MapValueForKey(m, "name") - if v4 != nil { - x.Name, ok = v4.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool allow_empty_value = 5; - v5 := compiler.MapValueForKey(m, "allowEmptyValue") - if v5 != nil { - x.AllowEmptyValue, ok = v5.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for allowEmptyValue: %+v (%T)", v5, v5) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string type = 6; - v6 := compiler.MapValueForKey(m, "type") - if v6 != nil { - x.Type, ok = v6.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v6, v6) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [string number boolean integer array] - if ok && !compiler.StringArrayContainsValue([]string{"string", "number", "boolean", "integer", "array"}, x.Type) { - message := fmt.Sprintf("has unexpected value for type: %+v (%T)", v6, v6) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string format = 7; - v7 := compiler.MapValueForKey(m, "format") - if v7 != nil { - x.Format, ok = v7.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for format: %+v (%T)", v7, v7) - errors = append(errors, compiler.NewError(context, message)) - } - } - // PrimitivesItems items = 8; - v8 := compiler.MapValueForKey(m, "items") - if v8 != nil { - var err error - x.Items, err = NewPrimitivesItems(v8, compiler.NewContext("items", context)) - if err != nil { - errors = append(errors, err) - } - } - // string collection_format = 9; - v9 := compiler.MapValueForKey(m, "collectionFormat") - if v9 != nil { - x.CollectionFormat, ok = v9.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for collectionFormat: %+v (%T)", v9, v9) - errors = append(errors, compiler.NewError(context, message)) - } - // check for valid enum values - // [csv ssv tsv pipes multi] - if ok && !compiler.StringArrayContainsValue([]string{"csv", "ssv", "tsv", "pipes", "multi"}, x.CollectionFormat) { - message := fmt.Sprintf("has unexpected value for collectionFormat: %+v (%T)", v9, v9) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Any default = 10; - v10 := compiler.MapValueForKey(m, "default") - if v10 != nil { - var err error - x.Default, err = NewAny(v10, compiler.NewContext("default", context)) - if err != nil { - errors = append(errors, err) - } - } - // float maximum = 11; - v11 := compiler.MapValueForKey(m, "maximum") - if v11 != nil { - switch v11 := v11.(type) { - case float64: - x.Maximum = v11 - case float32: - x.Maximum = float64(v11) - case uint64: - x.Maximum = float64(v11) - case uint32: - x.Maximum = float64(v11) - case int64: - x.Maximum = float64(v11) - case int32: - x.Maximum = float64(v11) - case int: - x.Maximum = float64(v11) - default: - message := fmt.Sprintf("has unexpected value for maximum: %+v (%T)", v11, v11) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool exclusive_maximum = 12; - v12 := compiler.MapValueForKey(m, "exclusiveMaximum") - if v12 != nil { - x.ExclusiveMaximum, ok = v12.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for exclusiveMaximum: %+v (%T)", v12, v12) - errors = append(errors, compiler.NewError(context, message)) - } - } - // float minimum = 13; - v13 := compiler.MapValueForKey(m, "minimum") - if v13 != nil { - switch v13 := v13.(type) { - case float64: - x.Minimum = v13 - case float32: - x.Minimum = float64(v13) - case uint64: - x.Minimum = float64(v13) - case uint32: - x.Minimum = float64(v13) - case int64: - x.Minimum = float64(v13) - case int32: - x.Minimum = float64(v13) - case int: - x.Minimum = float64(v13) - default: - message := fmt.Sprintf("has unexpected value for minimum: %+v (%T)", v13, v13) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool exclusive_minimum = 14; - v14 := compiler.MapValueForKey(m, "exclusiveMinimum") - if v14 != nil { - x.ExclusiveMinimum, ok = v14.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for exclusiveMinimum: %+v (%T)", v14, v14) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_length = 15; - v15 := compiler.MapValueForKey(m, "maxLength") - if v15 != nil { - t, ok := v15.(int) - if ok { - x.MaxLength = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxLength: %+v (%T)", v15, v15) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_length = 16; - v16 := compiler.MapValueForKey(m, "minLength") - if v16 != nil { - t, ok := v16.(int) - if ok { - x.MinLength = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minLength: %+v (%T)", v16, v16) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string pattern = 17; - v17 := compiler.MapValueForKey(m, "pattern") - if v17 != nil { - x.Pattern, ok = v17.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for pattern: %+v (%T)", v17, v17) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_items = 18; - v18 := compiler.MapValueForKey(m, "maxItems") - if v18 != nil { - t, ok := v18.(int) - if ok { - x.MaxItems = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxItems: %+v (%T)", v18, v18) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_items = 19; - v19 := compiler.MapValueForKey(m, "minItems") - if v19 != nil { - t, ok := v19.(int) - if ok { - x.MinItems = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minItems: %+v (%T)", v19, v19) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool unique_items = 20; - v20 := compiler.MapValueForKey(m, "uniqueItems") - if v20 != nil { - x.UniqueItems, ok = v20.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for uniqueItems: %+v (%T)", v20, v20) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated Any enum = 21; - v21 := compiler.MapValueForKey(m, "enum") - if v21 != nil { - // repeated Any - x.Enum = make([]*Any, 0) - a, ok := v21.([]interface{}) - if ok { - for _, item := range a { - y, err := NewAny(item, compiler.NewContext("enum", context)) - if err != nil { - errors = append(errors, err) - } - x.Enum = append(x.Enum, y) - } - } - } - // float multiple_of = 22; - v22 := compiler.MapValueForKey(m, "multipleOf") - if v22 != nil { - switch v22 := v22.(type) { - case float64: - x.MultipleOf = v22 - case float32: - x.MultipleOf = float64(v22) - case uint64: - x.MultipleOf = float64(v22) - case uint32: - x.MultipleOf = float64(v22) - case int64: - x.MultipleOf = float64(v22) - case int32: - x.MultipleOf = float64(v22) - case int: - x.MultipleOf = float64(v22) - default: - message := fmt.Sprintf("has unexpected value for multipleOf: %+v (%T)", v22, v22) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 23; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewResponse creates an object of type Response if possible, returning an error if not. -func NewResponse(in interface{}, context *compiler.Context) (*Response, error) { - errors := make([]error, 0) - x := &Response{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"description"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"description", "examples", "headers", "schema"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string description = 1; - v1 := compiler.MapValueForKey(m, "description") - if v1 != nil { - x.Description, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // SchemaItem schema = 2; - v2 := compiler.MapValueForKey(m, "schema") - if v2 != nil { - var err error - x.Schema, err = NewSchemaItem(v2, compiler.NewContext("schema", context)) - if err != nil { - errors = append(errors, err) - } - } - // Headers headers = 3; - v3 := compiler.MapValueForKey(m, "headers") - if v3 != nil { - var err error - x.Headers, err = NewHeaders(v3, compiler.NewContext("headers", context)) - if err != nil { - errors = append(errors, err) - } - } - // Examples examples = 4; - v4 := compiler.MapValueForKey(m, "examples") - if v4 != nil { - var err error - x.Examples, err = NewExamples(v4, compiler.NewContext("examples", context)) - if err != nil { - errors = append(errors, err) - } - } - // repeated NamedAny vendor_extension = 5; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewResponseDefinitions creates an object of type ResponseDefinitions if possible, returning an error if not. -func NewResponseDefinitions(in interface{}, context *compiler.Context) (*ResponseDefinitions, error) { - errors := make([]error, 0) - x := &ResponseDefinitions{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - // repeated NamedResponse additional_properties = 1; - // MAP: Response - x.AdditionalProperties = make([]*NamedResponse, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - pair := &NamedResponse{} - pair.Name = k - var err error - pair.Value, err = NewResponse(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - x.AdditionalProperties = append(x.AdditionalProperties, pair) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewResponseValue creates an object of type ResponseValue if possible, returning an error if not. -func NewResponseValue(in interface{}, context *compiler.Context) (*ResponseValue, error) { - errors := make([]error, 0) - x := &ResponseValue{} - matched := false - // Response response = 1; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewResponse(m, compiler.NewContext("response", context)) - if matchingError == nil { - x.Oneof = &ResponseValue_Response{Response: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - // JsonReference json_reference = 2; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewJsonReference(m, compiler.NewContext("jsonReference", context)) - if matchingError == nil { - x.Oneof = &ResponseValue_JsonReference{JsonReference: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - if matched { - // since the oneof matched one of its possibilities, discard any matching errors - errors = make([]error, 0) - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewResponses creates an object of type Responses if possible, returning an error if not. -func NewResponses(in interface{}, context *compiler.Context) (*Responses, error) { - errors := make([]error, 0) - x := &Responses{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{} - allowedPatterns := []*regexp.Regexp{pattern2, pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // repeated NamedResponseValue response_code = 1; - // MAP: ResponseValue ^([0-9]{3})$|^(default)$ - x.ResponseCode = make([]*NamedResponseValue, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if pattern2.MatchString(k) { - pair := &NamedResponseValue{} - pair.Name = k - var err error - pair.Value, err = NewResponseValue(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - x.ResponseCode = append(x.ResponseCode, pair) - } - } - } - // repeated NamedAny vendor_extension = 2; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewSchema creates an object of type Schema if possible, returning an error if not. -func NewSchema(in interface{}, context *compiler.Context) (*Schema, error) { - errors := make([]error, 0) - x := &Schema{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"$ref", "additionalProperties", "allOf", "default", "description", "discriminator", "enum", "example", "exclusiveMaximum", "exclusiveMinimum", "externalDocs", "format", "items", "maxItems", "maxLength", "maxProperties", "maximum", "minItems", "minLength", "minProperties", "minimum", "multipleOf", "pattern", "properties", "readOnly", "required", "title", "type", "uniqueItems", "xml"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string _ref = 1; - v1 := compiler.MapValueForKey(m, "$ref") - if v1 != nil { - x.XRef, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for $ref: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string format = 2; - v2 := compiler.MapValueForKey(m, "format") - if v2 != nil { - x.Format, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for format: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string title = 3; - v3 := compiler.MapValueForKey(m, "title") - if v3 != nil { - x.Title, ok = v3.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for title: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 4; - v4 := compiler.MapValueForKey(m, "description") - if v4 != nil { - x.Description, ok = v4.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Any default = 5; - v5 := compiler.MapValueForKey(m, "default") - if v5 != nil { - var err error - x.Default, err = NewAny(v5, compiler.NewContext("default", context)) - if err != nil { - errors = append(errors, err) - } - } - // float multiple_of = 6; - v6 := compiler.MapValueForKey(m, "multipleOf") - if v6 != nil { - switch v6 := v6.(type) { - case float64: - x.MultipleOf = v6 - case float32: - x.MultipleOf = float64(v6) - case uint64: - x.MultipleOf = float64(v6) - case uint32: - x.MultipleOf = float64(v6) - case int64: - x.MultipleOf = float64(v6) - case int32: - x.MultipleOf = float64(v6) - case int: - x.MultipleOf = float64(v6) - default: - message := fmt.Sprintf("has unexpected value for multipleOf: %+v (%T)", v6, v6) - errors = append(errors, compiler.NewError(context, message)) - } - } - // float maximum = 7; - v7 := compiler.MapValueForKey(m, "maximum") - if v7 != nil { - switch v7 := v7.(type) { - case float64: - x.Maximum = v7 - case float32: - x.Maximum = float64(v7) - case uint64: - x.Maximum = float64(v7) - case uint32: - x.Maximum = float64(v7) - case int64: - x.Maximum = float64(v7) - case int32: - x.Maximum = float64(v7) - case int: - x.Maximum = float64(v7) - default: - message := fmt.Sprintf("has unexpected value for maximum: %+v (%T)", v7, v7) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool exclusive_maximum = 8; - v8 := compiler.MapValueForKey(m, "exclusiveMaximum") - if v8 != nil { - x.ExclusiveMaximum, ok = v8.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for exclusiveMaximum: %+v (%T)", v8, v8) - errors = append(errors, compiler.NewError(context, message)) - } - } - // float minimum = 9; - v9 := compiler.MapValueForKey(m, "minimum") - if v9 != nil { - switch v9 := v9.(type) { - case float64: - x.Minimum = v9 - case float32: - x.Minimum = float64(v9) - case uint64: - x.Minimum = float64(v9) - case uint32: - x.Minimum = float64(v9) - case int64: - x.Minimum = float64(v9) - case int32: - x.Minimum = float64(v9) - case int: - x.Minimum = float64(v9) - default: - message := fmt.Sprintf("has unexpected value for minimum: %+v (%T)", v9, v9) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool exclusive_minimum = 10; - v10 := compiler.MapValueForKey(m, "exclusiveMinimum") - if v10 != nil { - x.ExclusiveMinimum, ok = v10.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for exclusiveMinimum: %+v (%T)", v10, v10) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_length = 11; - v11 := compiler.MapValueForKey(m, "maxLength") - if v11 != nil { - t, ok := v11.(int) - if ok { - x.MaxLength = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxLength: %+v (%T)", v11, v11) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_length = 12; - v12 := compiler.MapValueForKey(m, "minLength") - if v12 != nil { - t, ok := v12.(int) - if ok { - x.MinLength = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minLength: %+v (%T)", v12, v12) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string pattern = 13; - v13 := compiler.MapValueForKey(m, "pattern") - if v13 != nil { - x.Pattern, ok = v13.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for pattern: %+v (%T)", v13, v13) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_items = 14; - v14 := compiler.MapValueForKey(m, "maxItems") - if v14 != nil { - t, ok := v14.(int) - if ok { - x.MaxItems = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxItems: %+v (%T)", v14, v14) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_items = 15; - v15 := compiler.MapValueForKey(m, "minItems") - if v15 != nil { - t, ok := v15.(int) - if ok { - x.MinItems = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minItems: %+v (%T)", v15, v15) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool unique_items = 16; - v16 := compiler.MapValueForKey(m, "uniqueItems") - if v16 != nil { - x.UniqueItems, ok = v16.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for uniqueItems: %+v (%T)", v16, v16) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 max_properties = 17; - v17 := compiler.MapValueForKey(m, "maxProperties") - if v17 != nil { - t, ok := v17.(int) - if ok { - x.MaxProperties = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for maxProperties: %+v (%T)", v17, v17) - errors = append(errors, compiler.NewError(context, message)) - } - } - // int64 min_properties = 18; - v18 := compiler.MapValueForKey(m, "minProperties") - if v18 != nil { - t, ok := v18.(int) - if ok { - x.MinProperties = int64(t) - } else { - message := fmt.Sprintf("has unexpected value for minProperties: %+v (%T)", v18, v18) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated string required = 19; - v19 := compiler.MapValueForKey(m, "required") - if v19 != nil { - v, ok := v19.([]interface{}) - if ok { - x.Required = compiler.ConvertInterfaceArrayToStringArray(v) - } else { - message := fmt.Sprintf("has unexpected value for required: %+v (%T)", v19, v19) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated Any enum = 20; - v20 := compiler.MapValueForKey(m, "enum") - if v20 != nil { - // repeated Any - x.Enum = make([]*Any, 0) - a, ok := v20.([]interface{}) - if ok { - for _, item := range a { - y, err := NewAny(item, compiler.NewContext("enum", context)) - if err != nil { - errors = append(errors, err) - } - x.Enum = append(x.Enum, y) - } - } - } - // AdditionalPropertiesItem additional_properties = 21; - v21 := compiler.MapValueForKey(m, "additionalProperties") - if v21 != nil { - var err error - x.AdditionalProperties, err = NewAdditionalPropertiesItem(v21, compiler.NewContext("additionalProperties", context)) - if err != nil { - errors = append(errors, err) - } - } - // TypeItem type = 22; - v22 := compiler.MapValueForKey(m, "type") - if v22 != nil { - var err error - x.Type, err = NewTypeItem(v22, compiler.NewContext("type", context)) - if err != nil { - errors = append(errors, err) - } - } - // ItemsItem items = 23; - v23 := compiler.MapValueForKey(m, "items") - if v23 != nil { - var err error - x.Items, err = NewItemsItem(v23, compiler.NewContext("items", context)) - if err != nil { - errors = append(errors, err) - } - } - // repeated Schema all_of = 24; - v24 := compiler.MapValueForKey(m, "allOf") - if v24 != nil { - // repeated Schema - x.AllOf = make([]*Schema, 0) - a, ok := v24.([]interface{}) - if ok { - for _, item := range a { - y, err := NewSchema(item, compiler.NewContext("allOf", context)) - if err != nil { - errors = append(errors, err) - } - x.AllOf = append(x.AllOf, y) - } - } - } - // Properties properties = 25; - v25 := compiler.MapValueForKey(m, "properties") - if v25 != nil { - var err error - x.Properties, err = NewProperties(v25, compiler.NewContext("properties", context)) - if err != nil { - errors = append(errors, err) - } - } - // string discriminator = 26; - v26 := compiler.MapValueForKey(m, "discriminator") - if v26 != nil { - x.Discriminator, ok = v26.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for discriminator: %+v (%T)", v26, v26) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool read_only = 27; - v27 := compiler.MapValueForKey(m, "readOnly") - if v27 != nil { - x.ReadOnly, ok = v27.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for readOnly: %+v (%T)", v27, v27) - errors = append(errors, compiler.NewError(context, message)) - } - } - // Xml xml = 28; - v28 := compiler.MapValueForKey(m, "xml") - if v28 != nil { - var err error - x.Xml, err = NewXml(v28, compiler.NewContext("xml", context)) - if err != nil { - errors = append(errors, err) - } - } - // ExternalDocs external_docs = 29; - v29 := compiler.MapValueForKey(m, "externalDocs") - if v29 != nil { - var err error - x.ExternalDocs, err = NewExternalDocs(v29, compiler.NewContext("externalDocs", context)) - if err != nil { - errors = append(errors, err) - } - } - // Any example = 30; - v30 := compiler.MapValueForKey(m, "example") - if v30 != nil { - var err error - x.Example, err = NewAny(v30, compiler.NewContext("example", context)) - if err != nil { - errors = append(errors, err) - } - } - // repeated NamedAny vendor_extension = 31; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewSchemaItem creates an object of type SchemaItem if possible, returning an error if not. -func NewSchemaItem(in interface{}, context *compiler.Context) (*SchemaItem, error) { - errors := make([]error, 0) - x := &SchemaItem{} - matched := false - // Schema schema = 1; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewSchema(m, compiler.NewContext("schema", context)) - if matchingError == nil { - x.Oneof = &SchemaItem_Schema{Schema: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - // FileSchema file_schema = 2; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewFileSchema(m, compiler.NewContext("fileSchema", context)) - if matchingError == nil { - x.Oneof = &SchemaItem_FileSchema{FileSchema: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - if matched { - // since the oneof matched one of its possibilities, discard any matching errors - errors = make([]error, 0) - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewSecurityDefinitions creates an object of type SecurityDefinitions if possible, returning an error if not. -func NewSecurityDefinitions(in interface{}, context *compiler.Context) (*SecurityDefinitions, error) { - errors := make([]error, 0) - x := &SecurityDefinitions{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - // repeated NamedSecurityDefinitionsItem additional_properties = 1; - // MAP: SecurityDefinitionsItem - x.AdditionalProperties = make([]*NamedSecurityDefinitionsItem, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - pair := &NamedSecurityDefinitionsItem{} - pair.Name = k - var err error - pair.Value, err = NewSecurityDefinitionsItem(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - x.AdditionalProperties = append(x.AdditionalProperties, pair) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewSecurityDefinitionsItem creates an object of type SecurityDefinitionsItem if possible, returning an error if not. -func NewSecurityDefinitionsItem(in interface{}, context *compiler.Context) (*SecurityDefinitionsItem, error) { - errors := make([]error, 0) - x := &SecurityDefinitionsItem{} - matched := false - // BasicAuthenticationSecurity basic_authentication_security = 1; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewBasicAuthenticationSecurity(m, compiler.NewContext("basicAuthenticationSecurity", context)) - if matchingError == nil { - x.Oneof = &SecurityDefinitionsItem_BasicAuthenticationSecurity{BasicAuthenticationSecurity: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - // ApiKeySecurity api_key_security = 2; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewApiKeySecurity(m, compiler.NewContext("apiKeySecurity", context)) - if matchingError == nil { - x.Oneof = &SecurityDefinitionsItem_ApiKeySecurity{ApiKeySecurity: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - // Oauth2ImplicitSecurity oauth2_implicit_security = 3; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewOauth2ImplicitSecurity(m, compiler.NewContext("oauth2ImplicitSecurity", context)) - if matchingError == nil { - x.Oneof = &SecurityDefinitionsItem_Oauth2ImplicitSecurity{Oauth2ImplicitSecurity: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - // Oauth2PasswordSecurity oauth2_password_security = 4; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewOauth2PasswordSecurity(m, compiler.NewContext("oauth2PasswordSecurity", context)) - if matchingError == nil { - x.Oneof = &SecurityDefinitionsItem_Oauth2PasswordSecurity{Oauth2PasswordSecurity: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - // Oauth2ApplicationSecurity oauth2_application_security = 5; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewOauth2ApplicationSecurity(m, compiler.NewContext("oauth2ApplicationSecurity", context)) - if matchingError == nil { - x.Oneof = &SecurityDefinitionsItem_Oauth2ApplicationSecurity{Oauth2ApplicationSecurity: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - // Oauth2AccessCodeSecurity oauth2_access_code_security = 6; - { - m, ok := compiler.UnpackMap(in) - if ok { - // errors might be ok here, they mean we just don't have the right subtype - t, matchingError := NewOauth2AccessCodeSecurity(m, compiler.NewContext("oauth2AccessCodeSecurity", context)) - if matchingError == nil { - x.Oneof = &SecurityDefinitionsItem_Oauth2AccessCodeSecurity{Oauth2AccessCodeSecurity: t} - matched = true - } else { - errors = append(errors, matchingError) - } - } - } - if matched { - // since the oneof matched one of its possibilities, discard any matching errors - errors = make([]error, 0) - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewSecurityRequirement creates an object of type SecurityRequirement if possible, returning an error if not. -func NewSecurityRequirement(in interface{}, context *compiler.Context) (*SecurityRequirement, error) { - errors := make([]error, 0) - x := &SecurityRequirement{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - // repeated NamedStringArray additional_properties = 1; - // MAP: StringArray - x.AdditionalProperties = make([]*NamedStringArray, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - pair := &NamedStringArray{} - pair.Name = k - var err error - pair.Value, err = NewStringArray(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - x.AdditionalProperties = append(x.AdditionalProperties, pair) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewStringArray creates an object of type StringArray if possible, returning an error if not. -func NewStringArray(in interface{}, context *compiler.Context) (*StringArray, error) { - errors := make([]error, 0) - x := &StringArray{} - a, ok := in.([]interface{}) - if !ok { - message := fmt.Sprintf("has unexpected value for StringArray: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - x.Value = make([]string, 0) - for _, s := range a { - x.Value = append(x.Value, s.(string)) - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewTag creates an object of type Tag if possible, returning an error if not. -func NewTag(in interface{}, context *compiler.Context) (*Tag, error) { - errors := make([]error, 0) - x := &Tag{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - requiredKeys := []string{"name"} - missingKeys := compiler.MissingKeysInMap(m, requiredKeys) - if len(missingKeys) > 0 { - message := fmt.Sprintf("is missing required %s: %+v", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - allowedKeys := []string{"description", "externalDocs", "name"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string name = 1; - v1 := compiler.MapValueForKey(m, "name") - if v1 != nil { - x.Name, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string description = 2; - v2 := compiler.MapValueForKey(m, "description") - if v2 != nil { - x.Description, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for description: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // ExternalDocs external_docs = 3; - v3 := compiler.MapValueForKey(m, "externalDocs") - if v3 != nil { - var err error - x.ExternalDocs, err = NewExternalDocs(v3, compiler.NewContext("externalDocs", context)) - if err != nil { - errors = append(errors, err) - } - } - // repeated NamedAny vendor_extension = 4; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewTypeItem creates an object of type TypeItem if possible, returning an error if not. -func NewTypeItem(in interface{}, context *compiler.Context) (*TypeItem, error) { - errors := make([]error, 0) - x := &TypeItem{} - switch in := in.(type) { - case string: - x.Value = make([]string, 0) - x.Value = append(x.Value, in) - case []interface{}: - x.Value = make([]string, 0) - for _, v := range in { - value, ok := v.(string) - if ok { - x.Value = append(x.Value, value) - } else { - message := fmt.Sprintf("has unexpected value for string array element: %+v (%T)", value, value) - errors = append(errors, compiler.NewError(context, message)) - } - } - default: - message := fmt.Sprintf("has unexpected value for string array: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewVendorExtension creates an object of type VendorExtension if possible, returning an error if not. -func NewVendorExtension(in interface{}, context *compiler.Context) (*VendorExtension, error) { - errors := make([]error, 0) - x := &VendorExtension{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - // repeated NamedAny additional_properties = 1; - // MAP: Any - x.AdditionalProperties = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.AdditionalProperties = append(x.AdditionalProperties, pair) - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// NewXml creates an object of type Xml if possible, returning an error if not. -func NewXml(in interface{}, context *compiler.Context) (*Xml, error) { - errors := make([]error, 0) - x := &Xml{} - m, ok := compiler.UnpackMap(in) - if !ok { - message := fmt.Sprintf("has unexpected value: %+v (%T)", in, in) - errors = append(errors, compiler.NewError(context, message)) - } else { - allowedKeys := []string{"attribute", "name", "namespace", "prefix", "wrapped"} - allowedPatterns := []*regexp.Regexp{pattern0} - invalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns) - if len(invalidKeys) > 0 { - message := fmt.Sprintf("has invalid %s: %+v", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, ", ")) - errors = append(errors, compiler.NewError(context, message)) - } - // string name = 1; - v1 := compiler.MapValueForKey(m, "name") - if v1 != nil { - x.Name, ok = v1.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for name: %+v (%T)", v1, v1) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string namespace = 2; - v2 := compiler.MapValueForKey(m, "namespace") - if v2 != nil { - x.Namespace, ok = v2.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for namespace: %+v (%T)", v2, v2) - errors = append(errors, compiler.NewError(context, message)) - } - } - // string prefix = 3; - v3 := compiler.MapValueForKey(m, "prefix") - if v3 != nil { - x.Prefix, ok = v3.(string) - if !ok { - message := fmt.Sprintf("has unexpected value for prefix: %+v (%T)", v3, v3) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool attribute = 4; - v4 := compiler.MapValueForKey(m, "attribute") - if v4 != nil { - x.Attribute, ok = v4.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for attribute: %+v (%T)", v4, v4) - errors = append(errors, compiler.NewError(context, message)) - } - } - // bool wrapped = 5; - v5 := compiler.MapValueForKey(m, "wrapped") - if v5 != nil { - x.Wrapped, ok = v5.(bool) - if !ok { - message := fmt.Sprintf("has unexpected value for wrapped: %+v (%T)", v5, v5) - errors = append(errors, compiler.NewError(context, message)) - } - } - // repeated NamedAny vendor_extension = 6; - // MAP: Any ^x- - x.VendorExtension = make([]*NamedAny, 0) - for _, item := range m { - k, ok := compiler.StringValue(item.Key) - if ok { - v := item.Value - if strings.HasPrefix(k, "x-") { - pair := &NamedAny{} - pair.Name = k - result := &Any{} - handled, resultFromExt, err := compiler.HandleExtension(context, v, k) - if handled { - if err != nil { - errors = append(errors, err) - } else { - bytes, _ := yaml.Marshal(v) - result.Yaml = string(bytes) - result.Value = resultFromExt - pair.Value = result - } - } else { - pair.Value, err = NewAny(v, compiler.NewContext(k, context)) - if err != nil { - errors = append(errors, err) - } - } - x.VendorExtension = append(x.VendorExtension, pair) - } - } - } - } - return x, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside AdditionalPropertiesItem objects. -func (m *AdditionalPropertiesItem) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - { - p, ok := m.Oneof.(*AdditionalPropertiesItem_Schema) - if ok { - _, err := p.Schema.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Any objects. -func (m *Any) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside ApiKeySecurity objects. -func (m *ApiKeySecurity) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside BasicAuthenticationSecurity objects. -func (m *BasicAuthenticationSecurity) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside BodyParameter objects. -func (m *BodyParameter) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Schema != nil { - _, err := m.Schema.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Contact objects. -func (m *Contact) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Default objects. -func (m *Default) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.AdditionalProperties { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Definitions objects. -func (m *Definitions) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.AdditionalProperties { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Document objects. -func (m *Document) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Info != nil { - _, err := m.Info.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Paths != nil { - _, err := m.Paths.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Definitions != nil { - _, err := m.Definitions.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Parameters != nil { - _, err := m.Parameters.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Responses != nil { - _, err := m.Responses.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.Security { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - if m.SecurityDefinitions != nil { - _, err := m.SecurityDefinitions.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.Tags { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - if m.ExternalDocs != nil { - _, err := m.ExternalDocs.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Examples objects. -func (m *Examples) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.AdditionalProperties { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside ExternalDocs objects. -func (m *ExternalDocs) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside FileSchema objects. -func (m *FileSchema) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Default != nil { - _, err := m.Default.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.ExternalDocs != nil { - _, err := m.ExternalDocs.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Example != nil { - _, err := m.Example.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside FormDataParameterSubSchema objects. -func (m *FormDataParameterSubSchema) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Items != nil { - _, err := m.Items.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Default != nil { - _, err := m.Default.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.Enum { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Header objects. -func (m *Header) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Items != nil { - _, err := m.Items.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Default != nil { - _, err := m.Default.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.Enum { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside HeaderParameterSubSchema objects. -func (m *HeaderParameterSubSchema) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Items != nil { - _, err := m.Items.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Default != nil { - _, err := m.Default.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.Enum { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Headers objects. -func (m *Headers) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.AdditionalProperties { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Info objects. -func (m *Info) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Contact != nil { - _, err := m.Contact.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.License != nil { - _, err := m.License.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside ItemsItem objects. -func (m *ItemsItem) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.Schema { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside JsonReference objects. -func (m *JsonReference) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.XRef != "" { - info, err := compiler.ReadInfoForRef(root, m.XRef) - if err != nil { - return nil, err - } - if info != nil { - replacement, err := NewJsonReference(info, nil) - if err == nil { - *m = *replacement - return m.ResolveReferences(root) - } - } - return info, nil - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside License objects. -func (m *License) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside NamedAny objects. -func (m *NamedAny) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Value != nil { - _, err := m.Value.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside NamedHeader objects. -func (m *NamedHeader) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Value != nil { - _, err := m.Value.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside NamedParameter objects. -func (m *NamedParameter) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Value != nil { - _, err := m.Value.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside NamedPathItem objects. -func (m *NamedPathItem) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Value != nil { - _, err := m.Value.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside NamedResponse objects. -func (m *NamedResponse) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Value != nil { - _, err := m.Value.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside NamedResponseValue objects. -func (m *NamedResponseValue) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Value != nil { - _, err := m.Value.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside NamedSchema objects. -func (m *NamedSchema) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Value != nil { - _, err := m.Value.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside NamedSecurityDefinitionsItem objects. -func (m *NamedSecurityDefinitionsItem) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Value != nil { - _, err := m.Value.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside NamedString objects. -func (m *NamedString) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside NamedStringArray objects. -func (m *NamedStringArray) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Value != nil { - _, err := m.Value.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside NonBodyParameter objects. -func (m *NonBodyParameter) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - { - p, ok := m.Oneof.(*NonBodyParameter_HeaderParameterSubSchema) - if ok { - _, err := p.HeaderParameterSubSchema.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - { - p, ok := m.Oneof.(*NonBodyParameter_FormDataParameterSubSchema) - if ok { - _, err := p.FormDataParameterSubSchema.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - { - p, ok := m.Oneof.(*NonBodyParameter_QueryParameterSubSchema) - if ok { - _, err := p.QueryParameterSubSchema.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - { - p, ok := m.Oneof.(*NonBodyParameter_PathParameterSubSchema) - if ok { - _, err := p.PathParameterSubSchema.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Oauth2AccessCodeSecurity objects. -func (m *Oauth2AccessCodeSecurity) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Scopes != nil { - _, err := m.Scopes.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Oauth2ApplicationSecurity objects. -func (m *Oauth2ApplicationSecurity) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Scopes != nil { - _, err := m.Scopes.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Oauth2ImplicitSecurity objects. -func (m *Oauth2ImplicitSecurity) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Scopes != nil { - _, err := m.Scopes.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Oauth2PasswordSecurity objects. -func (m *Oauth2PasswordSecurity) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Scopes != nil { - _, err := m.Scopes.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Oauth2Scopes objects. -func (m *Oauth2Scopes) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.AdditionalProperties { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Operation objects. -func (m *Operation) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.ExternalDocs != nil { - _, err := m.ExternalDocs.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.Parameters { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - if m.Responses != nil { - _, err := m.Responses.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.Security { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Parameter objects. -func (m *Parameter) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - { - p, ok := m.Oneof.(*Parameter_BodyParameter) - if ok { - _, err := p.BodyParameter.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - { - p, ok := m.Oneof.(*Parameter_NonBodyParameter) - if ok { - _, err := p.NonBodyParameter.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside ParameterDefinitions objects. -func (m *ParameterDefinitions) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.AdditionalProperties { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside ParametersItem objects. -func (m *ParametersItem) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - { - p, ok := m.Oneof.(*ParametersItem_Parameter) - if ok { - _, err := p.Parameter.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - { - p, ok := m.Oneof.(*ParametersItem_JsonReference) - if ok { - info, err := p.JsonReference.ResolveReferences(root) - if err != nil { - return nil, err - } else if info != nil { - n, err := NewParametersItem(info, nil) - if err != nil { - return nil, err - } else if n != nil { - *m = *n - return nil, nil - } - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside PathItem objects. -func (m *PathItem) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.XRef != "" { - info, err := compiler.ReadInfoForRef(root, m.XRef) - if err != nil { - return nil, err - } - if info != nil { - replacement, err := NewPathItem(info, nil) - if err == nil { - *m = *replacement - return m.ResolveReferences(root) - } - } - return info, nil - } - if m.Get != nil { - _, err := m.Get.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Put != nil { - _, err := m.Put.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Post != nil { - _, err := m.Post.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Delete != nil { - _, err := m.Delete.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Options != nil { - _, err := m.Options.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Head != nil { - _, err := m.Head.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Patch != nil { - _, err := m.Patch.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.Parameters { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside PathParameterSubSchema objects. -func (m *PathParameterSubSchema) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Items != nil { - _, err := m.Items.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Default != nil { - _, err := m.Default.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.Enum { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Paths objects. -func (m *Paths) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - for _, item := range m.Path { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside PrimitivesItems objects. -func (m *PrimitivesItems) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Items != nil { - _, err := m.Items.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Default != nil { - _, err := m.Default.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.Enum { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Properties objects. -func (m *Properties) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.AdditionalProperties { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside QueryParameterSubSchema objects. -func (m *QueryParameterSubSchema) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Items != nil { - _, err := m.Items.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Default != nil { - _, err := m.Default.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.Enum { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Response objects. -func (m *Response) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.Schema != nil { - _, err := m.Schema.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Headers != nil { - _, err := m.Headers.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Examples != nil { - _, err := m.Examples.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside ResponseDefinitions objects. -func (m *ResponseDefinitions) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.AdditionalProperties { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside ResponseValue objects. -func (m *ResponseValue) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - { - p, ok := m.Oneof.(*ResponseValue_Response) - if ok { - _, err := p.Response.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - { - p, ok := m.Oneof.(*ResponseValue_JsonReference) - if ok { - info, err := p.JsonReference.ResolveReferences(root) - if err != nil { - return nil, err - } else if info != nil { - n, err := NewResponseValue(info, nil) - if err != nil { - return nil, err - } else if n != nil { - *m = *n - return nil, nil - } - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Responses objects. -func (m *Responses) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.ResponseCode { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Schema objects. -func (m *Schema) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.XRef != "" { - info, err := compiler.ReadInfoForRef(root, m.XRef) - if err != nil { - return nil, err - } - if info != nil { - replacement, err := NewSchema(info, nil) - if err == nil { - *m = *replacement - return m.ResolveReferences(root) - } - } - return info, nil - } - if m.Default != nil { - _, err := m.Default.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.Enum { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - if m.AdditionalProperties != nil { - _, err := m.AdditionalProperties.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Type != nil { - _, err := m.Type.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Items != nil { - _, err := m.Items.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.AllOf { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - if m.Properties != nil { - _, err := m.Properties.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Xml != nil { - _, err := m.Xml.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.ExternalDocs != nil { - _, err := m.ExternalDocs.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - if m.Example != nil { - _, err := m.Example.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside SchemaItem objects. -func (m *SchemaItem) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - { - p, ok := m.Oneof.(*SchemaItem_Schema) - if ok { - _, err := p.Schema.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - { - p, ok := m.Oneof.(*SchemaItem_FileSchema) - if ok { - _, err := p.FileSchema.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside SecurityDefinitions objects. -func (m *SecurityDefinitions) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.AdditionalProperties { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside SecurityDefinitionsItem objects. -func (m *SecurityDefinitionsItem) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - { - p, ok := m.Oneof.(*SecurityDefinitionsItem_BasicAuthenticationSecurity) - if ok { - _, err := p.BasicAuthenticationSecurity.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - { - p, ok := m.Oneof.(*SecurityDefinitionsItem_ApiKeySecurity) - if ok { - _, err := p.ApiKeySecurity.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - { - p, ok := m.Oneof.(*SecurityDefinitionsItem_Oauth2ImplicitSecurity) - if ok { - _, err := p.Oauth2ImplicitSecurity.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - { - p, ok := m.Oneof.(*SecurityDefinitionsItem_Oauth2PasswordSecurity) - if ok { - _, err := p.Oauth2PasswordSecurity.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - { - p, ok := m.Oneof.(*SecurityDefinitionsItem_Oauth2ApplicationSecurity) - if ok { - _, err := p.Oauth2ApplicationSecurity.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - { - p, ok := m.Oneof.(*SecurityDefinitionsItem_Oauth2AccessCodeSecurity) - if ok { - _, err := p.Oauth2AccessCodeSecurity.ResolveReferences(root) - if err != nil { - return nil, err - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside SecurityRequirement objects. -func (m *SecurityRequirement) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.AdditionalProperties { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside StringArray objects. -func (m *StringArray) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Tag objects. -func (m *Tag) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - if m.ExternalDocs != nil { - _, err := m.ExternalDocs.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside TypeItem objects. -func (m *TypeItem) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside VendorExtension objects. -func (m *VendorExtension) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.AdditionalProperties { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ResolveReferences resolves references found inside Xml objects. -func (m *Xml) ResolveReferences(root string) (interface{}, error) { - errors := make([]error, 0) - for _, item := range m.VendorExtension { - if item != nil { - _, err := item.ResolveReferences(root) - if err != nil { - errors = append(errors, err) - } - } - } - return nil, compiler.NewErrorGroupOrNil(errors) -} - -// ToRawInfo returns a description of AdditionalPropertiesItem suitable for JSON or YAML export. -func (m *AdditionalPropertiesItem) ToRawInfo() interface{} { - // ONE OF WRAPPER - // AdditionalPropertiesItem - // {Name:schema Type:Schema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v0 := m.GetSchema() - if v0 != nil { - return v0.ToRawInfo() - } - // {Name:boolean Type:bool StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if v1, ok := m.GetOneof().(*AdditionalPropertiesItem_Boolean); ok { - return v1.Boolean - } - return nil -} - -// ToRawInfo returns a description of Any suitable for JSON or YAML export. -func (m *Any) ToRawInfo() interface{} { - var err error - var info1 []yaml.MapSlice - err = yaml.Unmarshal([]byte(m.Yaml), &info1) - if err == nil { - return info1 - } - var info2 yaml.MapSlice - err = yaml.Unmarshal([]byte(m.Yaml), &info2) - if err == nil { - return info2 - } - var info3 interface{} - err = yaml.Unmarshal([]byte(m.Yaml), &info3) - if err == nil { - return info3 - } - return nil -} - -// ToRawInfo returns a description of ApiKeySecurity suitable for JSON or YAML export. -func (m *ApiKeySecurity) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Type != "" { - info = append(info, yaml.MapItem{"type", m.Type}) - } - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - if m.In != "" { - info = append(info, yaml.MapItem{"in", m.In}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of BasicAuthenticationSecurity suitable for JSON or YAML export. -func (m *BasicAuthenticationSecurity) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Type != "" { - info = append(info, yaml.MapItem{"type", m.Type}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of BodyParameter suitable for JSON or YAML export. -func (m *BodyParameter) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - if m.In != "" { - info = append(info, yaml.MapItem{"in", m.In}) - } - if m.Required != false { - info = append(info, yaml.MapItem{"required", m.Required}) - } - if m.Schema != nil { - info = append(info, yaml.MapItem{"schema", m.Schema.ToRawInfo()}) - } - // &{Name:schema Type:Schema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Contact suitable for JSON or YAML export. -func (m *Contact) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - if m.Url != "" { - info = append(info, yaml.MapItem{"url", m.Url}) - } - if m.Email != "" { - info = append(info, yaml.MapItem{"email", m.Email}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Default suitable for JSON or YAML export. -func (m *Default) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.AdditionalProperties != nil { - for _, item := range m.AdditionalProperties { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:additionalProperties Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern: Implicit:false Description:} - return info -} - -// ToRawInfo returns a description of Definitions suitable for JSON or YAML export. -func (m *Definitions) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.AdditionalProperties != nil { - for _, item := range m.AdditionalProperties { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:additionalProperties Type:NamedSchema StringEnumValues:[] MapType:Schema Repeated:true Pattern: Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Document suitable for JSON or YAML export. -func (m *Document) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Swagger != "" { - info = append(info, yaml.MapItem{"swagger", m.Swagger}) - } - if m.Info != nil { - info = append(info, yaml.MapItem{"info", m.Info.ToRawInfo()}) - } - // &{Name:info Type:Info StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Host != "" { - info = append(info, yaml.MapItem{"host", m.Host}) - } - if m.BasePath != "" { - info = append(info, yaml.MapItem{"basePath", m.BasePath}) - } - if len(m.Schemes) != 0 { - info = append(info, yaml.MapItem{"schemes", m.Schemes}) - } - if len(m.Consumes) != 0 { - info = append(info, yaml.MapItem{"consumes", m.Consumes}) - } - if len(m.Produces) != 0 { - info = append(info, yaml.MapItem{"produces", m.Produces}) - } - if m.Paths != nil { - info = append(info, yaml.MapItem{"paths", m.Paths.ToRawInfo()}) - } - // &{Name:paths Type:Paths StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Definitions != nil { - info = append(info, yaml.MapItem{"definitions", m.Definitions.ToRawInfo()}) - } - // &{Name:definitions Type:Definitions StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Parameters != nil { - info = append(info, yaml.MapItem{"parameters", m.Parameters.ToRawInfo()}) - } - // &{Name:parameters Type:ParameterDefinitions StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Responses != nil { - info = append(info, yaml.MapItem{"responses", m.Responses.ToRawInfo()}) - } - // &{Name:responses Type:ResponseDefinitions StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if len(m.Security) != 0 { - items := make([]interface{}, 0) - for _, item := range m.Security { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"security", items}) - } - // &{Name:security Type:SecurityRequirement StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:} - if m.SecurityDefinitions != nil { - info = append(info, yaml.MapItem{"securityDefinitions", m.SecurityDefinitions.ToRawInfo()}) - } - // &{Name:securityDefinitions Type:SecurityDefinitions StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if len(m.Tags) != 0 { - items := make([]interface{}, 0) - for _, item := range m.Tags { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"tags", items}) - } - // &{Name:tags Type:Tag StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:} - if m.ExternalDocs != nil { - info = append(info, yaml.MapItem{"externalDocs", m.ExternalDocs.ToRawInfo()}) - } - // &{Name:externalDocs Type:ExternalDocs StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Examples suitable for JSON or YAML export. -func (m *Examples) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.AdditionalProperties != nil { - for _, item := range m.AdditionalProperties { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:additionalProperties Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern: Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of ExternalDocs suitable for JSON or YAML export. -func (m *ExternalDocs) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.Url != "" { - info = append(info, yaml.MapItem{"url", m.Url}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of FileSchema suitable for JSON or YAML export. -func (m *FileSchema) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Format != "" { - info = append(info, yaml.MapItem{"format", m.Format}) - } - if m.Title != "" { - info = append(info, yaml.MapItem{"title", m.Title}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.Default != nil { - info = append(info, yaml.MapItem{"default", m.Default.ToRawInfo()}) - } - // &{Name:default Type:Any StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if len(m.Required) != 0 { - info = append(info, yaml.MapItem{"required", m.Required}) - } - if m.Type != "" { - info = append(info, yaml.MapItem{"type", m.Type}) - } - if m.ReadOnly != false { - info = append(info, yaml.MapItem{"readOnly", m.ReadOnly}) - } - if m.ExternalDocs != nil { - info = append(info, yaml.MapItem{"externalDocs", m.ExternalDocs.ToRawInfo()}) - } - // &{Name:externalDocs Type:ExternalDocs StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Example != nil { - info = append(info, yaml.MapItem{"example", m.Example.ToRawInfo()}) - } - // &{Name:example Type:Any StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of FormDataParameterSubSchema suitable for JSON or YAML export. -func (m *FormDataParameterSubSchema) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Required != false { - info = append(info, yaml.MapItem{"required", m.Required}) - } - if m.In != "" { - info = append(info, yaml.MapItem{"in", m.In}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - if m.AllowEmptyValue != false { - info = append(info, yaml.MapItem{"allowEmptyValue", m.AllowEmptyValue}) - } - if m.Type != "" { - info = append(info, yaml.MapItem{"type", m.Type}) - } - if m.Format != "" { - info = append(info, yaml.MapItem{"format", m.Format}) - } - if m.Items != nil { - info = append(info, yaml.MapItem{"items", m.Items.ToRawInfo()}) - } - // &{Name:items Type:PrimitivesItems StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.CollectionFormat != "" { - info = append(info, yaml.MapItem{"collectionFormat", m.CollectionFormat}) - } - if m.Default != nil { - info = append(info, yaml.MapItem{"default", m.Default.ToRawInfo()}) - } - // &{Name:default Type:Any StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Maximum != 0.0 { - info = append(info, yaml.MapItem{"maximum", m.Maximum}) - } - if m.ExclusiveMaximum != false { - info = append(info, yaml.MapItem{"exclusiveMaximum", m.ExclusiveMaximum}) - } - if m.Minimum != 0.0 { - info = append(info, yaml.MapItem{"minimum", m.Minimum}) - } - if m.ExclusiveMinimum != false { - info = append(info, yaml.MapItem{"exclusiveMinimum", m.ExclusiveMinimum}) - } - if m.MaxLength != 0 { - info = append(info, yaml.MapItem{"maxLength", m.MaxLength}) - } - if m.MinLength != 0 { - info = append(info, yaml.MapItem{"minLength", m.MinLength}) - } - if m.Pattern != "" { - info = append(info, yaml.MapItem{"pattern", m.Pattern}) - } - if m.MaxItems != 0 { - info = append(info, yaml.MapItem{"maxItems", m.MaxItems}) - } - if m.MinItems != 0 { - info = append(info, yaml.MapItem{"minItems", m.MinItems}) - } - if m.UniqueItems != false { - info = append(info, yaml.MapItem{"uniqueItems", m.UniqueItems}) - } - if len(m.Enum) != 0 { - items := make([]interface{}, 0) - for _, item := range m.Enum { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"enum", items}) - } - // &{Name:enum Type:Any StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:} - if m.MultipleOf != 0.0 { - info = append(info, yaml.MapItem{"multipleOf", m.MultipleOf}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Header suitable for JSON or YAML export. -func (m *Header) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Type != "" { - info = append(info, yaml.MapItem{"type", m.Type}) - } - if m.Format != "" { - info = append(info, yaml.MapItem{"format", m.Format}) - } - if m.Items != nil { - info = append(info, yaml.MapItem{"items", m.Items.ToRawInfo()}) - } - // &{Name:items Type:PrimitivesItems StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.CollectionFormat != "" { - info = append(info, yaml.MapItem{"collectionFormat", m.CollectionFormat}) - } - if m.Default != nil { - info = append(info, yaml.MapItem{"default", m.Default.ToRawInfo()}) - } - // &{Name:default Type:Any StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Maximum != 0.0 { - info = append(info, yaml.MapItem{"maximum", m.Maximum}) - } - if m.ExclusiveMaximum != false { - info = append(info, yaml.MapItem{"exclusiveMaximum", m.ExclusiveMaximum}) - } - if m.Minimum != 0.0 { - info = append(info, yaml.MapItem{"minimum", m.Minimum}) - } - if m.ExclusiveMinimum != false { - info = append(info, yaml.MapItem{"exclusiveMinimum", m.ExclusiveMinimum}) - } - if m.MaxLength != 0 { - info = append(info, yaml.MapItem{"maxLength", m.MaxLength}) - } - if m.MinLength != 0 { - info = append(info, yaml.MapItem{"minLength", m.MinLength}) - } - if m.Pattern != "" { - info = append(info, yaml.MapItem{"pattern", m.Pattern}) - } - if m.MaxItems != 0 { - info = append(info, yaml.MapItem{"maxItems", m.MaxItems}) - } - if m.MinItems != 0 { - info = append(info, yaml.MapItem{"minItems", m.MinItems}) - } - if m.UniqueItems != false { - info = append(info, yaml.MapItem{"uniqueItems", m.UniqueItems}) - } - if len(m.Enum) != 0 { - items := make([]interface{}, 0) - for _, item := range m.Enum { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"enum", items}) - } - // &{Name:enum Type:Any StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:} - if m.MultipleOf != 0.0 { - info = append(info, yaml.MapItem{"multipleOf", m.MultipleOf}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of HeaderParameterSubSchema suitable for JSON or YAML export. -func (m *HeaderParameterSubSchema) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Required != false { - info = append(info, yaml.MapItem{"required", m.Required}) - } - if m.In != "" { - info = append(info, yaml.MapItem{"in", m.In}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - if m.Type != "" { - info = append(info, yaml.MapItem{"type", m.Type}) - } - if m.Format != "" { - info = append(info, yaml.MapItem{"format", m.Format}) - } - if m.Items != nil { - info = append(info, yaml.MapItem{"items", m.Items.ToRawInfo()}) - } - // &{Name:items Type:PrimitivesItems StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.CollectionFormat != "" { - info = append(info, yaml.MapItem{"collectionFormat", m.CollectionFormat}) - } - if m.Default != nil { - info = append(info, yaml.MapItem{"default", m.Default.ToRawInfo()}) - } - // &{Name:default Type:Any StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Maximum != 0.0 { - info = append(info, yaml.MapItem{"maximum", m.Maximum}) - } - if m.ExclusiveMaximum != false { - info = append(info, yaml.MapItem{"exclusiveMaximum", m.ExclusiveMaximum}) - } - if m.Minimum != 0.0 { - info = append(info, yaml.MapItem{"minimum", m.Minimum}) - } - if m.ExclusiveMinimum != false { - info = append(info, yaml.MapItem{"exclusiveMinimum", m.ExclusiveMinimum}) - } - if m.MaxLength != 0 { - info = append(info, yaml.MapItem{"maxLength", m.MaxLength}) - } - if m.MinLength != 0 { - info = append(info, yaml.MapItem{"minLength", m.MinLength}) - } - if m.Pattern != "" { - info = append(info, yaml.MapItem{"pattern", m.Pattern}) - } - if m.MaxItems != 0 { - info = append(info, yaml.MapItem{"maxItems", m.MaxItems}) - } - if m.MinItems != 0 { - info = append(info, yaml.MapItem{"minItems", m.MinItems}) - } - if m.UniqueItems != false { - info = append(info, yaml.MapItem{"uniqueItems", m.UniqueItems}) - } - if len(m.Enum) != 0 { - items := make([]interface{}, 0) - for _, item := range m.Enum { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"enum", items}) - } - // &{Name:enum Type:Any StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:} - if m.MultipleOf != 0.0 { - info = append(info, yaml.MapItem{"multipleOf", m.MultipleOf}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Headers suitable for JSON or YAML export. -func (m *Headers) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.AdditionalProperties != nil { - for _, item := range m.AdditionalProperties { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:additionalProperties Type:NamedHeader StringEnumValues:[] MapType:Header Repeated:true Pattern: Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Info suitable for JSON or YAML export. -func (m *Info) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Title != "" { - info = append(info, yaml.MapItem{"title", m.Title}) - } - if m.Version != "" { - info = append(info, yaml.MapItem{"version", m.Version}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.TermsOfService != "" { - info = append(info, yaml.MapItem{"termsOfService", m.TermsOfService}) - } - if m.Contact != nil { - info = append(info, yaml.MapItem{"contact", m.Contact.ToRawInfo()}) - } - // &{Name:contact Type:Contact StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.License != nil { - info = append(info, yaml.MapItem{"license", m.License.ToRawInfo()}) - } - // &{Name:license Type:License StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of ItemsItem suitable for JSON or YAML export. -func (m *ItemsItem) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if len(m.Schema) != 0 { - items := make([]interface{}, 0) - for _, item := range m.Schema { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"schema", items}) - } - // &{Name:schema Type:Schema StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:} - return info -} - -// ToRawInfo returns a description of JsonReference suitable for JSON or YAML export. -func (m *JsonReference) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.XRef != "" { - info = append(info, yaml.MapItem{"$ref", m.XRef}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - return info -} - -// ToRawInfo returns a description of License suitable for JSON or YAML export. -func (m *License) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - if m.Url != "" { - info = append(info, yaml.MapItem{"url", m.Url}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of NamedAny suitable for JSON or YAML export. -func (m *NamedAny) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - // &{Name:value Type:Any StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value} - return info -} - -// ToRawInfo returns a description of NamedHeader suitable for JSON or YAML export. -func (m *NamedHeader) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - // &{Name:value Type:Header StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value} - return info -} - -// ToRawInfo returns a description of NamedParameter suitable for JSON or YAML export. -func (m *NamedParameter) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - // &{Name:value Type:Parameter StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value} - return info -} - -// ToRawInfo returns a description of NamedPathItem suitable for JSON or YAML export. -func (m *NamedPathItem) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - // &{Name:value Type:PathItem StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value} - return info -} - -// ToRawInfo returns a description of NamedResponse suitable for JSON or YAML export. -func (m *NamedResponse) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - // &{Name:value Type:Response StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value} - return info -} - -// ToRawInfo returns a description of NamedResponseValue suitable for JSON or YAML export. -func (m *NamedResponseValue) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - // &{Name:value Type:ResponseValue StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value} - return info -} - -// ToRawInfo returns a description of NamedSchema suitable for JSON or YAML export. -func (m *NamedSchema) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - // &{Name:value Type:Schema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value} - return info -} - -// ToRawInfo returns a description of NamedSecurityDefinitionsItem suitable for JSON or YAML export. -func (m *NamedSecurityDefinitionsItem) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - // &{Name:value Type:SecurityDefinitionsItem StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value} - return info -} - -// ToRawInfo returns a description of NamedString suitable for JSON or YAML export. -func (m *NamedString) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - if m.Value != "" { - info = append(info, yaml.MapItem{"value", m.Value}) - } - return info -} - -// ToRawInfo returns a description of NamedStringArray suitable for JSON or YAML export. -func (m *NamedStringArray) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - // &{Name:value Type:StringArray StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value} - return info -} - -// ToRawInfo returns a description of NonBodyParameter suitable for JSON or YAML export. -func (m *NonBodyParameter) ToRawInfo() interface{} { - // ONE OF WRAPPER - // NonBodyParameter - // {Name:headerParameterSubSchema Type:HeaderParameterSubSchema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v0 := m.GetHeaderParameterSubSchema() - if v0 != nil { - return v0.ToRawInfo() - } - // {Name:formDataParameterSubSchema Type:FormDataParameterSubSchema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v1 := m.GetFormDataParameterSubSchema() - if v1 != nil { - return v1.ToRawInfo() - } - // {Name:queryParameterSubSchema Type:QueryParameterSubSchema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v2 := m.GetQueryParameterSubSchema() - if v2 != nil { - return v2.ToRawInfo() - } - // {Name:pathParameterSubSchema Type:PathParameterSubSchema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v3 := m.GetPathParameterSubSchema() - if v3 != nil { - return v3.ToRawInfo() - } - return nil -} - -// ToRawInfo returns a description of Oauth2AccessCodeSecurity suitable for JSON or YAML export. -func (m *Oauth2AccessCodeSecurity) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Type != "" { - info = append(info, yaml.MapItem{"type", m.Type}) - } - if m.Flow != "" { - info = append(info, yaml.MapItem{"flow", m.Flow}) - } - if m.Scopes != nil { - info = append(info, yaml.MapItem{"scopes", m.Scopes.ToRawInfo()}) - } - // &{Name:scopes Type:Oauth2Scopes StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.AuthorizationUrl != "" { - info = append(info, yaml.MapItem{"authorizationUrl", m.AuthorizationUrl}) - } - if m.TokenUrl != "" { - info = append(info, yaml.MapItem{"tokenUrl", m.TokenUrl}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Oauth2ApplicationSecurity suitable for JSON or YAML export. -func (m *Oauth2ApplicationSecurity) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Type != "" { - info = append(info, yaml.MapItem{"type", m.Type}) - } - if m.Flow != "" { - info = append(info, yaml.MapItem{"flow", m.Flow}) - } - if m.Scopes != nil { - info = append(info, yaml.MapItem{"scopes", m.Scopes.ToRawInfo()}) - } - // &{Name:scopes Type:Oauth2Scopes StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.TokenUrl != "" { - info = append(info, yaml.MapItem{"tokenUrl", m.TokenUrl}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Oauth2ImplicitSecurity suitable for JSON or YAML export. -func (m *Oauth2ImplicitSecurity) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Type != "" { - info = append(info, yaml.MapItem{"type", m.Type}) - } - if m.Flow != "" { - info = append(info, yaml.MapItem{"flow", m.Flow}) - } - if m.Scopes != nil { - info = append(info, yaml.MapItem{"scopes", m.Scopes.ToRawInfo()}) - } - // &{Name:scopes Type:Oauth2Scopes StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.AuthorizationUrl != "" { - info = append(info, yaml.MapItem{"authorizationUrl", m.AuthorizationUrl}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Oauth2PasswordSecurity suitable for JSON or YAML export. -func (m *Oauth2PasswordSecurity) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Type != "" { - info = append(info, yaml.MapItem{"type", m.Type}) - } - if m.Flow != "" { - info = append(info, yaml.MapItem{"flow", m.Flow}) - } - if m.Scopes != nil { - info = append(info, yaml.MapItem{"scopes", m.Scopes.ToRawInfo()}) - } - // &{Name:scopes Type:Oauth2Scopes StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.TokenUrl != "" { - info = append(info, yaml.MapItem{"tokenUrl", m.TokenUrl}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Oauth2Scopes suitable for JSON or YAML export. -func (m *Oauth2Scopes) ToRawInfo() interface{} { - info := yaml.MapSlice{} - // &{Name:additionalProperties Type:NamedString StringEnumValues:[] MapType:string Repeated:true Pattern: Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Operation suitable for JSON or YAML export. -func (m *Operation) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if len(m.Tags) != 0 { - info = append(info, yaml.MapItem{"tags", m.Tags}) - } - if m.Summary != "" { - info = append(info, yaml.MapItem{"summary", m.Summary}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.ExternalDocs != nil { - info = append(info, yaml.MapItem{"externalDocs", m.ExternalDocs.ToRawInfo()}) - } - // &{Name:externalDocs Type:ExternalDocs StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.OperationId != "" { - info = append(info, yaml.MapItem{"operationId", m.OperationId}) - } - if len(m.Produces) != 0 { - info = append(info, yaml.MapItem{"produces", m.Produces}) - } - if len(m.Consumes) != 0 { - info = append(info, yaml.MapItem{"consumes", m.Consumes}) - } - if len(m.Parameters) != 0 { - items := make([]interface{}, 0) - for _, item := range m.Parameters { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"parameters", items}) - } - // &{Name:parameters Type:ParametersItem StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:The parameters needed to send a valid API call.} - if m.Responses != nil { - info = append(info, yaml.MapItem{"responses", m.Responses.ToRawInfo()}) - } - // &{Name:responses Type:Responses StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if len(m.Schemes) != 0 { - info = append(info, yaml.MapItem{"schemes", m.Schemes}) - } - if m.Deprecated != false { - info = append(info, yaml.MapItem{"deprecated", m.Deprecated}) - } - if len(m.Security) != 0 { - items := make([]interface{}, 0) - for _, item := range m.Security { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"security", items}) - } - // &{Name:security Type:SecurityRequirement StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:} - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Parameter suitable for JSON or YAML export. -func (m *Parameter) ToRawInfo() interface{} { - // ONE OF WRAPPER - // Parameter - // {Name:bodyParameter Type:BodyParameter StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v0 := m.GetBodyParameter() - if v0 != nil { - return v0.ToRawInfo() - } - // {Name:nonBodyParameter Type:NonBodyParameter StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v1 := m.GetNonBodyParameter() - if v1 != nil { - return v1.ToRawInfo() - } - return nil -} - -// ToRawInfo returns a description of ParameterDefinitions suitable for JSON or YAML export. -func (m *ParameterDefinitions) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.AdditionalProperties != nil { - for _, item := range m.AdditionalProperties { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:additionalProperties Type:NamedParameter StringEnumValues:[] MapType:Parameter Repeated:true Pattern: Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of ParametersItem suitable for JSON or YAML export. -func (m *ParametersItem) ToRawInfo() interface{} { - // ONE OF WRAPPER - // ParametersItem - // {Name:parameter Type:Parameter StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v0 := m.GetParameter() - if v0 != nil { - return v0.ToRawInfo() - } - // {Name:jsonReference Type:JsonReference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v1 := m.GetJsonReference() - if v1 != nil { - return v1.ToRawInfo() - } - return nil -} - -// ToRawInfo returns a description of PathItem suitable for JSON or YAML export. -func (m *PathItem) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.XRef != "" { - info = append(info, yaml.MapItem{"$ref", m.XRef}) - } - if m.Get != nil { - info = append(info, yaml.MapItem{"get", m.Get.ToRawInfo()}) - } - // &{Name:get Type:Operation StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Put != nil { - info = append(info, yaml.MapItem{"put", m.Put.ToRawInfo()}) - } - // &{Name:put Type:Operation StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Post != nil { - info = append(info, yaml.MapItem{"post", m.Post.ToRawInfo()}) - } - // &{Name:post Type:Operation StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Delete != nil { - info = append(info, yaml.MapItem{"delete", m.Delete.ToRawInfo()}) - } - // &{Name:delete Type:Operation StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Options != nil { - info = append(info, yaml.MapItem{"options", m.Options.ToRawInfo()}) - } - // &{Name:options Type:Operation StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Head != nil { - info = append(info, yaml.MapItem{"head", m.Head.ToRawInfo()}) - } - // &{Name:head Type:Operation StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Patch != nil { - info = append(info, yaml.MapItem{"patch", m.Patch.ToRawInfo()}) - } - // &{Name:patch Type:Operation StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if len(m.Parameters) != 0 { - items := make([]interface{}, 0) - for _, item := range m.Parameters { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"parameters", items}) - } - // &{Name:parameters Type:ParametersItem StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:The parameters needed to send a valid API call.} - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of PathParameterSubSchema suitable for JSON or YAML export. -func (m *PathParameterSubSchema) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Required != false { - info = append(info, yaml.MapItem{"required", m.Required}) - } - if m.In != "" { - info = append(info, yaml.MapItem{"in", m.In}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - if m.Type != "" { - info = append(info, yaml.MapItem{"type", m.Type}) - } - if m.Format != "" { - info = append(info, yaml.MapItem{"format", m.Format}) - } - if m.Items != nil { - info = append(info, yaml.MapItem{"items", m.Items.ToRawInfo()}) - } - // &{Name:items Type:PrimitivesItems StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.CollectionFormat != "" { - info = append(info, yaml.MapItem{"collectionFormat", m.CollectionFormat}) - } - if m.Default != nil { - info = append(info, yaml.MapItem{"default", m.Default.ToRawInfo()}) - } - // &{Name:default Type:Any StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Maximum != 0.0 { - info = append(info, yaml.MapItem{"maximum", m.Maximum}) - } - if m.ExclusiveMaximum != false { - info = append(info, yaml.MapItem{"exclusiveMaximum", m.ExclusiveMaximum}) - } - if m.Minimum != 0.0 { - info = append(info, yaml.MapItem{"minimum", m.Minimum}) - } - if m.ExclusiveMinimum != false { - info = append(info, yaml.MapItem{"exclusiveMinimum", m.ExclusiveMinimum}) - } - if m.MaxLength != 0 { - info = append(info, yaml.MapItem{"maxLength", m.MaxLength}) - } - if m.MinLength != 0 { - info = append(info, yaml.MapItem{"minLength", m.MinLength}) - } - if m.Pattern != "" { - info = append(info, yaml.MapItem{"pattern", m.Pattern}) - } - if m.MaxItems != 0 { - info = append(info, yaml.MapItem{"maxItems", m.MaxItems}) - } - if m.MinItems != 0 { - info = append(info, yaml.MapItem{"minItems", m.MinItems}) - } - if m.UniqueItems != false { - info = append(info, yaml.MapItem{"uniqueItems", m.UniqueItems}) - } - if len(m.Enum) != 0 { - items := make([]interface{}, 0) - for _, item := range m.Enum { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"enum", items}) - } - // &{Name:enum Type:Any StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:} - if m.MultipleOf != 0.0 { - info = append(info, yaml.MapItem{"multipleOf", m.MultipleOf}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Paths suitable for JSON or YAML export. -func (m *Paths) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - if m.Path != nil { - for _, item := range m.Path { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:Path Type:NamedPathItem StringEnumValues:[] MapType:PathItem Repeated:true Pattern:^/ Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of PrimitivesItems suitable for JSON or YAML export. -func (m *PrimitivesItems) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Type != "" { - info = append(info, yaml.MapItem{"type", m.Type}) - } - if m.Format != "" { - info = append(info, yaml.MapItem{"format", m.Format}) - } - if m.Items != nil { - info = append(info, yaml.MapItem{"items", m.Items.ToRawInfo()}) - } - // &{Name:items Type:PrimitivesItems StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.CollectionFormat != "" { - info = append(info, yaml.MapItem{"collectionFormat", m.CollectionFormat}) - } - if m.Default != nil { - info = append(info, yaml.MapItem{"default", m.Default.ToRawInfo()}) - } - // &{Name:default Type:Any StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Maximum != 0.0 { - info = append(info, yaml.MapItem{"maximum", m.Maximum}) - } - if m.ExclusiveMaximum != false { - info = append(info, yaml.MapItem{"exclusiveMaximum", m.ExclusiveMaximum}) - } - if m.Minimum != 0.0 { - info = append(info, yaml.MapItem{"minimum", m.Minimum}) - } - if m.ExclusiveMinimum != false { - info = append(info, yaml.MapItem{"exclusiveMinimum", m.ExclusiveMinimum}) - } - if m.MaxLength != 0 { - info = append(info, yaml.MapItem{"maxLength", m.MaxLength}) - } - if m.MinLength != 0 { - info = append(info, yaml.MapItem{"minLength", m.MinLength}) - } - if m.Pattern != "" { - info = append(info, yaml.MapItem{"pattern", m.Pattern}) - } - if m.MaxItems != 0 { - info = append(info, yaml.MapItem{"maxItems", m.MaxItems}) - } - if m.MinItems != 0 { - info = append(info, yaml.MapItem{"minItems", m.MinItems}) - } - if m.UniqueItems != false { - info = append(info, yaml.MapItem{"uniqueItems", m.UniqueItems}) - } - if len(m.Enum) != 0 { - items := make([]interface{}, 0) - for _, item := range m.Enum { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"enum", items}) - } - // &{Name:enum Type:Any StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:} - if m.MultipleOf != 0.0 { - info = append(info, yaml.MapItem{"multipleOf", m.MultipleOf}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Properties suitable for JSON or YAML export. -func (m *Properties) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.AdditionalProperties != nil { - for _, item := range m.AdditionalProperties { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:additionalProperties Type:NamedSchema StringEnumValues:[] MapType:Schema Repeated:true Pattern: Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of QueryParameterSubSchema suitable for JSON or YAML export. -func (m *QueryParameterSubSchema) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Required != false { - info = append(info, yaml.MapItem{"required", m.Required}) - } - if m.In != "" { - info = append(info, yaml.MapItem{"in", m.In}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - if m.AllowEmptyValue != false { - info = append(info, yaml.MapItem{"allowEmptyValue", m.AllowEmptyValue}) - } - if m.Type != "" { - info = append(info, yaml.MapItem{"type", m.Type}) - } - if m.Format != "" { - info = append(info, yaml.MapItem{"format", m.Format}) - } - if m.Items != nil { - info = append(info, yaml.MapItem{"items", m.Items.ToRawInfo()}) - } - // &{Name:items Type:PrimitivesItems StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.CollectionFormat != "" { - info = append(info, yaml.MapItem{"collectionFormat", m.CollectionFormat}) - } - if m.Default != nil { - info = append(info, yaml.MapItem{"default", m.Default.ToRawInfo()}) - } - // &{Name:default Type:Any StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Maximum != 0.0 { - info = append(info, yaml.MapItem{"maximum", m.Maximum}) - } - if m.ExclusiveMaximum != false { - info = append(info, yaml.MapItem{"exclusiveMaximum", m.ExclusiveMaximum}) - } - if m.Minimum != 0.0 { - info = append(info, yaml.MapItem{"minimum", m.Minimum}) - } - if m.ExclusiveMinimum != false { - info = append(info, yaml.MapItem{"exclusiveMinimum", m.ExclusiveMinimum}) - } - if m.MaxLength != 0 { - info = append(info, yaml.MapItem{"maxLength", m.MaxLength}) - } - if m.MinLength != 0 { - info = append(info, yaml.MapItem{"minLength", m.MinLength}) - } - if m.Pattern != "" { - info = append(info, yaml.MapItem{"pattern", m.Pattern}) - } - if m.MaxItems != 0 { - info = append(info, yaml.MapItem{"maxItems", m.MaxItems}) - } - if m.MinItems != 0 { - info = append(info, yaml.MapItem{"minItems", m.MinItems}) - } - if m.UniqueItems != false { - info = append(info, yaml.MapItem{"uniqueItems", m.UniqueItems}) - } - if len(m.Enum) != 0 { - items := make([]interface{}, 0) - for _, item := range m.Enum { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"enum", items}) - } - // &{Name:enum Type:Any StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:} - if m.MultipleOf != 0.0 { - info = append(info, yaml.MapItem{"multipleOf", m.MultipleOf}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Response suitable for JSON or YAML export. -func (m *Response) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.Schema != nil { - info = append(info, yaml.MapItem{"schema", m.Schema.ToRawInfo()}) - } - // &{Name:schema Type:SchemaItem StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Headers != nil { - info = append(info, yaml.MapItem{"headers", m.Headers.ToRawInfo()}) - } - // &{Name:headers Type:Headers StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Examples != nil { - info = append(info, yaml.MapItem{"examples", m.Examples.ToRawInfo()}) - } - // &{Name:examples Type:Examples StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of ResponseDefinitions suitable for JSON or YAML export. -func (m *ResponseDefinitions) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.AdditionalProperties != nil { - for _, item := range m.AdditionalProperties { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:additionalProperties Type:NamedResponse StringEnumValues:[] MapType:Response Repeated:true Pattern: Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of ResponseValue suitable for JSON or YAML export. -func (m *ResponseValue) ToRawInfo() interface{} { - // ONE OF WRAPPER - // ResponseValue - // {Name:response Type:Response StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v0 := m.GetResponse() - if v0 != nil { - return v0.ToRawInfo() - } - // {Name:jsonReference Type:JsonReference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v1 := m.GetJsonReference() - if v1 != nil { - return v1.ToRawInfo() - } - return nil -} - -// ToRawInfo returns a description of Responses suitable for JSON or YAML export. -func (m *Responses) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.ResponseCode != nil { - for _, item := range m.ResponseCode { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:ResponseCode Type:NamedResponseValue StringEnumValues:[] MapType:ResponseValue Repeated:true Pattern:^([0-9]{3})$|^(default)$ Implicit:true Description:} - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Schema suitable for JSON or YAML export. -func (m *Schema) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.XRef != "" { - info = append(info, yaml.MapItem{"$ref", m.XRef}) - } - if m.Format != "" { - info = append(info, yaml.MapItem{"format", m.Format}) - } - if m.Title != "" { - info = append(info, yaml.MapItem{"title", m.Title}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.Default != nil { - info = append(info, yaml.MapItem{"default", m.Default.ToRawInfo()}) - } - // &{Name:default Type:Any StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.MultipleOf != 0.0 { - info = append(info, yaml.MapItem{"multipleOf", m.MultipleOf}) - } - if m.Maximum != 0.0 { - info = append(info, yaml.MapItem{"maximum", m.Maximum}) - } - if m.ExclusiveMaximum != false { - info = append(info, yaml.MapItem{"exclusiveMaximum", m.ExclusiveMaximum}) - } - if m.Minimum != 0.0 { - info = append(info, yaml.MapItem{"minimum", m.Minimum}) - } - if m.ExclusiveMinimum != false { - info = append(info, yaml.MapItem{"exclusiveMinimum", m.ExclusiveMinimum}) - } - if m.MaxLength != 0 { - info = append(info, yaml.MapItem{"maxLength", m.MaxLength}) - } - if m.MinLength != 0 { - info = append(info, yaml.MapItem{"minLength", m.MinLength}) - } - if m.Pattern != "" { - info = append(info, yaml.MapItem{"pattern", m.Pattern}) - } - if m.MaxItems != 0 { - info = append(info, yaml.MapItem{"maxItems", m.MaxItems}) - } - if m.MinItems != 0 { - info = append(info, yaml.MapItem{"minItems", m.MinItems}) - } - if m.UniqueItems != false { - info = append(info, yaml.MapItem{"uniqueItems", m.UniqueItems}) - } - if m.MaxProperties != 0 { - info = append(info, yaml.MapItem{"maxProperties", m.MaxProperties}) - } - if m.MinProperties != 0 { - info = append(info, yaml.MapItem{"minProperties", m.MinProperties}) - } - if len(m.Required) != 0 { - info = append(info, yaml.MapItem{"required", m.Required}) - } - if len(m.Enum) != 0 { - items := make([]interface{}, 0) - for _, item := range m.Enum { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"enum", items}) - } - // &{Name:enum Type:Any StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:} - if m.AdditionalProperties != nil { - info = append(info, yaml.MapItem{"additionalProperties", m.AdditionalProperties.ToRawInfo()}) - } - // &{Name:additionalProperties Type:AdditionalPropertiesItem StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Type != nil { - if len(m.Type.Value) == 1 { - info = append(info, yaml.MapItem{"type", m.Type.Value[0]}) - } else { - info = append(info, yaml.MapItem{"type", m.Type.Value}) - } - } - // &{Name:type Type:TypeItem StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Items != nil { - items := make([]interface{}, 0) - for _, item := range m.Items.Schema { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"items", items[0]}) - } - // &{Name:items Type:ItemsItem StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if len(m.AllOf) != 0 { - items := make([]interface{}, 0) - for _, item := range m.AllOf { - items = append(items, item.ToRawInfo()) - } - info = append(info, yaml.MapItem{"allOf", items}) - } - // &{Name:allOf Type:Schema StringEnumValues:[] MapType: Repeated:true Pattern: Implicit:false Description:} - if m.Properties != nil { - info = append(info, yaml.MapItem{"properties", m.Properties.ToRawInfo()}) - } - // &{Name:properties Type:Properties StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Discriminator != "" { - info = append(info, yaml.MapItem{"discriminator", m.Discriminator}) - } - if m.ReadOnly != false { - info = append(info, yaml.MapItem{"readOnly", m.ReadOnly}) - } - if m.Xml != nil { - info = append(info, yaml.MapItem{"xml", m.Xml.ToRawInfo()}) - } - // &{Name:xml Type:Xml StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.ExternalDocs != nil { - info = append(info, yaml.MapItem{"externalDocs", m.ExternalDocs.ToRawInfo()}) - } - // &{Name:externalDocs Type:ExternalDocs StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.Example != nil { - info = append(info, yaml.MapItem{"example", m.Example.ToRawInfo()}) - } - // &{Name:example Type:Any StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of SchemaItem suitable for JSON or YAML export. -func (m *SchemaItem) ToRawInfo() interface{} { - // ONE OF WRAPPER - // SchemaItem - // {Name:schema Type:Schema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v0 := m.GetSchema() - if v0 != nil { - return v0.ToRawInfo() - } - // {Name:fileSchema Type:FileSchema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v1 := m.GetFileSchema() - if v1 != nil { - return v1.ToRawInfo() - } - return nil -} - -// ToRawInfo returns a description of SecurityDefinitions suitable for JSON or YAML export. -func (m *SecurityDefinitions) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.AdditionalProperties != nil { - for _, item := range m.AdditionalProperties { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:additionalProperties Type:NamedSecurityDefinitionsItem StringEnumValues:[] MapType:SecurityDefinitionsItem Repeated:true Pattern: Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of SecurityDefinitionsItem suitable for JSON or YAML export. -func (m *SecurityDefinitionsItem) ToRawInfo() interface{} { - // ONE OF WRAPPER - // SecurityDefinitionsItem - // {Name:basicAuthenticationSecurity Type:BasicAuthenticationSecurity StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v0 := m.GetBasicAuthenticationSecurity() - if v0 != nil { - return v0.ToRawInfo() - } - // {Name:apiKeySecurity Type:ApiKeySecurity StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v1 := m.GetApiKeySecurity() - if v1 != nil { - return v1.ToRawInfo() - } - // {Name:oauth2ImplicitSecurity Type:Oauth2ImplicitSecurity StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v2 := m.GetOauth2ImplicitSecurity() - if v2 != nil { - return v2.ToRawInfo() - } - // {Name:oauth2PasswordSecurity Type:Oauth2PasswordSecurity StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v3 := m.GetOauth2PasswordSecurity() - if v3 != nil { - return v3.ToRawInfo() - } - // {Name:oauth2ApplicationSecurity Type:Oauth2ApplicationSecurity StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v4 := m.GetOauth2ApplicationSecurity() - if v4 != nil { - return v4.ToRawInfo() - } - // {Name:oauth2AccessCodeSecurity Type:Oauth2AccessCodeSecurity StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - v5 := m.GetOauth2AccessCodeSecurity() - if v5 != nil { - return v5.ToRawInfo() - } - return nil -} - -// ToRawInfo returns a description of SecurityRequirement suitable for JSON or YAML export. -func (m *SecurityRequirement) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.AdditionalProperties != nil { - for _, item := range m.AdditionalProperties { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:additionalProperties Type:NamedStringArray StringEnumValues:[] MapType:StringArray Repeated:true Pattern: Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of StringArray suitable for JSON or YAML export. -func (m *StringArray) ToRawInfo() interface{} { - return m.Value -} - -// ToRawInfo returns a description of Tag suitable for JSON or YAML export. -func (m *Tag) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - if m.Description != "" { - info = append(info, yaml.MapItem{"description", m.Description}) - } - if m.ExternalDocs != nil { - info = append(info, yaml.MapItem{"externalDocs", m.ExternalDocs.ToRawInfo()}) - } - // &{Name:externalDocs Type:ExternalDocs StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:} - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of TypeItem suitable for JSON or YAML export. -func (m *TypeItem) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if len(m.Value) != 0 { - info = append(info, yaml.MapItem{"value", m.Value}) - } - return info -} - -// ToRawInfo returns a description of VendorExtension suitable for JSON or YAML export. -func (m *VendorExtension) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.AdditionalProperties != nil { - for _, item := range m.AdditionalProperties { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:additionalProperties Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern: Implicit:true Description:} - return info -} - -// ToRawInfo returns a description of Xml suitable for JSON or YAML export. -func (m *Xml) ToRawInfo() interface{} { - info := yaml.MapSlice{} - if m.Name != "" { - info = append(info, yaml.MapItem{"name", m.Name}) - } - if m.Namespace != "" { - info = append(info, yaml.MapItem{"namespace", m.Namespace}) - } - if m.Prefix != "" { - info = append(info, yaml.MapItem{"prefix", m.Prefix}) - } - if m.Attribute != false { - info = append(info, yaml.MapItem{"attribute", m.Attribute}) - } - if m.Wrapped != false { - info = append(info, yaml.MapItem{"wrapped", m.Wrapped}) - } - if m.VendorExtension != nil { - for _, item := range m.VendorExtension { - info = append(info, yaml.MapItem{item.Name, item.Value.ToRawInfo()}) - } - } - // &{Name:VendorExtension Type:NamedAny StringEnumValues:[] MapType:Any Repeated:true Pattern:^x- Implicit:true Description:} - return info -} - -var ( - pattern0 = regexp.MustCompile("^x-") - pattern1 = regexp.MustCompile("^/") - pattern2 = regexp.MustCompile("^([0-9]{3})$|^(default)$") -) diff --git a/vendor/github.com/googleapis/gnostic/OpenAPIv2/OpenAPIv2.pb.go b/vendor/github.com/googleapis/gnostic/OpenAPIv2/OpenAPIv2.pb.go deleted file mode 100644 index 37da7df25..000000000 --- a/vendor/github.com/googleapis/gnostic/OpenAPIv2/OpenAPIv2.pb.go +++ /dev/null @@ -1,4456 +0,0 @@ -// Code generated by protoc-gen-go. -// source: OpenAPIv2/OpenAPIv2.proto -// DO NOT EDIT! - -/* -Package openapi_v2 is a generated protocol buffer package. - -It is generated from these files: - OpenAPIv2/OpenAPIv2.proto - -It has these top-level messages: - AdditionalPropertiesItem - Any - ApiKeySecurity - BasicAuthenticationSecurity - BodyParameter - Contact - Default - Definitions - Document - Examples - ExternalDocs - FileSchema - FormDataParameterSubSchema - Header - HeaderParameterSubSchema - Headers - Info - ItemsItem - JsonReference - License - NamedAny - NamedHeader - NamedParameter - NamedPathItem - NamedResponse - NamedResponseValue - NamedSchema - NamedSecurityDefinitionsItem - NamedString - NamedStringArray - NonBodyParameter - Oauth2AccessCodeSecurity - Oauth2ApplicationSecurity - Oauth2ImplicitSecurity - Oauth2PasswordSecurity - Oauth2Scopes - Operation - Parameter - ParameterDefinitions - ParametersItem - PathItem - PathParameterSubSchema - Paths - PrimitivesItems - Properties - QueryParameterSubSchema - Response - ResponseDefinitions - ResponseValue - Responses - Schema - SchemaItem - SecurityDefinitions - SecurityDefinitionsItem - SecurityRequirement - StringArray - Tag - TypeItem - VendorExtension - Xml -*/ -package openapi_v2 - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import google_protobuf "github.com/golang/protobuf/ptypes/any" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -type AdditionalPropertiesItem struct { - // Types that are valid to be assigned to Oneof: - // *AdditionalPropertiesItem_Schema - // *AdditionalPropertiesItem_Boolean - Oneof isAdditionalPropertiesItem_Oneof `protobuf_oneof:"oneof"` -} - -func (m *AdditionalPropertiesItem) Reset() { *m = AdditionalPropertiesItem{} } -func (m *AdditionalPropertiesItem) String() string { return proto.CompactTextString(m) } -func (*AdditionalPropertiesItem) ProtoMessage() {} -func (*AdditionalPropertiesItem) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -type isAdditionalPropertiesItem_Oneof interface { - isAdditionalPropertiesItem_Oneof() -} - -type AdditionalPropertiesItem_Schema struct { - Schema *Schema `protobuf:"bytes,1,opt,name=schema,oneof"` -} -type AdditionalPropertiesItem_Boolean struct { - Boolean bool `protobuf:"varint,2,opt,name=boolean,oneof"` -} - -func (*AdditionalPropertiesItem_Schema) isAdditionalPropertiesItem_Oneof() {} -func (*AdditionalPropertiesItem_Boolean) isAdditionalPropertiesItem_Oneof() {} - -func (m *AdditionalPropertiesItem) GetOneof() isAdditionalPropertiesItem_Oneof { - if m != nil { - return m.Oneof - } - return nil -} - -func (m *AdditionalPropertiesItem) GetSchema() *Schema { - if x, ok := m.GetOneof().(*AdditionalPropertiesItem_Schema); ok { - return x.Schema - } - return nil -} - -func (m *AdditionalPropertiesItem) GetBoolean() bool { - if x, ok := m.GetOneof().(*AdditionalPropertiesItem_Boolean); ok { - return x.Boolean - } - return false -} - -// XXX_OneofFuncs is for the internal use of the proto package. -func (*AdditionalPropertiesItem) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _AdditionalPropertiesItem_OneofMarshaler, _AdditionalPropertiesItem_OneofUnmarshaler, _AdditionalPropertiesItem_OneofSizer, []interface{}{ - (*AdditionalPropertiesItem_Schema)(nil), - (*AdditionalPropertiesItem_Boolean)(nil), - } -} - -func _AdditionalPropertiesItem_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*AdditionalPropertiesItem) - // oneof - switch x := m.Oneof.(type) { - case *AdditionalPropertiesItem_Schema: - b.EncodeVarint(1<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.Schema); err != nil { - return err - } - case *AdditionalPropertiesItem_Boolean: - t := uint64(0) - if x.Boolean { - t = 1 - } - b.EncodeVarint(2<<3 | proto.WireVarint) - b.EncodeVarint(t) - case nil: - default: - return fmt.Errorf("AdditionalPropertiesItem.Oneof has unexpected type %T", x) - } - return nil -} - -func _AdditionalPropertiesItem_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*AdditionalPropertiesItem) - switch tag { - case 1: // oneof.schema - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(Schema) - err := b.DecodeMessage(msg) - m.Oneof = &AdditionalPropertiesItem_Schema{msg} - return true, err - case 2: // oneof.boolean - if wire != proto.WireVarint { - return true, proto.ErrInternalBadWireType - } - x, err := b.DecodeVarint() - m.Oneof = &AdditionalPropertiesItem_Boolean{x != 0} - return true, err - default: - return false, nil - } -} - -func _AdditionalPropertiesItem_OneofSizer(msg proto.Message) (n int) { - m := msg.(*AdditionalPropertiesItem) - // oneof - switch x := m.Oneof.(type) { - case *AdditionalPropertiesItem_Schema: - s := proto.Size(x.Schema) - n += proto.SizeVarint(1<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case *AdditionalPropertiesItem_Boolean: - n += proto.SizeVarint(2<<3 | proto.WireVarint) - n += 1 - case nil: - default: - panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) - } - return n -} - -type Any struct { - Value *google_protobuf.Any `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"` - Yaml string `protobuf:"bytes,2,opt,name=yaml" json:"yaml,omitempty"` -} - -func (m *Any) Reset() { *m = Any{} } -func (m *Any) String() string { return proto.CompactTextString(m) } -func (*Any) ProtoMessage() {} -func (*Any) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -func (m *Any) GetValue() *google_protobuf.Any { - if m != nil { - return m.Value - } - return nil -} - -func (m *Any) GetYaml() string { - if m != nil { - return m.Yaml - } - return "" -} - -type ApiKeySecurity struct { - Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` - In string `protobuf:"bytes,3,opt,name=in" json:"in,omitempty"` - Description string `protobuf:"bytes,4,opt,name=description" json:"description,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,5,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *ApiKeySecurity) Reset() { *m = ApiKeySecurity{} } -func (m *ApiKeySecurity) String() string { return proto.CompactTextString(m) } -func (*ApiKeySecurity) ProtoMessage() {} -func (*ApiKeySecurity) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } - -func (m *ApiKeySecurity) GetType() string { - if m != nil { - return m.Type - } - return "" -} - -func (m *ApiKeySecurity) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *ApiKeySecurity) GetIn() string { - if m != nil { - return m.In - } - return "" -} - -func (m *ApiKeySecurity) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *ApiKeySecurity) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type BasicAuthenticationSecurity struct { - Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description" json:"description,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,3,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *BasicAuthenticationSecurity) Reset() { *m = BasicAuthenticationSecurity{} } -func (m *BasicAuthenticationSecurity) String() string { return proto.CompactTextString(m) } -func (*BasicAuthenticationSecurity) ProtoMessage() {} -func (*BasicAuthenticationSecurity) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } - -func (m *BasicAuthenticationSecurity) GetType() string { - if m != nil { - return m.Type - } - return "" -} - -func (m *BasicAuthenticationSecurity) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *BasicAuthenticationSecurity) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type BodyParameter struct { - // A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed. - Description string `protobuf:"bytes,1,opt,name=description" json:"description,omitempty"` - // The name of the parameter. - Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` - // Determines the location of the parameter. - In string `protobuf:"bytes,3,opt,name=in" json:"in,omitempty"` - // Determines whether or not this parameter is required or optional. - Required bool `protobuf:"varint,4,opt,name=required" json:"required,omitempty"` - Schema *Schema `protobuf:"bytes,5,opt,name=schema" json:"schema,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,6,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *BodyParameter) Reset() { *m = BodyParameter{} } -func (m *BodyParameter) String() string { return proto.CompactTextString(m) } -func (*BodyParameter) ProtoMessage() {} -func (*BodyParameter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } - -func (m *BodyParameter) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *BodyParameter) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *BodyParameter) GetIn() string { - if m != nil { - return m.In - } - return "" -} - -func (m *BodyParameter) GetRequired() bool { - if m != nil { - return m.Required - } - return false -} - -func (m *BodyParameter) GetSchema() *Schema { - if m != nil { - return m.Schema - } - return nil -} - -func (m *BodyParameter) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -// Contact information for the owners of the API. -type Contact struct { - // The identifying name of the contact person/organization. - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // The URL pointing to the contact information. - Url string `protobuf:"bytes,2,opt,name=url" json:"url,omitempty"` - // The email address of the contact person/organization. - Email string `protobuf:"bytes,3,opt,name=email" json:"email,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,4,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *Contact) Reset() { *m = Contact{} } -func (m *Contact) String() string { return proto.CompactTextString(m) } -func (*Contact) ProtoMessage() {} -func (*Contact) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } - -func (m *Contact) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *Contact) GetUrl() string { - if m != nil { - return m.Url - } - return "" -} - -func (m *Contact) GetEmail() string { - if m != nil { - return m.Email - } - return "" -} - -func (m *Contact) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type Default struct { - AdditionalProperties []*NamedAny `protobuf:"bytes,1,rep,name=additional_properties,json=additionalProperties" json:"additional_properties,omitempty"` -} - -func (m *Default) Reset() { *m = Default{} } -func (m *Default) String() string { return proto.CompactTextString(m) } -func (*Default) ProtoMessage() {} -func (*Default) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } - -func (m *Default) GetAdditionalProperties() []*NamedAny { - if m != nil { - return m.AdditionalProperties - } - return nil -} - -// One or more JSON objects describing the schemas being consumed and produced by the API. -type Definitions struct { - AdditionalProperties []*NamedSchema `protobuf:"bytes,1,rep,name=additional_properties,json=additionalProperties" json:"additional_properties,omitempty"` -} - -func (m *Definitions) Reset() { *m = Definitions{} } -func (m *Definitions) String() string { return proto.CompactTextString(m) } -func (*Definitions) ProtoMessage() {} -func (*Definitions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } - -func (m *Definitions) GetAdditionalProperties() []*NamedSchema { - if m != nil { - return m.AdditionalProperties - } - return nil -} - -type Document struct { - // The Swagger version of this document. - Swagger string `protobuf:"bytes,1,opt,name=swagger" json:"swagger,omitempty"` - Info *Info `protobuf:"bytes,2,opt,name=info" json:"info,omitempty"` - // The host (name or ip) of the API. Example: 'swagger.io' - Host string `protobuf:"bytes,3,opt,name=host" json:"host,omitempty"` - // The base path to the API. Example: '/api'. - BasePath string `protobuf:"bytes,4,opt,name=base_path,json=basePath" json:"base_path,omitempty"` - // The transfer protocol of the API. - Schemes []string `protobuf:"bytes,5,rep,name=schemes" json:"schemes,omitempty"` - // A list of MIME types accepted by the API. - Consumes []string `protobuf:"bytes,6,rep,name=consumes" json:"consumes,omitempty"` - // A list of MIME types the API can produce. - Produces []string `protobuf:"bytes,7,rep,name=produces" json:"produces,omitempty"` - Paths *Paths `protobuf:"bytes,8,opt,name=paths" json:"paths,omitempty"` - Definitions *Definitions `protobuf:"bytes,9,opt,name=definitions" json:"definitions,omitempty"` - Parameters *ParameterDefinitions `protobuf:"bytes,10,opt,name=parameters" json:"parameters,omitempty"` - Responses *ResponseDefinitions `protobuf:"bytes,11,opt,name=responses" json:"responses,omitempty"` - Security []*SecurityRequirement `protobuf:"bytes,12,rep,name=security" json:"security,omitempty"` - SecurityDefinitions *SecurityDefinitions `protobuf:"bytes,13,opt,name=security_definitions,json=securityDefinitions" json:"security_definitions,omitempty"` - Tags []*Tag `protobuf:"bytes,14,rep,name=tags" json:"tags,omitempty"` - ExternalDocs *ExternalDocs `protobuf:"bytes,15,opt,name=external_docs,json=externalDocs" json:"external_docs,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,16,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *Document) Reset() { *m = Document{} } -func (m *Document) String() string { return proto.CompactTextString(m) } -func (*Document) ProtoMessage() {} -func (*Document) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } - -func (m *Document) GetSwagger() string { - if m != nil { - return m.Swagger - } - return "" -} - -func (m *Document) GetInfo() *Info { - if m != nil { - return m.Info - } - return nil -} - -func (m *Document) GetHost() string { - if m != nil { - return m.Host - } - return "" -} - -func (m *Document) GetBasePath() string { - if m != nil { - return m.BasePath - } - return "" -} - -func (m *Document) GetSchemes() []string { - if m != nil { - return m.Schemes - } - return nil -} - -func (m *Document) GetConsumes() []string { - if m != nil { - return m.Consumes - } - return nil -} - -func (m *Document) GetProduces() []string { - if m != nil { - return m.Produces - } - return nil -} - -func (m *Document) GetPaths() *Paths { - if m != nil { - return m.Paths - } - return nil -} - -func (m *Document) GetDefinitions() *Definitions { - if m != nil { - return m.Definitions - } - return nil -} - -func (m *Document) GetParameters() *ParameterDefinitions { - if m != nil { - return m.Parameters - } - return nil -} - -func (m *Document) GetResponses() *ResponseDefinitions { - if m != nil { - return m.Responses - } - return nil -} - -func (m *Document) GetSecurity() []*SecurityRequirement { - if m != nil { - return m.Security - } - return nil -} - -func (m *Document) GetSecurityDefinitions() *SecurityDefinitions { - if m != nil { - return m.SecurityDefinitions - } - return nil -} - -func (m *Document) GetTags() []*Tag { - if m != nil { - return m.Tags - } - return nil -} - -func (m *Document) GetExternalDocs() *ExternalDocs { - if m != nil { - return m.ExternalDocs - } - return nil -} - -func (m *Document) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type Examples struct { - AdditionalProperties []*NamedAny `protobuf:"bytes,1,rep,name=additional_properties,json=additionalProperties" json:"additional_properties,omitempty"` -} - -func (m *Examples) Reset() { *m = Examples{} } -func (m *Examples) String() string { return proto.CompactTextString(m) } -func (*Examples) ProtoMessage() {} -func (*Examples) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } - -func (m *Examples) GetAdditionalProperties() []*NamedAny { - if m != nil { - return m.AdditionalProperties - } - return nil -} - -// information about external documentation -type ExternalDocs struct { - Description string `protobuf:"bytes,1,opt,name=description" json:"description,omitempty"` - Url string `protobuf:"bytes,2,opt,name=url" json:"url,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,3,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *ExternalDocs) Reset() { *m = ExternalDocs{} } -func (m *ExternalDocs) String() string { return proto.CompactTextString(m) } -func (*ExternalDocs) ProtoMessage() {} -func (*ExternalDocs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } - -func (m *ExternalDocs) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *ExternalDocs) GetUrl() string { - if m != nil { - return m.Url - } - return "" -} - -func (m *ExternalDocs) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -// A deterministic version of a JSON Schema object. -type FileSchema struct { - Format string `protobuf:"bytes,1,opt,name=format" json:"format,omitempty"` - Title string `protobuf:"bytes,2,opt,name=title" json:"title,omitempty"` - Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"` - Default *Any `protobuf:"bytes,4,opt,name=default" json:"default,omitempty"` - Required []string `protobuf:"bytes,5,rep,name=required" json:"required,omitempty"` - Type string `protobuf:"bytes,6,opt,name=type" json:"type,omitempty"` - ReadOnly bool `protobuf:"varint,7,opt,name=read_only,json=readOnly" json:"read_only,omitempty"` - ExternalDocs *ExternalDocs `protobuf:"bytes,8,opt,name=external_docs,json=externalDocs" json:"external_docs,omitempty"` - Example *Any `protobuf:"bytes,9,opt,name=example" json:"example,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,10,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *FileSchema) Reset() { *m = FileSchema{} } -func (m *FileSchema) String() string { return proto.CompactTextString(m) } -func (*FileSchema) ProtoMessage() {} -func (*FileSchema) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } - -func (m *FileSchema) GetFormat() string { - if m != nil { - return m.Format - } - return "" -} - -func (m *FileSchema) GetTitle() string { - if m != nil { - return m.Title - } - return "" -} - -func (m *FileSchema) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *FileSchema) GetDefault() *Any { - if m != nil { - return m.Default - } - return nil -} - -func (m *FileSchema) GetRequired() []string { - if m != nil { - return m.Required - } - return nil -} - -func (m *FileSchema) GetType() string { - if m != nil { - return m.Type - } - return "" -} - -func (m *FileSchema) GetReadOnly() bool { - if m != nil { - return m.ReadOnly - } - return false -} - -func (m *FileSchema) GetExternalDocs() *ExternalDocs { - if m != nil { - return m.ExternalDocs - } - return nil -} - -func (m *FileSchema) GetExample() *Any { - if m != nil { - return m.Example - } - return nil -} - -func (m *FileSchema) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type FormDataParameterSubSchema struct { - // Determines whether or not this parameter is required or optional. - Required bool `protobuf:"varint,1,opt,name=required" json:"required,omitempty"` - // Determines the location of the parameter. - In string `protobuf:"bytes,2,opt,name=in" json:"in,omitempty"` - // A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed. - Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"` - // The name of the parameter. - Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` - // allows sending a parameter by name only or with an empty value. - AllowEmptyValue bool `protobuf:"varint,5,opt,name=allow_empty_value,json=allowEmptyValue" json:"allow_empty_value,omitempty"` - Type string `protobuf:"bytes,6,opt,name=type" json:"type,omitempty"` - Format string `protobuf:"bytes,7,opt,name=format" json:"format,omitempty"` - Items *PrimitivesItems `protobuf:"bytes,8,opt,name=items" json:"items,omitempty"` - CollectionFormat string `protobuf:"bytes,9,opt,name=collection_format,json=collectionFormat" json:"collection_format,omitempty"` - Default *Any `protobuf:"bytes,10,opt,name=default" json:"default,omitempty"` - Maximum float64 `protobuf:"fixed64,11,opt,name=maximum" json:"maximum,omitempty"` - ExclusiveMaximum bool `protobuf:"varint,12,opt,name=exclusive_maximum,json=exclusiveMaximum" json:"exclusive_maximum,omitempty"` - Minimum float64 `protobuf:"fixed64,13,opt,name=minimum" json:"minimum,omitempty"` - ExclusiveMinimum bool `protobuf:"varint,14,opt,name=exclusive_minimum,json=exclusiveMinimum" json:"exclusive_minimum,omitempty"` - MaxLength int64 `protobuf:"varint,15,opt,name=max_length,json=maxLength" json:"max_length,omitempty"` - MinLength int64 `protobuf:"varint,16,opt,name=min_length,json=minLength" json:"min_length,omitempty"` - Pattern string `protobuf:"bytes,17,opt,name=pattern" json:"pattern,omitempty"` - MaxItems int64 `protobuf:"varint,18,opt,name=max_items,json=maxItems" json:"max_items,omitempty"` - MinItems int64 `protobuf:"varint,19,opt,name=min_items,json=minItems" json:"min_items,omitempty"` - UniqueItems bool `protobuf:"varint,20,opt,name=unique_items,json=uniqueItems" json:"unique_items,omitempty"` - Enum []*Any `protobuf:"bytes,21,rep,name=enum" json:"enum,omitempty"` - MultipleOf float64 `protobuf:"fixed64,22,opt,name=multiple_of,json=multipleOf" json:"multiple_of,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,23,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *FormDataParameterSubSchema) Reset() { *m = FormDataParameterSubSchema{} } -func (m *FormDataParameterSubSchema) String() string { return proto.CompactTextString(m) } -func (*FormDataParameterSubSchema) ProtoMessage() {} -func (*FormDataParameterSubSchema) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } - -func (m *FormDataParameterSubSchema) GetRequired() bool { - if m != nil { - return m.Required - } - return false -} - -func (m *FormDataParameterSubSchema) GetIn() string { - if m != nil { - return m.In - } - return "" -} - -func (m *FormDataParameterSubSchema) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *FormDataParameterSubSchema) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *FormDataParameterSubSchema) GetAllowEmptyValue() bool { - if m != nil { - return m.AllowEmptyValue - } - return false -} - -func (m *FormDataParameterSubSchema) GetType() string { - if m != nil { - return m.Type - } - return "" -} - -func (m *FormDataParameterSubSchema) GetFormat() string { - if m != nil { - return m.Format - } - return "" -} - -func (m *FormDataParameterSubSchema) GetItems() *PrimitivesItems { - if m != nil { - return m.Items - } - return nil -} - -func (m *FormDataParameterSubSchema) GetCollectionFormat() string { - if m != nil { - return m.CollectionFormat - } - return "" -} - -func (m *FormDataParameterSubSchema) GetDefault() *Any { - if m != nil { - return m.Default - } - return nil -} - -func (m *FormDataParameterSubSchema) GetMaximum() float64 { - if m != nil { - return m.Maximum - } - return 0 -} - -func (m *FormDataParameterSubSchema) GetExclusiveMaximum() bool { - if m != nil { - return m.ExclusiveMaximum - } - return false -} - -func (m *FormDataParameterSubSchema) GetMinimum() float64 { - if m != nil { - return m.Minimum - } - return 0 -} - -func (m *FormDataParameterSubSchema) GetExclusiveMinimum() bool { - if m != nil { - return m.ExclusiveMinimum - } - return false -} - -func (m *FormDataParameterSubSchema) GetMaxLength() int64 { - if m != nil { - return m.MaxLength - } - return 0 -} - -func (m *FormDataParameterSubSchema) GetMinLength() int64 { - if m != nil { - return m.MinLength - } - return 0 -} - -func (m *FormDataParameterSubSchema) GetPattern() string { - if m != nil { - return m.Pattern - } - return "" -} - -func (m *FormDataParameterSubSchema) GetMaxItems() int64 { - if m != nil { - return m.MaxItems - } - return 0 -} - -func (m *FormDataParameterSubSchema) GetMinItems() int64 { - if m != nil { - return m.MinItems - } - return 0 -} - -func (m *FormDataParameterSubSchema) GetUniqueItems() bool { - if m != nil { - return m.UniqueItems - } - return false -} - -func (m *FormDataParameterSubSchema) GetEnum() []*Any { - if m != nil { - return m.Enum - } - return nil -} - -func (m *FormDataParameterSubSchema) GetMultipleOf() float64 { - if m != nil { - return m.MultipleOf - } - return 0 -} - -func (m *FormDataParameterSubSchema) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type Header struct { - Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` - Format string `protobuf:"bytes,2,opt,name=format" json:"format,omitempty"` - Items *PrimitivesItems `protobuf:"bytes,3,opt,name=items" json:"items,omitempty"` - CollectionFormat string `protobuf:"bytes,4,opt,name=collection_format,json=collectionFormat" json:"collection_format,omitempty"` - Default *Any `protobuf:"bytes,5,opt,name=default" json:"default,omitempty"` - Maximum float64 `protobuf:"fixed64,6,opt,name=maximum" json:"maximum,omitempty"` - ExclusiveMaximum bool `protobuf:"varint,7,opt,name=exclusive_maximum,json=exclusiveMaximum" json:"exclusive_maximum,omitempty"` - Minimum float64 `protobuf:"fixed64,8,opt,name=minimum" json:"minimum,omitempty"` - ExclusiveMinimum bool `protobuf:"varint,9,opt,name=exclusive_minimum,json=exclusiveMinimum" json:"exclusive_minimum,omitempty"` - MaxLength int64 `protobuf:"varint,10,opt,name=max_length,json=maxLength" json:"max_length,omitempty"` - MinLength int64 `protobuf:"varint,11,opt,name=min_length,json=minLength" json:"min_length,omitempty"` - Pattern string `protobuf:"bytes,12,opt,name=pattern" json:"pattern,omitempty"` - MaxItems int64 `protobuf:"varint,13,opt,name=max_items,json=maxItems" json:"max_items,omitempty"` - MinItems int64 `protobuf:"varint,14,opt,name=min_items,json=minItems" json:"min_items,omitempty"` - UniqueItems bool `protobuf:"varint,15,opt,name=unique_items,json=uniqueItems" json:"unique_items,omitempty"` - Enum []*Any `protobuf:"bytes,16,rep,name=enum" json:"enum,omitempty"` - MultipleOf float64 `protobuf:"fixed64,17,opt,name=multiple_of,json=multipleOf" json:"multiple_of,omitempty"` - Description string `protobuf:"bytes,18,opt,name=description" json:"description,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,19,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *Header) Reset() { *m = Header{} } -func (m *Header) String() string { return proto.CompactTextString(m) } -func (*Header) ProtoMessage() {} -func (*Header) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } - -func (m *Header) GetType() string { - if m != nil { - return m.Type - } - return "" -} - -func (m *Header) GetFormat() string { - if m != nil { - return m.Format - } - return "" -} - -func (m *Header) GetItems() *PrimitivesItems { - if m != nil { - return m.Items - } - return nil -} - -func (m *Header) GetCollectionFormat() string { - if m != nil { - return m.CollectionFormat - } - return "" -} - -func (m *Header) GetDefault() *Any { - if m != nil { - return m.Default - } - return nil -} - -func (m *Header) GetMaximum() float64 { - if m != nil { - return m.Maximum - } - return 0 -} - -func (m *Header) GetExclusiveMaximum() bool { - if m != nil { - return m.ExclusiveMaximum - } - return false -} - -func (m *Header) GetMinimum() float64 { - if m != nil { - return m.Minimum - } - return 0 -} - -func (m *Header) GetExclusiveMinimum() bool { - if m != nil { - return m.ExclusiveMinimum - } - return false -} - -func (m *Header) GetMaxLength() int64 { - if m != nil { - return m.MaxLength - } - return 0 -} - -func (m *Header) GetMinLength() int64 { - if m != nil { - return m.MinLength - } - return 0 -} - -func (m *Header) GetPattern() string { - if m != nil { - return m.Pattern - } - return "" -} - -func (m *Header) GetMaxItems() int64 { - if m != nil { - return m.MaxItems - } - return 0 -} - -func (m *Header) GetMinItems() int64 { - if m != nil { - return m.MinItems - } - return 0 -} - -func (m *Header) GetUniqueItems() bool { - if m != nil { - return m.UniqueItems - } - return false -} - -func (m *Header) GetEnum() []*Any { - if m != nil { - return m.Enum - } - return nil -} - -func (m *Header) GetMultipleOf() float64 { - if m != nil { - return m.MultipleOf - } - return 0 -} - -func (m *Header) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *Header) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type HeaderParameterSubSchema struct { - // Determines whether or not this parameter is required or optional. - Required bool `protobuf:"varint,1,opt,name=required" json:"required,omitempty"` - // Determines the location of the parameter. - In string `protobuf:"bytes,2,opt,name=in" json:"in,omitempty"` - // A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed. - Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"` - // The name of the parameter. - Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` - Type string `protobuf:"bytes,5,opt,name=type" json:"type,omitempty"` - Format string `protobuf:"bytes,6,opt,name=format" json:"format,omitempty"` - Items *PrimitivesItems `protobuf:"bytes,7,opt,name=items" json:"items,omitempty"` - CollectionFormat string `protobuf:"bytes,8,opt,name=collection_format,json=collectionFormat" json:"collection_format,omitempty"` - Default *Any `protobuf:"bytes,9,opt,name=default" json:"default,omitempty"` - Maximum float64 `protobuf:"fixed64,10,opt,name=maximum" json:"maximum,omitempty"` - ExclusiveMaximum bool `protobuf:"varint,11,opt,name=exclusive_maximum,json=exclusiveMaximum" json:"exclusive_maximum,omitempty"` - Minimum float64 `protobuf:"fixed64,12,opt,name=minimum" json:"minimum,omitempty"` - ExclusiveMinimum bool `protobuf:"varint,13,opt,name=exclusive_minimum,json=exclusiveMinimum" json:"exclusive_minimum,omitempty"` - MaxLength int64 `protobuf:"varint,14,opt,name=max_length,json=maxLength" json:"max_length,omitempty"` - MinLength int64 `protobuf:"varint,15,opt,name=min_length,json=minLength" json:"min_length,omitempty"` - Pattern string `protobuf:"bytes,16,opt,name=pattern" json:"pattern,omitempty"` - MaxItems int64 `protobuf:"varint,17,opt,name=max_items,json=maxItems" json:"max_items,omitempty"` - MinItems int64 `protobuf:"varint,18,opt,name=min_items,json=minItems" json:"min_items,omitempty"` - UniqueItems bool `protobuf:"varint,19,opt,name=unique_items,json=uniqueItems" json:"unique_items,omitempty"` - Enum []*Any `protobuf:"bytes,20,rep,name=enum" json:"enum,omitempty"` - MultipleOf float64 `protobuf:"fixed64,21,opt,name=multiple_of,json=multipleOf" json:"multiple_of,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,22,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *HeaderParameterSubSchema) Reset() { *m = HeaderParameterSubSchema{} } -func (m *HeaderParameterSubSchema) String() string { return proto.CompactTextString(m) } -func (*HeaderParameterSubSchema) ProtoMessage() {} -func (*HeaderParameterSubSchema) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } - -func (m *HeaderParameterSubSchema) GetRequired() bool { - if m != nil { - return m.Required - } - return false -} - -func (m *HeaderParameterSubSchema) GetIn() string { - if m != nil { - return m.In - } - return "" -} - -func (m *HeaderParameterSubSchema) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *HeaderParameterSubSchema) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *HeaderParameterSubSchema) GetType() string { - if m != nil { - return m.Type - } - return "" -} - -func (m *HeaderParameterSubSchema) GetFormat() string { - if m != nil { - return m.Format - } - return "" -} - -func (m *HeaderParameterSubSchema) GetItems() *PrimitivesItems { - if m != nil { - return m.Items - } - return nil -} - -func (m *HeaderParameterSubSchema) GetCollectionFormat() string { - if m != nil { - return m.CollectionFormat - } - return "" -} - -func (m *HeaderParameterSubSchema) GetDefault() *Any { - if m != nil { - return m.Default - } - return nil -} - -func (m *HeaderParameterSubSchema) GetMaximum() float64 { - if m != nil { - return m.Maximum - } - return 0 -} - -func (m *HeaderParameterSubSchema) GetExclusiveMaximum() bool { - if m != nil { - return m.ExclusiveMaximum - } - return false -} - -func (m *HeaderParameterSubSchema) GetMinimum() float64 { - if m != nil { - return m.Minimum - } - return 0 -} - -func (m *HeaderParameterSubSchema) GetExclusiveMinimum() bool { - if m != nil { - return m.ExclusiveMinimum - } - return false -} - -func (m *HeaderParameterSubSchema) GetMaxLength() int64 { - if m != nil { - return m.MaxLength - } - return 0 -} - -func (m *HeaderParameterSubSchema) GetMinLength() int64 { - if m != nil { - return m.MinLength - } - return 0 -} - -func (m *HeaderParameterSubSchema) GetPattern() string { - if m != nil { - return m.Pattern - } - return "" -} - -func (m *HeaderParameterSubSchema) GetMaxItems() int64 { - if m != nil { - return m.MaxItems - } - return 0 -} - -func (m *HeaderParameterSubSchema) GetMinItems() int64 { - if m != nil { - return m.MinItems - } - return 0 -} - -func (m *HeaderParameterSubSchema) GetUniqueItems() bool { - if m != nil { - return m.UniqueItems - } - return false -} - -func (m *HeaderParameterSubSchema) GetEnum() []*Any { - if m != nil { - return m.Enum - } - return nil -} - -func (m *HeaderParameterSubSchema) GetMultipleOf() float64 { - if m != nil { - return m.MultipleOf - } - return 0 -} - -func (m *HeaderParameterSubSchema) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type Headers struct { - AdditionalProperties []*NamedHeader `protobuf:"bytes,1,rep,name=additional_properties,json=additionalProperties" json:"additional_properties,omitempty"` -} - -func (m *Headers) Reset() { *m = Headers{} } -func (m *Headers) String() string { return proto.CompactTextString(m) } -func (*Headers) ProtoMessage() {} -func (*Headers) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } - -func (m *Headers) GetAdditionalProperties() []*NamedHeader { - if m != nil { - return m.AdditionalProperties - } - return nil -} - -// General information about the API. -type Info struct { - // A unique and precise title of the API. - Title string `protobuf:"bytes,1,opt,name=title" json:"title,omitempty"` - // A semantic version number of the API. - Version string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"` - // A longer description of the API. Should be different from the title. GitHub Flavored Markdown is allowed. - Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"` - // The terms of service for the API. - TermsOfService string `protobuf:"bytes,4,opt,name=terms_of_service,json=termsOfService" json:"terms_of_service,omitempty"` - Contact *Contact `protobuf:"bytes,5,opt,name=contact" json:"contact,omitempty"` - License *License `protobuf:"bytes,6,opt,name=license" json:"license,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,7,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *Info) Reset() { *m = Info{} } -func (m *Info) String() string { return proto.CompactTextString(m) } -func (*Info) ProtoMessage() {} -func (*Info) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } - -func (m *Info) GetTitle() string { - if m != nil { - return m.Title - } - return "" -} - -func (m *Info) GetVersion() string { - if m != nil { - return m.Version - } - return "" -} - -func (m *Info) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *Info) GetTermsOfService() string { - if m != nil { - return m.TermsOfService - } - return "" -} - -func (m *Info) GetContact() *Contact { - if m != nil { - return m.Contact - } - return nil -} - -func (m *Info) GetLicense() *License { - if m != nil { - return m.License - } - return nil -} - -func (m *Info) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type ItemsItem struct { - Schema []*Schema `protobuf:"bytes,1,rep,name=schema" json:"schema,omitempty"` -} - -func (m *ItemsItem) Reset() { *m = ItemsItem{} } -func (m *ItemsItem) String() string { return proto.CompactTextString(m) } -func (*ItemsItem) ProtoMessage() {} -func (*ItemsItem) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } - -func (m *ItemsItem) GetSchema() []*Schema { - if m != nil { - return m.Schema - } - return nil -} - -type JsonReference struct { - XRef string `protobuf:"bytes,1,opt,name=_ref,json=Ref" json:"_ref,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description" json:"description,omitempty"` -} - -func (m *JsonReference) Reset() { *m = JsonReference{} } -func (m *JsonReference) String() string { return proto.CompactTextString(m) } -func (*JsonReference) ProtoMessage() {} -func (*JsonReference) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } - -func (m *JsonReference) GetXRef() string { - if m != nil { - return m.XRef - } - return "" -} - -func (m *JsonReference) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -type License struct { - // The name of the license type. It's encouraged to use an OSI compatible license. - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // The URL pointing to the license. - Url string `protobuf:"bytes,2,opt,name=url" json:"url,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,3,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *License) Reset() { *m = License{} } -func (m *License) String() string { return proto.CompactTextString(m) } -func (*License) ProtoMessage() {} -func (*License) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } - -func (m *License) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *License) GetUrl() string { - if m != nil { - return m.Url - } - return "" -} - -func (m *License) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -// Automatically-generated message used to represent maps of Any as ordered (name,value) pairs. -type NamedAny struct { - // Map key - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // Mapped value - Value *Any `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (m *NamedAny) Reset() { *m = NamedAny{} } -func (m *NamedAny) String() string { return proto.CompactTextString(m) } -func (*NamedAny) ProtoMessage() {} -func (*NamedAny) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } - -func (m *NamedAny) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *NamedAny) GetValue() *Any { - if m != nil { - return m.Value - } - return nil -} - -// Automatically-generated message used to represent maps of Header as ordered (name,value) pairs. -type NamedHeader struct { - // Map key - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // Mapped value - Value *Header `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (m *NamedHeader) Reset() { *m = NamedHeader{} } -func (m *NamedHeader) String() string { return proto.CompactTextString(m) } -func (*NamedHeader) ProtoMessage() {} -func (*NamedHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } - -func (m *NamedHeader) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *NamedHeader) GetValue() *Header { - if m != nil { - return m.Value - } - return nil -} - -// Automatically-generated message used to represent maps of Parameter as ordered (name,value) pairs. -type NamedParameter struct { - // Map key - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // Mapped value - Value *Parameter `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (m *NamedParameter) Reset() { *m = NamedParameter{} } -func (m *NamedParameter) String() string { return proto.CompactTextString(m) } -func (*NamedParameter) ProtoMessage() {} -func (*NamedParameter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } - -func (m *NamedParameter) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *NamedParameter) GetValue() *Parameter { - if m != nil { - return m.Value - } - return nil -} - -// Automatically-generated message used to represent maps of PathItem as ordered (name,value) pairs. -type NamedPathItem struct { - // Map key - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // Mapped value - Value *PathItem `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (m *NamedPathItem) Reset() { *m = NamedPathItem{} } -func (m *NamedPathItem) String() string { return proto.CompactTextString(m) } -func (*NamedPathItem) ProtoMessage() {} -func (*NamedPathItem) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } - -func (m *NamedPathItem) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *NamedPathItem) GetValue() *PathItem { - if m != nil { - return m.Value - } - return nil -} - -// Automatically-generated message used to represent maps of Response as ordered (name,value) pairs. -type NamedResponse struct { - // Map key - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // Mapped value - Value *Response `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (m *NamedResponse) Reset() { *m = NamedResponse{} } -func (m *NamedResponse) String() string { return proto.CompactTextString(m) } -func (*NamedResponse) ProtoMessage() {} -func (*NamedResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } - -func (m *NamedResponse) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *NamedResponse) GetValue() *Response { - if m != nil { - return m.Value - } - return nil -} - -// Automatically-generated message used to represent maps of ResponseValue as ordered (name,value) pairs. -type NamedResponseValue struct { - // Map key - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // Mapped value - Value *ResponseValue `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (m *NamedResponseValue) Reset() { *m = NamedResponseValue{} } -func (m *NamedResponseValue) String() string { return proto.CompactTextString(m) } -func (*NamedResponseValue) ProtoMessage() {} -func (*NamedResponseValue) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } - -func (m *NamedResponseValue) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *NamedResponseValue) GetValue() *ResponseValue { - if m != nil { - return m.Value - } - return nil -} - -// Automatically-generated message used to represent maps of Schema as ordered (name,value) pairs. -type NamedSchema struct { - // Map key - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // Mapped value - Value *Schema `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (m *NamedSchema) Reset() { *m = NamedSchema{} } -func (m *NamedSchema) String() string { return proto.CompactTextString(m) } -func (*NamedSchema) ProtoMessage() {} -func (*NamedSchema) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } - -func (m *NamedSchema) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *NamedSchema) GetValue() *Schema { - if m != nil { - return m.Value - } - return nil -} - -// Automatically-generated message used to represent maps of SecurityDefinitionsItem as ordered (name,value) pairs. -type NamedSecurityDefinitionsItem struct { - // Map key - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // Mapped value - Value *SecurityDefinitionsItem `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (m *NamedSecurityDefinitionsItem) Reset() { *m = NamedSecurityDefinitionsItem{} } -func (m *NamedSecurityDefinitionsItem) String() string { return proto.CompactTextString(m) } -func (*NamedSecurityDefinitionsItem) ProtoMessage() {} -func (*NamedSecurityDefinitionsItem) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } - -func (m *NamedSecurityDefinitionsItem) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *NamedSecurityDefinitionsItem) GetValue() *SecurityDefinitionsItem { - if m != nil { - return m.Value - } - return nil -} - -// Automatically-generated message used to represent maps of string as ordered (name,value) pairs. -type NamedString struct { - // Map key - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // Mapped value - Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (m *NamedString) Reset() { *m = NamedString{} } -func (m *NamedString) String() string { return proto.CompactTextString(m) } -func (*NamedString) ProtoMessage() {} -func (*NamedString) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } - -func (m *NamedString) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *NamedString) GetValue() string { - if m != nil { - return m.Value - } - return "" -} - -// Automatically-generated message used to represent maps of StringArray as ordered (name,value) pairs. -type NamedStringArray struct { - // Map key - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // Mapped value - Value *StringArray `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (m *NamedStringArray) Reset() { *m = NamedStringArray{} } -func (m *NamedStringArray) String() string { return proto.CompactTextString(m) } -func (*NamedStringArray) ProtoMessage() {} -func (*NamedStringArray) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} } - -func (m *NamedStringArray) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *NamedStringArray) GetValue() *StringArray { - if m != nil { - return m.Value - } - return nil -} - -type NonBodyParameter struct { - // Types that are valid to be assigned to Oneof: - // *NonBodyParameter_HeaderParameterSubSchema - // *NonBodyParameter_FormDataParameterSubSchema - // *NonBodyParameter_QueryParameterSubSchema - // *NonBodyParameter_PathParameterSubSchema - Oneof isNonBodyParameter_Oneof `protobuf_oneof:"oneof"` -} - -func (m *NonBodyParameter) Reset() { *m = NonBodyParameter{} } -func (m *NonBodyParameter) String() string { return proto.CompactTextString(m) } -func (*NonBodyParameter) ProtoMessage() {} -func (*NonBodyParameter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} } - -type isNonBodyParameter_Oneof interface { - isNonBodyParameter_Oneof() -} - -type NonBodyParameter_HeaderParameterSubSchema struct { - HeaderParameterSubSchema *HeaderParameterSubSchema `protobuf:"bytes,1,opt,name=header_parameter_sub_schema,json=headerParameterSubSchema,oneof"` -} -type NonBodyParameter_FormDataParameterSubSchema struct { - FormDataParameterSubSchema *FormDataParameterSubSchema `protobuf:"bytes,2,opt,name=form_data_parameter_sub_schema,json=formDataParameterSubSchema,oneof"` -} -type NonBodyParameter_QueryParameterSubSchema struct { - QueryParameterSubSchema *QueryParameterSubSchema `protobuf:"bytes,3,opt,name=query_parameter_sub_schema,json=queryParameterSubSchema,oneof"` -} -type NonBodyParameter_PathParameterSubSchema struct { - PathParameterSubSchema *PathParameterSubSchema `protobuf:"bytes,4,opt,name=path_parameter_sub_schema,json=pathParameterSubSchema,oneof"` -} - -func (*NonBodyParameter_HeaderParameterSubSchema) isNonBodyParameter_Oneof() {} -func (*NonBodyParameter_FormDataParameterSubSchema) isNonBodyParameter_Oneof() {} -func (*NonBodyParameter_QueryParameterSubSchema) isNonBodyParameter_Oneof() {} -func (*NonBodyParameter_PathParameterSubSchema) isNonBodyParameter_Oneof() {} - -func (m *NonBodyParameter) GetOneof() isNonBodyParameter_Oneof { - if m != nil { - return m.Oneof - } - return nil -} - -func (m *NonBodyParameter) GetHeaderParameterSubSchema() *HeaderParameterSubSchema { - if x, ok := m.GetOneof().(*NonBodyParameter_HeaderParameterSubSchema); ok { - return x.HeaderParameterSubSchema - } - return nil -} - -func (m *NonBodyParameter) GetFormDataParameterSubSchema() *FormDataParameterSubSchema { - if x, ok := m.GetOneof().(*NonBodyParameter_FormDataParameterSubSchema); ok { - return x.FormDataParameterSubSchema - } - return nil -} - -func (m *NonBodyParameter) GetQueryParameterSubSchema() *QueryParameterSubSchema { - if x, ok := m.GetOneof().(*NonBodyParameter_QueryParameterSubSchema); ok { - return x.QueryParameterSubSchema - } - return nil -} - -func (m *NonBodyParameter) GetPathParameterSubSchema() *PathParameterSubSchema { - if x, ok := m.GetOneof().(*NonBodyParameter_PathParameterSubSchema); ok { - return x.PathParameterSubSchema - } - return nil -} - -// XXX_OneofFuncs is for the internal use of the proto package. -func (*NonBodyParameter) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _NonBodyParameter_OneofMarshaler, _NonBodyParameter_OneofUnmarshaler, _NonBodyParameter_OneofSizer, []interface{}{ - (*NonBodyParameter_HeaderParameterSubSchema)(nil), - (*NonBodyParameter_FormDataParameterSubSchema)(nil), - (*NonBodyParameter_QueryParameterSubSchema)(nil), - (*NonBodyParameter_PathParameterSubSchema)(nil), - } -} - -func _NonBodyParameter_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*NonBodyParameter) - // oneof - switch x := m.Oneof.(type) { - case *NonBodyParameter_HeaderParameterSubSchema: - b.EncodeVarint(1<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.HeaderParameterSubSchema); err != nil { - return err - } - case *NonBodyParameter_FormDataParameterSubSchema: - b.EncodeVarint(2<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.FormDataParameterSubSchema); err != nil { - return err - } - case *NonBodyParameter_QueryParameterSubSchema: - b.EncodeVarint(3<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.QueryParameterSubSchema); err != nil { - return err - } - case *NonBodyParameter_PathParameterSubSchema: - b.EncodeVarint(4<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.PathParameterSubSchema); err != nil { - return err - } - case nil: - default: - return fmt.Errorf("NonBodyParameter.Oneof has unexpected type %T", x) - } - return nil -} - -func _NonBodyParameter_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*NonBodyParameter) - switch tag { - case 1: // oneof.header_parameter_sub_schema - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(HeaderParameterSubSchema) - err := b.DecodeMessage(msg) - m.Oneof = &NonBodyParameter_HeaderParameterSubSchema{msg} - return true, err - case 2: // oneof.form_data_parameter_sub_schema - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(FormDataParameterSubSchema) - err := b.DecodeMessage(msg) - m.Oneof = &NonBodyParameter_FormDataParameterSubSchema{msg} - return true, err - case 3: // oneof.query_parameter_sub_schema - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(QueryParameterSubSchema) - err := b.DecodeMessage(msg) - m.Oneof = &NonBodyParameter_QueryParameterSubSchema{msg} - return true, err - case 4: // oneof.path_parameter_sub_schema - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(PathParameterSubSchema) - err := b.DecodeMessage(msg) - m.Oneof = &NonBodyParameter_PathParameterSubSchema{msg} - return true, err - default: - return false, nil - } -} - -func _NonBodyParameter_OneofSizer(msg proto.Message) (n int) { - m := msg.(*NonBodyParameter) - // oneof - switch x := m.Oneof.(type) { - case *NonBodyParameter_HeaderParameterSubSchema: - s := proto.Size(x.HeaderParameterSubSchema) - n += proto.SizeVarint(1<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case *NonBodyParameter_FormDataParameterSubSchema: - s := proto.Size(x.FormDataParameterSubSchema) - n += proto.SizeVarint(2<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case *NonBodyParameter_QueryParameterSubSchema: - s := proto.Size(x.QueryParameterSubSchema) - n += proto.SizeVarint(3<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case *NonBodyParameter_PathParameterSubSchema: - s := proto.Size(x.PathParameterSubSchema) - n += proto.SizeVarint(4<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case nil: - default: - panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) - } - return n -} - -type Oauth2AccessCodeSecurity struct { - Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` - Flow string `protobuf:"bytes,2,opt,name=flow" json:"flow,omitempty"` - Scopes *Oauth2Scopes `protobuf:"bytes,3,opt,name=scopes" json:"scopes,omitempty"` - AuthorizationUrl string `protobuf:"bytes,4,opt,name=authorization_url,json=authorizationUrl" json:"authorization_url,omitempty"` - TokenUrl string `protobuf:"bytes,5,opt,name=token_url,json=tokenUrl" json:"token_url,omitempty"` - Description string `protobuf:"bytes,6,opt,name=description" json:"description,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,7,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *Oauth2AccessCodeSecurity) Reset() { *m = Oauth2AccessCodeSecurity{} } -func (m *Oauth2AccessCodeSecurity) String() string { return proto.CompactTextString(m) } -func (*Oauth2AccessCodeSecurity) ProtoMessage() {} -func (*Oauth2AccessCodeSecurity) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} } - -func (m *Oauth2AccessCodeSecurity) GetType() string { - if m != nil { - return m.Type - } - return "" -} - -func (m *Oauth2AccessCodeSecurity) GetFlow() string { - if m != nil { - return m.Flow - } - return "" -} - -func (m *Oauth2AccessCodeSecurity) GetScopes() *Oauth2Scopes { - if m != nil { - return m.Scopes - } - return nil -} - -func (m *Oauth2AccessCodeSecurity) GetAuthorizationUrl() string { - if m != nil { - return m.AuthorizationUrl - } - return "" -} - -func (m *Oauth2AccessCodeSecurity) GetTokenUrl() string { - if m != nil { - return m.TokenUrl - } - return "" -} - -func (m *Oauth2AccessCodeSecurity) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *Oauth2AccessCodeSecurity) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type Oauth2ApplicationSecurity struct { - Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` - Flow string `protobuf:"bytes,2,opt,name=flow" json:"flow,omitempty"` - Scopes *Oauth2Scopes `protobuf:"bytes,3,opt,name=scopes" json:"scopes,omitempty"` - TokenUrl string `protobuf:"bytes,4,opt,name=token_url,json=tokenUrl" json:"token_url,omitempty"` - Description string `protobuf:"bytes,5,opt,name=description" json:"description,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,6,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *Oauth2ApplicationSecurity) Reset() { *m = Oauth2ApplicationSecurity{} } -func (m *Oauth2ApplicationSecurity) String() string { return proto.CompactTextString(m) } -func (*Oauth2ApplicationSecurity) ProtoMessage() {} -func (*Oauth2ApplicationSecurity) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} } - -func (m *Oauth2ApplicationSecurity) GetType() string { - if m != nil { - return m.Type - } - return "" -} - -func (m *Oauth2ApplicationSecurity) GetFlow() string { - if m != nil { - return m.Flow - } - return "" -} - -func (m *Oauth2ApplicationSecurity) GetScopes() *Oauth2Scopes { - if m != nil { - return m.Scopes - } - return nil -} - -func (m *Oauth2ApplicationSecurity) GetTokenUrl() string { - if m != nil { - return m.TokenUrl - } - return "" -} - -func (m *Oauth2ApplicationSecurity) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *Oauth2ApplicationSecurity) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type Oauth2ImplicitSecurity struct { - Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` - Flow string `protobuf:"bytes,2,opt,name=flow" json:"flow,omitempty"` - Scopes *Oauth2Scopes `protobuf:"bytes,3,opt,name=scopes" json:"scopes,omitempty"` - AuthorizationUrl string `protobuf:"bytes,4,opt,name=authorization_url,json=authorizationUrl" json:"authorization_url,omitempty"` - Description string `protobuf:"bytes,5,opt,name=description" json:"description,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,6,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *Oauth2ImplicitSecurity) Reset() { *m = Oauth2ImplicitSecurity{} } -func (m *Oauth2ImplicitSecurity) String() string { return proto.CompactTextString(m) } -func (*Oauth2ImplicitSecurity) ProtoMessage() {} -func (*Oauth2ImplicitSecurity) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} } - -func (m *Oauth2ImplicitSecurity) GetType() string { - if m != nil { - return m.Type - } - return "" -} - -func (m *Oauth2ImplicitSecurity) GetFlow() string { - if m != nil { - return m.Flow - } - return "" -} - -func (m *Oauth2ImplicitSecurity) GetScopes() *Oauth2Scopes { - if m != nil { - return m.Scopes - } - return nil -} - -func (m *Oauth2ImplicitSecurity) GetAuthorizationUrl() string { - if m != nil { - return m.AuthorizationUrl - } - return "" -} - -func (m *Oauth2ImplicitSecurity) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *Oauth2ImplicitSecurity) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type Oauth2PasswordSecurity struct { - Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` - Flow string `protobuf:"bytes,2,opt,name=flow" json:"flow,omitempty"` - Scopes *Oauth2Scopes `protobuf:"bytes,3,opt,name=scopes" json:"scopes,omitempty"` - TokenUrl string `protobuf:"bytes,4,opt,name=token_url,json=tokenUrl" json:"token_url,omitempty"` - Description string `protobuf:"bytes,5,opt,name=description" json:"description,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,6,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *Oauth2PasswordSecurity) Reset() { *m = Oauth2PasswordSecurity{} } -func (m *Oauth2PasswordSecurity) String() string { return proto.CompactTextString(m) } -func (*Oauth2PasswordSecurity) ProtoMessage() {} -func (*Oauth2PasswordSecurity) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} } - -func (m *Oauth2PasswordSecurity) GetType() string { - if m != nil { - return m.Type - } - return "" -} - -func (m *Oauth2PasswordSecurity) GetFlow() string { - if m != nil { - return m.Flow - } - return "" -} - -func (m *Oauth2PasswordSecurity) GetScopes() *Oauth2Scopes { - if m != nil { - return m.Scopes - } - return nil -} - -func (m *Oauth2PasswordSecurity) GetTokenUrl() string { - if m != nil { - return m.TokenUrl - } - return "" -} - -func (m *Oauth2PasswordSecurity) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *Oauth2PasswordSecurity) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type Oauth2Scopes struct { - AdditionalProperties []*NamedString `protobuf:"bytes,1,rep,name=additional_properties,json=additionalProperties" json:"additional_properties,omitempty"` -} - -func (m *Oauth2Scopes) Reset() { *m = Oauth2Scopes{} } -func (m *Oauth2Scopes) String() string { return proto.CompactTextString(m) } -func (*Oauth2Scopes) ProtoMessage() {} -func (*Oauth2Scopes) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} } - -func (m *Oauth2Scopes) GetAdditionalProperties() []*NamedString { - if m != nil { - return m.AdditionalProperties - } - return nil -} - -type Operation struct { - Tags []string `protobuf:"bytes,1,rep,name=tags" json:"tags,omitempty"` - // A brief summary of the operation. - Summary string `protobuf:"bytes,2,opt,name=summary" json:"summary,omitempty"` - // A longer description of the operation, GitHub Flavored Markdown is allowed. - Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"` - ExternalDocs *ExternalDocs `protobuf:"bytes,4,opt,name=external_docs,json=externalDocs" json:"external_docs,omitempty"` - // A unique identifier of the operation. - OperationId string `protobuf:"bytes,5,opt,name=operation_id,json=operationId" json:"operation_id,omitempty"` - // A list of MIME types the API can produce. - Produces []string `protobuf:"bytes,6,rep,name=produces" json:"produces,omitempty"` - // A list of MIME types the API can consume. - Consumes []string `protobuf:"bytes,7,rep,name=consumes" json:"consumes,omitempty"` - // The parameters needed to send a valid API call. - Parameters []*ParametersItem `protobuf:"bytes,8,rep,name=parameters" json:"parameters,omitempty"` - Responses *Responses `protobuf:"bytes,9,opt,name=responses" json:"responses,omitempty"` - // The transfer protocol of the API. - Schemes []string `protobuf:"bytes,10,rep,name=schemes" json:"schemes,omitempty"` - Deprecated bool `protobuf:"varint,11,opt,name=deprecated" json:"deprecated,omitempty"` - Security []*SecurityRequirement `protobuf:"bytes,12,rep,name=security" json:"security,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,13,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *Operation) Reset() { *m = Operation{} } -func (m *Operation) String() string { return proto.CompactTextString(m) } -func (*Operation) ProtoMessage() {} -func (*Operation) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} } - -func (m *Operation) GetTags() []string { - if m != nil { - return m.Tags - } - return nil -} - -func (m *Operation) GetSummary() string { - if m != nil { - return m.Summary - } - return "" -} - -func (m *Operation) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *Operation) GetExternalDocs() *ExternalDocs { - if m != nil { - return m.ExternalDocs - } - return nil -} - -func (m *Operation) GetOperationId() string { - if m != nil { - return m.OperationId - } - return "" -} - -func (m *Operation) GetProduces() []string { - if m != nil { - return m.Produces - } - return nil -} - -func (m *Operation) GetConsumes() []string { - if m != nil { - return m.Consumes - } - return nil -} - -func (m *Operation) GetParameters() []*ParametersItem { - if m != nil { - return m.Parameters - } - return nil -} - -func (m *Operation) GetResponses() *Responses { - if m != nil { - return m.Responses - } - return nil -} - -func (m *Operation) GetSchemes() []string { - if m != nil { - return m.Schemes - } - return nil -} - -func (m *Operation) GetDeprecated() bool { - if m != nil { - return m.Deprecated - } - return false -} - -func (m *Operation) GetSecurity() []*SecurityRequirement { - if m != nil { - return m.Security - } - return nil -} - -func (m *Operation) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type Parameter struct { - // Types that are valid to be assigned to Oneof: - // *Parameter_BodyParameter - // *Parameter_NonBodyParameter - Oneof isParameter_Oneof `protobuf_oneof:"oneof"` -} - -func (m *Parameter) Reset() { *m = Parameter{} } -func (m *Parameter) String() string { return proto.CompactTextString(m) } -func (*Parameter) ProtoMessage() {} -func (*Parameter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} } - -type isParameter_Oneof interface { - isParameter_Oneof() -} - -type Parameter_BodyParameter struct { - BodyParameter *BodyParameter `protobuf:"bytes,1,opt,name=body_parameter,json=bodyParameter,oneof"` -} -type Parameter_NonBodyParameter struct { - NonBodyParameter *NonBodyParameter `protobuf:"bytes,2,opt,name=non_body_parameter,json=nonBodyParameter,oneof"` -} - -func (*Parameter_BodyParameter) isParameter_Oneof() {} -func (*Parameter_NonBodyParameter) isParameter_Oneof() {} - -func (m *Parameter) GetOneof() isParameter_Oneof { - if m != nil { - return m.Oneof - } - return nil -} - -func (m *Parameter) GetBodyParameter() *BodyParameter { - if x, ok := m.GetOneof().(*Parameter_BodyParameter); ok { - return x.BodyParameter - } - return nil -} - -func (m *Parameter) GetNonBodyParameter() *NonBodyParameter { - if x, ok := m.GetOneof().(*Parameter_NonBodyParameter); ok { - return x.NonBodyParameter - } - return nil -} - -// XXX_OneofFuncs is for the internal use of the proto package. -func (*Parameter) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _Parameter_OneofMarshaler, _Parameter_OneofUnmarshaler, _Parameter_OneofSizer, []interface{}{ - (*Parameter_BodyParameter)(nil), - (*Parameter_NonBodyParameter)(nil), - } -} - -func _Parameter_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*Parameter) - // oneof - switch x := m.Oneof.(type) { - case *Parameter_BodyParameter: - b.EncodeVarint(1<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.BodyParameter); err != nil { - return err - } - case *Parameter_NonBodyParameter: - b.EncodeVarint(2<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.NonBodyParameter); err != nil { - return err - } - case nil: - default: - return fmt.Errorf("Parameter.Oneof has unexpected type %T", x) - } - return nil -} - -func _Parameter_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*Parameter) - switch tag { - case 1: // oneof.body_parameter - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(BodyParameter) - err := b.DecodeMessage(msg) - m.Oneof = &Parameter_BodyParameter{msg} - return true, err - case 2: // oneof.non_body_parameter - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(NonBodyParameter) - err := b.DecodeMessage(msg) - m.Oneof = &Parameter_NonBodyParameter{msg} - return true, err - default: - return false, nil - } -} - -func _Parameter_OneofSizer(msg proto.Message) (n int) { - m := msg.(*Parameter) - // oneof - switch x := m.Oneof.(type) { - case *Parameter_BodyParameter: - s := proto.Size(x.BodyParameter) - n += proto.SizeVarint(1<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case *Parameter_NonBodyParameter: - s := proto.Size(x.NonBodyParameter) - n += proto.SizeVarint(2<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case nil: - default: - panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) - } - return n -} - -// One or more JSON representations for parameters -type ParameterDefinitions struct { - AdditionalProperties []*NamedParameter `protobuf:"bytes,1,rep,name=additional_properties,json=additionalProperties" json:"additional_properties,omitempty"` -} - -func (m *ParameterDefinitions) Reset() { *m = ParameterDefinitions{} } -func (m *ParameterDefinitions) String() string { return proto.CompactTextString(m) } -func (*ParameterDefinitions) ProtoMessage() {} -func (*ParameterDefinitions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{38} } - -func (m *ParameterDefinitions) GetAdditionalProperties() []*NamedParameter { - if m != nil { - return m.AdditionalProperties - } - return nil -} - -type ParametersItem struct { - // Types that are valid to be assigned to Oneof: - // *ParametersItem_Parameter - // *ParametersItem_JsonReference - Oneof isParametersItem_Oneof `protobuf_oneof:"oneof"` -} - -func (m *ParametersItem) Reset() { *m = ParametersItem{} } -func (m *ParametersItem) String() string { return proto.CompactTextString(m) } -func (*ParametersItem) ProtoMessage() {} -func (*ParametersItem) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} } - -type isParametersItem_Oneof interface { - isParametersItem_Oneof() -} - -type ParametersItem_Parameter struct { - Parameter *Parameter `protobuf:"bytes,1,opt,name=parameter,oneof"` -} -type ParametersItem_JsonReference struct { - JsonReference *JsonReference `protobuf:"bytes,2,opt,name=json_reference,json=jsonReference,oneof"` -} - -func (*ParametersItem_Parameter) isParametersItem_Oneof() {} -func (*ParametersItem_JsonReference) isParametersItem_Oneof() {} - -func (m *ParametersItem) GetOneof() isParametersItem_Oneof { - if m != nil { - return m.Oneof - } - return nil -} - -func (m *ParametersItem) GetParameter() *Parameter { - if x, ok := m.GetOneof().(*ParametersItem_Parameter); ok { - return x.Parameter - } - return nil -} - -func (m *ParametersItem) GetJsonReference() *JsonReference { - if x, ok := m.GetOneof().(*ParametersItem_JsonReference); ok { - return x.JsonReference - } - return nil -} - -// XXX_OneofFuncs is for the internal use of the proto package. -func (*ParametersItem) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _ParametersItem_OneofMarshaler, _ParametersItem_OneofUnmarshaler, _ParametersItem_OneofSizer, []interface{}{ - (*ParametersItem_Parameter)(nil), - (*ParametersItem_JsonReference)(nil), - } -} - -func _ParametersItem_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*ParametersItem) - // oneof - switch x := m.Oneof.(type) { - case *ParametersItem_Parameter: - b.EncodeVarint(1<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.Parameter); err != nil { - return err - } - case *ParametersItem_JsonReference: - b.EncodeVarint(2<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.JsonReference); err != nil { - return err - } - case nil: - default: - return fmt.Errorf("ParametersItem.Oneof has unexpected type %T", x) - } - return nil -} - -func _ParametersItem_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*ParametersItem) - switch tag { - case 1: // oneof.parameter - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(Parameter) - err := b.DecodeMessage(msg) - m.Oneof = &ParametersItem_Parameter{msg} - return true, err - case 2: // oneof.json_reference - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(JsonReference) - err := b.DecodeMessage(msg) - m.Oneof = &ParametersItem_JsonReference{msg} - return true, err - default: - return false, nil - } -} - -func _ParametersItem_OneofSizer(msg proto.Message) (n int) { - m := msg.(*ParametersItem) - // oneof - switch x := m.Oneof.(type) { - case *ParametersItem_Parameter: - s := proto.Size(x.Parameter) - n += proto.SizeVarint(1<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case *ParametersItem_JsonReference: - s := proto.Size(x.JsonReference) - n += proto.SizeVarint(2<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case nil: - default: - panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) - } - return n -} - -type PathItem struct { - XRef string `protobuf:"bytes,1,opt,name=_ref,json=Ref" json:"_ref,omitempty"` - Get *Operation `protobuf:"bytes,2,opt,name=get" json:"get,omitempty"` - Put *Operation `protobuf:"bytes,3,opt,name=put" json:"put,omitempty"` - Post *Operation `protobuf:"bytes,4,opt,name=post" json:"post,omitempty"` - Delete *Operation `protobuf:"bytes,5,opt,name=delete" json:"delete,omitempty"` - Options *Operation `protobuf:"bytes,6,opt,name=options" json:"options,omitempty"` - Head *Operation `protobuf:"bytes,7,opt,name=head" json:"head,omitempty"` - Patch *Operation `protobuf:"bytes,8,opt,name=patch" json:"patch,omitempty"` - // The parameters needed to send a valid API call. - Parameters []*ParametersItem `protobuf:"bytes,9,rep,name=parameters" json:"parameters,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,10,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *PathItem) Reset() { *m = PathItem{} } -func (m *PathItem) String() string { return proto.CompactTextString(m) } -func (*PathItem) ProtoMessage() {} -func (*PathItem) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{40} } - -func (m *PathItem) GetXRef() string { - if m != nil { - return m.XRef - } - return "" -} - -func (m *PathItem) GetGet() *Operation { - if m != nil { - return m.Get - } - return nil -} - -func (m *PathItem) GetPut() *Operation { - if m != nil { - return m.Put - } - return nil -} - -func (m *PathItem) GetPost() *Operation { - if m != nil { - return m.Post - } - return nil -} - -func (m *PathItem) GetDelete() *Operation { - if m != nil { - return m.Delete - } - return nil -} - -func (m *PathItem) GetOptions() *Operation { - if m != nil { - return m.Options - } - return nil -} - -func (m *PathItem) GetHead() *Operation { - if m != nil { - return m.Head - } - return nil -} - -func (m *PathItem) GetPatch() *Operation { - if m != nil { - return m.Patch - } - return nil -} - -func (m *PathItem) GetParameters() []*ParametersItem { - if m != nil { - return m.Parameters - } - return nil -} - -func (m *PathItem) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type PathParameterSubSchema struct { - // Determines whether or not this parameter is required or optional. - Required bool `protobuf:"varint,1,opt,name=required" json:"required,omitempty"` - // Determines the location of the parameter. - In string `protobuf:"bytes,2,opt,name=in" json:"in,omitempty"` - // A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed. - Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"` - // The name of the parameter. - Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` - Type string `protobuf:"bytes,5,opt,name=type" json:"type,omitempty"` - Format string `protobuf:"bytes,6,opt,name=format" json:"format,omitempty"` - Items *PrimitivesItems `protobuf:"bytes,7,opt,name=items" json:"items,omitempty"` - CollectionFormat string `protobuf:"bytes,8,opt,name=collection_format,json=collectionFormat" json:"collection_format,omitempty"` - Default *Any `protobuf:"bytes,9,opt,name=default" json:"default,omitempty"` - Maximum float64 `protobuf:"fixed64,10,opt,name=maximum" json:"maximum,omitempty"` - ExclusiveMaximum bool `protobuf:"varint,11,opt,name=exclusive_maximum,json=exclusiveMaximum" json:"exclusive_maximum,omitempty"` - Minimum float64 `protobuf:"fixed64,12,opt,name=minimum" json:"minimum,omitempty"` - ExclusiveMinimum bool `protobuf:"varint,13,opt,name=exclusive_minimum,json=exclusiveMinimum" json:"exclusive_minimum,omitempty"` - MaxLength int64 `protobuf:"varint,14,opt,name=max_length,json=maxLength" json:"max_length,omitempty"` - MinLength int64 `protobuf:"varint,15,opt,name=min_length,json=minLength" json:"min_length,omitempty"` - Pattern string `protobuf:"bytes,16,opt,name=pattern" json:"pattern,omitempty"` - MaxItems int64 `protobuf:"varint,17,opt,name=max_items,json=maxItems" json:"max_items,omitempty"` - MinItems int64 `protobuf:"varint,18,opt,name=min_items,json=minItems" json:"min_items,omitempty"` - UniqueItems bool `protobuf:"varint,19,opt,name=unique_items,json=uniqueItems" json:"unique_items,omitempty"` - Enum []*Any `protobuf:"bytes,20,rep,name=enum" json:"enum,omitempty"` - MultipleOf float64 `protobuf:"fixed64,21,opt,name=multiple_of,json=multipleOf" json:"multiple_of,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,22,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *PathParameterSubSchema) Reset() { *m = PathParameterSubSchema{} } -func (m *PathParameterSubSchema) String() string { return proto.CompactTextString(m) } -func (*PathParameterSubSchema) ProtoMessage() {} -func (*PathParameterSubSchema) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{41} } - -func (m *PathParameterSubSchema) GetRequired() bool { - if m != nil { - return m.Required - } - return false -} - -func (m *PathParameterSubSchema) GetIn() string { - if m != nil { - return m.In - } - return "" -} - -func (m *PathParameterSubSchema) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *PathParameterSubSchema) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *PathParameterSubSchema) GetType() string { - if m != nil { - return m.Type - } - return "" -} - -func (m *PathParameterSubSchema) GetFormat() string { - if m != nil { - return m.Format - } - return "" -} - -func (m *PathParameterSubSchema) GetItems() *PrimitivesItems { - if m != nil { - return m.Items - } - return nil -} - -func (m *PathParameterSubSchema) GetCollectionFormat() string { - if m != nil { - return m.CollectionFormat - } - return "" -} - -func (m *PathParameterSubSchema) GetDefault() *Any { - if m != nil { - return m.Default - } - return nil -} - -func (m *PathParameterSubSchema) GetMaximum() float64 { - if m != nil { - return m.Maximum - } - return 0 -} - -func (m *PathParameterSubSchema) GetExclusiveMaximum() bool { - if m != nil { - return m.ExclusiveMaximum - } - return false -} - -func (m *PathParameterSubSchema) GetMinimum() float64 { - if m != nil { - return m.Minimum - } - return 0 -} - -func (m *PathParameterSubSchema) GetExclusiveMinimum() bool { - if m != nil { - return m.ExclusiveMinimum - } - return false -} - -func (m *PathParameterSubSchema) GetMaxLength() int64 { - if m != nil { - return m.MaxLength - } - return 0 -} - -func (m *PathParameterSubSchema) GetMinLength() int64 { - if m != nil { - return m.MinLength - } - return 0 -} - -func (m *PathParameterSubSchema) GetPattern() string { - if m != nil { - return m.Pattern - } - return "" -} - -func (m *PathParameterSubSchema) GetMaxItems() int64 { - if m != nil { - return m.MaxItems - } - return 0 -} - -func (m *PathParameterSubSchema) GetMinItems() int64 { - if m != nil { - return m.MinItems - } - return 0 -} - -func (m *PathParameterSubSchema) GetUniqueItems() bool { - if m != nil { - return m.UniqueItems - } - return false -} - -func (m *PathParameterSubSchema) GetEnum() []*Any { - if m != nil { - return m.Enum - } - return nil -} - -func (m *PathParameterSubSchema) GetMultipleOf() float64 { - if m != nil { - return m.MultipleOf - } - return 0 -} - -func (m *PathParameterSubSchema) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -// Relative paths to the individual endpoints. They must be relative to the 'basePath'. -type Paths struct { - VendorExtension []*NamedAny `protobuf:"bytes,1,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` - Path []*NamedPathItem `protobuf:"bytes,2,rep,name=path" json:"path,omitempty"` -} - -func (m *Paths) Reset() { *m = Paths{} } -func (m *Paths) String() string { return proto.CompactTextString(m) } -func (*Paths) ProtoMessage() {} -func (*Paths) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{42} } - -func (m *Paths) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -func (m *Paths) GetPath() []*NamedPathItem { - if m != nil { - return m.Path - } - return nil -} - -type PrimitivesItems struct { - Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` - Format string `protobuf:"bytes,2,opt,name=format" json:"format,omitempty"` - Items *PrimitivesItems `protobuf:"bytes,3,opt,name=items" json:"items,omitempty"` - CollectionFormat string `protobuf:"bytes,4,opt,name=collection_format,json=collectionFormat" json:"collection_format,omitempty"` - Default *Any `protobuf:"bytes,5,opt,name=default" json:"default,omitempty"` - Maximum float64 `protobuf:"fixed64,6,opt,name=maximum" json:"maximum,omitempty"` - ExclusiveMaximum bool `protobuf:"varint,7,opt,name=exclusive_maximum,json=exclusiveMaximum" json:"exclusive_maximum,omitempty"` - Minimum float64 `protobuf:"fixed64,8,opt,name=minimum" json:"minimum,omitempty"` - ExclusiveMinimum bool `protobuf:"varint,9,opt,name=exclusive_minimum,json=exclusiveMinimum" json:"exclusive_minimum,omitempty"` - MaxLength int64 `protobuf:"varint,10,opt,name=max_length,json=maxLength" json:"max_length,omitempty"` - MinLength int64 `protobuf:"varint,11,opt,name=min_length,json=minLength" json:"min_length,omitempty"` - Pattern string `protobuf:"bytes,12,opt,name=pattern" json:"pattern,omitempty"` - MaxItems int64 `protobuf:"varint,13,opt,name=max_items,json=maxItems" json:"max_items,omitempty"` - MinItems int64 `protobuf:"varint,14,opt,name=min_items,json=minItems" json:"min_items,omitempty"` - UniqueItems bool `protobuf:"varint,15,opt,name=unique_items,json=uniqueItems" json:"unique_items,omitempty"` - Enum []*Any `protobuf:"bytes,16,rep,name=enum" json:"enum,omitempty"` - MultipleOf float64 `protobuf:"fixed64,17,opt,name=multiple_of,json=multipleOf" json:"multiple_of,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,18,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *PrimitivesItems) Reset() { *m = PrimitivesItems{} } -func (m *PrimitivesItems) String() string { return proto.CompactTextString(m) } -func (*PrimitivesItems) ProtoMessage() {} -func (*PrimitivesItems) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{43} } - -func (m *PrimitivesItems) GetType() string { - if m != nil { - return m.Type - } - return "" -} - -func (m *PrimitivesItems) GetFormat() string { - if m != nil { - return m.Format - } - return "" -} - -func (m *PrimitivesItems) GetItems() *PrimitivesItems { - if m != nil { - return m.Items - } - return nil -} - -func (m *PrimitivesItems) GetCollectionFormat() string { - if m != nil { - return m.CollectionFormat - } - return "" -} - -func (m *PrimitivesItems) GetDefault() *Any { - if m != nil { - return m.Default - } - return nil -} - -func (m *PrimitivesItems) GetMaximum() float64 { - if m != nil { - return m.Maximum - } - return 0 -} - -func (m *PrimitivesItems) GetExclusiveMaximum() bool { - if m != nil { - return m.ExclusiveMaximum - } - return false -} - -func (m *PrimitivesItems) GetMinimum() float64 { - if m != nil { - return m.Minimum - } - return 0 -} - -func (m *PrimitivesItems) GetExclusiveMinimum() bool { - if m != nil { - return m.ExclusiveMinimum - } - return false -} - -func (m *PrimitivesItems) GetMaxLength() int64 { - if m != nil { - return m.MaxLength - } - return 0 -} - -func (m *PrimitivesItems) GetMinLength() int64 { - if m != nil { - return m.MinLength - } - return 0 -} - -func (m *PrimitivesItems) GetPattern() string { - if m != nil { - return m.Pattern - } - return "" -} - -func (m *PrimitivesItems) GetMaxItems() int64 { - if m != nil { - return m.MaxItems - } - return 0 -} - -func (m *PrimitivesItems) GetMinItems() int64 { - if m != nil { - return m.MinItems - } - return 0 -} - -func (m *PrimitivesItems) GetUniqueItems() bool { - if m != nil { - return m.UniqueItems - } - return false -} - -func (m *PrimitivesItems) GetEnum() []*Any { - if m != nil { - return m.Enum - } - return nil -} - -func (m *PrimitivesItems) GetMultipleOf() float64 { - if m != nil { - return m.MultipleOf - } - return 0 -} - -func (m *PrimitivesItems) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type Properties struct { - AdditionalProperties []*NamedSchema `protobuf:"bytes,1,rep,name=additional_properties,json=additionalProperties" json:"additional_properties,omitempty"` -} - -func (m *Properties) Reset() { *m = Properties{} } -func (m *Properties) String() string { return proto.CompactTextString(m) } -func (*Properties) ProtoMessage() {} -func (*Properties) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{44} } - -func (m *Properties) GetAdditionalProperties() []*NamedSchema { - if m != nil { - return m.AdditionalProperties - } - return nil -} - -type QueryParameterSubSchema struct { - // Determines whether or not this parameter is required or optional. - Required bool `protobuf:"varint,1,opt,name=required" json:"required,omitempty"` - // Determines the location of the parameter. - In string `protobuf:"bytes,2,opt,name=in" json:"in,omitempty"` - // A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed. - Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"` - // The name of the parameter. - Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` - // allows sending a parameter by name only or with an empty value. - AllowEmptyValue bool `protobuf:"varint,5,opt,name=allow_empty_value,json=allowEmptyValue" json:"allow_empty_value,omitempty"` - Type string `protobuf:"bytes,6,opt,name=type" json:"type,omitempty"` - Format string `protobuf:"bytes,7,opt,name=format" json:"format,omitempty"` - Items *PrimitivesItems `protobuf:"bytes,8,opt,name=items" json:"items,omitempty"` - CollectionFormat string `protobuf:"bytes,9,opt,name=collection_format,json=collectionFormat" json:"collection_format,omitempty"` - Default *Any `protobuf:"bytes,10,opt,name=default" json:"default,omitempty"` - Maximum float64 `protobuf:"fixed64,11,opt,name=maximum" json:"maximum,omitempty"` - ExclusiveMaximum bool `protobuf:"varint,12,opt,name=exclusive_maximum,json=exclusiveMaximum" json:"exclusive_maximum,omitempty"` - Minimum float64 `protobuf:"fixed64,13,opt,name=minimum" json:"minimum,omitempty"` - ExclusiveMinimum bool `protobuf:"varint,14,opt,name=exclusive_minimum,json=exclusiveMinimum" json:"exclusive_minimum,omitempty"` - MaxLength int64 `protobuf:"varint,15,opt,name=max_length,json=maxLength" json:"max_length,omitempty"` - MinLength int64 `protobuf:"varint,16,opt,name=min_length,json=minLength" json:"min_length,omitempty"` - Pattern string `protobuf:"bytes,17,opt,name=pattern" json:"pattern,omitempty"` - MaxItems int64 `protobuf:"varint,18,opt,name=max_items,json=maxItems" json:"max_items,omitempty"` - MinItems int64 `protobuf:"varint,19,opt,name=min_items,json=minItems" json:"min_items,omitempty"` - UniqueItems bool `protobuf:"varint,20,opt,name=unique_items,json=uniqueItems" json:"unique_items,omitempty"` - Enum []*Any `protobuf:"bytes,21,rep,name=enum" json:"enum,omitempty"` - MultipleOf float64 `protobuf:"fixed64,22,opt,name=multiple_of,json=multipleOf" json:"multiple_of,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,23,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *QueryParameterSubSchema) Reset() { *m = QueryParameterSubSchema{} } -func (m *QueryParameterSubSchema) String() string { return proto.CompactTextString(m) } -func (*QueryParameterSubSchema) ProtoMessage() {} -func (*QueryParameterSubSchema) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{45} } - -func (m *QueryParameterSubSchema) GetRequired() bool { - if m != nil { - return m.Required - } - return false -} - -func (m *QueryParameterSubSchema) GetIn() string { - if m != nil { - return m.In - } - return "" -} - -func (m *QueryParameterSubSchema) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *QueryParameterSubSchema) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *QueryParameterSubSchema) GetAllowEmptyValue() bool { - if m != nil { - return m.AllowEmptyValue - } - return false -} - -func (m *QueryParameterSubSchema) GetType() string { - if m != nil { - return m.Type - } - return "" -} - -func (m *QueryParameterSubSchema) GetFormat() string { - if m != nil { - return m.Format - } - return "" -} - -func (m *QueryParameterSubSchema) GetItems() *PrimitivesItems { - if m != nil { - return m.Items - } - return nil -} - -func (m *QueryParameterSubSchema) GetCollectionFormat() string { - if m != nil { - return m.CollectionFormat - } - return "" -} - -func (m *QueryParameterSubSchema) GetDefault() *Any { - if m != nil { - return m.Default - } - return nil -} - -func (m *QueryParameterSubSchema) GetMaximum() float64 { - if m != nil { - return m.Maximum - } - return 0 -} - -func (m *QueryParameterSubSchema) GetExclusiveMaximum() bool { - if m != nil { - return m.ExclusiveMaximum - } - return false -} - -func (m *QueryParameterSubSchema) GetMinimum() float64 { - if m != nil { - return m.Minimum - } - return 0 -} - -func (m *QueryParameterSubSchema) GetExclusiveMinimum() bool { - if m != nil { - return m.ExclusiveMinimum - } - return false -} - -func (m *QueryParameterSubSchema) GetMaxLength() int64 { - if m != nil { - return m.MaxLength - } - return 0 -} - -func (m *QueryParameterSubSchema) GetMinLength() int64 { - if m != nil { - return m.MinLength - } - return 0 -} - -func (m *QueryParameterSubSchema) GetPattern() string { - if m != nil { - return m.Pattern - } - return "" -} - -func (m *QueryParameterSubSchema) GetMaxItems() int64 { - if m != nil { - return m.MaxItems - } - return 0 -} - -func (m *QueryParameterSubSchema) GetMinItems() int64 { - if m != nil { - return m.MinItems - } - return 0 -} - -func (m *QueryParameterSubSchema) GetUniqueItems() bool { - if m != nil { - return m.UniqueItems - } - return false -} - -func (m *QueryParameterSubSchema) GetEnum() []*Any { - if m != nil { - return m.Enum - } - return nil -} - -func (m *QueryParameterSubSchema) GetMultipleOf() float64 { - if m != nil { - return m.MultipleOf - } - return 0 -} - -func (m *QueryParameterSubSchema) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type Response struct { - Description string `protobuf:"bytes,1,opt,name=description" json:"description,omitempty"` - Schema *SchemaItem `protobuf:"bytes,2,opt,name=schema" json:"schema,omitempty"` - Headers *Headers `protobuf:"bytes,3,opt,name=headers" json:"headers,omitempty"` - Examples *Examples `protobuf:"bytes,4,opt,name=examples" json:"examples,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,5,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *Response) Reset() { *m = Response{} } -func (m *Response) String() string { return proto.CompactTextString(m) } -func (*Response) ProtoMessage() {} -func (*Response) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{46} } - -func (m *Response) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *Response) GetSchema() *SchemaItem { - if m != nil { - return m.Schema - } - return nil -} - -func (m *Response) GetHeaders() *Headers { - if m != nil { - return m.Headers - } - return nil -} - -func (m *Response) GetExamples() *Examples { - if m != nil { - return m.Examples - } - return nil -} - -func (m *Response) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -// One or more JSON representations for parameters -type ResponseDefinitions struct { - AdditionalProperties []*NamedResponse `protobuf:"bytes,1,rep,name=additional_properties,json=additionalProperties" json:"additional_properties,omitempty"` -} - -func (m *ResponseDefinitions) Reset() { *m = ResponseDefinitions{} } -func (m *ResponseDefinitions) String() string { return proto.CompactTextString(m) } -func (*ResponseDefinitions) ProtoMessage() {} -func (*ResponseDefinitions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{47} } - -func (m *ResponseDefinitions) GetAdditionalProperties() []*NamedResponse { - if m != nil { - return m.AdditionalProperties - } - return nil -} - -type ResponseValue struct { - // Types that are valid to be assigned to Oneof: - // *ResponseValue_Response - // *ResponseValue_JsonReference - Oneof isResponseValue_Oneof `protobuf_oneof:"oneof"` -} - -func (m *ResponseValue) Reset() { *m = ResponseValue{} } -func (m *ResponseValue) String() string { return proto.CompactTextString(m) } -func (*ResponseValue) ProtoMessage() {} -func (*ResponseValue) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{48} } - -type isResponseValue_Oneof interface { - isResponseValue_Oneof() -} - -type ResponseValue_Response struct { - Response *Response `protobuf:"bytes,1,opt,name=response,oneof"` -} -type ResponseValue_JsonReference struct { - JsonReference *JsonReference `protobuf:"bytes,2,opt,name=json_reference,json=jsonReference,oneof"` -} - -func (*ResponseValue_Response) isResponseValue_Oneof() {} -func (*ResponseValue_JsonReference) isResponseValue_Oneof() {} - -func (m *ResponseValue) GetOneof() isResponseValue_Oneof { - if m != nil { - return m.Oneof - } - return nil -} - -func (m *ResponseValue) GetResponse() *Response { - if x, ok := m.GetOneof().(*ResponseValue_Response); ok { - return x.Response - } - return nil -} - -func (m *ResponseValue) GetJsonReference() *JsonReference { - if x, ok := m.GetOneof().(*ResponseValue_JsonReference); ok { - return x.JsonReference - } - return nil -} - -// XXX_OneofFuncs is for the internal use of the proto package. -func (*ResponseValue) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _ResponseValue_OneofMarshaler, _ResponseValue_OneofUnmarshaler, _ResponseValue_OneofSizer, []interface{}{ - (*ResponseValue_Response)(nil), - (*ResponseValue_JsonReference)(nil), - } -} - -func _ResponseValue_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*ResponseValue) - // oneof - switch x := m.Oneof.(type) { - case *ResponseValue_Response: - b.EncodeVarint(1<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.Response); err != nil { - return err - } - case *ResponseValue_JsonReference: - b.EncodeVarint(2<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.JsonReference); err != nil { - return err - } - case nil: - default: - return fmt.Errorf("ResponseValue.Oneof has unexpected type %T", x) - } - return nil -} - -func _ResponseValue_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*ResponseValue) - switch tag { - case 1: // oneof.response - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(Response) - err := b.DecodeMessage(msg) - m.Oneof = &ResponseValue_Response{msg} - return true, err - case 2: // oneof.json_reference - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(JsonReference) - err := b.DecodeMessage(msg) - m.Oneof = &ResponseValue_JsonReference{msg} - return true, err - default: - return false, nil - } -} - -func _ResponseValue_OneofSizer(msg proto.Message) (n int) { - m := msg.(*ResponseValue) - // oneof - switch x := m.Oneof.(type) { - case *ResponseValue_Response: - s := proto.Size(x.Response) - n += proto.SizeVarint(1<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case *ResponseValue_JsonReference: - s := proto.Size(x.JsonReference) - n += proto.SizeVarint(2<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case nil: - default: - panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) - } - return n -} - -// Response objects names can either be any valid HTTP status code or 'default'. -type Responses struct { - ResponseCode []*NamedResponseValue `protobuf:"bytes,1,rep,name=response_code,json=responseCode" json:"response_code,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,2,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *Responses) Reset() { *m = Responses{} } -func (m *Responses) String() string { return proto.CompactTextString(m) } -func (*Responses) ProtoMessage() {} -func (*Responses) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{49} } - -func (m *Responses) GetResponseCode() []*NamedResponseValue { - if m != nil { - return m.ResponseCode - } - return nil -} - -func (m *Responses) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -// A deterministic version of a JSON Schema object. -type Schema struct { - XRef string `protobuf:"bytes,1,opt,name=_ref,json=Ref" json:"_ref,omitempty"` - Format string `protobuf:"bytes,2,opt,name=format" json:"format,omitempty"` - Title string `protobuf:"bytes,3,opt,name=title" json:"title,omitempty"` - Description string `protobuf:"bytes,4,opt,name=description" json:"description,omitempty"` - Default *Any `protobuf:"bytes,5,opt,name=default" json:"default,omitempty"` - MultipleOf float64 `protobuf:"fixed64,6,opt,name=multiple_of,json=multipleOf" json:"multiple_of,omitempty"` - Maximum float64 `protobuf:"fixed64,7,opt,name=maximum" json:"maximum,omitempty"` - ExclusiveMaximum bool `protobuf:"varint,8,opt,name=exclusive_maximum,json=exclusiveMaximum" json:"exclusive_maximum,omitempty"` - Minimum float64 `protobuf:"fixed64,9,opt,name=minimum" json:"minimum,omitempty"` - ExclusiveMinimum bool `protobuf:"varint,10,opt,name=exclusive_minimum,json=exclusiveMinimum" json:"exclusive_minimum,omitempty"` - MaxLength int64 `protobuf:"varint,11,opt,name=max_length,json=maxLength" json:"max_length,omitempty"` - MinLength int64 `protobuf:"varint,12,opt,name=min_length,json=minLength" json:"min_length,omitempty"` - Pattern string `protobuf:"bytes,13,opt,name=pattern" json:"pattern,omitempty"` - MaxItems int64 `protobuf:"varint,14,opt,name=max_items,json=maxItems" json:"max_items,omitempty"` - MinItems int64 `protobuf:"varint,15,opt,name=min_items,json=minItems" json:"min_items,omitempty"` - UniqueItems bool `protobuf:"varint,16,opt,name=unique_items,json=uniqueItems" json:"unique_items,omitempty"` - MaxProperties int64 `protobuf:"varint,17,opt,name=max_properties,json=maxProperties" json:"max_properties,omitempty"` - MinProperties int64 `protobuf:"varint,18,opt,name=min_properties,json=minProperties" json:"min_properties,omitempty"` - Required []string `protobuf:"bytes,19,rep,name=required" json:"required,omitempty"` - Enum []*Any `protobuf:"bytes,20,rep,name=enum" json:"enum,omitempty"` - AdditionalProperties *AdditionalPropertiesItem `protobuf:"bytes,21,opt,name=additional_properties,json=additionalProperties" json:"additional_properties,omitempty"` - Type *TypeItem `protobuf:"bytes,22,opt,name=type" json:"type,omitempty"` - Items *ItemsItem `protobuf:"bytes,23,opt,name=items" json:"items,omitempty"` - AllOf []*Schema `protobuf:"bytes,24,rep,name=all_of,json=allOf" json:"all_of,omitempty"` - Properties *Properties `protobuf:"bytes,25,opt,name=properties" json:"properties,omitempty"` - Discriminator string `protobuf:"bytes,26,opt,name=discriminator" json:"discriminator,omitempty"` - ReadOnly bool `protobuf:"varint,27,opt,name=read_only,json=readOnly" json:"read_only,omitempty"` - Xml *Xml `protobuf:"bytes,28,opt,name=xml" json:"xml,omitempty"` - ExternalDocs *ExternalDocs `protobuf:"bytes,29,opt,name=external_docs,json=externalDocs" json:"external_docs,omitempty"` - Example *Any `protobuf:"bytes,30,opt,name=example" json:"example,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,31,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *Schema) Reset() { *m = Schema{} } -func (m *Schema) String() string { return proto.CompactTextString(m) } -func (*Schema) ProtoMessage() {} -func (*Schema) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{50} } - -func (m *Schema) GetXRef() string { - if m != nil { - return m.XRef - } - return "" -} - -func (m *Schema) GetFormat() string { - if m != nil { - return m.Format - } - return "" -} - -func (m *Schema) GetTitle() string { - if m != nil { - return m.Title - } - return "" -} - -func (m *Schema) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *Schema) GetDefault() *Any { - if m != nil { - return m.Default - } - return nil -} - -func (m *Schema) GetMultipleOf() float64 { - if m != nil { - return m.MultipleOf - } - return 0 -} - -func (m *Schema) GetMaximum() float64 { - if m != nil { - return m.Maximum - } - return 0 -} - -func (m *Schema) GetExclusiveMaximum() bool { - if m != nil { - return m.ExclusiveMaximum - } - return false -} - -func (m *Schema) GetMinimum() float64 { - if m != nil { - return m.Minimum - } - return 0 -} - -func (m *Schema) GetExclusiveMinimum() bool { - if m != nil { - return m.ExclusiveMinimum - } - return false -} - -func (m *Schema) GetMaxLength() int64 { - if m != nil { - return m.MaxLength - } - return 0 -} - -func (m *Schema) GetMinLength() int64 { - if m != nil { - return m.MinLength - } - return 0 -} - -func (m *Schema) GetPattern() string { - if m != nil { - return m.Pattern - } - return "" -} - -func (m *Schema) GetMaxItems() int64 { - if m != nil { - return m.MaxItems - } - return 0 -} - -func (m *Schema) GetMinItems() int64 { - if m != nil { - return m.MinItems - } - return 0 -} - -func (m *Schema) GetUniqueItems() bool { - if m != nil { - return m.UniqueItems - } - return false -} - -func (m *Schema) GetMaxProperties() int64 { - if m != nil { - return m.MaxProperties - } - return 0 -} - -func (m *Schema) GetMinProperties() int64 { - if m != nil { - return m.MinProperties - } - return 0 -} - -func (m *Schema) GetRequired() []string { - if m != nil { - return m.Required - } - return nil -} - -func (m *Schema) GetEnum() []*Any { - if m != nil { - return m.Enum - } - return nil -} - -func (m *Schema) GetAdditionalProperties() *AdditionalPropertiesItem { - if m != nil { - return m.AdditionalProperties - } - return nil -} - -func (m *Schema) GetType() *TypeItem { - if m != nil { - return m.Type - } - return nil -} - -func (m *Schema) GetItems() *ItemsItem { - if m != nil { - return m.Items - } - return nil -} - -func (m *Schema) GetAllOf() []*Schema { - if m != nil { - return m.AllOf - } - return nil -} - -func (m *Schema) GetProperties() *Properties { - if m != nil { - return m.Properties - } - return nil -} - -func (m *Schema) GetDiscriminator() string { - if m != nil { - return m.Discriminator - } - return "" -} - -func (m *Schema) GetReadOnly() bool { - if m != nil { - return m.ReadOnly - } - return false -} - -func (m *Schema) GetXml() *Xml { - if m != nil { - return m.Xml - } - return nil -} - -func (m *Schema) GetExternalDocs() *ExternalDocs { - if m != nil { - return m.ExternalDocs - } - return nil -} - -func (m *Schema) GetExample() *Any { - if m != nil { - return m.Example - } - return nil -} - -func (m *Schema) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type SchemaItem struct { - // Types that are valid to be assigned to Oneof: - // *SchemaItem_Schema - // *SchemaItem_FileSchema - Oneof isSchemaItem_Oneof `protobuf_oneof:"oneof"` -} - -func (m *SchemaItem) Reset() { *m = SchemaItem{} } -func (m *SchemaItem) String() string { return proto.CompactTextString(m) } -func (*SchemaItem) ProtoMessage() {} -func (*SchemaItem) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{51} } - -type isSchemaItem_Oneof interface { - isSchemaItem_Oneof() -} - -type SchemaItem_Schema struct { - Schema *Schema `protobuf:"bytes,1,opt,name=schema,oneof"` -} -type SchemaItem_FileSchema struct { - FileSchema *FileSchema `protobuf:"bytes,2,opt,name=file_schema,json=fileSchema,oneof"` -} - -func (*SchemaItem_Schema) isSchemaItem_Oneof() {} -func (*SchemaItem_FileSchema) isSchemaItem_Oneof() {} - -func (m *SchemaItem) GetOneof() isSchemaItem_Oneof { - if m != nil { - return m.Oneof - } - return nil -} - -func (m *SchemaItem) GetSchema() *Schema { - if x, ok := m.GetOneof().(*SchemaItem_Schema); ok { - return x.Schema - } - return nil -} - -func (m *SchemaItem) GetFileSchema() *FileSchema { - if x, ok := m.GetOneof().(*SchemaItem_FileSchema); ok { - return x.FileSchema - } - return nil -} - -// XXX_OneofFuncs is for the internal use of the proto package. -func (*SchemaItem) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _SchemaItem_OneofMarshaler, _SchemaItem_OneofUnmarshaler, _SchemaItem_OneofSizer, []interface{}{ - (*SchemaItem_Schema)(nil), - (*SchemaItem_FileSchema)(nil), - } -} - -func _SchemaItem_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*SchemaItem) - // oneof - switch x := m.Oneof.(type) { - case *SchemaItem_Schema: - b.EncodeVarint(1<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.Schema); err != nil { - return err - } - case *SchemaItem_FileSchema: - b.EncodeVarint(2<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.FileSchema); err != nil { - return err - } - case nil: - default: - return fmt.Errorf("SchemaItem.Oneof has unexpected type %T", x) - } - return nil -} - -func _SchemaItem_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*SchemaItem) - switch tag { - case 1: // oneof.schema - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(Schema) - err := b.DecodeMessage(msg) - m.Oneof = &SchemaItem_Schema{msg} - return true, err - case 2: // oneof.file_schema - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(FileSchema) - err := b.DecodeMessage(msg) - m.Oneof = &SchemaItem_FileSchema{msg} - return true, err - default: - return false, nil - } -} - -func _SchemaItem_OneofSizer(msg proto.Message) (n int) { - m := msg.(*SchemaItem) - // oneof - switch x := m.Oneof.(type) { - case *SchemaItem_Schema: - s := proto.Size(x.Schema) - n += proto.SizeVarint(1<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case *SchemaItem_FileSchema: - s := proto.Size(x.FileSchema) - n += proto.SizeVarint(2<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case nil: - default: - panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) - } - return n -} - -type SecurityDefinitions struct { - AdditionalProperties []*NamedSecurityDefinitionsItem `protobuf:"bytes,1,rep,name=additional_properties,json=additionalProperties" json:"additional_properties,omitempty"` -} - -func (m *SecurityDefinitions) Reset() { *m = SecurityDefinitions{} } -func (m *SecurityDefinitions) String() string { return proto.CompactTextString(m) } -func (*SecurityDefinitions) ProtoMessage() {} -func (*SecurityDefinitions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{52} } - -func (m *SecurityDefinitions) GetAdditionalProperties() []*NamedSecurityDefinitionsItem { - if m != nil { - return m.AdditionalProperties - } - return nil -} - -type SecurityDefinitionsItem struct { - // Types that are valid to be assigned to Oneof: - // *SecurityDefinitionsItem_BasicAuthenticationSecurity - // *SecurityDefinitionsItem_ApiKeySecurity - // *SecurityDefinitionsItem_Oauth2ImplicitSecurity - // *SecurityDefinitionsItem_Oauth2PasswordSecurity - // *SecurityDefinitionsItem_Oauth2ApplicationSecurity - // *SecurityDefinitionsItem_Oauth2AccessCodeSecurity - Oneof isSecurityDefinitionsItem_Oneof `protobuf_oneof:"oneof"` -} - -func (m *SecurityDefinitionsItem) Reset() { *m = SecurityDefinitionsItem{} } -func (m *SecurityDefinitionsItem) String() string { return proto.CompactTextString(m) } -func (*SecurityDefinitionsItem) ProtoMessage() {} -func (*SecurityDefinitionsItem) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{53} } - -type isSecurityDefinitionsItem_Oneof interface { - isSecurityDefinitionsItem_Oneof() -} - -type SecurityDefinitionsItem_BasicAuthenticationSecurity struct { - BasicAuthenticationSecurity *BasicAuthenticationSecurity `protobuf:"bytes,1,opt,name=basic_authentication_security,json=basicAuthenticationSecurity,oneof"` -} -type SecurityDefinitionsItem_ApiKeySecurity struct { - ApiKeySecurity *ApiKeySecurity `protobuf:"bytes,2,opt,name=api_key_security,json=apiKeySecurity,oneof"` -} -type SecurityDefinitionsItem_Oauth2ImplicitSecurity struct { - Oauth2ImplicitSecurity *Oauth2ImplicitSecurity `protobuf:"bytes,3,opt,name=oauth2_implicit_security,json=oauth2ImplicitSecurity,oneof"` -} -type SecurityDefinitionsItem_Oauth2PasswordSecurity struct { - Oauth2PasswordSecurity *Oauth2PasswordSecurity `protobuf:"bytes,4,opt,name=oauth2_password_security,json=oauth2PasswordSecurity,oneof"` -} -type SecurityDefinitionsItem_Oauth2ApplicationSecurity struct { - Oauth2ApplicationSecurity *Oauth2ApplicationSecurity `protobuf:"bytes,5,opt,name=oauth2_application_security,json=oauth2ApplicationSecurity,oneof"` -} -type SecurityDefinitionsItem_Oauth2AccessCodeSecurity struct { - Oauth2AccessCodeSecurity *Oauth2AccessCodeSecurity `protobuf:"bytes,6,opt,name=oauth2_access_code_security,json=oauth2AccessCodeSecurity,oneof"` -} - -func (*SecurityDefinitionsItem_BasicAuthenticationSecurity) isSecurityDefinitionsItem_Oneof() {} -func (*SecurityDefinitionsItem_ApiKeySecurity) isSecurityDefinitionsItem_Oneof() {} -func (*SecurityDefinitionsItem_Oauth2ImplicitSecurity) isSecurityDefinitionsItem_Oneof() {} -func (*SecurityDefinitionsItem_Oauth2PasswordSecurity) isSecurityDefinitionsItem_Oneof() {} -func (*SecurityDefinitionsItem_Oauth2ApplicationSecurity) isSecurityDefinitionsItem_Oneof() {} -func (*SecurityDefinitionsItem_Oauth2AccessCodeSecurity) isSecurityDefinitionsItem_Oneof() {} - -func (m *SecurityDefinitionsItem) GetOneof() isSecurityDefinitionsItem_Oneof { - if m != nil { - return m.Oneof - } - return nil -} - -func (m *SecurityDefinitionsItem) GetBasicAuthenticationSecurity() *BasicAuthenticationSecurity { - if x, ok := m.GetOneof().(*SecurityDefinitionsItem_BasicAuthenticationSecurity); ok { - return x.BasicAuthenticationSecurity - } - return nil -} - -func (m *SecurityDefinitionsItem) GetApiKeySecurity() *ApiKeySecurity { - if x, ok := m.GetOneof().(*SecurityDefinitionsItem_ApiKeySecurity); ok { - return x.ApiKeySecurity - } - return nil -} - -func (m *SecurityDefinitionsItem) GetOauth2ImplicitSecurity() *Oauth2ImplicitSecurity { - if x, ok := m.GetOneof().(*SecurityDefinitionsItem_Oauth2ImplicitSecurity); ok { - return x.Oauth2ImplicitSecurity - } - return nil -} - -func (m *SecurityDefinitionsItem) GetOauth2PasswordSecurity() *Oauth2PasswordSecurity { - if x, ok := m.GetOneof().(*SecurityDefinitionsItem_Oauth2PasswordSecurity); ok { - return x.Oauth2PasswordSecurity - } - return nil -} - -func (m *SecurityDefinitionsItem) GetOauth2ApplicationSecurity() *Oauth2ApplicationSecurity { - if x, ok := m.GetOneof().(*SecurityDefinitionsItem_Oauth2ApplicationSecurity); ok { - return x.Oauth2ApplicationSecurity - } - return nil -} - -func (m *SecurityDefinitionsItem) GetOauth2AccessCodeSecurity() *Oauth2AccessCodeSecurity { - if x, ok := m.GetOneof().(*SecurityDefinitionsItem_Oauth2AccessCodeSecurity); ok { - return x.Oauth2AccessCodeSecurity - } - return nil -} - -// XXX_OneofFuncs is for the internal use of the proto package. -func (*SecurityDefinitionsItem) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _SecurityDefinitionsItem_OneofMarshaler, _SecurityDefinitionsItem_OneofUnmarshaler, _SecurityDefinitionsItem_OneofSizer, []interface{}{ - (*SecurityDefinitionsItem_BasicAuthenticationSecurity)(nil), - (*SecurityDefinitionsItem_ApiKeySecurity)(nil), - (*SecurityDefinitionsItem_Oauth2ImplicitSecurity)(nil), - (*SecurityDefinitionsItem_Oauth2PasswordSecurity)(nil), - (*SecurityDefinitionsItem_Oauth2ApplicationSecurity)(nil), - (*SecurityDefinitionsItem_Oauth2AccessCodeSecurity)(nil), - } -} - -func _SecurityDefinitionsItem_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*SecurityDefinitionsItem) - // oneof - switch x := m.Oneof.(type) { - case *SecurityDefinitionsItem_BasicAuthenticationSecurity: - b.EncodeVarint(1<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.BasicAuthenticationSecurity); err != nil { - return err - } - case *SecurityDefinitionsItem_ApiKeySecurity: - b.EncodeVarint(2<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.ApiKeySecurity); err != nil { - return err - } - case *SecurityDefinitionsItem_Oauth2ImplicitSecurity: - b.EncodeVarint(3<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.Oauth2ImplicitSecurity); err != nil { - return err - } - case *SecurityDefinitionsItem_Oauth2PasswordSecurity: - b.EncodeVarint(4<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.Oauth2PasswordSecurity); err != nil { - return err - } - case *SecurityDefinitionsItem_Oauth2ApplicationSecurity: - b.EncodeVarint(5<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.Oauth2ApplicationSecurity); err != nil { - return err - } - case *SecurityDefinitionsItem_Oauth2AccessCodeSecurity: - b.EncodeVarint(6<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.Oauth2AccessCodeSecurity); err != nil { - return err - } - case nil: - default: - return fmt.Errorf("SecurityDefinitionsItem.Oneof has unexpected type %T", x) - } - return nil -} - -func _SecurityDefinitionsItem_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*SecurityDefinitionsItem) - switch tag { - case 1: // oneof.basic_authentication_security - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(BasicAuthenticationSecurity) - err := b.DecodeMessage(msg) - m.Oneof = &SecurityDefinitionsItem_BasicAuthenticationSecurity{msg} - return true, err - case 2: // oneof.api_key_security - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(ApiKeySecurity) - err := b.DecodeMessage(msg) - m.Oneof = &SecurityDefinitionsItem_ApiKeySecurity{msg} - return true, err - case 3: // oneof.oauth2_implicit_security - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(Oauth2ImplicitSecurity) - err := b.DecodeMessage(msg) - m.Oneof = &SecurityDefinitionsItem_Oauth2ImplicitSecurity{msg} - return true, err - case 4: // oneof.oauth2_password_security - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(Oauth2PasswordSecurity) - err := b.DecodeMessage(msg) - m.Oneof = &SecurityDefinitionsItem_Oauth2PasswordSecurity{msg} - return true, err - case 5: // oneof.oauth2_application_security - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(Oauth2ApplicationSecurity) - err := b.DecodeMessage(msg) - m.Oneof = &SecurityDefinitionsItem_Oauth2ApplicationSecurity{msg} - return true, err - case 6: // oneof.oauth2_access_code_security - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(Oauth2AccessCodeSecurity) - err := b.DecodeMessage(msg) - m.Oneof = &SecurityDefinitionsItem_Oauth2AccessCodeSecurity{msg} - return true, err - default: - return false, nil - } -} - -func _SecurityDefinitionsItem_OneofSizer(msg proto.Message) (n int) { - m := msg.(*SecurityDefinitionsItem) - // oneof - switch x := m.Oneof.(type) { - case *SecurityDefinitionsItem_BasicAuthenticationSecurity: - s := proto.Size(x.BasicAuthenticationSecurity) - n += proto.SizeVarint(1<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case *SecurityDefinitionsItem_ApiKeySecurity: - s := proto.Size(x.ApiKeySecurity) - n += proto.SizeVarint(2<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case *SecurityDefinitionsItem_Oauth2ImplicitSecurity: - s := proto.Size(x.Oauth2ImplicitSecurity) - n += proto.SizeVarint(3<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case *SecurityDefinitionsItem_Oauth2PasswordSecurity: - s := proto.Size(x.Oauth2PasswordSecurity) - n += proto.SizeVarint(4<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case *SecurityDefinitionsItem_Oauth2ApplicationSecurity: - s := proto.Size(x.Oauth2ApplicationSecurity) - n += proto.SizeVarint(5<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case *SecurityDefinitionsItem_Oauth2AccessCodeSecurity: - s := proto.Size(x.Oauth2AccessCodeSecurity) - n += proto.SizeVarint(6<<3 | proto.WireBytes) - n += proto.SizeVarint(uint64(s)) - n += s - case nil: - default: - panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) - } - return n -} - -type SecurityRequirement struct { - AdditionalProperties []*NamedStringArray `protobuf:"bytes,1,rep,name=additional_properties,json=additionalProperties" json:"additional_properties,omitempty"` -} - -func (m *SecurityRequirement) Reset() { *m = SecurityRequirement{} } -func (m *SecurityRequirement) String() string { return proto.CompactTextString(m) } -func (*SecurityRequirement) ProtoMessage() {} -func (*SecurityRequirement) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{54} } - -func (m *SecurityRequirement) GetAdditionalProperties() []*NamedStringArray { - if m != nil { - return m.AdditionalProperties - } - return nil -} - -type StringArray struct { - Value []string `protobuf:"bytes,1,rep,name=value" json:"value,omitempty"` -} - -func (m *StringArray) Reset() { *m = StringArray{} } -func (m *StringArray) String() string { return proto.CompactTextString(m) } -func (*StringArray) ProtoMessage() {} -func (*StringArray) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{55} } - -func (m *StringArray) GetValue() []string { - if m != nil { - return m.Value - } - return nil -} - -type Tag struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description" json:"description,omitempty"` - ExternalDocs *ExternalDocs `protobuf:"bytes,3,opt,name=external_docs,json=externalDocs" json:"external_docs,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,4,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *Tag) Reset() { *m = Tag{} } -func (m *Tag) String() string { return proto.CompactTextString(m) } -func (*Tag) ProtoMessage() {} -func (*Tag) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{56} } - -func (m *Tag) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *Tag) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *Tag) GetExternalDocs() *ExternalDocs { - if m != nil { - return m.ExternalDocs - } - return nil -} - -func (m *Tag) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -type TypeItem struct { - Value []string `protobuf:"bytes,1,rep,name=value" json:"value,omitempty"` -} - -func (m *TypeItem) Reset() { *m = TypeItem{} } -func (m *TypeItem) String() string { return proto.CompactTextString(m) } -func (*TypeItem) ProtoMessage() {} -func (*TypeItem) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{57} } - -func (m *TypeItem) GetValue() []string { - if m != nil { - return m.Value - } - return nil -} - -// Any property starting with x- is valid. -type VendorExtension struct { - AdditionalProperties []*NamedAny `protobuf:"bytes,1,rep,name=additional_properties,json=additionalProperties" json:"additional_properties,omitempty"` -} - -func (m *VendorExtension) Reset() { *m = VendorExtension{} } -func (m *VendorExtension) String() string { return proto.CompactTextString(m) } -func (*VendorExtension) ProtoMessage() {} -func (*VendorExtension) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{58} } - -func (m *VendorExtension) GetAdditionalProperties() []*NamedAny { - if m != nil { - return m.AdditionalProperties - } - return nil -} - -type Xml struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Namespace string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"` - Prefix string `protobuf:"bytes,3,opt,name=prefix" json:"prefix,omitempty"` - Attribute bool `protobuf:"varint,4,opt,name=attribute" json:"attribute,omitempty"` - Wrapped bool `protobuf:"varint,5,opt,name=wrapped" json:"wrapped,omitempty"` - VendorExtension []*NamedAny `protobuf:"bytes,6,rep,name=vendor_extension,json=vendorExtension" json:"vendor_extension,omitempty"` -} - -func (m *Xml) Reset() { *m = Xml{} } -func (m *Xml) String() string { return proto.CompactTextString(m) } -func (*Xml) ProtoMessage() {} -func (*Xml) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{59} } - -func (m *Xml) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *Xml) GetNamespace() string { - if m != nil { - return m.Namespace - } - return "" -} - -func (m *Xml) GetPrefix() string { - if m != nil { - return m.Prefix - } - return "" -} - -func (m *Xml) GetAttribute() bool { - if m != nil { - return m.Attribute - } - return false -} - -func (m *Xml) GetWrapped() bool { - if m != nil { - return m.Wrapped - } - return false -} - -func (m *Xml) GetVendorExtension() []*NamedAny { - if m != nil { - return m.VendorExtension - } - return nil -} - -func init() { - proto.RegisterType((*AdditionalPropertiesItem)(nil), "openapi.v2.AdditionalPropertiesItem") - proto.RegisterType((*Any)(nil), "openapi.v2.Any") - proto.RegisterType((*ApiKeySecurity)(nil), "openapi.v2.ApiKeySecurity") - proto.RegisterType((*BasicAuthenticationSecurity)(nil), "openapi.v2.BasicAuthenticationSecurity") - proto.RegisterType((*BodyParameter)(nil), "openapi.v2.BodyParameter") - proto.RegisterType((*Contact)(nil), "openapi.v2.Contact") - proto.RegisterType((*Default)(nil), "openapi.v2.Default") - proto.RegisterType((*Definitions)(nil), "openapi.v2.Definitions") - proto.RegisterType((*Document)(nil), "openapi.v2.Document") - proto.RegisterType((*Examples)(nil), "openapi.v2.Examples") - proto.RegisterType((*ExternalDocs)(nil), "openapi.v2.ExternalDocs") - proto.RegisterType((*FileSchema)(nil), "openapi.v2.FileSchema") - proto.RegisterType((*FormDataParameterSubSchema)(nil), "openapi.v2.FormDataParameterSubSchema") - proto.RegisterType((*Header)(nil), "openapi.v2.Header") - proto.RegisterType((*HeaderParameterSubSchema)(nil), "openapi.v2.HeaderParameterSubSchema") - proto.RegisterType((*Headers)(nil), "openapi.v2.Headers") - proto.RegisterType((*Info)(nil), "openapi.v2.Info") - proto.RegisterType((*ItemsItem)(nil), "openapi.v2.ItemsItem") - proto.RegisterType((*JsonReference)(nil), "openapi.v2.JsonReference") - proto.RegisterType((*License)(nil), "openapi.v2.License") - proto.RegisterType((*NamedAny)(nil), "openapi.v2.NamedAny") - proto.RegisterType((*NamedHeader)(nil), "openapi.v2.NamedHeader") - proto.RegisterType((*NamedParameter)(nil), "openapi.v2.NamedParameter") - proto.RegisterType((*NamedPathItem)(nil), "openapi.v2.NamedPathItem") - proto.RegisterType((*NamedResponse)(nil), "openapi.v2.NamedResponse") - proto.RegisterType((*NamedResponseValue)(nil), "openapi.v2.NamedResponseValue") - proto.RegisterType((*NamedSchema)(nil), "openapi.v2.NamedSchema") - proto.RegisterType((*NamedSecurityDefinitionsItem)(nil), "openapi.v2.NamedSecurityDefinitionsItem") - proto.RegisterType((*NamedString)(nil), "openapi.v2.NamedString") - proto.RegisterType((*NamedStringArray)(nil), "openapi.v2.NamedStringArray") - proto.RegisterType((*NonBodyParameter)(nil), "openapi.v2.NonBodyParameter") - proto.RegisterType((*Oauth2AccessCodeSecurity)(nil), "openapi.v2.Oauth2AccessCodeSecurity") - proto.RegisterType((*Oauth2ApplicationSecurity)(nil), "openapi.v2.Oauth2ApplicationSecurity") - proto.RegisterType((*Oauth2ImplicitSecurity)(nil), "openapi.v2.Oauth2ImplicitSecurity") - proto.RegisterType((*Oauth2PasswordSecurity)(nil), "openapi.v2.Oauth2PasswordSecurity") - proto.RegisterType((*Oauth2Scopes)(nil), "openapi.v2.Oauth2Scopes") - proto.RegisterType((*Operation)(nil), "openapi.v2.Operation") - proto.RegisterType((*Parameter)(nil), "openapi.v2.Parameter") - proto.RegisterType((*ParameterDefinitions)(nil), "openapi.v2.ParameterDefinitions") - proto.RegisterType((*ParametersItem)(nil), "openapi.v2.ParametersItem") - proto.RegisterType((*PathItem)(nil), "openapi.v2.PathItem") - proto.RegisterType((*PathParameterSubSchema)(nil), "openapi.v2.PathParameterSubSchema") - proto.RegisterType((*Paths)(nil), "openapi.v2.Paths") - proto.RegisterType((*PrimitivesItems)(nil), "openapi.v2.PrimitivesItems") - proto.RegisterType((*Properties)(nil), "openapi.v2.Properties") - proto.RegisterType((*QueryParameterSubSchema)(nil), "openapi.v2.QueryParameterSubSchema") - proto.RegisterType((*Response)(nil), "openapi.v2.Response") - proto.RegisterType((*ResponseDefinitions)(nil), "openapi.v2.ResponseDefinitions") - proto.RegisterType((*ResponseValue)(nil), "openapi.v2.ResponseValue") - proto.RegisterType((*Responses)(nil), "openapi.v2.Responses") - proto.RegisterType((*Schema)(nil), "openapi.v2.Schema") - proto.RegisterType((*SchemaItem)(nil), "openapi.v2.SchemaItem") - proto.RegisterType((*SecurityDefinitions)(nil), "openapi.v2.SecurityDefinitions") - proto.RegisterType((*SecurityDefinitionsItem)(nil), "openapi.v2.SecurityDefinitionsItem") - proto.RegisterType((*SecurityRequirement)(nil), "openapi.v2.SecurityRequirement") - proto.RegisterType((*StringArray)(nil), "openapi.v2.StringArray") - proto.RegisterType((*Tag)(nil), "openapi.v2.Tag") - proto.RegisterType((*TypeItem)(nil), "openapi.v2.TypeItem") - proto.RegisterType((*VendorExtension)(nil), "openapi.v2.VendorExtension") - proto.RegisterType((*Xml)(nil), "openapi.v2.Xml") -} - -func init() { proto.RegisterFile("OpenAPIv2/OpenAPIv2.proto", fileDescriptor0) } - -var fileDescriptor0 = []byte{ - // 3129 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x3b, 0x4b, 0x73, 0x1c, 0x57, - 0xd5, 0xf3, 0x7e, 0x1c, 0x69, 0x46, 0xa3, 0x96, 0x2c, 0xb7, 0x24, 0xc7, 0x71, 0xe4, 0x3c, 0x6c, - 0xe7, 0xb3, 0x9c, 0x4f, 0x29, 0x48, 0x05, 0x2a, 0x05, 0xf2, 0xab, 0xc6, 0xc4, 0x44, 0x4a, 0xcb, - 0x0e, 0x09, 0x04, 0xba, 0xae, 0x66, 0xee, 0x48, 0x9d, 0x74, 0xf7, 0x6d, 0x77, 0xf7, 0xc8, 0x1a, - 0x16, 0x2c, 0xa0, 0x8a, 0x35, 0x50, 0x59, 0x53, 0x15, 0x16, 0x14, 0x55, 0x59, 0xb0, 0x62, 0xc5, - 0x1f, 0x60, 0xc7, 0x3f, 0x60, 0x0d, 0x5b, 0xaa, 0x58, 0x51, 0x3c, 0xea, 0xbe, 0xfa, 0x31, 0x7d, - 0x7b, 0x1e, 0x96, 0x0b, 0x28, 0xd0, 0x6a, 0xe6, 0xde, 0x73, 0xee, 0xb9, 0xa7, 0x4f, 0x9f, 0xd7, - 0x3d, 0xe7, 0x36, 0xac, 0xef, 0x79, 0xd8, 0xdd, 0xdd, 0x7f, 0x70, 0xb2, 0x73, 0x2b, 0xfa, 0xb7, - 0xed, 0xf9, 0x24, 0x24, 0x1a, 0x10, 0x0f, 0xbb, 0xc8, 0xb3, 0xb6, 0x4f, 0x76, 0x36, 0xd6, 0x8f, - 0x08, 0x39, 0xb2, 0xf1, 0x2d, 0x06, 0x39, 0x1c, 0x0e, 0x6e, 0x21, 0x77, 0xc4, 0xd1, 0xb6, 0x1c, - 0xd0, 0x77, 0xfb, 0x7d, 0x2b, 0xb4, 0x88, 0x8b, 0xec, 0x7d, 0x9f, 0x78, 0xd8, 0x0f, 0x2d, 0x1c, - 0x3c, 0x08, 0xb1, 0xa3, 0xfd, 0x1f, 0xd4, 0x82, 0xde, 0x31, 0x76, 0x90, 0x5e, 0xbc, 0x52, 0xbc, - 0xb6, 0xb0, 0xa3, 0x6d, 0xc7, 0x34, 0xb7, 0x0f, 0x18, 0xa4, 0x5b, 0x30, 0x04, 0x8e, 0xb6, 0x01, - 0xf5, 0x43, 0x42, 0x6c, 0x8c, 0x5c, 0xbd, 0x74, 0xa5, 0x78, 0xad, 0xd1, 0x2d, 0x18, 0x72, 0xe2, - 0x76, 0x1d, 0xaa, 0xc4, 0xc5, 0x64, 0xb0, 0x75, 0x0f, 0xca, 0xbb, 0xee, 0x48, 0xbb, 0x01, 0xd5, - 0x13, 0x64, 0x0f, 0xb1, 0x20, 0xbc, 0xba, 0xcd, 0x19, 0xdc, 0x96, 0x0c, 0x6e, 0xef, 0xba, 0x23, - 0x83, 0xa3, 0x68, 0x1a, 0x54, 0x46, 0xc8, 0xb1, 0x19, 0xd1, 0xa6, 0xc1, 0xfe, 0x6f, 0x7d, 0x51, - 0x84, 0xf6, 0xae, 0x67, 0xbd, 0x8b, 0x47, 0x07, 0xb8, 0x37, 0xf4, 0xad, 0x70, 0x44, 0xd1, 0xc2, - 0x91, 0xc7, 0x29, 0x36, 0x0d, 0xf6, 0x9f, 0xce, 0xb9, 0xc8, 0xc1, 0x72, 0x29, 0xfd, 0xaf, 0xb5, - 0xa1, 0x64, 0xb9, 0x7a, 0x99, 0xcd, 0x94, 0x2c, 0x57, 0xbb, 0x02, 0x0b, 0x7d, 0x1c, 0xf4, 0x7c, - 0xcb, 0xa3, 0x32, 0xd0, 0x2b, 0x0c, 0x90, 0x9c, 0xd2, 0xbe, 0x06, 0x9d, 0x13, 0xec, 0xf6, 0x89, - 0x6f, 0xe2, 0xd3, 0x10, 0xbb, 0x01, 0x45, 0xab, 0x5e, 0x29, 0x33, 0xbe, 0x13, 0x02, 0x79, 0x0f, - 0x39, 0xb8, 0x4f, 0xf9, 0x5e, 0xe2, 0xd8, 0xf7, 0x24, 0xf2, 0xd6, 0x67, 0x45, 0xd8, 0xbc, 0x8d, - 0x02, 0xab, 0xb7, 0x3b, 0x0c, 0x8f, 0xb1, 0x1b, 0x5a, 0x3d, 0x44, 0x09, 0x4f, 0x64, 0x7d, 0x8c, - 0xad, 0xd2, 0x6c, 0x6c, 0x95, 0xe7, 0x61, 0xeb, 0x0f, 0x45, 0x68, 0xdd, 0x26, 0xfd, 0xd1, 0x3e, - 0xf2, 0x91, 0x83, 0x43, 0xec, 0x8f, 0x6f, 0x5a, 0xcc, 0x6e, 0x3a, 0x8b, 0x44, 0x37, 0xa0, 0xe1, - 0xe3, 0x27, 0x43, 0xcb, 0xc7, 0x7d, 0x26, 0xce, 0x86, 0x11, 0x8d, 0xb5, 0x1b, 0x91, 0x4a, 0x55, - 0xf3, 0x54, 0x2a, 0x52, 0x28, 0xd5, 0x03, 0xd6, 0xe6, 0x79, 0xc0, 0x1f, 0x17, 0xa1, 0x7e, 0x87, - 0xb8, 0x21, 0xea, 0x85, 0x11, 0xe3, 0xc5, 0x04, 0xe3, 0x1d, 0x28, 0x0f, 0x7d, 0xa9, 0x58, 0xf4, - 0xaf, 0xb6, 0x0a, 0x55, 0xec, 0x20, 0xcb, 0x16, 0x4f, 0xc3, 0x07, 0x4a, 0x46, 0x2a, 0xf3, 0x30, - 0xf2, 0x08, 0xea, 0x77, 0xf1, 0x00, 0x0d, 0xed, 0x50, 0x7b, 0x00, 0x17, 0x50, 0x64, 0x6f, 0xa6, - 0x17, 0x19, 0x9c, 0x5e, 0x9c, 0x40, 0x70, 0x15, 0x29, 0x4c, 0x74, 0xeb, 0x3b, 0xb0, 0x70, 0x17, - 0x0f, 0x2c, 0x97, 0x41, 0x02, 0xed, 0xe1, 0x64, 0xca, 0x17, 0x33, 0x94, 0x85, 0xb8, 0xd5, 0xc4, - 0xff, 0x58, 0x85, 0xc6, 0x5d, 0xd2, 0x1b, 0x3a, 0xd8, 0x0d, 0x35, 0x1d, 0xea, 0xc1, 0x53, 0x74, - 0x74, 0x84, 0x7d, 0x21, 0x3f, 0x39, 0xd4, 0x5e, 0x86, 0x8a, 0xe5, 0x0e, 0x08, 0x93, 0xe1, 0xc2, - 0x4e, 0x27, 0xb9, 0xc7, 0x03, 0x77, 0x40, 0x0c, 0x06, 0xa5, 0xc2, 0x3f, 0x26, 0x41, 0x28, 0xa4, - 0xca, 0xfe, 0x6b, 0x9b, 0xd0, 0x3c, 0x44, 0x01, 0x36, 0x3d, 0x14, 0x1e, 0x0b, 0xab, 0x6b, 0xd0, - 0x89, 0x7d, 0x14, 0x1e, 0xb3, 0x0d, 0x29, 0x77, 0x38, 0x60, 0x96, 0x46, 0x37, 0xe4, 0x43, 0xaa, - 0x5c, 0x3d, 0xe2, 0x06, 0x43, 0x0a, 0xaa, 0x31, 0x50, 0x34, 0xa6, 0x30, 0xcf, 0x27, 0xfd, 0x61, - 0x0f, 0x07, 0x7a, 0x9d, 0xc3, 0xe4, 0x58, 0x7b, 0x0d, 0xaa, 0x74, 0xa7, 0x40, 0x6f, 0x30, 0x4e, - 0x97, 0x93, 0x9c, 0xd2, 0x2d, 0x03, 0x83, 0xc3, 0xb5, 0xb7, 0xa9, 0x0d, 0x44, 0x52, 0xd5, 0x9b, - 0x0c, 0x3d, 0x25, 0xbc, 0x84, 0xd0, 0x8d, 0x24, 0xae, 0xf6, 0x75, 0x00, 0x4f, 0xda, 0x52, 0xa0, - 0x03, 0x5b, 0x79, 0x25, 0xbd, 0x91, 0x80, 0x26, 0x49, 0x24, 0xd6, 0x68, 0xef, 0x40, 0xd3, 0xc7, - 0x81, 0x47, 0xdc, 0x00, 0x07, 0xfa, 0x02, 0x23, 0xf0, 0x62, 0x92, 0x80, 0x21, 0x80, 0xc9, 0xf5, - 0xf1, 0x0a, 0xed, 0xab, 0xd0, 0x08, 0x84, 0x53, 0xd1, 0x17, 0xd9, 0x5b, 0x4f, 0xad, 0x96, 0x0e, - 0xc7, 0xe0, 0xd6, 0x48, 0x5f, 0xad, 0x11, 0x2d, 0xd0, 0x0c, 0x58, 0x95, 0xff, 0xcd, 0xa4, 0x04, - 0x5a, 0x59, 0x36, 0x24, 0xa1, 0x24, 0x1b, 0x2b, 0x41, 0x76, 0x52, 0xbb, 0x0a, 0x95, 0x10, 0x1d, - 0x05, 0x7a, 0x9b, 0x31, 0xb3, 0x94, 0xa4, 0xf1, 0x08, 0x1d, 0x19, 0x0c, 0xa8, 0xbd, 0x03, 0x2d, - 0x6a, 0x57, 0x3e, 0x55, 0xdb, 0x3e, 0xe9, 0x05, 0xfa, 0x12, 0xdb, 0x51, 0x4f, 0x62, 0xdf, 0x13, - 0x08, 0x77, 0x49, 0x2f, 0x30, 0x16, 0x71, 0x62, 0xa4, 0xb4, 0xce, 0xce, 0x3c, 0xd6, 0xf9, 0x18, - 0x1a, 0xf7, 0x4e, 0x91, 0xe3, 0xd9, 0x38, 0x78, 0x9e, 0xe6, 0xf9, 0xa3, 0x22, 0x2c, 0x26, 0xd9, - 0x9e, 0xc1, 0xbb, 0x66, 0x1d, 0xd2, 0x99, 0x9d, 0xfc, 0x3f, 0x4a, 0x00, 0xf7, 0x2d, 0x1b, 0x73, - 0x63, 0xd7, 0xd6, 0xa0, 0x36, 0x20, 0xbe, 0x83, 0x42, 0xb1, 0xbd, 0x18, 0x51, 0xc7, 0x17, 0x5a, - 0xa1, 0x2d, 0x1d, 0x3b, 0x1f, 0x8c, 0x73, 0x5c, 0xce, 0x72, 0x7c, 0x1d, 0xea, 0x7d, 0xee, 0xd9, - 0x98, 0x0d, 0x8f, 0xbd, 0x63, 0xca, 0x91, 0x84, 0xa7, 0xc2, 0x02, 0x37, 0xea, 0x38, 0x2c, 0xc8, - 0x08, 0x58, 0x4b, 0x44, 0xc0, 0x4d, 0x6a, 0x0b, 0xa8, 0x6f, 0x12, 0xd7, 0x1e, 0xe9, 0x75, 0x19, - 0x47, 0x50, 0x7f, 0xcf, 0xb5, 0x47, 0x59, 0x9d, 0x69, 0xcc, 0xa5, 0x33, 0xd7, 0xa1, 0x8e, 0xf9, - 0x2b, 0x17, 0x06, 0x9e, 0x65, 0x5b, 0xc0, 0x95, 0x6f, 0x00, 0xe6, 0x79, 0x03, 0x5f, 0xd4, 0x60, - 0xe3, 0x3e, 0xf1, 0x9d, 0xbb, 0x28, 0x44, 0x91, 0x03, 0x38, 0x18, 0x1e, 0x1e, 0xc8, 0xb4, 0x29, - 0x16, 0x4b, 0x71, 0x2c, 0x5a, 0xf2, 0xc8, 0x5a, 0xca, 0xcb, 0x55, 0xca, 0xf9, 0xf1, 0xb9, 0x92, - 0x08, 0x73, 0x37, 0x60, 0x19, 0xd9, 0x36, 0x79, 0x6a, 0x62, 0xc7, 0x0b, 0x47, 0x26, 0x4f, 0xbc, - 0xaa, 0x6c, 0xab, 0x25, 0x06, 0xb8, 0x47, 0xe7, 0x3f, 0x90, 0xc9, 0x56, 0xe6, 0x45, 0xc4, 0x3a, - 0x53, 0x4f, 0xe9, 0xcc, 0xff, 0x43, 0xd5, 0x0a, 0xb1, 0x23, 0x65, 0xbf, 0x99, 0xf2, 0x74, 0xbe, - 0xe5, 0x58, 0xa1, 0x75, 0xc2, 0x33, 0xc9, 0xc0, 0xe0, 0x98, 0xda, 0xeb, 0xb0, 0xdc, 0x23, 0xb6, - 0x8d, 0x7b, 0x94, 0x59, 0x53, 0x50, 0x6d, 0x32, 0xaa, 0x9d, 0x18, 0x70, 0x9f, 0xd3, 0x4f, 0xe8, - 0x16, 0x4c, 0xd1, 0x2d, 0x1d, 0xea, 0x0e, 0x3a, 0xb5, 0x9c, 0xa1, 0xc3, 0xbc, 0x66, 0xd1, 0x90, - 0x43, 0xba, 0x23, 0x3e, 0xed, 0xd9, 0xc3, 0xc0, 0x3a, 0xc1, 0xa6, 0xc4, 0x59, 0x64, 0x0f, 0xdf, - 0x89, 0x00, 0xdf, 0x14, 0xc8, 0x94, 0x8c, 0xe5, 0x32, 0x94, 0x96, 0x20, 0xc3, 0x87, 0x63, 0x64, - 0x04, 0x4e, 0x7b, 0x9c, 0x8c, 0x40, 0x7e, 0x01, 0xc0, 0x41, 0xa7, 0xa6, 0x8d, 0xdd, 0xa3, 0xf0, - 0x98, 0x79, 0xb3, 0xb2, 0xd1, 0x74, 0xd0, 0xe9, 0x43, 0x36, 0xc1, 0xc0, 0x96, 0x2b, 0xc1, 0x1d, - 0x01, 0xb6, 0x5c, 0x01, 0xd6, 0xa1, 0xee, 0xa1, 0x90, 0x2a, 0xab, 0xbe, 0xcc, 0x83, 0xad, 0x18, - 0x52, 0x8b, 0xa0, 0x74, 0xb9, 0xd0, 0x35, 0xb6, 0xae, 0xe1, 0xa0, 0x53, 0x26, 0x61, 0x06, 0xb4, - 0x5c, 0x01, 0x5c, 0x11, 0x40, 0xcb, 0xe5, 0xc0, 0x97, 0x60, 0x71, 0xe8, 0x5a, 0x4f, 0x86, 0x58, - 0xc0, 0x57, 0x19, 0xe7, 0x0b, 0x7c, 0x8e, 0xa3, 0x5c, 0x85, 0x0a, 0x76, 0x87, 0x8e, 0x7e, 0x21, - 0xeb, 0xaa, 0xa9, 0xa8, 0x19, 0x50, 0x7b, 0x11, 0x16, 0x9c, 0xa1, 0x1d, 0x5a, 0x9e, 0x8d, 0x4d, - 0x32, 0xd0, 0xd7, 0x98, 0x90, 0x40, 0x4e, 0xed, 0x0d, 0x94, 0xd6, 0x72, 0x71, 0x2e, 0x6b, 0xa9, - 0x42, 0xad, 0x8b, 0x51, 0x1f, 0xfb, 0xca, 0xb4, 0x38, 0xd6, 0xc5, 0x92, 0x5a, 0x17, 0xcb, 0x67, - 0xd3, 0xc5, 0xca, 0x74, 0x5d, 0xac, 0xce, 0xae, 0x8b, 0xb5, 0x19, 0x74, 0xb1, 0x3e, 0x5d, 0x17, - 0x1b, 0x33, 0xe8, 0x62, 0x73, 0x26, 0x5d, 0x84, 0xc9, 0xba, 0xb8, 0x30, 0x41, 0x17, 0x17, 0x27, - 0xe8, 0x62, 0x6b, 0x92, 0x2e, 0xb6, 0xa7, 0xe8, 0xe2, 0x52, 0xbe, 0x2e, 0x76, 0xe6, 0xd0, 0xc5, - 0xe5, 0x8c, 0x2e, 0x8e, 0x79, 0x4b, 0x6d, 0xb6, 0x23, 0xd4, 0xca, 0x3c, 0xda, 0xfa, 0xb7, 0x2a, - 0xe8, 0x5c, 0x5b, 0xff, 0x2d, 0x9e, 0x5d, 0x5a, 0x48, 0x55, 0x69, 0x21, 0x35, 0xb5, 0x85, 0xd4, - 0xcf, 0x66, 0x21, 0x8d, 0xe9, 0x16, 0xd2, 0x9c, 0xdd, 0x42, 0x60, 0x06, 0x0b, 0x59, 0x98, 0x6e, - 0x21, 0x8b, 0x33, 0x58, 0x48, 0x6b, 0x26, 0x0b, 0x69, 0x4f, 0xb6, 0x90, 0xa5, 0x09, 0x16, 0xd2, - 0x99, 0x60, 0x21, 0xcb, 0x93, 0x2c, 0x44, 0x9b, 0x62, 0x21, 0x2b, 0xf9, 0x16, 0xb2, 0x3a, 0x87, - 0x85, 0x5c, 0x98, 0xc9, 0x5b, 0xaf, 0xcd, 0xa3, 0xff, 0xdf, 0x82, 0x3a, 0x57, 0xff, 0x67, 0x38, - 0x7e, 0xf2, 0x85, 0x39, 0xc9, 0xf3, 0xe7, 0x25, 0xa8, 0xd0, 0x03, 0x64, 0x9c, 0x98, 0x16, 0x93, - 0x89, 0xa9, 0x0e, 0xf5, 0x13, 0xec, 0x07, 0x71, 0x65, 0x44, 0x0e, 0x67, 0x30, 0xa4, 0x6b, 0xd0, - 0x09, 0xb1, 0xef, 0x04, 0x26, 0x19, 0x98, 0x01, 0xf6, 0x4f, 0xac, 0x9e, 0x34, 0xaa, 0x36, 0x9b, - 0xdf, 0x1b, 0x1c, 0xf0, 0x59, 0xed, 0x26, 0xd4, 0x7b, 0xbc, 0x7c, 0x20, 0x9c, 0xfe, 0x4a, 0xf2, - 0x21, 0x44, 0x65, 0xc1, 0x90, 0x38, 0x14, 0xdd, 0xb6, 0x7a, 0xd8, 0x0d, 0x78, 0xfa, 0x34, 0x86, - 0xfe, 0x90, 0x83, 0x0c, 0x89, 0xa3, 0x14, 0x7e, 0x7d, 0x1e, 0xe1, 0xbf, 0x05, 0x4d, 0xa6, 0x0c, - 0xac, 0x56, 0x77, 0x23, 0x51, 0xab, 0x2b, 0x4f, 0x2e, 0xac, 0x6c, 0xdd, 0x85, 0xd6, 0x37, 0x02, - 0xe2, 0x1a, 0x78, 0x80, 0x7d, 0xec, 0xf6, 0xb0, 0xb6, 0x0c, 0x15, 0xd3, 0xc7, 0x03, 0x21, 0xe3, - 0xb2, 0x81, 0x07, 0xd3, 0xeb, 0x4f, 0x5b, 0x1e, 0xd4, 0xc5, 0x33, 0xcd, 0x58, 0x5c, 0x39, 0xf3, - 0x59, 0xe6, 0x1e, 0x34, 0x24, 0x50, 0xb9, 0xe5, 0x2b, 0xb2, 0xaa, 0x58, 0x52, 0x3b, 0x20, 0x0e, - 0xdd, 0x7a, 0x17, 0x16, 0x12, 0x0a, 0xa8, 0xa4, 0x74, 0x2d, 0x4d, 0x29, 0x25, 0x4c, 0xa1, 0xb7, - 0x82, 0xd8, 0xfb, 0xd0, 0x66, 0xc4, 0xe2, 0x22, 0x9a, 0x8a, 0xde, 0xeb, 0x69, 0x7a, 0x17, 0x94, - 0x45, 0x01, 0x49, 0x72, 0x0f, 0x5a, 0x82, 0x64, 0x78, 0xcc, 0xde, 0xad, 0x8a, 0xe2, 0x8d, 0x34, - 0xc5, 0xd5, 0xf1, 0x7a, 0x06, 0x5d, 0x38, 0x4e, 0x50, 0x56, 0x0f, 0xe6, 0x26, 0x28, 0x17, 0x4a, - 0x82, 0x1f, 0x81, 0x96, 0x22, 0x18, 0x9d, 0x1d, 0x32, 0x54, 0x6f, 0xa5, 0xa9, 0xae, 0xab, 0xa8, - 0xb2, 0xd5, 0xe3, 0x2f, 0x47, 0xc4, 0xd0, 0x79, 0x5f, 0x8e, 0xd0, 0x74, 0x41, 0xcc, 0x81, 0x4b, - 0x9c, 0x58, 0xb6, 0x34, 0x91, 0x2b, 0xd8, 0xb7, 0xd3, 0xd4, 0xaf, 0x4e, 0xa9, 0x7b, 0x24, 0xe5, - 0xfc, 0x96, 0xe4, 0x3d, 0xf4, 0x2d, 0xf7, 0x48, 0x49, 0x7d, 0x35, 0x49, 0xbd, 0x29, 0x17, 0x3e, - 0x86, 0x4e, 0x62, 0xe1, 0xae, 0xef, 0x23, 0xb5, 0x82, 0xdf, 0x4c, 0xf3, 0x96, 0xf2, 0xa9, 0x89, - 0xb5, 0x92, 0xec, 0x6f, 0xca, 0xd0, 0x79, 0x8f, 0xb8, 0xe9, 0x1a, 0x2f, 0x86, 0xcd, 0x63, 0xa6, - 0xc1, 0x66, 0x54, 0x77, 0x32, 0x83, 0xe1, 0xa1, 0x99, 0xaa, 0xf4, 0xbf, 0x9c, 0x55, 0xf8, 0x6c, - 0x82, 0xd3, 0x2d, 0x18, 0xfa, 0x71, 0x5e, 0xf2, 0x63, 0xc3, 0x65, 0x9a, 0x30, 0x98, 0x7d, 0x14, - 0x22, 0xf5, 0x4e, 0xfc, 0x19, 0x5e, 0x4d, 0xee, 0x94, 0x7f, 0x4c, 0xee, 0x16, 0x8c, 0x8d, 0x41, - 0xfe, 0x21, 0xfa, 0x10, 0x36, 0x9e, 0x0c, 0xb1, 0x3f, 0x52, 0xef, 0x54, 0xce, 0xbe, 0xc9, 0xf7, - 0x29, 0xb6, 0x72, 0x9b, 0x8b, 0x4f, 0xd4, 0x20, 0xcd, 0x84, 0x75, 0x0f, 0x85, 0xc7, 0xea, 0x2d, - 0x78, 0xf1, 0x63, 0x6b, 0xdc, 0x0a, 0x95, 0x3b, 0xac, 0x79, 0x4a, 0x48, 0xdc, 0x24, 0xf9, 0xbc, - 0x04, 0xfa, 0x1e, 0x1a, 0x86, 0xc7, 0x3b, 0xbb, 0xbd, 0x1e, 0x0e, 0x82, 0x3b, 0xa4, 0x8f, 0xa7, - 0xf5, 0x39, 0x06, 0x36, 0x79, 0x2a, 0xab, 0xf2, 0xf4, 0xbf, 0xf6, 0x06, 0x0d, 0x08, 0xc4, 0xc3, - 0xf2, 0x48, 0x94, 0x2a, 0x8d, 0x70, 0xea, 0x07, 0x0c, 0x6e, 0x08, 0x3c, 0x9a, 0x35, 0xd1, 0x69, - 0xe2, 0x5b, 0xdf, 0x67, 0xfd, 0x09, 0x93, 0xfa, 0x6f, 0x71, 0x20, 0x4a, 0x01, 0x1e, 0xfb, 0x36, - 0x4d, 0x60, 0x42, 0xf2, 0x29, 0xe6, 0x48, 0x3c, 0xff, 0x6c, 0xb0, 0x09, 0x0a, 0x1c, 0x0b, 0x1e, - 0xb5, 0xd9, 0x32, 0xef, 0xb9, 0x82, 0xdf, 0x5f, 0x8a, 0xb0, 0x2e, 0x64, 0xe4, 0x79, 0xf6, 0x2c, - 0x1d, 0x95, 0xe7, 0x23, 0xa4, 0xd4, 0x73, 0x57, 0x26, 0x3f, 0x77, 0x75, 0xb6, 0xe7, 0x9e, 0xab, - 0xa7, 0xf1, 0xc3, 0x12, 0xac, 0x71, 0xc6, 0x1e, 0x38, 0xf4, 0xb9, 0xad, 0xf0, 0x3f, 0x4d, 0x33, - 0xfe, 0x05, 0x42, 0xf8, 0x73, 0x51, 0x0a, 0x61, 0x1f, 0x05, 0xc1, 0x53, 0xe2, 0xf7, 0xff, 0x07, - 0xde, 0xfc, 0xc7, 0xb0, 0x98, 0xe4, 0xeb, 0x19, 0xfa, 0x3d, 0x2c, 0x42, 0xe4, 0x24, 0xdc, 0x3f, - 0xaf, 0x40, 0x73, 0xcf, 0xc3, 0x3e, 0x92, 0x87, 0x4d, 0x56, 0xb7, 0x2f, 0xb2, 0x3a, 0x2d, 0x2f, - 0xd3, 0xeb, 0x50, 0x0f, 0x86, 0x8e, 0x83, 0xfc, 0x91, 0xcc, 0xb9, 0xc5, 0x70, 0x86, 0x9c, 0x3b, - 0x53, 0xae, 0xad, 0xcc, 0x55, 0xae, 0x7d, 0x09, 0x16, 0x89, 0xe4, 0xcd, 0xb4, 0xfa, 0x52, 0xbc, - 0xd1, 0xdc, 0x83, 0x7e, 0xaa, 0xf7, 0x53, 0x1b, 0xeb, 0xfd, 0x24, 0x7b, 0x46, 0xf5, 0xb1, 0x9e, - 0xd1, 0x57, 0x52, 0x3d, 0x9b, 0x06, 0x13, 0xdd, 0x86, 0x32, 0x3d, 0xe3, 0xa1, 0x3e, 0xd9, 0xad, - 0x79, 0x33, 0xd9, 0xad, 0x69, 0x66, 0x33, 0x3b, 0x99, 0xe0, 0xa4, 0x7a, 0x34, 0x89, 0xd6, 0x16, - 0xa4, 0x5b, 0x5b, 0x97, 0x01, 0xfa, 0xd8, 0xf3, 0x71, 0x0f, 0x85, 0xb8, 0x2f, 0x4e, 0xbd, 0x89, - 0x99, 0xb3, 0x75, 0x77, 0x54, 0xea, 0xd7, 0x9a, 0x47, 0xfd, 0x7e, 0x59, 0x84, 0x66, 0x9c, 0x45, - 0xdc, 0x86, 0xf6, 0x21, 0xe9, 0x27, 0xe2, 0xad, 0x48, 0x1c, 0x52, 0x09, 0x5e, 0x2a, 0xf1, 0xe8, - 0x16, 0x8c, 0xd6, 0x61, 0x2a, 0x13, 0x79, 0x08, 0x9a, 0x4b, 0x5c, 0x73, 0x8c, 0x0e, 0x4f, 0x0b, - 0x2e, 0xa5, 0x98, 0x1a, 0xcb, 0x61, 0xba, 0x05, 0xa3, 0xe3, 0x8e, 0xcd, 0xc5, 0xd1, 0xf3, 0x08, - 0x56, 0x55, 0x7d, 0x36, 0x6d, 0x6f, 0xb2, 0xbd, 0x6c, 0x64, 0xc4, 0x10, 0x27, 0xe6, 0x6a, 0x93, - 0xf9, 0xac, 0x08, 0xed, 0xb4, 0x76, 0x68, 0x5f, 0x82, 0xe6, 0xb8, 0x44, 0xd4, 0xb9, 0x7e, 0xb7, - 0x60, 0xc4, 0x98, 0x54, 0x9a, 0x9f, 0x04, 0xc4, 0xa5, 0x67, 0x30, 0x7e, 0x22, 0x53, 0xa5, 0xcb, - 0xa9, 0x23, 0x1b, 0x95, 0xe6, 0x27, 0xc9, 0x89, 0xf8, 0xf9, 0x7f, 0x5f, 0x86, 0x46, 0x74, 0x74, - 0x50, 0x9c, 0xec, 0x5e, 0x83, 0xf2, 0x11, 0x0e, 0x55, 0x27, 0x91, 0xc8, 0xfe, 0x0d, 0x8a, 0x41, - 0x11, 0xbd, 0x61, 0x28, 0xfc, 0x63, 0x1e, 0xa2, 0x37, 0x0c, 0xb5, 0xeb, 0x50, 0xf1, 0x48, 0x20, - 0x3b, 0x40, 0x39, 0x98, 0x0c, 0x45, 0xbb, 0x09, 0xb5, 0x3e, 0xb6, 0x71, 0x88, 0xc5, 0x89, 0x3a, - 0x07, 0x59, 0x20, 0x69, 0xb7, 0xa0, 0x4e, 0x3c, 0xde, 0x86, 0xac, 0x4d, 0xc2, 0x97, 0x58, 0x94, - 0x15, 0x9a, 0x92, 0x8a, 0x22, 0x57, 0x1e, 0x2b, 0x14, 0x85, 0x9e, 0xc9, 0x3c, 0x14, 0xf6, 0x8e, - 0x45, 0xfb, 0x22, 0x07, 0x97, 0xe3, 0x8c, 0xb9, 0x89, 0xe6, 0x5c, 0x6e, 0xe2, 0xcc, 0x1d, 0xa4, - 0xbf, 0x56, 0x61, 0x4d, 0x9d, 0x4d, 0x9e, 0xd7, 0x18, 0xcf, 0x6b, 0x8c, 0xff, 0xed, 0x35, 0xc6, - 0xa7, 0x50, 0x65, 0x17, 0x34, 0x94, 0x94, 0x8a, 0x73, 0x50, 0xd2, 0x6e, 0x42, 0x85, 0xdd, 0x36, - 0x29, 0xb1, 0x45, 0xeb, 0x0a, 0x87, 0x2f, 0xea, 0x26, 0x0c, 0x6d, 0xeb, 0x67, 0x55, 0x58, 0x1a, - 0xd3, 0xda, 0xf3, 0x9e, 0xd4, 0x79, 0x4f, 0xea, 0x4c, 0x3d, 0x29, 0x95, 0x0e, 0x6b, 0xf3, 0x58, - 0xc3, 0xb7, 0x01, 0xe2, 0x14, 0xe4, 0x39, 0xdf, 0xf9, 0xfa, 0x55, 0x0d, 0x2e, 0xe6, 0x14, 0x46, - 0xce, 0xaf, 0x29, 0x9c, 0x5f, 0x53, 0x38, 0xbf, 0xa6, 0x10, 0x9b, 0xe1, 0xdf, 0x8b, 0xd0, 0x88, - 0xca, 0xe9, 0xd3, 0x2f, 0x76, 0x6d, 0x47, 0xdd, 0x19, 0x9e, 0x76, 0xaf, 0x65, 0x6b, 0xd6, 0x2c, - 0xf0, 0xc8, 0xab, 0xaf, 0x37, 0xa1, 0xce, 0x2b, 0xab, 0x32, 0x78, 0xac, 0x64, 0x0b, 0xb2, 0x81, - 0x21, 0x71, 0xb4, 0x37, 0xa0, 0x21, 0xae, 0x2b, 0xc9, 0x93, 0xf5, 0x6a, 0xfa, 0x64, 0xcd, 0x61, - 0x46, 0x84, 0x75, 0xf6, 0x3b, 0xcd, 0x18, 0x56, 0x14, 0x97, 0x11, 0xb5, 0xf7, 0x26, 0x3b, 0xa4, - 0x6c, 0xcc, 0x8d, 0x5a, 0x0b, 0x6a, 0x97, 0xf4, 0x93, 0x22, 0xb4, 0xd2, 0x5d, 0x86, 0x1d, 0xea, - 0x88, 0xf8, 0x44, 0x74, 0x7b, 0x5c, 0x71, 0xe6, 0xee, 0x16, 0x8c, 0x08, 0xef, 0xf9, 0x9e, 0xaf, - 0x7e, 0x5a, 0x84, 0x66, 0x74, 0xb2, 0xd7, 0xee, 0x40, 0x4b, 0x6e, 0x63, 0xf6, 0x48, 0x1f, 0x8b, - 0x07, 0xbd, 0x9c, 0xfb, 0xa0, 0xbc, 0xdb, 0xb1, 0x28, 0x17, 0xdd, 0x21, 0x7d, 0x75, 0x2b, 0xb0, - 0x34, 0xcf, 0xdb, 0xf8, 0x75, 0x13, 0x6a, 0xc2, 0x51, 0x2b, 0x4e, 0x7c, 0x79, 0x09, 0x4a, 0xd4, - 0x5b, 0x2d, 0x4f, 0xb8, 0xf4, 0x57, 0x99, 0x78, 0xe9, 0x6f, 0x5a, 0xe2, 0x31, 0x66, 0x89, 0xb5, - 0x8c, 0x25, 0x26, 0x5c, 0x62, 0x7d, 0x06, 0x97, 0xd8, 0x98, 0xee, 0x12, 0x9b, 0x33, 0xb8, 0x44, - 0x98, 0xc9, 0x25, 0x2e, 0x4c, 0x76, 0x89, 0x8b, 0x13, 0x5c, 0x62, 0x6b, 0x82, 0x4b, 0x6c, 0x4f, - 0x72, 0x89, 0x4b, 0x53, 0x5c, 0x62, 0x27, 0xeb, 0x12, 0x5f, 0x81, 0x36, 0x25, 0x9e, 0x30, 0x36, - 0x7e, 0x12, 0x68, 0x39, 0xe8, 0x34, 0x91, 0x2b, 0x50, 0x34, 0xcb, 0x4d, 0xa2, 0x69, 0x02, 0xcd, - 0x72, 0x13, 0x68, 0xc9, 0x40, 0xbf, 0x32, 0x76, 0x4d, 0x73, 0xa6, 0x13, 0xc1, 0x47, 0x79, 0x2e, - 0xe0, 0x42, 0xb6, 0xb5, 0x94, 0xf7, 0xe9, 0x89, 0xda, 0x1b, 0x68, 0xd7, 0x44, 0xd8, 0x5f, 0xcb, - 0xda, 0xfd, 0xa3, 0x91, 0x87, 0x79, 0xee, 0xce, 0x92, 0x81, 0xd7, 0x65, 0xd0, 0xbf, 0x98, 0x3d, - 0xdc, 0x47, 0x4d, 0x73, 0x19, 0xee, 0xaf, 0x43, 0x0d, 0xd9, 0x36, 0xd5, 0x4f, 0x3d, 0xb7, 0x77, - 0x5e, 0x45, 0xb6, 0xbd, 0x37, 0xd0, 0xbe, 0x0c, 0x90, 0x78, 0xa2, 0xf5, 0xac, 0x33, 0x8f, 0xb9, - 0x35, 0x12, 0x98, 0xda, 0xcb, 0xd0, 0xea, 0x5b, 0xd4, 0x82, 0x1c, 0xcb, 0x45, 0x21, 0xf1, 0xf5, - 0x0d, 0xa6, 0x20, 0xe9, 0xc9, 0xf4, 0x95, 0xd7, 0xcd, 0xb1, 0x2b, 0xaf, 0x2f, 0x41, 0xf9, 0xd4, - 0xb1, 0xf5, 0x4b, 0x59, 0x8b, 0xfb, 0xd0, 0xb1, 0x0d, 0x0a, 0xcb, 0x96, 0x59, 0x5f, 0x78, 0xd6, - 0x5b, 0xb1, 0x97, 0x9f, 0xe1, 0x56, 0xec, 0x8b, 0xf3, 0x78, 0xac, 0x1f, 0x00, 0xc4, 0x71, 0x6f, - 0xce, 0x2f, 0x8d, 0xde, 0x86, 0x85, 0x81, 0x65, 0x63, 0x33, 0x3f, 0xa4, 0xc6, 0x37, 0x9e, 0xbb, - 0x05, 0x03, 0x06, 0xd1, 0x28, 0xf6, 0xe2, 0x21, 0xac, 0x28, 0xba, 0xb9, 0xda, 0x77, 0x27, 0xc7, - 0xaf, 0x6b, 0xd9, 0x84, 0x3a, 0xa7, 0x25, 0xac, 0x0e, 0x67, 0x7f, 0xaa, 0xc0, 0xc5, 0xbc, 0x66, - 0xb4, 0x03, 0x2f, 0x1c, 0xa2, 0xc0, 0xea, 0x99, 0x28, 0xf5, 0x95, 0x90, 0x19, 0xd5, 0x7c, 0xb9, - 0x68, 0x5e, 0x4b, 0x55, 0x58, 0xf3, 0xbf, 0x2a, 0xea, 0x16, 0x8c, 0xcd, 0xc3, 0x09, 0x1f, 0x1d, - 0xdd, 0x87, 0x0e, 0xf2, 0x2c, 0xf3, 0x53, 0x3c, 0x8a, 0x77, 0xe0, 0x92, 0x4c, 0xd5, 0xb5, 0xd2, - 0x5f, 0x59, 0x75, 0x0b, 0x46, 0x1b, 0xa5, 0xbf, 0xbb, 0xfa, 0x1e, 0xe8, 0x84, 0xb5, 0x25, 0x4c, - 0x4b, 0x34, 0xa4, 0x62, 0x7a, 0xe5, 0x6c, 0x57, 0x54, 0xdd, 0xbb, 0xea, 0x16, 0x8c, 0x35, 0xa2, - 0xee, 0x6a, 0xc5, 0xf4, 0x3d, 0xd1, 0xeb, 0x89, 0xe9, 0x57, 0xf2, 0xe8, 0x8f, 0xb7, 0x85, 0x62, - 0xfa, 0x99, 0x86, 0xd1, 0x11, 0x6c, 0x0a, 0xfa, 0x28, 0x6e, 0x24, 0xc6, 0x5b, 0xf0, 0x00, 0xf7, - 0x4a, 0x76, 0x0b, 0x45, 0xdb, 0xb1, 0x5b, 0x30, 0xd6, 0x49, 0x6e, 0x4f, 0x12, 0xc7, 0x1b, 0xb1, - 0xae, 0x2e, 0x4b, 0x17, 0xe2, 0x8d, 0x6a, 0x59, 0xef, 0x98, 0xd7, 0x03, 0xee, 0x16, 0x0c, 0x21, - 0x93, 0x2c, 0x2c, 0xd6, 0xf0, 0xe3, 0x58, 0xc3, 0x13, 0x2d, 0x01, 0xed, 0xfd, 0xc9, 0x1a, 0x7e, - 0x29, 0xa7, 0x6d, 0xc4, 0x2f, 0x16, 0xa8, 0xb5, 0xfa, 0x2a, 0x2c, 0x24, 0x6f, 0x2e, 0xac, 0xc6, - 0x1f, 0xf7, 0x95, 0xe3, 0x3b, 0x0e, 0xbf, 0x2d, 0x42, 0xf9, 0x11, 0x52, 0xdf, 0x8a, 0x98, 0xfe, - 0xb1, 0x5b, 0xc6, 0xb3, 0x95, 0xcf, 0xfc, 0x8d, 0xc8, 0x5c, 0x5f, 0x70, 0x5d, 0x81, 0x86, 0x8c, - 0x30, 0x39, 0xcf, 0xf7, 0x31, 0x2c, 0x7d, 0x30, 0x56, 0x6f, 0x7a, 0x8e, 0x1f, 0x93, 0xfc, 0xae, - 0x08, 0xe5, 0x0f, 0x1d, 0x5b, 0x29, 0xbd, 0x4b, 0xd0, 0xa4, 0xbf, 0x81, 0x87, 0x7a, 0xf2, 0x5e, - 0x49, 0x3c, 0x41, 0x93, 0x3f, 0xcf, 0xc7, 0x03, 0xeb, 0x54, 0x64, 0x79, 0x62, 0x44, 0x57, 0xa1, - 0x30, 0xf4, 0xad, 0xc3, 0x61, 0x88, 0xc5, 0x67, 0x7a, 0xf1, 0x04, 0x4d, 0x65, 0x9e, 0xfa, 0xc8, - 0xf3, 0x70, 0x5f, 0x1c, 0xc1, 0xe5, 0xf0, 0xcc, 0x7d, 0xcc, 0xdb, 0xaf, 0x42, 0x9b, 0xf8, 0x47, - 0x12, 0xd7, 0x3c, 0xd9, 0xb9, 0xbd, 0x28, 0xbe, 0x5d, 0xdd, 0xf7, 0x49, 0x48, 0xf6, 0x8b, 0xbf, - 0x28, 0x95, 0xf7, 0x76, 0x0f, 0x0e, 0x6b, 0xec, 0x63, 0xd0, 0x37, 0xff, 0x19, 0x00, 0x00, 0xff, - 0xff, 0xd4, 0x0a, 0xef, 0xca, 0xe4, 0x3a, 0x00, 0x00, -} diff --git a/vendor/github.com/googleapis/gnostic/compiler/context.go b/vendor/github.com/googleapis/gnostic/compiler/context.go deleted file mode 100644 index a64c1b75d..000000000 --- a/vendor/github.com/googleapis/gnostic/compiler/context.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2017 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package compiler - -// Context contains state of the compiler as it traverses a document. -type Context struct { - Parent *Context - Name string - ExtensionHandlers *[]ExtensionHandler -} - -// NewContextWithExtensions returns a new object representing the compiler state -func NewContextWithExtensions(name string, parent *Context, extensionHandlers *[]ExtensionHandler) *Context { - return &Context{Name: name, Parent: parent, ExtensionHandlers: extensionHandlers} -} - -// NewContext returns a new object representing the compiler state -func NewContext(name string, parent *Context) *Context { - if parent != nil { - return &Context{Name: name, Parent: parent, ExtensionHandlers: parent.ExtensionHandlers} - } - return &Context{Name: name, Parent: parent, ExtensionHandlers: nil} -} - -// Description returns a text description of the compiler state -func (context *Context) Description() string { - if context.Parent != nil { - return context.Parent.Description() + "." + context.Name - } - return context.Name -} diff --git a/vendor/github.com/googleapis/gnostic/compiler/error.go b/vendor/github.com/googleapis/gnostic/compiler/error.go deleted file mode 100644 index d8672c100..000000000 --- a/vendor/github.com/googleapis/gnostic/compiler/error.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2017 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package compiler - -// Error represents compiler errors and their location in the document. -type Error struct { - Context *Context - Message string -} - -// NewError creates an Error. -func NewError(context *Context, message string) *Error { - return &Error{Context: context, Message: message} -} - -// Error returns the string value of an Error. -func (err *Error) Error() string { - if err.Context == nil { - return "ERROR " + err.Message - } - return "ERROR " + err.Context.Description() + " " + err.Message -} - -// ErrorGroup is a container for groups of Error values. -type ErrorGroup struct { - Errors []error -} - -// NewErrorGroupOrNil returns a new ErrorGroup for a slice of errors or nil if the slice is empty. -func NewErrorGroupOrNil(errors []error) error { - if len(errors) == 0 { - return nil - } else if len(errors) == 1 { - return errors[0] - } else { - return &ErrorGroup{Errors: errors} - } -} - -func (group *ErrorGroup) Error() string { - result := "" - for i, err := range group.Errors { - if i > 0 { - result += "\n" - } - result += err.Error() - } - return result -} diff --git a/vendor/github.com/googleapis/gnostic/compiler/extension-handler.go b/vendor/github.com/googleapis/gnostic/compiler/extension-handler.go deleted file mode 100644 index 1f85b650e..000000000 --- a/vendor/github.com/googleapis/gnostic/compiler/extension-handler.go +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2017 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package compiler - -import ( - "bytes" - "fmt" - "os/exec" - - "strings" - - "errors" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes/any" - ext_plugin "github.com/googleapis/gnostic/extensions" - yaml "gopkg.in/yaml.v2" -) - -// ExtensionHandler describes a binary that is called by the compiler to handle specification extensions. -type ExtensionHandler struct { - Name string -} - -// HandleExtension calls a binary extension handler. -func HandleExtension(context *Context, in interface{}, extensionName string) (bool, *any.Any, error) { - handled := false - var errFromPlugin error - var outFromPlugin *any.Any - - if context != nil && context.ExtensionHandlers != nil && len(*(context.ExtensionHandlers)) != 0 { - for _, customAnyProtoGenerator := range *(context.ExtensionHandlers) { - outFromPlugin, errFromPlugin = customAnyProtoGenerator.handle(in, extensionName) - if outFromPlugin == nil { - continue - } else { - handled = true - break - } - } - } - return handled, outFromPlugin, errFromPlugin -} - -func (extensionHandlers *ExtensionHandler) handle(in interface{}, extensionName string) (*any.Any, error) { - if extensionHandlers.Name != "" { - binary, _ := yaml.Marshal(in) - - request := &ext_plugin.ExtensionHandlerRequest{} - - version := &ext_plugin.Version{} - version.Major = 0 - version.Minor = 1 - version.Patch = 0 - request.CompilerVersion = version - - request.Wrapper = &ext_plugin.Wrapper{} - - request.Wrapper.Version = "v2" - request.Wrapper.Yaml = string(binary) - request.Wrapper.ExtensionName = extensionName - - requestBytes, _ := proto.Marshal(request) - cmd := exec.Command(extensionHandlers.Name) - cmd.Stdin = bytes.NewReader(requestBytes) - output, err := cmd.Output() - - if err != nil { - fmt.Printf("Error: %+v\n", err) - return nil, err - } - response := &ext_plugin.ExtensionHandlerResponse{} - err = proto.Unmarshal(output, response) - if err != nil { - fmt.Printf("Error: %+v\n", err) - fmt.Printf("%s\n", string(output)) - return nil, err - } - if !response.Handled { - return nil, nil - } - if len(response.Error) != 0 { - message := fmt.Sprintf("Errors when parsing: %+v for field %s by vendor extension handler %s. Details %+v", in, extensionName, extensionHandlers.Name, strings.Join(response.Error, ",")) - return nil, errors.New(message) - } - return response.Value, nil - } - return nil, nil -} diff --git a/vendor/github.com/googleapis/gnostic/compiler/helpers.go b/vendor/github.com/googleapis/gnostic/compiler/helpers.go deleted file mode 100644 index 76df635ff..000000000 --- a/vendor/github.com/googleapis/gnostic/compiler/helpers.go +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright 2017 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package compiler - -import ( - "fmt" - "gopkg.in/yaml.v2" - "regexp" - "sort" - "strconv" -) - -// compiler helper functions, usually called from generated code - -// UnpackMap gets a yaml.MapSlice if possible. -func UnpackMap(in interface{}) (yaml.MapSlice, bool) { - m, ok := in.(yaml.MapSlice) - if ok { - return m, true - } - // do we have an empty array? - a, ok := in.([]interface{}) - if ok && len(a) == 0 { - // if so, return an empty map - return yaml.MapSlice{}, true - } - return nil, false -} - -// SortedKeysForMap returns the sorted keys of a yaml.MapSlice. -func SortedKeysForMap(m yaml.MapSlice) []string { - keys := make([]string, 0) - for _, item := range m { - keys = append(keys, item.Key.(string)) - } - sort.Strings(keys) - return keys -} - -// MapHasKey returns true if a yaml.MapSlice contains a specified key. -func MapHasKey(m yaml.MapSlice, key string) bool { - for _, item := range m { - itemKey, ok := item.Key.(string) - if ok && key == itemKey { - return true - } - } - return false -} - -// MapValueForKey gets the value of a map value for a specified key. -func MapValueForKey(m yaml.MapSlice, key string) interface{} { - for _, item := range m { - itemKey, ok := item.Key.(string) - if ok && key == itemKey { - return item.Value - } - } - return nil -} - -// ConvertInterfaceArrayToStringArray converts an array of interfaces to an array of strings, if possible. -func ConvertInterfaceArrayToStringArray(interfaceArray []interface{}) []string { - stringArray := make([]string, 0) - for _, item := range interfaceArray { - v, ok := item.(string) - if ok { - stringArray = append(stringArray, v) - } - } - return stringArray -} - -// MissingKeysInMap identifies which keys from a list of required keys are not in a map. -func MissingKeysInMap(m yaml.MapSlice, requiredKeys []string) []string { - missingKeys := make([]string, 0) - for _, k := range requiredKeys { - if !MapHasKey(m, k) { - missingKeys = append(missingKeys, k) - } - } - return missingKeys -} - -// InvalidKeysInMap returns keys in a map that don't match a list of allowed keys and patterns. -func InvalidKeysInMap(m yaml.MapSlice, allowedKeys []string, allowedPatterns []*regexp.Regexp) []string { - invalidKeys := make([]string, 0) - for _, item := range m { - itemKey, ok := item.Key.(string) - if ok { - key := itemKey - found := false - // does the key match an allowed key? - for _, allowedKey := range allowedKeys { - if key == allowedKey { - found = true - break - } - } - if !found { - // does the key match an allowed pattern? - for _, allowedPattern := range allowedPatterns { - if allowedPattern.MatchString(key) { - found = true - break - } - } - if !found { - invalidKeys = append(invalidKeys, key) - } - } - } - } - return invalidKeys -} - -// DescribeMap describes a map (for debugging purposes). -func DescribeMap(in interface{}, indent string) string { - description := "" - m, ok := in.(map[string]interface{}) - if ok { - keys := make([]string, 0) - for k := range m { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - v := m[k] - description += fmt.Sprintf("%s%s:\n", indent, k) - description += DescribeMap(v, indent+" ") - } - return description - } - a, ok := in.([]interface{}) - if ok { - for i, v := range a { - description += fmt.Sprintf("%s%d:\n", indent, i) - description += DescribeMap(v, indent+" ") - } - return description - } - description += fmt.Sprintf("%s%+v\n", indent, in) - return description -} - -// PluralProperties returns the string "properties" pluralized. -func PluralProperties(count int) string { - if count == 1 { - return "property" - } - return "properties" -} - -// StringArrayContainsValue returns true if a string array contains a specified value. -func StringArrayContainsValue(array []string, value string) bool { - for _, item := range array { - if item == value { - return true - } - } - return false -} - -// StringArrayContainsValues returns true if a string array contains all of a list of specified values. -func StringArrayContainsValues(array []string, values []string) bool { - for _, value := range values { - if !StringArrayContainsValue(array, value) { - return false - } - } - return true -} - -// StringValue returns the string value of an item. -func StringValue(item interface{}) (value string, ok bool) { - value, ok = item.(string) - if ok { - return value, ok - } - intValue, ok := item.(int) - if ok { - return strconv.Itoa(intValue), true - } - return "", false -} diff --git a/vendor/github.com/googleapis/gnostic/compiler/main.go b/vendor/github.com/googleapis/gnostic/compiler/main.go deleted file mode 100644 index 9713a21cc..000000000 --- a/vendor/github.com/googleapis/gnostic/compiler/main.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package compiler provides support functions to generated compiler code. -package compiler diff --git a/vendor/github.com/googleapis/gnostic/compiler/reader.go b/vendor/github.com/googleapis/gnostic/compiler/reader.go deleted file mode 100644 index 2d4b3303d..000000000 --- a/vendor/github.com/googleapis/gnostic/compiler/reader.go +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2017 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package compiler - -import ( - "errors" - "fmt" - "gopkg.in/yaml.v2" - "io/ioutil" - "log" - "net/http" - "net/url" - "path/filepath" - "strings" -) - -var fileCache map[string][]byte -var infoCache map[string]interface{} -var count int64 - -var verboseReader = false - -func initializeFileCache() { - if fileCache == nil { - fileCache = make(map[string][]byte, 0) - } -} - -func initializeInfoCache() { - if infoCache == nil { - infoCache = make(map[string]interface{}, 0) - } -} - -// FetchFile gets a specified file from the local filesystem or a remote location. -func FetchFile(fileurl string) ([]byte, error) { - initializeFileCache() - bytes, ok := fileCache[fileurl] - if ok { - if verboseReader { - log.Printf("Cache hit %s", fileurl) - } - return bytes, nil - } - if verboseReader { - log.Printf("Fetching %s", fileurl) - } - response, err := http.Get(fileurl) - if err != nil { - return nil, err - } - if response.StatusCode != 200 { - return nil, errors.New(fmt.Sprintf("Error downloading %s: %s", fileurl, response.Status)) - } - defer response.Body.Close() - bytes, err = ioutil.ReadAll(response.Body) - if err == nil { - fileCache[fileurl] = bytes - } - return bytes, err -} - -// ReadBytesForFile reads the bytes of a file. -func ReadBytesForFile(filename string) ([]byte, error) { - // is the filename a url? - fileurl, _ := url.Parse(filename) - if fileurl.Scheme != "" { - // yes, fetch it - bytes, err := FetchFile(filename) - if err != nil { - return nil, err - } - return bytes, nil - } - // no, it's a local filename - bytes, err := ioutil.ReadFile(filename) - if err != nil { - return nil, err - } - return bytes, nil -} - -// ReadInfoFromBytes unmarshals a file as a yaml.MapSlice. -func ReadInfoFromBytes(filename string, bytes []byte) (interface{}, error) { - initializeInfoCache() - cachedInfo, ok := infoCache[filename] - if ok { - if verboseReader { - log.Printf("Cache hit info for file %s", filename) - } - return cachedInfo, nil - } - if verboseReader { - log.Printf("Reading info for file %s", filename) - } - var info yaml.MapSlice - err := yaml.Unmarshal(bytes, &info) - if err != nil { - return nil, err - } - infoCache[filename] = info - return info, nil -} - -// ReadInfoForRef reads a file and return the fragment needed to resolve a $ref. -func ReadInfoForRef(basefile string, ref string) (interface{}, error) { - initializeInfoCache() - { - info, ok := infoCache[ref] - if ok { - if verboseReader { - log.Printf("Cache hit for ref %s#%s", basefile, ref) - } - return info, nil - } - } - if verboseReader { - log.Printf("Reading info for ref %s#%s", basefile, ref) - } - count = count + 1 - basedir, _ := filepath.Split(basefile) - parts := strings.Split(ref, "#") - var filename string - if parts[0] != "" { - filename = basedir + parts[0] - } else { - filename = basefile - } - bytes, err := ReadBytesForFile(filename) - if err != nil { - return nil, err - } - info, err := ReadInfoFromBytes(filename, bytes) - if err != nil { - log.Printf("File error: %v\n", err) - } else { - if len(parts) > 1 { - path := strings.Split(parts[1], "/") - for i, key := range path { - if i > 0 { - m, ok := info.(yaml.MapSlice) - if ok { - found := false - for _, section := range m { - if section.Key == key { - info = section.Value - found = true - } - } - if !found { - infoCache[ref] = nil - return nil, NewError(nil, fmt.Sprintf("could not resolve %s", ref)) - } - } - } - } - } - } - infoCache[ref] = info - return info, nil -} diff --git a/vendor/github.com/googleapis/gnostic/extensions/extension.pb.go b/vendor/github.com/googleapis/gnostic/extensions/extension.pb.go deleted file mode 100644 index 7c6b91496..000000000 --- a/vendor/github.com/googleapis/gnostic/extensions/extension.pb.go +++ /dev/null @@ -1,219 +0,0 @@ -// Code generated by protoc-gen-go. -// source: extension.proto -// DO NOT EDIT! - -/* -Package openapiextension_v1 is a generated protocol buffer package. - -It is generated from these files: - extension.proto - -It has these top-level messages: - Version - ExtensionHandlerRequest - ExtensionHandlerResponse - Wrapper -*/ -package openapiextension_v1 - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import google_protobuf "github.com/golang/protobuf/ptypes/any" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -// The version number of OpenAPI compiler. -type Version struct { - Major int32 `protobuf:"varint,1,opt,name=major" json:"major,omitempty"` - Minor int32 `protobuf:"varint,2,opt,name=minor" json:"minor,omitempty"` - Patch int32 `protobuf:"varint,3,opt,name=patch" json:"patch,omitempty"` - // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should - // be empty for mainline stable releases. - Suffix string `protobuf:"bytes,4,opt,name=suffix" json:"suffix,omitempty"` -} - -func (m *Version) Reset() { *m = Version{} } -func (m *Version) String() string { return proto.CompactTextString(m) } -func (*Version) ProtoMessage() {} -func (*Version) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -func (m *Version) GetMajor() int32 { - if m != nil { - return m.Major - } - return 0 -} - -func (m *Version) GetMinor() int32 { - if m != nil { - return m.Minor - } - return 0 -} - -func (m *Version) GetPatch() int32 { - if m != nil { - return m.Patch - } - return 0 -} - -func (m *Version) GetSuffix() string { - if m != nil { - return m.Suffix - } - return "" -} - -// An encoded Request is written to the ExtensionHandler's stdin. -type ExtensionHandlerRequest struct { - // The OpenAPI descriptions that were explicitly listed on the command line. - // The specifications will appear in the order they are specified to openapic. - Wrapper *Wrapper `protobuf:"bytes,1,opt,name=wrapper" json:"wrapper,omitempty"` - // The version number of openapi compiler. - CompilerVersion *Version `protobuf:"bytes,3,opt,name=compiler_version,json=compilerVersion" json:"compiler_version,omitempty"` -} - -func (m *ExtensionHandlerRequest) Reset() { *m = ExtensionHandlerRequest{} } -func (m *ExtensionHandlerRequest) String() string { return proto.CompactTextString(m) } -func (*ExtensionHandlerRequest) ProtoMessage() {} -func (*ExtensionHandlerRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -func (m *ExtensionHandlerRequest) GetWrapper() *Wrapper { - if m != nil { - return m.Wrapper - } - return nil -} - -func (m *ExtensionHandlerRequest) GetCompilerVersion() *Version { - if m != nil { - return m.CompilerVersion - } - return nil -} - -// The extensions writes an encoded ExtensionHandlerResponse to stdout. -type ExtensionHandlerResponse struct { - // true if the extension is handled by the extension handler; false otherwise - Handled bool `protobuf:"varint,1,opt,name=handled" json:"handled,omitempty"` - // Error message. If non-empty, the extension handling failed. - // The extension handler process should exit with status code zero - // even if it reports an error in this way. - // - // This should be used to indicate errors which prevent the extension from - // operating as intended. Errors which indicate a problem in gnostic - // itself -- such as the input Document being unparseable -- should be - // reported by writing a message to stderr and exiting with a non-zero - // status code. - Error []string `protobuf:"bytes,2,rep,name=error" json:"error,omitempty"` - // text output - Value *google_protobuf.Any `protobuf:"bytes,3,opt,name=value" json:"value,omitempty"` -} - -func (m *ExtensionHandlerResponse) Reset() { *m = ExtensionHandlerResponse{} } -func (m *ExtensionHandlerResponse) String() string { return proto.CompactTextString(m) } -func (*ExtensionHandlerResponse) ProtoMessage() {} -func (*ExtensionHandlerResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } - -func (m *ExtensionHandlerResponse) GetHandled() bool { - if m != nil { - return m.Handled - } - return false -} - -func (m *ExtensionHandlerResponse) GetError() []string { - if m != nil { - return m.Error - } - return nil -} - -func (m *ExtensionHandlerResponse) GetValue() *google_protobuf.Any { - if m != nil { - return m.Value - } - return nil -} - -type Wrapper struct { - // version of the OpenAPI specification in which this extension was written. - Version string `protobuf:"bytes,1,opt,name=version" json:"version,omitempty"` - // Name of the extension - ExtensionName string `protobuf:"bytes,2,opt,name=extension_name,json=extensionName" json:"extension_name,omitempty"` - // Must be a valid yaml for the proto - Yaml string `protobuf:"bytes,3,opt,name=yaml" json:"yaml,omitempty"` -} - -func (m *Wrapper) Reset() { *m = Wrapper{} } -func (m *Wrapper) String() string { return proto.CompactTextString(m) } -func (*Wrapper) ProtoMessage() {} -func (*Wrapper) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } - -func (m *Wrapper) GetVersion() string { - if m != nil { - return m.Version - } - return "" -} - -func (m *Wrapper) GetExtensionName() string { - if m != nil { - return m.ExtensionName - } - return "" -} - -func (m *Wrapper) GetYaml() string { - if m != nil { - return m.Yaml - } - return "" -} - -func init() { - proto.RegisterType((*Version)(nil), "openapiextension.v1.Version") - proto.RegisterType((*ExtensionHandlerRequest)(nil), "openapiextension.v1.ExtensionHandlerRequest") - proto.RegisterType((*ExtensionHandlerResponse)(nil), "openapiextension.v1.ExtensionHandlerResponse") - proto.RegisterType((*Wrapper)(nil), "openapiextension.v1.Wrapper") -} - -func init() { proto.RegisterFile("extension.proto", fileDescriptor0) } - -var fileDescriptor0 = []byte{ - // 355 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0x4d, 0x4b, 0xf3, 0x40, - 0x1c, 0xc4, 0x49, 0xdf, 0xf2, 0x64, 0x1f, 0xb4, 0xb2, 0x16, 0x8d, 0xe2, 0xa1, 0x04, 0x84, 0x22, - 0xb8, 0xa5, 0x0a, 0xde, 0x5b, 0x28, 0xea, 0xc5, 0x96, 0x3d, 0xd4, 0x9b, 0x65, 0x9b, 0xfe, 0xdb, - 0x46, 0x92, 0xdd, 0x75, 0xf3, 0x62, 0xfb, 0x55, 0x3c, 0xfa, 0x49, 0x25, 0xbb, 0xd9, 0x7a, 0x50, - 0x6f, 0x99, 0x1f, 0x93, 0xfc, 0x67, 0x26, 0xa8, 0x0d, 0xdb, 0x0c, 0x78, 0x1a, 0x09, 0x4e, 0xa4, - 0x12, 0x99, 0xc0, 0xc7, 0x42, 0x02, 0x67, 0x32, 0xfa, 0xe6, 0xc5, 0xe0, 0xfc, 0x6c, 0x2d, 0xc4, - 0x3a, 0x86, 0xbe, 0xb6, 0x2c, 0xf2, 0x55, 0x9f, 0xf1, 0x9d, 0xf1, 0x07, 0x21, 0x72, 0x67, 0xa0, - 0x4a, 0x23, 0xee, 0xa0, 0x66, 0xc2, 0x5e, 0x85, 0xf2, 0x9d, 0xae, 0xd3, 0x6b, 0x52, 0x23, 0x34, - 0x8d, 0xb8, 0x50, 0x7e, 0xad, 0xa2, 0xa5, 0x28, 0xa9, 0x64, 0x59, 0xb8, 0xf1, 0xeb, 0x86, 0x6a, - 0x81, 0x4f, 0x50, 0x2b, 0xcd, 0x57, 0xab, 0x68, 0xeb, 0x37, 0xba, 0x4e, 0xcf, 0xa3, 0x95, 0x0a, - 0x3e, 0x1c, 0x74, 0x3a, 0xb6, 0x81, 0x1e, 0x18, 0x5f, 0xc6, 0xa0, 0x28, 0xbc, 0xe5, 0x90, 0x66, - 0xf8, 0x0e, 0xb9, 0xef, 0x8a, 0x49, 0x09, 0xe6, 0xee, 0xff, 0x9b, 0x0b, 0xf2, 0x4b, 0x05, 0xf2, - 0x6c, 0x3c, 0xd4, 0x9a, 0xf1, 0x3d, 0x3a, 0x0a, 0x45, 0x22, 0xa3, 0x18, 0xd4, 0xbc, 0x30, 0x0d, - 0x74, 0x98, 0xbf, 0x3e, 0x50, 0xb5, 0xa4, 0x6d, 0xfb, 0x56, 0x05, 0x82, 0x02, 0xf9, 0x3f, 0xb3, - 0xa5, 0x52, 0xf0, 0x14, 0xb0, 0x8f, 0xdc, 0x8d, 0x46, 0x4b, 0x1d, 0xee, 0x1f, 0xb5, 0xb2, 0x1c, - 0x00, 0x94, 0xd2, 0xb3, 0xd4, 0x7b, 0x1e, 0x35, 0x02, 0x5f, 0xa1, 0x66, 0xc1, 0xe2, 0x1c, 0xaa, - 0x24, 0x1d, 0x62, 0x86, 0x27, 0x76, 0x78, 0x32, 0xe4, 0x3b, 0x6a, 0x2c, 0xc1, 0x0b, 0x72, 0xab, - 0x52, 0xe5, 0x19, 0x5b, 0xc1, 0xd1, 0xc3, 0x59, 0x89, 0x2f, 0xd1, 0xe1, 0xbe, 0xc5, 0x9c, 0xb3, - 0x04, 0xf4, 0x6f, 0xf0, 0xe8, 0xc1, 0x9e, 0x3e, 0xb1, 0x04, 0x30, 0x46, 0x8d, 0x1d, 0x4b, 0x62, - 0x7d, 0xd6, 0xa3, 0xfa, 0x79, 0x74, 0x8d, 0xda, 0x42, 0xad, 0xed, 0x16, 0x21, 0x29, 0x06, 0x23, - 0x3c, 0x91, 0xc0, 0x87, 0xd3, 0xc7, 0x7d, 0xdf, 0xd9, 0x60, 0xea, 0x7c, 0xd6, 0xea, 0x93, 0xe1, - 0x78, 0xd1, 0xd2, 0x19, 0x6f, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x56, 0x40, 0x4d, 0x52, - 0x02, 0x00, 0x00, -} diff --git a/vendor/github.com/googleapis/gnostic/extensions/extensions.go b/vendor/github.com/googleapis/gnostic/extensions/extensions.go deleted file mode 100644 index 94a8e62a7..000000000 --- a/vendor/github.com/googleapis/gnostic/extensions/extensions.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2017 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package openapiextension_v1 - -import ( - "fmt" - "io/ioutil" - "os" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" -) - -type documentHandler func(version string, extensionName string, document string) -type extensionHandler func(name string, yamlInput string) (bool, proto.Message, error) - -func forInputYamlFromOpenapic(handler documentHandler) { - data, err := ioutil.ReadAll(os.Stdin) - if err != nil { - fmt.Println("File error:", err.Error()) - os.Exit(1) - } - if len(data) == 0 { - fmt.Println("No input data.") - os.Exit(1) - } - request := &ExtensionHandlerRequest{} - err = proto.Unmarshal(data, request) - if err != nil { - fmt.Println("Input error:", err.Error()) - os.Exit(1) - } - handler(request.Wrapper.Version, request.Wrapper.ExtensionName, request.Wrapper.Yaml) -} - -// ProcessExtension calles the handler for a specified extension. -func ProcessExtension(handleExtension extensionHandler) { - response := &ExtensionHandlerResponse{} - forInputYamlFromOpenapic( - func(version string, extensionName string, yamlInput string) { - var newObject proto.Message - var err error - - handled, newObject, err := handleExtension(extensionName, yamlInput) - if !handled { - responseBytes, _ := proto.Marshal(response) - os.Stdout.Write(responseBytes) - os.Exit(0) - } - - // If we reach here, then the extension is handled - response.Handled = true - if err != nil { - response.Error = append(response.Error, err.Error()) - responseBytes, _ := proto.Marshal(response) - os.Stdout.Write(responseBytes) - os.Exit(0) - } - response.Value, err = ptypes.MarshalAny(newObject) - if err != nil { - response.Error = append(response.Error, err.Error()) - responseBytes, _ := proto.Marshal(response) - os.Stdout.Write(responseBytes) - os.Exit(0) - } - }) - - responseBytes, _ := proto.Marshal(response) - os.Stdout.Write(responseBytes) -} diff --git a/vendor/github.com/inconshreveable/mousetrap/LICENSE b/vendor/github.com/inconshreveable/mousetrap/LICENSE deleted file mode 100644 index 5f0d1fb6a..000000000 --- a/vendor/github.com/inconshreveable/mousetrap/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2014 Alan Shreve - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_others.go b/vendor/github.com/inconshreveable/mousetrap/trap_others.go deleted file mode 100644 index 9d2d8a4ba..000000000 --- a/vendor/github.com/inconshreveable/mousetrap/trap_others.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build !windows - -package mousetrap - -// StartedByExplorer returns true if the program was invoked by the user -// double-clicking on the executable from explorer.exe -// -// It is conservative and returns false if any of the internal calls fail. -// It does not guarantee that the program was run from a terminal. It only can tell you -// whether it was launched from explorer.exe -// -// On non-Windows platforms, it always returns false. -func StartedByExplorer() bool { - return false -} diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_windows.go b/vendor/github.com/inconshreveable/mousetrap/trap_windows.go deleted file mode 100644 index 336142a5e..000000000 --- a/vendor/github.com/inconshreveable/mousetrap/trap_windows.go +++ /dev/null @@ -1,98 +0,0 @@ -// +build windows -// +build !go1.4 - -package mousetrap - -import ( - "fmt" - "os" - "syscall" - "unsafe" -) - -const ( - // defined by the Win32 API - th32cs_snapprocess uintptr = 0x2 -) - -var ( - kernel = syscall.MustLoadDLL("kernel32.dll") - CreateToolhelp32Snapshot = kernel.MustFindProc("CreateToolhelp32Snapshot") - Process32First = kernel.MustFindProc("Process32FirstW") - Process32Next = kernel.MustFindProc("Process32NextW") -) - -// ProcessEntry32 structure defined by the Win32 API -type processEntry32 struct { - dwSize uint32 - cntUsage uint32 - th32ProcessID uint32 - th32DefaultHeapID int - th32ModuleID uint32 - cntThreads uint32 - th32ParentProcessID uint32 - pcPriClassBase int32 - dwFlags uint32 - szExeFile [syscall.MAX_PATH]uint16 -} - -func getProcessEntry(pid int) (pe *processEntry32, err error) { - snapshot, _, e1 := CreateToolhelp32Snapshot.Call(th32cs_snapprocess, uintptr(0)) - if snapshot == uintptr(syscall.InvalidHandle) { - err = fmt.Errorf("CreateToolhelp32Snapshot: %v", e1) - return - } - defer syscall.CloseHandle(syscall.Handle(snapshot)) - - var processEntry processEntry32 - processEntry.dwSize = uint32(unsafe.Sizeof(processEntry)) - ok, _, e1 := Process32First.Call(snapshot, uintptr(unsafe.Pointer(&processEntry))) - if ok == 0 { - err = fmt.Errorf("Process32First: %v", e1) - return - } - - for { - if processEntry.th32ProcessID == uint32(pid) { - pe = &processEntry - return - } - - ok, _, e1 = Process32Next.Call(snapshot, uintptr(unsafe.Pointer(&processEntry))) - if ok == 0 { - err = fmt.Errorf("Process32Next: %v", e1) - return - } - } -} - -func getppid() (pid int, err error) { - pe, err := getProcessEntry(os.Getpid()) - if err != nil { - return - } - - pid = int(pe.th32ParentProcessID) - return -} - -// StartedByExplorer returns true if the program was invoked by the user double-clicking -// on the executable from explorer.exe -// -// It is conservative and returns false if any of the internal calls fail. -// It does not guarantee that the program was run from a terminal. It only can tell you -// whether it was launched from explorer.exe -func StartedByExplorer() bool { - ppid, err := getppid() - if err != nil { - return false - } - - pe, err := getProcessEntry(ppid) - if err != nil { - return false - } - - name := syscall.UTF16ToString(pe.szExeFile[:]) - return name == "explorer.exe" -} diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go b/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go deleted file mode 100644 index 9a28e57c3..000000000 --- a/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go +++ /dev/null @@ -1,46 +0,0 @@ -// +build windows -// +build go1.4 - -package mousetrap - -import ( - "os" - "syscall" - "unsafe" -) - -func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) { - snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0) - if err != nil { - return nil, err - } - defer syscall.CloseHandle(snapshot) - var procEntry syscall.ProcessEntry32 - procEntry.Size = uint32(unsafe.Sizeof(procEntry)) - if err = syscall.Process32First(snapshot, &procEntry); err != nil { - return nil, err - } - for { - if procEntry.ProcessID == uint32(pid) { - return &procEntry, nil - } - err = syscall.Process32Next(snapshot, &procEntry) - if err != nil { - return nil, err - } - } -} - -// StartedByExplorer returns true if the program was invoked by the user double-clicking -// on the executable from explorer.exe -// -// It is conservative and returns false if any of the internal calls fail. -// It does not guarantee that the program was run from a terminal. It only can tell you -// whether it was launched from explorer.exe -func StartedByExplorer() bool { - pe, err := getProcessEntry(os.Getppid()) - if err != nil { - return false - } - return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:]) -} diff --git a/vendor/github.com/json-iterator/go/LICENSE b/vendor/github.com/json-iterator/go/LICENSE deleted file mode 100644 index 2cf4f5ab2..000000000 --- a/vendor/github.com/json-iterator/go/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 json-iterator - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/json-iterator/go/adapter.go b/vendor/github.com/json-iterator/go/adapter.go deleted file mode 100644 index 3a494eeb4..000000000 --- a/vendor/github.com/json-iterator/go/adapter.go +++ /dev/null @@ -1,141 +0,0 @@ -package jsoniter - -import ( - "bytes" - "io" -) - -// RawMessage to make replace json with jsoniter -type RawMessage []byte - -// Unmarshal adapts to json/encoding Unmarshal API -// -// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. -// Refer to https://godoc.org/encoding/json#Unmarshal for more information -func Unmarshal(data []byte, v interface{}) error { - return ConfigDefault.Unmarshal(data, v) -} - -// UnmarshalFromString convenient method to read from string instead of []byte -func UnmarshalFromString(str string, v interface{}) error { - return ConfigDefault.UnmarshalFromString(str, v) -} - -// Get quick method to get value from deeply nested JSON structure -func Get(data []byte, path ...interface{}) Any { - return ConfigDefault.Get(data, path...) -} - -// Marshal adapts to json/encoding Marshal API -// -// Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API -// Refer to https://godoc.org/encoding/json#Marshal for more information -func Marshal(v interface{}) ([]byte, error) { - return ConfigDefault.Marshal(v) -} - -// MarshalIndent same as json.MarshalIndent. Prefix is not supported. -func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { - return ConfigDefault.MarshalIndent(v, prefix, indent) -} - -// MarshalToString convenient method to write as string instead of []byte -func MarshalToString(v interface{}) (string, error) { - return ConfigDefault.MarshalToString(v) -} - -// NewDecoder adapts to json/stream NewDecoder API. -// -// NewDecoder returns a new decoder that reads from r. -// -// Instead of a json/encoding Decoder, an Decoder is returned -// Refer to https://godoc.org/encoding/json#NewDecoder for more information -func NewDecoder(reader io.Reader) *Decoder { - return ConfigDefault.NewDecoder(reader) -} - -// Decoder reads and decodes JSON values from an input stream. -// Decoder provides identical APIs with json/stream Decoder (Token() and UseNumber() are in progress) -type Decoder struct { - iter *Iterator -} - -// Decode decode JSON into interface{} -func (adapter *Decoder) Decode(obj interface{}) error { - if adapter.iter.head == adapter.iter.tail && adapter.iter.reader != nil { - if !adapter.iter.loadMore() { - return io.EOF - } - } - adapter.iter.ReadVal(obj) - err := adapter.iter.Error - if err == io.EOF { - return nil - } - return adapter.iter.Error -} - -// More is there more? -func (adapter *Decoder) More() bool { - return adapter.iter.head != adapter.iter.tail -} - -// Buffered remaining buffer -func (adapter *Decoder) Buffered() io.Reader { - remaining := adapter.iter.buf[adapter.iter.head:adapter.iter.tail] - return bytes.NewReader(remaining) -} - -// UseNumber causes the Decoder to unmarshal a number into an interface{} as a -// Number instead of as a float64. -func (adapter *Decoder) UseNumber() { - cfg := adapter.iter.cfg.configBeforeFrozen - cfg.UseNumber = true - adapter.iter.cfg = cfg.frozeWithCacheReuse() -} - -// DisallowUnknownFields causes the Decoder to return an error when the destination -// is a struct and the input contains object keys which do not match any -// non-ignored, exported fields in the destination. -func (adapter *Decoder) DisallowUnknownFields() { - cfg := adapter.iter.cfg.configBeforeFrozen - cfg.DisallowUnknownFields = true - adapter.iter.cfg = cfg.frozeWithCacheReuse() -} - -// NewEncoder same as json.NewEncoder -func NewEncoder(writer io.Writer) *Encoder { - return ConfigDefault.NewEncoder(writer) -} - -// Encoder same as json.Encoder -type Encoder struct { - stream *Stream -} - -// Encode encode interface{} as JSON to io.Writer -func (adapter *Encoder) Encode(val interface{}) error { - adapter.stream.WriteVal(val) - adapter.stream.WriteRaw("\n") - adapter.stream.Flush() - return adapter.stream.Error -} - -// SetIndent set the indention. Prefix is not supported -func (adapter *Encoder) SetIndent(prefix, indent string) { - config := adapter.stream.cfg.configBeforeFrozen - config.IndentionStep = len(indent) - adapter.stream.cfg = config.frozeWithCacheReuse() -} - -// SetEscapeHTML escape html by default, set to false to disable -func (adapter *Encoder) SetEscapeHTML(escapeHTML bool) { - config := adapter.stream.cfg.configBeforeFrozen - config.EscapeHTML = escapeHTML - adapter.stream.cfg = config.frozeWithCacheReuse() -} - -// Valid reports whether data is a valid JSON encoding. -func Valid(data []byte) bool { - return ConfigDefault.Valid(data) -} diff --git a/vendor/github.com/json-iterator/go/any.go b/vendor/github.com/json-iterator/go/any.go deleted file mode 100644 index daecfed61..000000000 --- a/vendor/github.com/json-iterator/go/any.go +++ /dev/null @@ -1,321 +0,0 @@ -package jsoniter - -import ( - "errors" - "fmt" - "github.com/modern-go/reflect2" - "io" - "reflect" - "strconv" - "unsafe" -) - -// Any generic object representation. -// The lazy json implementation holds []byte and parse lazily. -type Any interface { - LastError() error - ValueType() ValueType - MustBeValid() Any - ToBool() bool - ToInt() int - ToInt32() int32 - ToInt64() int64 - ToUint() uint - ToUint32() uint32 - ToUint64() uint64 - ToFloat32() float32 - ToFloat64() float64 - ToString() string - ToVal(val interface{}) - Get(path ...interface{}) Any - Size() int - Keys() []string - GetInterface() interface{} - WriteTo(stream *Stream) -} - -type baseAny struct{} - -func (any *baseAny) Get(path ...interface{}) Any { - return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} -} - -func (any *baseAny) Size() int { - return 0 -} - -func (any *baseAny) Keys() []string { - return []string{} -} - -func (any *baseAny) ToVal(obj interface{}) { - panic("not implemented") -} - -// WrapInt32 turn int32 into Any interface -func WrapInt32(val int32) Any { - return &int32Any{baseAny{}, val} -} - -// WrapInt64 turn int64 into Any interface -func WrapInt64(val int64) Any { - return &int64Any{baseAny{}, val} -} - -// WrapUint32 turn uint32 into Any interface -func WrapUint32(val uint32) Any { - return &uint32Any{baseAny{}, val} -} - -// WrapUint64 turn uint64 into Any interface -func WrapUint64(val uint64) Any { - return &uint64Any{baseAny{}, val} -} - -// WrapFloat64 turn float64 into Any interface -func WrapFloat64(val float64) Any { - return &floatAny{baseAny{}, val} -} - -// WrapString turn string into Any interface -func WrapString(val string) Any { - return &stringAny{baseAny{}, val} -} - -// Wrap turn a go object into Any interface -func Wrap(val interface{}) Any { - if val == nil { - return &nilAny{} - } - asAny, isAny := val.(Any) - if isAny { - return asAny - } - typ := reflect2.TypeOf(val) - switch typ.Kind() { - case reflect.Slice: - return wrapArray(val) - case reflect.Struct: - return wrapStruct(val) - case reflect.Map: - return wrapMap(val) - case reflect.String: - return WrapString(val.(string)) - case reflect.Int: - if strconv.IntSize == 32 { - return WrapInt32(int32(val.(int))) - } - return WrapInt64(int64(val.(int))) - case reflect.Int8: - return WrapInt32(int32(val.(int8))) - case reflect.Int16: - return WrapInt32(int32(val.(int16))) - case reflect.Int32: - return WrapInt32(val.(int32)) - case reflect.Int64: - return WrapInt64(val.(int64)) - case reflect.Uint: - if strconv.IntSize == 32 { - return WrapUint32(uint32(val.(uint))) - } - return WrapUint64(uint64(val.(uint))) - case reflect.Uintptr: - if ptrSize == 32 { - return WrapUint32(uint32(val.(uintptr))) - } - return WrapUint64(uint64(val.(uintptr))) - case reflect.Uint8: - return WrapUint32(uint32(val.(uint8))) - case reflect.Uint16: - return WrapUint32(uint32(val.(uint16))) - case reflect.Uint32: - return WrapUint32(uint32(val.(uint32))) - case reflect.Uint64: - return WrapUint64(val.(uint64)) - case reflect.Float32: - return WrapFloat64(float64(val.(float32))) - case reflect.Float64: - return WrapFloat64(val.(float64)) - case reflect.Bool: - if val.(bool) == true { - return &trueAny{} - } - return &falseAny{} - } - return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)} -} - -// ReadAny read next JSON element as an Any object. It is a better json.RawMessage. -func (iter *Iterator) ReadAny() Any { - return iter.readAny() -} - -func (iter *Iterator) readAny() Any { - c := iter.nextToken() - switch c { - case '"': - iter.unreadByte() - return &stringAny{baseAny{}, iter.ReadString()} - case 'n': - iter.skipThreeBytes('u', 'l', 'l') // null - return &nilAny{} - case 't': - iter.skipThreeBytes('r', 'u', 'e') // true - return &trueAny{} - case 'f': - iter.skipFourBytes('a', 'l', 's', 'e') // false - return &falseAny{} - case '{': - return iter.readObjectAny() - case '[': - return iter.readArrayAny() - case '-': - return iter.readNumberAny(false) - case 0: - return &invalidAny{baseAny{}, errors.New("input is empty")} - default: - return iter.readNumberAny(true) - } -} - -func (iter *Iterator) readNumberAny(positive bool) Any { - iter.startCapture(iter.head - 1) - iter.skipNumber() - lazyBuf := iter.stopCapture() - return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} -} - -func (iter *Iterator) readObjectAny() Any { - iter.startCapture(iter.head - 1) - iter.skipObject() - lazyBuf := iter.stopCapture() - return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} -} - -func (iter *Iterator) readArrayAny() Any { - iter.startCapture(iter.head - 1) - iter.skipArray() - lazyBuf := iter.stopCapture() - return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} -} - -func locateObjectField(iter *Iterator, target string) []byte { - var found []byte - iter.ReadObjectCB(func(iter *Iterator, field string) bool { - if field == target { - found = iter.SkipAndReturnBytes() - return false - } - iter.Skip() - return true - }) - return found -} - -func locateArrayElement(iter *Iterator, target int) []byte { - var found []byte - n := 0 - iter.ReadArrayCB(func(iter *Iterator) bool { - if n == target { - found = iter.SkipAndReturnBytes() - return false - } - iter.Skip() - n++ - return true - }) - return found -} - -func locatePath(iter *Iterator, path []interface{}) Any { - for i, pathKeyObj := range path { - switch pathKey := pathKeyObj.(type) { - case string: - valueBytes := locateObjectField(iter, pathKey) - if valueBytes == nil { - return newInvalidAny(path[i:]) - } - iter.ResetBytes(valueBytes) - case int: - valueBytes := locateArrayElement(iter, pathKey) - if valueBytes == nil { - return newInvalidAny(path[i:]) - } - iter.ResetBytes(valueBytes) - case int32: - if '*' == pathKey { - return iter.readAny().Get(path[i:]...) - } - return newInvalidAny(path[i:]) - default: - return newInvalidAny(path[i:]) - } - } - if iter.Error != nil && iter.Error != io.EOF { - return &invalidAny{baseAny{}, iter.Error} - } - return iter.readAny() -} - -var anyType = reflect2.TypeOfPtr((*Any)(nil)).Elem() - -func createDecoderOfAny(ctx *ctx, typ reflect2.Type) ValDecoder { - if typ == anyType { - return &directAnyCodec{} - } - if typ.Implements(anyType) { - return &anyCodec{ - valType: typ, - } - } - return nil -} - -func createEncoderOfAny(ctx *ctx, typ reflect2.Type) ValEncoder { - if typ == anyType { - return &directAnyCodec{} - } - if typ.Implements(anyType) { - return &anyCodec{ - valType: typ, - } - } - return nil -} - -type anyCodec struct { - valType reflect2.Type -} - -func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - panic("not implemented") -} - -func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - obj := codec.valType.UnsafeIndirect(ptr) - any := obj.(Any) - any.WriteTo(stream) -} - -func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool { - obj := codec.valType.UnsafeIndirect(ptr) - any := obj.(Any) - return any.Size() == 0 -} - -type directAnyCodec struct { -} - -func (codec *directAnyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *(*Any)(ptr) = iter.readAny() -} - -func (codec *directAnyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - any := *(*Any)(ptr) - any.WriteTo(stream) -} - -func (codec *directAnyCodec) IsEmpty(ptr unsafe.Pointer) bool { - any := *(*Any)(ptr) - return any.Size() == 0 -} diff --git a/vendor/github.com/json-iterator/go/any_array.go b/vendor/github.com/json-iterator/go/any_array.go deleted file mode 100644 index 0449e9aa4..000000000 --- a/vendor/github.com/json-iterator/go/any_array.go +++ /dev/null @@ -1,278 +0,0 @@ -package jsoniter - -import ( - "reflect" - "unsafe" -) - -type arrayLazyAny struct { - baseAny - cfg *frozenConfig - buf []byte - err error -} - -func (any *arrayLazyAny) ValueType() ValueType { - return ArrayValue -} - -func (any *arrayLazyAny) MustBeValid() Any { - return any -} - -func (any *arrayLazyAny) LastError() error { - return any.err -} - -func (any *arrayLazyAny) ToBool() bool { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - return iter.ReadArray() -} - -func (any *arrayLazyAny) ToInt() int { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToInt32() int32 { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToInt64() int64 { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToUint() uint { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToUint32() uint32 { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToUint64() uint64 { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToFloat32() float32 { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToFloat64() float64 { - if any.ToBool() { - return 1 - } - return 0 -} - -func (any *arrayLazyAny) ToString() string { - return *(*string)(unsafe.Pointer(&any.buf)) -} - -func (any *arrayLazyAny) ToVal(val interface{}) { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - iter.ReadVal(val) -} - -func (any *arrayLazyAny) Get(path ...interface{}) Any { - if len(path) == 0 { - return any - } - switch firstPath := path[0].(type) { - case int: - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - valueBytes := locateArrayElement(iter, firstPath) - if valueBytes == nil { - return newInvalidAny(path) - } - iter.ResetBytes(valueBytes) - return locatePath(iter, path[1:]) - case int32: - if '*' == firstPath { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - arr := make([]Any, 0) - iter.ReadArrayCB(func(iter *Iterator) bool { - found := iter.readAny().Get(path[1:]...) - if found.ValueType() != InvalidValue { - arr = append(arr, found) - } - return true - }) - return wrapArray(arr) - } - return newInvalidAny(path) - default: - return newInvalidAny(path) - } -} - -func (any *arrayLazyAny) Size() int { - size := 0 - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - iter.ReadArrayCB(func(iter *Iterator) bool { - size++ - iter.Skip() - return true - }) - return size -} - -func (any *arrayLazyAny) WriteTo(stream *Stream) { - stream.Write(any.buf) -} - -func (any *arrayLazyAny) GetInterface() interface{} { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - return iter.Read() -} - -type arrayAny struct { - baseAny - val reflect.Value -} - -func wrapArray(val interface{}) *arrayAny { - return &arrayAny{baseAny{}, reflect.ValueOf(val)} -} - -func (any *arrayAny) ValueType() ValueType { - return ArrayValue -} - -func (any *arrayAny) MustBeValid() Any { - return any -} - -func (any *arrayAny) LastError() error { - return nil -} - -func (any *arrayAny) ToBool() bool { - return any.val.Len() != 0 -} - -func (any *arrayAny) ToInt() int { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToInt32() int32 { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToInt64() int64 { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToUint() uint { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToUint32() uint32 { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToUint64() uint64 { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToFloat32() float32 { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToFloat64() float64 { - if any.val.Len() == 0 { - return 0 - } - return 1 -} - -func (any *arrayAny) ToString() string { - str, _ := MarshalToString(any.val.Interface()) - return str -} - -func (any *arrayAny) Get(path ...interface{}) Any { - if len(path) == 0 { - return any - } - switch firstPath := path[0].(type) { - case int: - if firstPath < 0 || firstPath >= any.val.Len() { - return newInvalidAny(path) - } - return Wrap(any.val.Index(firstPath).Interface()) - case int32: - if '*' == firstPath { - mappedAll := make([]Any, 0) - for i := 0; i < any.val.Len(); i++ { - mapped := Wrap(any.val.Index(i).Interface()).Get(path[1:]...) - if mapped.ValueType() != InvalidValue { - mappedAll = append(mappedAll, mapped) - } - } - return wrapArray(mappedAll) - } - return newInvalidAny(path) - default: - return newInvalidAny(path) - } -} - -func (any *arrayAny) Size() int { - return any.val.Len() -} - -func (any *arrayAny) WriteTo(stream *Stream) { - stream.WriteVal(any.val) -} - -func (any *arrayAny) GetInterface() interface{} { - return any.val.Interface() -} diff --git a/vendor/github.com/json-iterator/go/any_bool.go b/vendor/github.com/json-iterator/go/any_bool.go deleted file mode 100644 index 9452324af..000000000 --- a/vendor/github.com/json-iterator/go/any_bool.go +++ /dev/null @@ -1,137 +0,0 @@ -package jsoniter - -type trueAny struct { - baseAny -} - -func (any *trueAny) LastError() error { - return nil -} - -func (any *trueAny) ToBool() bool { - return true -} - -func (any *trueAny) ToInt() int { - return 1 -} - -func (any *trueAny) ToInt32() int32 { - return 1 -} - -func (any *trueAny) ToInt64() int64 { - return 1 -} - -func (any *trueAny) ToUint() uint { - return 1 -} - -func (any *trueAny) ToUint32() uint32 { - return 1 -} - -func (any *trueAny) ToUint64() uint64 { - return 1 -} - -func (any *trueAny) ToFloat32() float32 { - return 1 -} - -func (any *trueAny) ToFloat64() float64 { - return 1 -} - -func (any *trueAny) ToString() string { - return "true" -} - -func (any *trueAny) WriteTo(stream *Stream) { - stream.WriteTrue() -} - -func (any *trueAny) Parse() *Iterator { - return nil -} - -func (any *trueAny) GetInterface() interface{} { - return true -} - -func (any *trueAny) ValueType() ValueType { - return BoolValue -} - -func (any *trueAny) MustBeValid() Any { - return any -} - -type falseAny struct { - baseAny -} - -func (any *falseAny) LastError() error { - return nil -} - -func (any *falseAny) ToBool() bool { - return false -} - -func (any *falseAny) ToInt() int { - return 0 -} - -func (any *falseAny) ToInt32() int32 { - return 0 -} - -func (any *falseAny) ToInt64() int64 { - return 0 -} - -func (any *falseAny) ToUint() uint { - return 0 -} - -func (any *falseAny) ToUint32() uint32 { - return 0 -} - -func (any *falseAny) ToUint64() uint64 { - return 0 -} - -func (any *falseAny) ToFloat32() float32 { - return 0 -} - -func (any *falseAny) ToFloat64() float64 { - return 0 -} - -func (any *falseAny) ToString() string { - return "false" -} - -func (any *falseAny) WriteTo(stream *Stream) { - stream.WriteFalse() -} - -func (any *falseAny) Parse() *Iterator { - return nil -} - -func (any *falseAny) GetInterface() interface{} { - return false -} - -func (any *falseAny) ValueType() ValueType { - return BoolValue -} - -func (any *falseAny) MustBeValid() Any { - return any -} diff --git a/vendor/github.com/json-iterator/go/any_float.go b/vendor/github.com/json-iterator/go/any_float.go deleted file mode 100644 index 35fdb0949..000000000 --- a/vendor/github.com/json-iterator/go/any_float.go +++ /dev/null @@ -1,83 +0,0 @@ -package jsoniter - -import ( - "strconv" -) - -type floatAny struct { - baseAny - val float64 -} - -func (any *floatAny) Parse() *Iterator { - return nil -} - -func (any *floatAny) ValueType() ValueType { - return NumberValue -} - -func (any *floatAny) MustBeValid() Any { - return any -} - -func (any *floatAny) LastError() error { - return nil -} - -func (any *floatAny) ToBool() bool { - return any.ToFloat64() != 0 -} - -func (any *floatAny) ToInt() int { - return int(any.val) -} - -func (any *floatAny) ToInt32() int32 { - return int32(any.val) -} - -func (any *floatAny) ToInt64() int64 { - return int64(any.val) -} - -func (any *floatAny) ToUint() uint { - if any.val > 0 { - return uint(any.val) - } - return 0 -} - -func (any *floatAny) ToUint32() uint32 { - if any.val > 0 { - return uint32(any.val) - } - return 0 -} - -func (any *floatAny) ToUint64() uint64 { - if any.val > 0 { - return uint64(any.val) - } - return 0 -} - -func (any *floatAny) ToFloat32() float32 { - return float32(any.val) -} - -func (any *floatAny) ToFloat64() float64 { - return any.val -} - -func (any *floatAny) ToString() string { - return strconv.FormatFloat(any.val, 'E', -1, 64) -} - -func (any *floatAny) WriteTo(stream *Stream) { - stream.WriteFloat64(any.val) -} - -func (any *floatAny) GetInterface() interface{} { - return any.val -} diff --git a/vendor/github.com/json-iterator/go/any_int32.go b/vendor/github.com/json-iterator/go/any_int32.go deleted file mode 100644 index 1b56f3991..000000000 --- a/vendor/github.com/json-iterator/go/any_int32.go +++ /dev/null @@ -1,74 +0,0 @@ -package jsoniter - -import ( - "strconv" -) - -type int32Any struct { - baseAny - val int32 -} - -func (any *int32Any) LastError() error { - return nil -} - -func (any *int32Any) ValueType() ValueType { - return NumberValue -} - -func (any *int32Any) MustBeValid() Any { - return any -} - -func (any *int32Any) ToBool() bool { - return any.val != 0 -} - -func (any *int32Any) ToInt() int { - return int(any.val) -} - -func (any *int32Any) ToInt32() int32 { - return any.val -} - -func (any *int32Any) ToInt64() int64 { - return int64(any.val) -} - -func (any *int32Any) ToUint() uint { - return uint(any.val) -} - -func (any *int32Any) ToUint32() uint32 { - return uint32(any.val) -} - -func (any *int32Any) ToUint64() uint64 { - return uint64(any.val) -} - -func (any *int32Any) ToFloat32() float32 { - return float32(any.val) -} - -func (any *int32Any) ToFloat64() float64 { - return float64(any.val) -} - -func (any *int32Any) ToString() string { - return strconv.FormatInt(int64(any.val), 10) -} - -func (any *int32Any) WriteTo(stream *Stream) { - stream.WriteInt32(any.val) -} - -func (any *int32Any) Parse() *Iterator { - return nil -} - -func (any *int32Any) GetInterface() interface{} { - return any.val -} diff --git a/vendor/github.com/json-iterator/go/any_int64.go b/vendor/github.com/json-iterator/go/any_int64.go deleted file mode 100644 index c440d72b6..000000000 --- a/vendor/github.com/json-iterator/go/any_int64.go +++ /dev/null @@ -1,74 +0,0 @@ -package jsoniter - -import ( - "strconv" -) - -type int64Any struct { - baseAny - val int64 -} - -func (any *int64Any) LastError() error { - return nil -} - -func (any *int64Any) ValueType() ValueType { - return NumberValue -} - -func (any *int64Any) MustBeValid() Any { - return any -} - -func (any *int64Any) ToBool() bool { - return any.val != 0 -} - -func (any *int64Any) ToInt() int { - return int(any.val) -} - -func (any *int64Any) ToInt32() int32 { - return int32(any.val) -} - -func (any *int64Any) ToInt64() int64 { - return any.val -} - -func (any *int64Any) ToUint() uint { - return uint(any.val) -} - -func (any *int64Any) ToUint32() uint32 { - return uint32(any.val) -} - -func (any *int64Any) ToUint64() uint64 { - return uint64(any.val) -} - -func (any *int64Any) ToFloat32() float32 { - return float32(any.val) -} - -func (any *int64Any) ToFloat64() float64 { - return float64(any.val) -} - -func (any *int64Any) ToString() string { - return strconv.FormatInt(any.val, 10) -} - -func (any *int64Any) WriteTo(stream *Stream) { - stream.WriteInt64(any.val) -} - -func (any *int64Any) Parse() *Iterator { - return nil -} - -func (any *int64Any) GetInterface() interface{} { - return any.val -} diff --git a/vendor/github.com/json-iterator/go/any_invalid.go b/vendor/github.com/json-iterator/go/any_invalid.go deleted file mode 100644 index 1d859eac3..000000000 --- a/vendor/github.com/json-iterator/go/any_invalid.go +++ /dev/null @@ -1,82 +0,0 @@ -package jsoniter - -import "fmt" - -type invalidAny struct { - baseAny - err error -} - -func newInvalidAny(path []interface{}) *invalidAny { - return &invalidAny{baseAny{}, fmt.Errorf("%v not found", path)} -} - -func (any *invalidAny) LastError() error { - return any.err -} - -func (any *invalidAny) ValueType() ValueType { - return InvalidValue -} - -func (any *invalidAny) MustBeValid() Any { - panic(any.err) -} - -func (any *invalidAny) ToBool() bool { - return false -} - -func (any *invalidAny) ToInt() int { - return 0 -} - -func (any *invalidAny) ToInt32() int32 { - return 0 -} - -func (any *invalidAny) ToInt64() int64 { - return 0 -} - -func (any *invalidAny) ToUint() uint { - return 0 -} - -func (any *invalidAny) ToUint32() uint32 { - return 0 -} - -func (any *invalidAny) ToUint64() uint64 { - return 0 -} - -func (any *invalidAny) ToFloat32() float32 { - return 0 -} - -func (any *invalidAny) ToFloat64() float64 { - return 0 -} - -func (any *invalidAny) ToString() string { - return "" -} - -func (any *invalidAny) WriteTo(stream *Stream) { -} - -func (any *invalidAny) Get(path ...interface{}) Any { - if any.err == nil { - return &invalidAny{baseAny{}, fmt.Errorf("get %v from invalid", path)} - } - return &invalidAny{baseAny{}, fmt.Errorf("%v, get %v from invalid", any.err, path)} -} - -func (any *invalidAny) Parse() *Iterator { - return nil -} - -func (any *invalidAny) GetInterface() interface{} { - return nil -} diff --git a/vendor/github.com/json-iterator/go/any_nil.go b/vendor/github.com/json-iterator/go/any_nil.go deleted file mode 100644 index d04cb54c1..000000000 --- a/vendor/github.com/json-iterator/go/any_nil.go +++ /dev/null @@ -1,69 +0,0 @@ -package jsoniter - -type nilAny struct { - baseAny -} - -func (any *nilAny) LastError() error { - return nil -} - -func (any *nilAny) ValueType() ValueType { - return NilValue -} - -func (any *nilAny) MustBeValid() Any { - return any -} - -func (any *nilAny) ToBool() bool { - return false -} - -func (any *nilAny) ToInt() int { - return 0 -} - -func (any *nilAny) ToInt32() int32 { - return 0 -} - -func (any *nilAny) ToInt64() int64 { - return 0 -} - -func (any *nilAny) ToUint() uint { - return 0 -} - -func (any *nilAny) ToUint32() uint32 { - return 0 -} - -func (any *nilAny) ToUint64() uint64 { - return 0 -} - -func (any *nilAny) ToFloat32() float32 { - return 0 -} - -func (any *nilAny) ToFloat64() float64 { - return 0 -} - -func (any *nilAny) ToString() string { - return "" -} - -func (any *nilAny) WriteTo(stream *Stream) { - stream.WriteNil() -} - -func (any *nilAny) Parse() *Iterator { - return nil -} - -func (any *nilAny) GetInterface() interface{} { - return nil -} diff --git a/vendor/github.com/json-iterator/go/any_number.go b/vendor/github.com/json-iterator/go/any_number.go deleted file mode 100644 index 9d1e901a6..000000000 --- a/vendor/github.com/json-iterator/go/any_number.go +++ /dev/null @@ -1,123 +0,0 @@ -package jsoniter - -import ( - "io" - "unsafe" -) - -type numberLazyAny struct { - baseAny - cfg *frozenConfig - buf []byte - err error -} - -func (any *numberLazyAny) ValueType() ValueType { - return NumberValue -} - -func (any *numberLazyAny) MustBeValid() Any { - return any -} - -func (any *numberLazyAny) LastError() error { - return any.err -} - -func (any *numberLazyAny) ToBool() bool { - return any.ToFloat64() != 0 -} - -func (any *numberLazyAny) ToInt() int { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadInt() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToInt32() int32 { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadInt32() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToInt64() int64 { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadInt64() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToUint() uint { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadUint() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToUint32() uint32 { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadUint32() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToUint64() uint64 { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadUint64() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToFloat32() float32 { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadFloat32() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToFloat64() float64 { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - val := iter.ReadFloat64() - if iter.Error != nil && iter.Error != io.EOF { - any.err = iter.Error - } - return val -} - -func (any *numberLazyAny) ToString() string { - return *(*string)(unsafe.Pointer(&any.buf)) -} - -func (any *numberLazyAny) WriteTo(stream *Stream) { - stream.Write(any.buf) -} - -func (any *numberLazyAny) GetInterface() interface{} { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - return iter.Read() -} diff --git a/vendor/github.com/json-iterator/go/any_object.go b/vendor/github.com/json-iterator/go/any_object.go deleted file mode 100644 index c44ef5c98..000000000 --- a/vendor/github.com/json-iterator/go/any_object.go +++ /dev/null @@ -1,374 +0,0 @@ -package jsoniter - -import ( - "reflect" - "unsafe" -) - -type objectLazyAny struct { - baseAny - cfg *frozenConfig - buf []byte - err error -} - -func (any *objectLazyAny) ValueType() ValueType { - return ObjectValue -} - -func (any *objectLazyAny) MustBeValid() Any { - return any -} - -func (any *objectLazyAny) LastError() error { - return any.err -} - -func (any *objectLazyAny) ToBool() bool { - return true -} - -func (any *objectLazyAny) ToInt() int { - return 0 -} - -func (any *objectLazyAny) ToInt32() int32 { - return 0 -} - -func (any *objectLazyAny) ToInt64() int64 { - return 0 -} - -func (any *objectLazyAny) ToUint() uint { - return 0 -} - -func (any *objectLazyAny) ToUint32() uint32 { - return 0 -} - -func (any *objectLazyAny) ToUint64() uint64 { - return 0 -} - -func (any *objectLazyAny) ToFloat32() float32 { - return 0 -} - -func (any *objectLazyAny) ToFloat64() float64 { - return 0 -} - -func (any *objectLazyAny) ToString() string { - return *(*string)(unsafe.Pointer(&any.buf)) -} - -func (any *objectLazyAny) ToVal(obj interface{}) { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - iter.ReadVal(obj) -} - -func (any *objectLazyAny) Get(path ...interface{}) Any { - if len(path) == 0 { - return any - } - switch firstPath := path[0].(type) { - case string: - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - valueBytes := locateObjectField(iter, firstPath) - if valueBytes == nil { - return newInvalidAny(path) - } - iter.ResetBytes(valueBytes) - return locatePath(iter, path[1:]) - case int32: - if '*' == firstPath { - mappedAll := map[string]Any{} - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - iter.ReadMapCB(func(iter *Iterator, field string) bool { - mapped := locatePath(iter, path[1:]) - if mapped.ValueType() != InvalidValue { - mappedAll[field] = mapped - } - return true - }) - return wrapMap(mappedAll) - } - return newInvalidAny(path) - default: - return newInvalidAny(path) - } -} - -func (any *objectLazyAny) Keys() []string { - keys := []string{} - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - iter.ReadMapCB(func(iter *Iterator, field string) bool { - iter.Skip() - keys = append(keys, field) - return true - }) - return keys -} - -func (any *objectLazyAny) Size() int { - size := 0 - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - iter.ReadObjectCB(func(iter *Iterator, field string) bool { - iter.Skip() - size++ - return true - }) - return size -} - -func (any *objectLazyAny) WriteTo(stream *Stream) { - stream.Write(any.buf) -} - -func (any *objectLazyAny) GetInterface() interface{} { - iter := any.cfg.BorrowIterator(any.buf) - defer any.cfg.ReturnIterator(iter) - return iter.Read() -} - -type objectAny struct { - baseAny - err error - val reflect.Value -} - -func wrapStruct(val interface{}) *objectAny { - return &objectAny{baseAny{}, nil, reflect.ValueOf(val)} -} - -func (any *objectAny) ValueType() ValueType { - return ObjectValue -} - -func (any *objectAny) MustBeValid() Any { - return any -} - -func (any *objectAny) Parse() *Iterator { - return nil -} - -func (any *objectAny) LastError() error { - return any.err -} - -func (any *objectAny) ToBool() bool { - return any.val.NumField() != 0 -} - -func (any *objectAny) ToInt() int { - return 0 -} - -func (any *objectAny) ToInt32() int32 { - return 0 -} - -func (any *objectAny) ToInt64() int64 { - return 0 -} - -func (any *objectAny) ToUint() uint { - return 0 -} - -func (any *objectAny) ToUint32() uint32 { - return 0 -} - -func (any *objectAny) ToUint64() uint64 { - return 0 -} - -func (any *objectAny) ToFloat32() float32 { - return 0 -} - -func (any *objectAny) ToFloat64() float64 { - return 0 -} - -func (any *objectAny) ToString() string { - str, err := MarshalToString(any.val.Interface()) - any.err = err - return str -} - -func (any *objectAny) Get(path ...interface{}) Any { - if len(path) == 0 { - return any - } - switch firstPath := path[0].(type) { - case string: - field := any.val.FieldByName(firstPath) - if !field.IsValid() { - return newInvalidAny(path) - } - return Wrap(field.Interface()) - case int32: - if '*' == firstPath { - mappedAll := map[string]Any{} - for i := 0; i < any.val.NumField(); i++ { - field := any.val.Field(i) - if field.CanInterface() { - mapped := Wrap(field.Interface()).Get(path[1:]...) - if mapped.ValueType() != InvalidValue { - mappedAll[any.val.Type().Field(i).Name] = mapped - } - } - } - return wrapMap(mappedAll) - } - return newInvalidAny(path) - default: - return newInvalidAny(path) - } -} - -func (any *objectAny) Keys() []string { - keys := make([]string, 0, any.val.NumField()) - for i := 0; i < any.val.NumField(); i++ { - keys = append(keys, any.val.Type().Field(i).Name) - } - return keys -} - -func (any *objectAny) Size() int { - return any.val.NumField() -} - -func (any *objectAny) WriteTo(stream *Stream) { - stream.WriteVal(any.val) -} - -func (any *objectAny) GetInterface() interface{} { - return any.val.Interface() -} - -type mapAny struct { - baseAny - err error - val reflect.Value -} - -func wrapMap(val interface{}) *mapAny { - return &mapAny{baseAny{}, nil, reflect.ValueOf(val)} -} - -func (any *mapAny) ValueType() ValueType { - return ObjectValue -} - -func (any *mapAny) MustBeValid() Any { - return any -} - -func (any *mapAny) Parse() *Iterator { - return nil -} - -func (any *mapAny) LastError() error { - return any.err -} - -func (any *mapAny) ToBool() bool { - return true -} - -func (any *mapAny) ToInt() int { - return 0 -} - -func (any *mapAny) ToInt32() int32 { - return 0 -} - -func (any *mapAny) ToInt64() int64 { - return 0 -} - -func (any *mapAny) ToUint() uint { - return 0 -} - -func (any *mapAny) ToUint32() uint32 { - return 0 -} - -func (any *mapAny) ToUint64() uint64 { - return 0 -} - -func (any *mapAny) ToFloat32() float32 { - return 0 -} - -func (any *mapAny) ToFloat64() float64 { - return 0 -} - -func (any *mapAny) ToString() string { - str, err := MarshalToString(any.val.Interface()) - any.err = err - return str -} - -func (any *mapAny) Get(path ...interface{}) Any { - if len(path) == 0 { - return any - } - switch firstPath := path[0].(type) { - case int32: - if '*' == firstPath { - mappedAll := map[string]Any{} - for _, key := range any.val.MapKeys() { - keyAsStr := key.String() - element := Wrap(any.val.MapIndex(key).Interface()) - mapped := element.Get(path[1:]...) - if mapped.ValueType() != InvalidValue { - mappedAll[keyAsStr] = mapped - } - } - return wrapMap(mappedAll) - } - return newInvalidAny(path) - default: - value := any.val.MapIndex(reflect.ValueOf(firstPath)) - if !value.IsValid() { - return newInvalidAny(path) - } - return Wrap(value.Interface()) - } -} - -func (any *mapAny) Keys() []string { - keys := make([]string, 0, any.val.Len()) - for _, key := range any.val.MapKeys() { - keys = append(keys, key.String()) - } - return keys -} - -func (any *mapAny) Size() int { - return any.val.Len() -} - -func (any *mapAny) WriteTo(stream *Stream) { - stream.WriteVal(any.val) -} - -func (any *mapAny) GetInterface() interface{} { - return any.val.Interface() -} diff --git a/vendor/github.com/json-iterator/go/any_str.go b/vendor/github.com/json-iterator/go/any_str.go deleted file mode 100644 index a4b93c78c..000000000 --- a/vendor/github.com/json-iterator/go/any_str.go +++ /dev/null @@ -1,166 +0,0 @@ -package jsoniter - -import ( - "fmt" - "strconv" -) - -type stringAny struct { - baseAny - val string -} - -func (any *stringAny) Get(path ...interface{}) Any { - if len(path) == 0 { - return any - } - return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} -} - -func (any *stringAny) Parse() *Iterator { - return nil -} - -func (any *stringAny) ValueType() ValueType { - return StringValue -} - -func (any *stringAny) MustBeValid() Any { - return any -} - -func (any *stringAny) LastError() error { - return nil -} - -func (any *stringAny) ToBool() bool { - str := any.ToString() - if str == "0" { - return false - } - for _, c := range str { - switch c { - case ' ', '\n', '\r', '\t': - default: - return true - } - } - return false -} - -func (any *stringAny) ToInt() int { - return int(any.ToInt64()) - -} - -func (any *stringAny) ToInt32() int32 { - return int32(any.ToInt64()) -} - -func (any *stringAny) ToInt64() int64 { - if any.val == "" { - return 0 - } - - flag := 1 - startPos := 0 - endPos := 0 - if any.val[0] == '+' || any.val[0] == '-' { - startPos = 1 - } - - if any.val[0] == '-' { - flag = -1 - } - - for i := startPos; i < len(any.val); i++ { - if any.val[i] >= '0' && any.val[i] <= '9' { - endPos = i + 1 - } else { - break - } - } - parsed, _ := strconv.ParseInt(any.val[startPos:endPos], 10, 64) - return int64(flag) * parsed -} - -func (any *stringAny) ToUint() uint { - return uint(any.ToUint64()) -} - -func (any *stringAny) ToUint32() uint32 { - return uint32(any.ToUint64()) -} - -func (any *stringAny) ToUint64() uint64 { - if any.val == "" { - return 0 - } - - startPos := 0 - endPos := 0 - - if any.val[0] == '-' { - return 0 - } - if any.val[0] == '+' { - startPos = 1 - } - - for i := startPos; i < len(any.val); i++ { - if any.val[i] >= '0' && any.val[i] <= '9' { - endPos = i + 1 - } else { - break - } - } - parsed, _ := strconv.ParseUint(any.val[startPos:endPos], 10, 64) - return parsed -} - -func (any *stringAny) ToFloat32() float32 { - return float32(any.ToFloat64()) -} - -func (any *stringAny) ToFloat64() float64 { - if len(any.val) == 0 { - return 0 - } - - // first char invalid - if any.val[0] != '+' && any.val[0] != '-' && (any.val[0] > '9' || any.val[0] < '0') { - return 0 - } - - // extract valid num expression from string - // eg 123true => 123, -12.12xxa => -12.12 - endPos := 1 - for i := 1; i < len(any.val); i++ { - if any.val[i] == '.' || any.val[i] == 'e' || any.val[i] == 'E' || any.val[i] == '+' || any.val[i] == '-' { - endPos = i + 1 - continue - } - - // end position is the first char which is not digit - if any.val[i] >= '0' && any.val[i] <= '9' { - endPos = i + 1 - } else { - endPos = i - break - } - } - parsed, _ := strconv.ParseFloat(any.val[:endPos], 64) - return parsed -} - -func (any *stringAny) ToString() string { - return any.val -} - -func (any *stringAny) WriteTo(stream *Stream) { - stream.WriteString(any.val) -} - -func (any *stringAny) GetInterface() interface{} { - return any.val -} diff --git a/vendor/github.com/json-iterator/go/any_uint32.go b/vendor/github.com/json-iterator/go/any_uint32.go deleted file mode 100644 index 656bbd33d..000000000 --- a/vendor/github.com/json-iterator/go/any_uint32.go +++ /dev/null @@ -1,74 +0,0 @@ -package jsoniter - -import ( - "strconv" -) - -type uint32Any struct { - baseAny - val uint32 -} - -func (any *uint32Any) LastError() error { - return nil -} - -func (any *uint32Any) ValueType() ValueType { - return NumberValue -} - -func (any *uint32Any) MustBeValid() Any { - return any -} - -func (any *uint32Any) ToBool() bool { - return any.val != 0 -} - -func (any *uint32Any) ToInt() int { - return int(any.val) -} - -func (any *uint32Any) ToInt32() int32 { - return int32(any.val) -} - -func (any *uint32Any) ToInt64() int64 { - return int64(any.val) -} - -func (any *uint32Any) ToUint() uint { - return uint(any.val) -} - -func (any *uint32Any) ToUint32() uint32 { - return any.val -} - -func (any *uint32Any) ToUint64() uint64 { - return uint64(any.val) -} - -func (any *uint32Any) ToFloat32() float32 { - return float32(any.val) -} - -func (any *uint32Any) ToFloat64() float64 { - return float64(any.val) -} - -func (any *uint32Any) ToString() string { - return strconv.FormatInt(int64(any.val), 10) -} - -func (any *uint32Any) WriteTo(stream *Stream) { - stream.WriteUint32(any.val) -} - -func (any *uint32Any) Parse() *Iterator { - return nil -} - -func (any *uint32Any) GetInterface() interface{} { - return any.val -} diff --git a/vendor/github.com/json-iterator/go/any_uint64.go b/vendor/github.com/json-iterator/go/any_uint64.go deleted file mode 100644 index 7df2fce33..000000000 --- a/vendor/github.com/json-iterator/go/any_uint64.go +++ /dev/null @@ -1,74 +0,0 @@ -package jsoniter - -import ( - "strconv" -) - -type uint64Any struct { - baseAny - val uint64 -} - -func (any *uint64Any) LastError() error { - return nil -} - -func (any *uint64Any) ValueType() ValueType { - return NumberValue -} - -func (any *uint64Any) MustBeValid() Any { - return any -} - -func (any *uint64Any) ToBool() bool { - return any.val != 0 -} - -func (any *uint64Any) ToInt() int { - return int(any.val) -} - -func (any *uint64Any) ToInt32() int32 { - return int32(any.val) -} - -func (any *uint64Any) ToInt64() int64 { - return int64(any.val) -} - -func (any *uint64Any) ToUint() uint { - return uint(any.val) -} - -func (any *uint64Any) ToUint32() uint32 { - return uint32(any.val) -} - -func (any *uint64Any) ToUint64() uint64 { - return any.val -} - -func (any *uint64Any) ToFloat32() float32 { - return float32(any.val) -} - -func (any *uint64Any) ToFloat64() float64 { - return float64(any.val) -} - -func (any *uint64Any) ToString() string { - return strconv.FormatUint(any.val, 10) -} - -func (any *uint64Any) WriteTo(stream *Stream) { - stream.WriteUint64(any.val) -} - -func (any *uint64Any) Parse() *Iterator { - return nil -} - -func (any *uint64Any) GetInterface() interface{} { - return any.val -} diff --git a/vendor/github.com/json-iterator/go/config.go b/vendor/github.com/json-iterator/go/config.go deleted file mode 100644 index bd66947d7..000000000 --- a/vendor/github.com/json-iterator/go/config.go +++ /dev/null @@ -1,368 +0,0 @@ -package jsoniter - -import ( - "encoding/json" - "github.com/modern-go/concurrent" - "github.com/modern-go/reflect2" - "io" - "reflect" - "sync" - "unsafe" -) - -// Config customize how the API should behave. -// The API is created from Config by Froze. -type Config struct { - IndentionStep int - MarshalFloatWith6Digits bool - EscapeHTML bool - SortMapKeys bool - UseNumber bool - DisallowUnknownFields bool - TagKey string - OnlyTaggedField bool - ValidateJsonRawMessage bool - ObjectFieldMustBeSimpleString bool -} - -// API the public interface of this package. -// Primary Marshal and Unmarshal. -type API interface { - IteratorPool - StreamPool - MarshalToString(v interface{}) (string, error) - Marshal(v interface{}) ([]byte, error) - MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) - UnmarshalFromString(str string, v interface{}) error - Unmarshal(data []byte, v interface{}) error - Get(data []byte, path ...interface{}) Any - NewEncoder(writer io.Writer) *Encoder - NewDecoder(reader io.Reader) *Decoder - Valid(data []byte) bool - RegisterExtension(extension Extension) - DecoderOf(typ reflect2.Type) ValDecoder - EncoderOf(typ reflect2.Type) ValEncoder -} - -// ConfigDefault the default API -var ConfigDefault = Config{ - EscapeHTML: true, -}.Froze() - -// ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior -var ConfigCompatibleWithStandardLibrary = Config{ - EscapeHTML: true, - SortMapKeys: true, - ValidateJsonRawMessage: true, -}.Froze() - -// ConfigFastest marshals float with only 6 digits precision -var ConfigFastest = Config{ - EscapeHTML: false, - MarshalFloatWith6Digits: true, // will lose precession - ObjectFieldMustBeSimpleString: true, // do not unescape object field -}.Froze() - -type frozenConfig struct { - configBeforeFrozen Config - sortMapKeys bool - indentionStep int - objectFieldMustBeSimpleString bool - onlyTaggedField bool - disallowUnknownFields bool - decoderCache *concurrent.Map - encoderCache *concurrent.Map - extensions []Extension - streamPool *sync.Pool - iteratorPool *sync.Pool -} - -func (cfg *frozenConfig) initCache() { - cfg.decoderCache = concurrent.NewMap() - cfg.encoderCache = concurrent.NewMap() -} - -func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) { - cfg.decoderCache.Store(cacheKey, decoder) -} - -func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) { - cfg.encoderCache.Store(cacheKey, encoder) -} - -func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder { - decoder, found := cfg.decoderCache.Load(cacheKey) - if found { - return decoder.(ValDecoder) - } - return nil -} - -func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder { - encoder, found := cfg.encoderCache.Load(cacheKey) - if found { - return encoder.(ValEncoder) - } - return nil -} - -var cfgCache = concurrent.NewMap() - -func getFrozenConfigFromCache(cfg Config) *frozenConfig { - obj, found := cfgCache.Load(cfg) - if found { - return obj.(*frozenConfig) - } - return nil -} - -func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) { - cfgCache.Store(cfg, frozenConfig) -} - -// Froze forge API from config -func (cfg Config) Froze() API { - api := &frozenConfig{ - sortMapKeys: cfg.SortMapKeys, - indentionStep: cfg.IndentionStep, - objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString, - onlyTaggedField: cfg.OnlyTaggedField, - disallowUnknownFields: cfg.DisallowUnknownFields, - } - api.streamPool = &sync.Pool{ - New: func() interface{} { - return NewStream(api, nil, 512) - }, - } - api.iteratorPool = &sync.Pool{ - New: func() interface{} { - return NewIterator(api) - }, - } - api.initCache() - encoderExtension := EncoderExtension{} - decoderExtension := DecoderExtension{} - if cfg.MarshalFloatWith6Digits { - api.marshalFloatWith6Digits(encoderExtension) - } - if cfg.EscapeHTML { - api.escapeHTML(encoderExtension) - } - if cfg.UseNumber { - api.useNumber(decoderExtension) - } - if cfg.ValidateJsonRawMessage { - api.validateJsonRawMessage(encoderExtension) - } - if len(encoderExtension) > 0 { - api.extensions = append(api.extensions, encoderExtension) - } - if len(decoderExtension) > 0 { - api.extensions = append(api.extensions, decoderExtension) - } - api.configBeforeFrozen = cfg - return api -} - -func (cfg Config) frozeWithCacheReuse() *frozenConfig { - api := getFrozenConfigFromCache(cfg) - if api != nil { - return api - } - api = cfg.Froze().(*frozenConfig) - addFrozenConfigToCache(cfg, api) - return api -} - -func (cfg *frozenConfig) validateJsonRawMessage(extension EncoderExtension) { - encoder := &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) { - rawMessage := *(*json.RawMessage)(ptr) - iter := cfg.BorrowIterator([]byte(rawMessage)) - iter.Read() - if iter.Error != nil { - stream.WriteRaw("null") - } else { - cfg.ReturnIterator(iter) - stream.WriteRaw(string(rawMessage)) - } - }, func(ptr unsafe.Pointer) bool { - return false - }} - extension[reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()] = encoder - extension[reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()] = encoder -} - -func (cfg *frozenConfig) useNumber(extension DecoderExtension) { - extension[reflect2.TypeOfPtr((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) { - exitingValue := *((*interface{})(ptr)) - if exitingValue != nil && reflect.TypeOf(exitingValue).Kind() == reflect.Ptr { - iter.ReadVal(exitingValue) - return - } - if iter.WhatIsNext() == NumberValue { - *((*interface{})(ptr)) = json.Number(iter.readNumberAsString()) - } else { - *((*interface{})(ptr)) = iter.Read() - } - }} -} -func (cfg *frozenConfig) getTagKey() string { - tagKey := cfg.configBeforeFrozen.TagKey - if tagKey == "" { - return "json" - } - return tagKey -} - -func (cfg *frozenConfig) RegisterExtension(extension Extension) { - cfg.extensions = append(cfg.extensions, extension) -} - -type lossyFloat32Encoder struct { -} - -func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteFloat32Lossy(*((*float32)(ptr))) -} - -func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool { - return *((*float32)(ptr)) == 0 -} - -type lossyFloat64Encoder struct { -} - -func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteFloat64Lossy(*((*float64)(ptr))) -} - -func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool { - return *((*float64)(ptr)) == 0 -} - -// EnableLossyFloatMarshalling keeps 10**(-6) precision -// for float variables for better performance. -func (cfg *frozenConfig) marshalFloatWith6Digits(extension EncoderExtension) { - // for better performance - extension[reflect2.TypeOfPtr((*float32)(nil)).Elem()] = &lossyFloat32Encoder{} - extension[reflect2.TypeOfPtr((*float64)(nil)).Elem()] = &lossyFloat64Encoder{} -} - -type htmlEscapedStringEncoder struct { -} - -func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - str := *((*string)(ptr)) - stream.WriteStringWithHTMLEscaped(str) -} - -func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return *((*string)(ptr)) == "" -} - -func (cfg *frozenConfig) escapeHTML(encoderExtension EncoderExtension) { - encoderExtension[reflect2.TypeOfPtr((*string)(nil)).Elem()] = &htmlEscapedStringEncoder{} -} - -func (cfg *frozenConfig) cleanDecoders() { - typeDecoders = map[string]ValDecoder{} - fieldDecoders = map[string]ValDecoder{} - *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) -} - -func (cfg *frozenConfig) cleanEncoders() { - typeEncoders = map[string]ValEncoder{} - fieldEncoders = map[string]ValEncoder{} - *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) -} - -func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) { - stream := cfg.BorrowStream(nil) - defer cfg.ReturnStream(stream) - stream.WriteVal(v) - if stream.Error != nil { - return "", stream.Error - } - return string(stream.Buffer()), nil -} - -func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) { - stream := cfg.BorrowStream(nil) - defer cfg.ReturnStream(stream) - stream.WriteVal(v) - if stream.Error != nil { - return nil, stream.Error - } - result := stream.Buffer() - copied := make([]byte, len(result)) - copy(copied, result) - return copied, nil -} - -func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { - if prefix != "" { - panic("prefix is not supported") - } - for _, r := range indent { - if r != ' ' { - panic("indent can only be space") - } - } - newCfg := cfg.configBeforeFrozen - newCfg.IndentionStep = len(indent) - return newCfg.frozeWithCacheReuse().Marshal(v) -} - -func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error { - data := []byte(str) - iter := cfg.BorrowIterator(data) - defer cfg.ReturnIterator(iter) - iter.ReadVal(v) - c := iter.nextToken() - if c == 0 { - if iter.Error == io.EOF { - return nil - } - return iter.Error - } - iter.ReportError("Unmarshal", "there are bytes left after unmarshal") - return iter.Error -} - -func (cfg *frozenConfig) Get(data []byte, path ...interface{}) Any { - iter := cfg.BorrowIterator(data) - defer cfg.ReturnIterator(iter) - return locatePath(iter, path) -} - -func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error { - iter := cfg.BorrowIterator(data) - defer cfg.ReturnIterator(iter) - iter.ReadVal(v) - c := iter.nextToken() - if c == 0 { - if iter.Error == io.EOF { - return nil - } - return iter.Error - } - iter.ReportError("Unmarshal", "there are bytes left after unmarshal") - return iter.Error -} - -func (cfg *frozenConfig) NewEncoder(writer io.Writer) *Encoder { - stream := NewStream(cfg, writer, 512) - return &Encoder{stream} -} - -func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder { - iter := Parse(cfg, reader, 512) - return &Decoder{iter} -} - -func (cfg *frozenConfig) Valid(data []byte) bool { - iter := cfg.BorrowIterator(data) - defer cfg.ReturnIterator(iter) - iter.Skip() - return iter.Error == nil -} diff --git a/vendor/github.com/json-iterator/go/iter.go b/vendor/github.com/json-iterator/go/iter.go deleted file mode 100644 index 95ae54fbf..000000000 --- a/vendor/github.com/json-iterator/go/iter.go +++ /dev/null @@ -1,322 +0,0 @@ -package jsoniter - -import ( - "encoding/json" - "fmt" - "io" -) - -// ValueType the type for JSON element -type ValueType int - -const ( - // InvalidValue invalid JSON element - InvalidValue ValueType = iota - // StringValue JSON element "string" - StringValue - // NumberValue JSON element 100 or 0.10 - NumberValue - // NilValue JSON element null - NilValue - // BoolValue JSON element true or false - BoolValue - // ArrayValue JSON element [] - ArrayValue - // ObjectValue JSON element {} - ObjectValue -) - -var hexDigits []byte -var valueTypes []ValueType - -func init() { - hexDigits = make([]byte, 256) - for i := 0; i < len(hexDigits); i++ { - hexDigits[i] = 255 - } - for i := '0'; i <= '9'; i++ { - hexDigits[i] = byte(i - '0') - } - for i := 'a'; i <= 'f'; i++ { - hexDigits[i] = byte((i - 'a') + 10) - } - for i := 'A'; i <= 'F'; i++ { - hexDigits[i] = byte((i - 'A') + 10) - } - valueTypes = make([]ValueType, 256) - for i := 0; i < len(valueTypes); i++ { - valueTypes[i] = InvalidValue - } - valueTypes['"'] = StringValue - valueTypes['-'] = NumberValue - valueTypes['0'] = NumberValue - valueTypes['1'] = NumberValue - valueTypes['2'] = NumberValue - valueTypes['3'] = NumberValue - valueTypes['4'] = NumberValue - valueTypes['5'] = NumberValue - valueTypes['6'] = NumberValue - valueTypes['7'] = NumberValue - valueTypes['8'] = NumberValue - valueTypes['9'] = NumberValue - valueTypes['t'] = BoolValue - valueTypes['f'] = BoolValue - valueTypes['n'] = NilValue - valueTypes['['] = ArrayValue - valueTypes['{'] = ObjectValue -} - -// Iterator is a io.Reader like object, with JSON specific read functions. -// Error is not returned as return value, but stored as Error member on this iterator instance. -type Iterator struct { - cfg *frozenConfig - reader io.Reader - buf []byte - head int - tail int - captureStartedAt int - captured []byte - Error error - Attachment interface{} // open for customized decoder -} - -// NewIterator creates an empty Iterator instance -func NewIterator(cfg API) *Iterator { - return &Iterator{ - cfg: cfg.(*frozenConfig), - reader: nil, - buf: nil, - head: 0, - tail: 0, - } -} - -// Parse creates an Iterator instance from io.Reader -func Parse(cfg API, reader io.Reader, bufSize int) *Iterator { - return &Iterator{ - cfg: cfg.(*frozenConfig), - reader: reader, - buf: make([]byte, bufSize), - head: 0, - tail: 0, - } -} - -// ParseBytes creates an Iterator instance from byte array -func ParseBytes(cfg API, input []byte) *Iterator { - return &Iterator{ - cfg: cfg.(*frozenConfig), - reader: nil, - buf: input, - head: 0, - tail: len(input), - } -} - -// ParseString creates an Iterator instance from string -func ParseString(cfg API, input string) *Iterator { - return ParseBytes(cfg, []byte(input)) -} - -// Pool returns a pool can provide more iterator with same configuration -func (iter *Iterator) Pool() IteratorPool { - return iter.cfg -} - -// Reset reuse iterator instance by specifying another reader -func (iter *Iterator) Reset(reader io.Reader) *Iterator { - iter.reader = reader - iter.head = 0 - iter.tail = 0 - return iter -} - -// ResetBytes reuse iterator instance by specifying another byte array as input -func (iter *Iterator) ResetBytes(input []byte) *Iterator { - iter.reader = nil - iter.buf = input - iter.head = 0 - iter.tail = len(input) - return iter -} - -// WhatIsNext gets ValueType of relatively next json element -func (iter *Iterator) WhatIsNext() ValueType { - valueType := valueTypes[iter.nextToken()] - iter.unreadByte() - return valueType -} - -func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool { - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - switch c { - case ' ', '\n', '\t', '\r': - continue - } - iter.head = i - return false - } - return true -} - -func (iter *Iterator) isObjectEnd() bool { - c := iter.nextToken() - if c == ',' { - return false - } - if c == '}' { - return true - } - iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c})) - return true -} - -func (iter *Iterator) nextToken() byte { - // a variation of skip whitespaces, returning the next non-whitespace token - for { - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - switch c { - case ' ', '\n', '\t', '\r': - continue - } - iter.head = i + 1 - return c - } - if !iter.loadMore() { - return 0 - } - } -} - -// ReportError record a error in iterator instance with current position. -func (iter *Iterator) ReportError(operation string, msg string) { - if iter.Error != nil { - if iter.Error != io.EOF { - return - } - } - peekStart := iter.head - 10 - if peekStart < 0 { - peekStart = 0 - } - peekEnd := iter.head + 10 - if peekEnd > iter.tail { - peekEnd = iter.tail - } - parsing := string(iter.buf[peekStart:peekEnd]) - contextStart := iter.head - 50 - if contextStart < 0 { - contextStart = 0 - } - contextEnd := iter.head + 50 - if contextEnd > iter.tail { - contextEnd = iter.tail - } - context := string(iter.buf[contextStart:contextEnd]) - iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...", - operation, msg, iter.head-peekStart, parsing, context) -} - -// CurrentBuffer gets current buffer as string for debugging purpose -func (iter *Iterator) CurrentBuffer() string { - peekStart := iter.head - 10 - if peekStart < 0 { - peekStart = 0 - } - return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head, - string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail])) -} - -func (iter *Iterator) readByte() (ret byte) { - if iter.head == iter.tail { - if iter.loadMore() { - ret = iter.buf[iter.head] - iter.head++ - return ret - } - return 0 - } - ret = iter.buf[iter.head] - iter.head++ - return ret -} - -func (iter *Iterator) loadMore() bool { - if iter.reader == nil { - if iter.Error == nil { - iter.head = iter.tail - iter.Error = io.EOF - } - return false - } - if iter.captured != nil { - iter.captured = append(iter.captured, - iter.buf[iter.captureStartedAt:iter.tail]...) - iter.captureStartedAt = 0 - } - for { - n, err := iter.reader.Read(iter.buf) - if n == 0 { - if err != nil { - if iter.Error == nil { - iter.Error = err - } - return false - } - } else { - iter.head = 0 - iter.tail = n - return true - } - } -} - -func (iter *Iterator) unreadByte() { - if iter.Error != nil { - return - } - iter.head-- - return -} - -// Read read the next JSON element as generic interface{}. -func (iter *Iterator) Read() interface{} { - valueType := iter.WhatIsNext() - switch valueType { - case StringValue: - return iter.ReadString() - case NumberValue: - if iter.cfg.configBeforeFrozen.UseNumber { - return json.Number(iter.readNumberAsString()) - } - return iter.ReadFloat64() - case NilValue: - iter.skipFourBytes('n', 'u', 'l', 'l') - return nil - case BoolValue: - return iter.ReadBool() - case ArrayValue: - arr := []interface{}{} - iter.ReadArrayCB(func(iter *Iterator) bool { - var elem interface{} - iter.ReadVal(&elem) - arr = append(arr, elem) - return true - }) - return arr - case ObjectValue: - obj := map[string]interface{}{} - iter.ReadMapCB(func(Iter *Iterator, field string) bool { - var elem interface{} - iter.ReadVal(&elem) - obj[field] = elem - return true - }) - return obj - default: - iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType)) - return nil - } -} diff --git a/vendor/github.com/json-iterator/go/iter_array.go b/vendor/github.com/json-iterator/go/iter_array.go deleted file mode 100644 index 6188cb457..000000000 --- a/vendor/github.com/json-iterator/go/iter_array.go +++ /dev/null @@ -1,58 +0,0 @@ -package jsoniter - -// ReadArray read array element, tells if the array has more element to read. -func (iter *Iterator) ReadArray() (ret bool) { - c := iter.nextToken() - switch c { - case 'n': - iter.skipThreeBytes('u', 'l', 'l') - return false // null - case '[': - c = iter.nextToken() - if c != ']' { - iter.unreadByte() - return true - } - return false - case ']': - return false - case ',': - return true - default: - iter.ReportError("ReadArray", "expect [ or , or ] or n, but found "+string([]byte{c})) - return - } -} - -// ReadArrayCB read array with callback -func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) { - c := iter.nextToken() - if c == '[' { - c = iter.nextToken() - if c != ']' { - iter.unreadByte() - if !callback(iter) { - return false - } - c = iter.nextToken() - for c == ',' { - if !callback(iter) { - return false - } - c = iter.nextToken() - } - if c != ']' { - iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c})) - return false - } - return true - } - return true - } - if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - return true // null - } - iter.ReportError("ReadArrayCB", "expect [ or n, but found "+string([]byte{c})) - return false -} diff --git a/vendor/github.com/json-iterator/go/iter_float.go b/vendor/github.com/json-iterator/go/iter_float.go deleted file mode 100644 index 4f883c095..000000000 --- a/vendor/github.com/json-iterator/go/iter_float.go +++ /dev/null @@ -1,347 +0,0 @@ -package jsoniter - -import ( - "encoding/json" - "io" - "math/big" - "strconv" - "strings" - "unsafe" -) - -var floatDigits []int8 - -const invalidCharForNumber = int8(-1) -const endOfNumber = int8(-2) -const dotInNumber = int8(-3) - -func init() { - floatDigits = make([]int8, 256) - for i := 0; i < len(floatDigits); i++ { - floatDigits[i] = invalidCharForNumber - } - for i := int8('0'); i <= int8('9'); i++ { - floatDigits[i] = i - int8('0') - } - floatDigits[','] = endOfNumber - floatDigits[']'] = endOfNumber - floatDigits['}'] = endOfNumber - floatDigits[' '] = endOfNumber - floatDigits['\t'] = endOfNumber - floatDigits['\n'] = endOfNumber - floatDigits['.'] = dotInNumber -} - -// ReadBigFloat read big.Float -func (iter *Iterator) ReadBigFloat() (ret *big.Float) { - str := iter.readNumberAsString() - if iter.Error != nil && iter.Error != io.EOF { - return nil - } - prec := 64 - if len(str) > prec { - prec = len(str) - } - val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero) - if err != nil { - iter.Error = err - return nil - } - return val -} - -// ReadBigInt read big.Int -func (iter *Iterator) ReadBigInt() (ret *big.Int) { - str := iter.readNumberAsString() - if iter.Error != nil && iter.Error != io.EOF { - return nil - } - ret = big.NewInt(0) - var success bool - ret, success = ret.SetString(str, 10) - if !success { - iter.ReportError("ReadBigInt", "invalid big int") - return nil - } - return ret -} - -//ReadFloat32 read float32 -func (iter *Iterator) ReadFloat32() (ret float32) { - c := iter.nextToken() - if c == '-' { - return -iter.readPositiveFloat32() - } - iter.unreadByte() - return iter.readPositiveFloat32() -} - -func (iter *Iterator) readPositiveFloat32() (ret float32) { - value := uint64(0) - c := byte(' ') - i := iter.head - // first char - if i == iter.tail { - return iter.readFloat32SlowPath() - } - c = iter.buf[i] - i++ - ind := floatDigits[c] - switch ind { - case invalidCharForNumber: - return iter.readFloat32SlowPath() - case endOfNumber: - iter.ReportError("readFloat32", "empty number") - return - case dotInNumber: - iter.ReportError("readFloat32", "leading dot is invalid") - return - case 0: - if i == iter.tail { - return iter.readFloat32SlowPath() - } - c = iter.buf[i] - switch c { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - iter.ReportError("readFloat32", "leading zero is invalid") - return - } - } - value = uint64(ind) - // chars before dot -non_decimal_loop: - for ; i < iter.tail; i++ { - c = iter.buf[i] - ind := floatDigits[c] - switch ind { - case invalidCharForNumber: - return iter.readFloat32SlowPath() - case endOfNumber: - iter.head = i - return float32(value) - case dotInNumber: - break non_decimal_loop - } - if value > uint64SafeToMultiple10 { - return iter.readFloat32SlowPath() - } - value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; - } - // chars after dot - if c == '.' { - i++ - decimalPlaces := 0 - if i == iter.tail { - return iter.readFloat32SlowPath() - } - for ; i < iter.tail; i++ { - c = iter.buf[i] - ind := floatDigits[c] - switch ind { - case endOfNumber: - if decimalPlaces > 0 && decimalPlaces < len(pow10) { - iter.head = i - return float32(float64(value) / float64(pow10[decimalPlaces])) - } - // too many decimal places - return iter.readFloat32SlowPath() - case invalidCharForNumber: - fallthrough - case dotInNumber: - return iter.readFloat32SlowPath() - } - decimalPlaces++ - if value > uint64SafeToMultiple10 { - return iter.readFloat32SlowPath() - } - value = (value << 3) + (value << 1) + uint64(ind) - } - } - return iter.readFloat32SlowPath() -} - -func (iter *Iterator) readNumberAsString() (ret string) { - strBuf := [16]byte{} - str := strBuf[0:0] -load_loop: - for { - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - switch c { - case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - str = append(str, c) - continue - default: - iter.head = i - break load_loop - } - } - if !iter.loadMore() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF { - return - } - if len(str) == 0 { - iter.ReportError("readNumberAsString", "invalid number") - } - return *(*string)(unsafe.Pointer(&str)) -} - -func (iter *Iterator) readFloat32SlowPath() (ret float32) { - str := iter.readNumberAsString() - if iter.Error != nil && iter.Error != io.EOF { - return - } - errMsg := validateFloat(str) - if errMsg != "" { - iter.ReportError("readFloat32SlowPath", errMsg) - return - } - val, err := strconv.ParseFloat(str, 32) - if err != nil { - iter.Error = err - return - } - return float32(val) -} - -// ReadFloat64 read float64 -func (iter *Iterator) ReadFloat64() (ret float64) { - c := iter.nextToken() - if c == '-' { - return -iter.readPositiveFloat64() - } - iter.unreadByte() - return iter.readPositiveFloat64() -} - -func (iter *Iterator) readPositiveFloat64() (ret float64) { - value := uint64(0) - c := byte(' ') - i := iter.head - // first char - if i == iter.tail { - return iter.readFloat64SlowPath() - } - c = iter.buf[i] - i++ - ind := floatDigits[c] - switch ind { - case invalidCharForNumber: - return iter.readFloat64SlowPath() - case endOfNumber: - iter.ReportError("readFloat64", "empty number") - return - case dotInNumber: - iter.ReportError("readFloat64", "leading dot is invalid") - return - case 0: - if i == iter.tail { - return iter.readFloat64SlowPath() - } - c = iter.buf[i] - switch c { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - iter.ReportError("readFloat64", "leading zero is invalid") - return - } - } - value = uint64(ind) - // chars before dot -non_decimal_loop: - for ; i < iter.tail; i++ { - c = iter.buf[i] - ind := floatDigits[c] - switch ind { - case invalidCharForNumber: - return iter.readFloat64SlowPath() - case endOfNumber: - iter.head = i - return float64(value) - case dotInNumber: - break non_decimal_loop - } - if value > uint64SafeToMultiple10 { - return iter.readFloat64SlowPath() - } - value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; - } - // chars after dot - if c == '.' { - i++ - decimalPlaces := 0 - if i == iter.tail { - return iter.readFloat64SlowPath() - } - for ; i < iter.tail; i++ { - c = iter.buf[i] - ind := floatDigits[c] - switch ind { - case endOfNumber: - if decimalPlaces > 0 && decimalPlaces < len(pow10) { - iter.head = i - return float64(value) / float64(pow10[decimalPlaces]) - } - // too many decimal places - return iter.readFloat64SlowPath() - case invalidCharForNumber: - fallthrough - case dotInNumber: - return iter.readFloat64SlowPath() - } - decimalPlaces++ - if value > uint64SafeToMultiple10 { - return iter.readFloat64SlowPath() - } - value = (value << 3) + (value << 1) + uint64(ind) - } - } - return iter.readFloat64SlowPath() -} - -func (iter *Iterator) readFloat64SlowPath() (ret float64) { - str := iter.readNumberAsString() - if iter.Error != nil && iter.Error != io.EOF { - return - } - errMsg := validateFloat(str) - if errMsg != "" { - iter.ReportError("readFloat64SlowPath", errMsg) - return - } - val, err := strconv.ParseFloat(str, 64) - if err != nil { - iter.Error = err - return - } - return val -} - -func validateFloat(str string) string { - // strconv.ParseFloat is not validating `1.` or `1.e1` - if len(str) == 0 { - return "empty number" - } - if str[0] == '-' { - return "-- is not valid" - } - dotPos := strings.IndexByte(str, '.') - if dotPos != -1 { - if dotPos == len(str)-1 { - return "dot can not be last character" - } - switch str[dotPos+1] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - default: - return "missing digit after dot" - } - } - return "" -} - -// ReadNumber read json.Number -func (iter *Iterator) ReadNumber() (ret json.Number) { - return json.Number(iter.readNumberAsString()) -} diff --git a/vendor/github.com/json-iterator/go/iter_int.go b/vendor/github.com/json-iterator/go/iter_int.go deleted file mode 100644 index 214232035..000000000 --- a/vendor/github.com/json-iterator/go/iter_int.go +++ /dev/null @@ -1,345 +0,0 @@ -package jsoniter - -import ( - "math" - "strconv" -) - -var intDigits []int8 - -const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1 -const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1 - -func init() { - intDigits = make([]int8, 256) - for i := 0; i < len(intDigits); i++ { - intDigits[i] = invalidCharForNumber - } - for i := int8('0'); i <= int8('9'); i++ { - intDigits[i] = i - int8('0') - } -} - -// ReadUint read uint -func (iter *Iterator) ReadUint() uint { - if strconv.IntSize == 32 { - return uint(iter.ReadUint32()) - } - return uint(iter.ReadUint64()) -} - -// ReadInt read int -func (iter *Iterator) ReadInt() int { - if strconv.IntSize == 32 { - return int(iter.ReadInt32()) - } - return int(iter.ReadInt64()) -} - -// ReadInt8 read int8 -func (iter *Iterator) ReadInt8() (ret int8) { - c := iter.nextToken() - if c == '-' { - val := iter.readUint32(iter.readByte()) - if val > math.MaxInt8+1 { - iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return -int8(val) - } - val := iter.readUint32(c) - if val > math.MaxInt8 { - iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return int8(val) -} - -// ReadUint8 read uint8 -func (iter *Iterator) ReadUint8() (ret uint8) { - val := iter.readUint32(iter.nextToken()) - if val > math.MaxUint8 { - iter.ReportError("ReadUint8", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return uint8(val) -} - -// ReadInt16 read int16 -func (iter *Iterator) ReadInt16() (ret int16) { - c := iter.nextToken() - if c == '-' { - val := iter.readUint32(iter.readByte()) - if val > math.MaxInt16+1 { - iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return -int16(val) - } - val := iter.readUint32(c) - if val > math.MaxInt16 { - iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return int16(val) -} - -// ReadUint16 read uint16 -func (iter *Iterator) ReadUint16() (ret uint16) { - val := iter.readUint32(iter.nextToken()) - if val > math.MaxUint16 { - iter.ReportError("ReadUint16", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return uint16(val) -} - -// ReadInt32 read int32 -func (iter *Iterator) ReadInt32() (ret int32) { - c := iter.nextToken() - if c == '-' { - val := iter.readUint32(iter.readByte()) - if val > math.MaxInt32+1 { - iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return -int32(val) - } - val := iter.readUint32(c) - if val > math.MaxInt32 { - iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) - return - } - return int32(val) -} - -// ReadUint32 read uint32 -func (iter *Iterator) ReadUint32() (ret uint32) { - return iter.readUint32(iter.nextToken()) -} - -func (iter *Iterator) readUint32(c byte) (ret uint32) { - ind := intDigits[c] - if ind == 0 { - iter.assertInteger() - return 0 // single zero - } - if ind == invalidCharForNumber { - iter.ReportError("readUint32", "unexpected character: "+string([]byte{byte(ind)})) - return - } - value := uint32(ind) - if iter.tail-iter.head > 10 { - i := iter.head - ind2 := intDigits[iter.buf[i]] - if ind2 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value - } - i++ - ind3 := intDigits[iter.buf[i]] - if ind3 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*10 + uint32(ind2) - } - //iter.head = i + 1 - //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) - i++ - ind4 := intDigits[iter.buf[i]] - if ind4 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*100 + uint32(ind2)*10 + uint32(ind3) - } - i++ - ind5 := intDigits[iter.buf[i]] - if ind5 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4) - } - i++ - ind6 := intDigits[iter.buf[i]] - if ind6 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5) - } - i++ - ind7 := intDigits[iter.buf[i]] - if ind7 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6) - } - i++ - ind8 := intDigits[iter.buf[i]] - if ind8 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7) - } - i++ - ind9 := intDigits[iter.buf[i]] - value = value*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8) - iter.head = i - if ind9 == invalidCharForNumber { - iter.assertInteger() - return value - } - } - for { - for i := iter.head; i < iter.tail; i++ { - ind = intDigits[iter.buf[i]] - if ind == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value - } - if value > uint32SafeToMultiply10 { - value2 := (value << 3) + (value << 1) + uint32(ind) - if value2 < value { - iter.ReportError("readUint32", "overflow") - return - } - value = value2 - continue - } - value = (value << 3) + (value << 1) + uint32(ind) - } - if !iter.loadMore() { - iter.assertInteger() - return value - } - } -} - -// ReadInt64 read int64 -func (iter *Iterator) ReadInt64() (ret int64) { - c := iter.nextToken() - if c == '-' { - val := iter.readUint64(iter.readByte()) - if val > math.MaxInt64+1 { - iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) - return - } - return -int64(val) - } - val := iter.readUint64(c) - if val > math.MaxInt64 { - iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) - return - } - return int64(val) -} - -// ReadUint64 read uint64 -func (iter *Iterator) ReadUint64() uint64 { - return iter.readUint64(iter.nextToken()) -} - -func (iter *Iterator) readUint64(c byte) (ret uint64) { - ind := intDigits[c] - if ind == 0 { - iter.assertInteger() - return 0 // single zero - } - if ind == invalidCharForNumber { - iter.ReportError("readUint64", "unexpected character: "+string([]byte{byte(ind)})) - return - } - value := uint64(ind) - if iter.tail-iter.head > 10 { - i := iter.head - ind2 := intDigits[iter.buf[i]] - if ind2 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value - } - i++ - ind3 := intDigits[iter.buf[i]] - if ind3 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*10 + uint64(ind2) - } - //iter.head = i + 1 - //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) - i++ - ind4 := intDigits[iter.buf[i]] - if ind4 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*100 + uint64(ind2)*10 + uint64(ind3) - } - i++ - ind5 := intDigits[iter.buf[i]] - if ind5 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4) - } - i++ - ind6 := intDigits[iter.buf[i]] - if ind6 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5) - } - i++ - ind7 := intDigits[iter.buf[i]] - if ind7 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6) - } - i++ - ind8 := intDigits[iter.buf[i]] - if ind8 == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7) - } - i++ - ind9 := intDigits[iter.buf[i]] - value = value*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8) - iter.head = i - if ind9 == invalidCharForNumber { - iter.assertInteger() - return value - } - } - for { - for i := iter.head; i < iter.tail; i++ { - ind = intDigits[iter.buf[i]] - if ind == invalidCharForNumber { - iter.head = i - iter.assertInteger() - return value - } - if value > uint64SafeToMultiple10 { - value2 := (value << 3) + (value << 1) + uint64(ind) - if value2 < value { - iter.ReportError("readUint64", "overflow") - return - } - value = value2 - continue - } - value = (value << 3) + (value << 1) + uint64(ind) - } - if !iter.loadMore() { - iter.assertInteger() - return value - } - } -} - -func (iter *Iterator) assertInteger() { - if iter.head < len(iter.buf) && iter.buf[iter.head] == '.' { - iter.ReportError("assertInteger", "can not decode float as int") - } -} diff --git a/vendor/github.com/json-iterator/go/iter_object.go b/vendor/github.com/json-iterator/go/iter_object.go deleted file mode 100644 index ebd3da895..000000000 --- a/vendor/github.com/json-iterator/go/iter_object.go +++ /dev/null @@ -1,248 +0,0 @@ -package jsoniter - -import ( - "fmt" - "unicode" -) - -// ReadObject read one field from object. -// If object ended, returns empty string. -// Otherwise, returns the field name. -func (iter *Iterator) ReadObject() (ret string) { - c := iter.nextToken() - switch c { - case 'n': - iter.skipThreeBytes('u', 'l', 'l') - return "" // null - case '{': - c = iter.nextToken() - if c == '"' { - iter.unreadByte() - field := iter.ReadString() - c = iter.nextToken() - if c != ':' { - iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) - } - return field - } - if c == '}' { - return "" // end of object - } - iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c})) - return - case ',': - field := iter.ReadString() - c = iter.nextToken() - if c != ':' { - iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) - } - return field - case '}': - return "" // end of object - default: - iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c}))) - return - } -} - -// CaseInsensitive -func (iter *Iterator) readFieldHash() int64 { - hash := int64(0x811c9dc5) - c := iter.nextToken() - if c != '"' { - iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c})) - return 0 - } - for { - for i := iter.head; i < iter.tail; i++ { - // require ascii string and no escape - b := iter.buf[i] - if b == '\\' { - iter.head = i - for _, b := range iter.readStringSlowPath() { - if 'A' <= b && b <= 'Z' { - b += 'a' - 'A' - } - hash ^= int64(b) - hash *= 0x1000193 - } - c = iter.nextToken() - if c != ':' { - iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) - return 0 - } - return hash - } - if b == '"' { - iter.head = i + 1 - c = iter.nextToken() - if c != ':' { - iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) - return 0 - } - return hash - } - if 'A' <= b && b <= 'Z' { - b += 'a' - 'A' - } - hash ^= int64(b) - hash *= 0x1000193 - } - if !iter.loadMore() { - iter.ReportError("readFieldHash", `incomplete field name`) - return 0 - } - } -} - -func calcHash(str string) int64 { - hash := int64(0x811c9dc5) - for _, b := range str { - hash ^= int64(unicode.ToLower(b)) - hash *= 0x1000193 - } - return int64(hash) -} - -// ReadObjectCB read object with callback, the key is ascii only and field name not copied -func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool { - c := iter.nextToken() - var field string - if c == '{' { - c = iter.nextToken() - if c == '"' { - iter.unreadByte() - field = iter.ReadString() - c = iter.nextToken() - if c != ':' { - iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) - } - if !callback(iter, field) { - return false - } - c = iter.nextToken() - for c == ',' { - field = iter.ReadString() - c = iter.nextToken() - if c != ':' { - iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) - } - if !callback(iter, field) { - return false - } - c = iter.nextToken() - } - if c != '}' { - iter.ReportError("ReadObjectCB", `object not ended with }`) - return false - } - return true - } - if c == '}' { - return true - } - iter.ReportError("ReadObjectCB", `expect " after }, but found `+string([]byte{c})) - return false - } - if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - return true // null - } - iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c})) - return false -} - -// ReadMapCB read map with callback, the key can be any string -func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { - c := iter.nextToken() - if c == '{' { - c = iter.nextToken() - if c == '"' { - iter.unreadByte() - field := iter.ReadString() - if iter.nextToken() != ':' { - iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) - return false - } - if !callback(iter, field) { - return false - } - c = iter.nextToken() - for c == ',' { - field = iter.ReadString() - if iter.nextToken() != ':' { - iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) - return false - } - if !callback(iter, field) { - return false - } - c = iter.nextToken() - } - if c != '}' { - iter.ReportError("ReadMapCB", `object not ended with }`) - return false - } - return true - } - if c == '}' { - return true - } - iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c})) - return false - } - if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - return true // null - } - iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) - return false -} - -func (iter *Iterator) readObjectStart() bool { - c := iter.nextToken() - if c == '{' { - c = iter.nextToken() - if c == '}' { - return false - } - iter.unreadByte() - return true - } else if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - return false - } - iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c})) - return false -} - -func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) { - str := iter.ReadStringAsSlice() - if iter.skipWhitespacesWithoutLoadMore() { - if ret == nil { - ret = make([]byte, len(str)) - copy(ret, str) - } - if !iter.loadMore() { - return - } - } - if iter.buf[iter.head] != ':' { - iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]})) - return - } - iter.head++ - if iter.skipWhitespacesWithoutLoadMore() { - if ret == nil { - ret = make([]byte, len(str)) - copy(ret, str) - } - if !iter.loadMore() { - return - } - } - if ret == nil { - return str - } - return ret -} diff --git a/vendor/github.com/json-iterator/go/iter_skip.go b/vendor/github.com/json-iterator/go/iter_skip.go deleted file mode 100644 index f58beb913..000000000 --- a/vendor/github.com/json-iterator/go/iter_skip.go +++ /dev/null @@ -1,129 +0,0 @@ -package jsoniter - -import "fmt" - -// ReadNil reads a json object as nil and -// returns whether it's a nil or not -func (iter *Iterator) ReadNil() (ret bool) { - c := iter.nextToken() - if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') // null - return true - } - iter.unreadByte() - return false -} - -// ReadBool reads a json object as BoolValue -func (iter *Iterator) ReadBool() (ret bool) { - c := iter.nextToken() - if c == 't' { - iter.skipThreeBytes('r', 'u', 'e') - return true - } - if c == 'f' { - iter.skipFourBytes('a', 'l', 's', 'e') - return false - } - iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c})) - return -} - -// SkipAndReturnBytes skip next JSON element, and return its content as []byte. -// The []byte can be kept, it is a copy of data. -func (iter *Iterator) SkipAndReturnBytes() []byte { - iter.startCapture(iter.head) - iter.Skip() - return iter.stopCapture() -} - -type captureBuffer struct { - startedAt int - captured []byte -} - -func (iter *Iterator) startCapture(captureStartedAt int) { - if iter.captured != nil { - panic("already in capture mode") - } - iter.captureStartedAt = captureStartedAt - iter.captured = make([]byte, 0, 32) -} - -func (iter *Iterator) stopCapture() []byte { - if iter.captured == nil { - panic("not in capture mode") - } - captured := iter.captured - remaining := iter.buf[iter.captureStartedAt:iter.head] - iter.captureStartedAt = -1 - iter.captured = nil - if len(captured) == 0 { - copied := make([]byte, len(remaining)) - copy(copied, remaining) - return copied - } - captured = append(captured, remaining...) - return captured -} - -// Skip skips a json object and positions to relatively the next json object -func (iter *Iterator) Skip() { - c := iter.nextToken() - switch c { - case '"': - iter.skipString() - case 'n': - iter.skipThreeBytes('u', 'l', 'l') // null - case 't': - iter.skipThreeBytes('r', 'u', 'e') // true - case 'f': - iter.skipFourBytes('a', 'l', 's', 'e') // false - case '0': - iter.unreadByte() - iter.ReadFloat32() - case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9': - iter.skipNumber() - case '[': - iter.skipArray() - case '{': - iter.skipObject() - default: - iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c)) - return - } -} - -func (iter *Iterator) skipFourBytes(b1, b2, b3, b4 byte) { - if iter.readByte() != b1 { - iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) - return - } - if iter.readByte() != b2 { - iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) - return - } - if iter.readByte() != b3 { - iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) - return - } - if iter.readByte() != b4 { - iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) - return - } -} - -func (iter *Iterator) skipThreeBytes(b1, b2, b3 byte) { - if iter.readByte() != b1 { - iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) - return - } - if iter.readByte() != b2 { - iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) - return - } - if iter.readByte() != b3 { - iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) - return - } -} diff --git a/vendor/github.com/json-iterator/go/iter_skip_sloppy.go b/vendor/github.com/json-iterator/go/iter_skip_sloppy.go deleted file mode 100644 index 8fcdc3b69..000000000 --- a/vendor/github.com/json-iterator/go/iter_skip_sloppy.go +++ /dev/null @@ -1,144 +0,0 @@ -//+build jsoniter_sloppy - -package jsoniter - -// sloppy but faster implementation, do not validate the input json - -func (iter *Iterator) skipNumber() { - for { - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - switch c { - case ' ', '\n', '\r', '\t', ',', '}', ']': - iter.head = i - return - } - } - if !iter.loadMore() { - return - } - } -} - -func (iter *Iterator) skipArray() { - level := 1 - for { - for i := iter.head; i < iter.tail; i++ { - switch iter.buf[i] { - case '"': // If inside string, skip it - iter.head = i + 1 - iter.skipString() - i = iter.head - 1 // it will be i++ soon - case '[': // If open symbol, increase level - level++ - case ']': // If close symbol, increase level - level-- - - // If we have returned to the original level, we're done - if level == 0 { - iter.head = i + 1 - return - } - } - } - if !iter.loadMore() { - iter.ReportError("skipObject", "incomplete array") - return - } - } -} - -func (iter *Iterator) skipObject() { - level := 1 - for { - for i := iter.head; i < iter.tail; i++ { - switch iter.buf[i] { - case '"': // If inside string, skip it - iter.head = i + 1 - iter.skipString() - i = iter.head - 1 // it will be i++ soon - case '{': // If open symbol, increase level - level++ - case '}': // If close symbol, increase level - level-- - - // If we have returned to the original level, we're done - if level == 0 { - iter.head = i + 1 - return - } - } - } - if !iter.loadMore() { - iter.ReportError("skipObject", "incomplete object") - return - } - } -} - -func (iter *Iterator) skipString() { - for { - end, escaped := iter.findStringEnd() - if end == -1 { - if !iter.loadMore() { - iter.ReportError("skipString", "incomplete string") - return - } - if escaped { - iter.head = 1 // skip the first char as last char read is \ - } - } else { - iter.head = end - return - } - } -} - -// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go -// Tries to find the end of string -// Support if string contains escaped quote symbols. -func (iter *Iterator) findStringEnd() (int, bool) { - escaped := false - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - if c == '"' { - if !escaped { - return i + 1, false - } - j := i - 1 - for { - if j < iter.head || iter.buf[j] != '\\' { - // even number of backslashes - // either end of buffer, or " found - return i + 1, true - } - j-- - if j < iter.head || iter.buf[j] != '\\' { - // odd number of backslashes - // it is \" or \\\" - break - } - j-- - } - } else if c == '\\' { - escaped = true - } - } - j := iter.tail - 1 - for { - if j < iter.head || iter.buf[j] != '\\' { - // even number of backslashes - // either end of buffer, or " found - return -1, false // do not end with \ - } - j-- - if j < iter.head || iter.buf[j] != '\\' { - // odd number of backslashes - // it is \" or \\\" - break - } - j-- - - } - return -1, true // end with \ -} diff --git a/vendor/github.com/json-iterator/go/iter_skip_strict.go b/vendor/github.com/json-iterator/go/iter_skip_strict.go deleted file mode 100644 index f67bc2e83..000000000 --- a/vendor/github.com/json-iterator/go/iter_skip_strict.go +++ /dev/null @@ -1,89 +0,0 @@ -//+build !jsoniter_sloppy - -package jsoniter - -import "fmt" - -func (iter *Iterator) skipNumber() { - if !iter.trySkipNumber() { - iter.unreadByte() - iter.ReadFloat32() - } -} - -func (iter *Iterator) trySkipNumber() bool { - dotFound := false - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - switch c { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - case '.': - if dotFound { - iter.ReportError("validateNumber", `more than one dot found in number`) - return true // already failed - } - if i+1 == iter.tail { - return false - } - c = iter.buf[i+1] - switch c { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - default: - iter.ReportError("validateNumber", `missing digit after dot`) - return true // already failed - } - dotFound = true - default: - switch c { - case ',', ']', '}', ' ', '\t', '\n', '\r': - if iter.head == i { - return false // if - without following digits - } - iter.head = i - return true // must be valid - } - return false // may be invalid - } - } - return false -} - -func (iter *Iterator) skipString() { - if !iter.trySkipString() { - iter.unreadByte() - iter.ReadString() - } -} - -func (iter *Iterator) trySkipString() bool { - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - if c == '"' { - iter.head = i + 1 - return true // valid - } else if c == '\\' { - return false - } else if c < ' ' { - iter.ReportError("trySkipString", - fmt.Sprintf(`invalid control character found: %d`, c)) - return true // already failed - } - } - return false -} - -func (iter *Iterator) skipObject() { - iter.unreadByte() - iter.ReadObjectCB(func(iter *Iterator, field string) bool { - iter.Skip() - return true - }) -} - -func (iter *Iterator) skipArray() { - iter.unreadByte() - iter.ReadArrayCB(func(iter *Iterator) bool { - iter.Skip() - return true - }) -} diff --git a/vendor/github.com/json-iterator/go/iter_str.go b/vendor/github.com/json-iterator/go/iter_str.go deleted file mode 100644 index adc487ea8..000000000 --- a/vendor/github.com/json-iterator/go/iter_str.go +++ /dev/null @@ -1,215 +0,0 @@ -package jsoniter - -import ( - "fmt" - "unicode/utf16" -) - -// ReadString read string from iterator -func (iter *Iterator) ReadString() (ret string) { - c := iter.nextToken() - if c == '"' { - for i := iter.head; i < iter.tail; i++ { - c := iter.buf[i] - if c == '"' { - ret = string(iter.buf[iter.head:i]) - iter.head = i + 1 - return ret - } else if c == '\\' { - break - } else if c < ' ' { - iter.ReportError("ReadString", - fmt.Sprintf(`invalid control character found: %d`, c)) - return - } - } - return iter.readStringSlowPath() - } else if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - return "" - } - iter.ReportError("ReadString", `expects " or n, but found `+string([]byte{c})) - return -} - -func (iter *Iterator) readStringSlowPath() (ret string) { - var str []byte - var c byte - for iter.Error == nil { - c = iter.readByte() - if c == '"' { - return string(str) - } - if c == '\\' { - c = iter.readByte() - str = iter.readEscapedChar(c, str) - } else { - str = append(str, c) - } - } - iter.ReportError("readStringSlowPath", "unexpected end of input") - return -} - -func (iter *Iterator) readEscapedChar(c byte, str []byte) []byte { - switch c { - case 'u': - r := iter.readU4() - if utf16.IsSurrogate(r) { - c = iter.readByte() - if iter.Error != nil { - return nil - } - if c != '\\' { - iter.unreadByte() - str = appendRune(str, r) - return str - } - c = iter.readByte() - if iter.Error != nil { - return nil - } - if c != 'u' { - str = appendRune(str, r) - return iter.readEscapedChar(c, str) - } - r2 := iter.readU4() - if iter.Error != nil { - return nil - } - combined := utf16.DecodeRune(r, r2) - if combined == '\uFFFD' { - str = appendRune(str, r) - str = appendRune(str, r2) - } else { - str = appendRune(str, combined) - } - } else { - str = appendRune(str, r) - } - case '"': - str = append(str, '"') - case '\\': - str = append(str, '\\') - case '/': - str = append(str, '/') - case 'b': - str = append(str, '\b') - case 'f': - str = append(str, '\f') - case 'n': - str = append(str, '\n') - case 'r': - str = append(str, '\r') - case 't': - str = append(str, '\t') - default: - iter.ReportError("readEscapedChar", - `invalid escape char after \`) - return nil - } - return str -} - -// ReadStringAsSlice read string from iterator without copying into string form. -// The []byte can not be kept, as it will change after next iterator call. -func (iter *Iterator) ReadStringAsSlice() (ret []byte) { - c := iter.nextToken() - if c == '"' { - for i := iter.head; i < iter.tail; i++ { - // require ascii string and no escape - // for: field name, base64, number - if iter.buf[i] == '"' { - // fast path: reuse the underlying buffer - ret = iter.buf[iter.head:i] - iter.head = i + 1 - return ret - } - } - readLen := iter.tail - iter.head - copied := make([]byte, readLen, readLen*2) - copy(copied, iter.buf[iter.head:iter.tail]) - iter.head = iter.tail - for iter.Error == nil { - c := iter.readByte() - if c == '"' { - return copied - } - copied = append(copied, c) - } - return copied - } - iter.ReportError("ReadStringAsSlice", `expects " or n, but found `+string([]byte{c})) - return -} - -func (iter *Iterator) readU4() (ret rune) { - for i := 0; i < 4; i++ { - c := iter.readByte() - if iter.Error != nil { - return - } - if c >= '0' && c <= '9' { - ret = ret*16 + rune(c-'0') - } else if c >= 'a' && c <= 'f' { - ret = ret*16 + rune(c-'a'+10) - } else if c >= 'A' && c <= 'F' { - ret = ret*16 + rune(c-'A'+10) - } else { - iter.ReportError("readU4", "expects 0~9 or a~f, but found "+string([]byte{c})) - return - } - } - return ret -} - -const ( - t1 = 0x00 // 0000 0000 - tx = 0x80 // 1000 0000 - t2 = 0xC0 // 1100 0000 - t3 = 0xE0 // 1110 0000 - t4 = 0xF0 // 1111 0000 - t5 = 0xF8 // 1111 1000 - - maskx = 0x3F // 0011 1111 - mask2 = 0x1F // 0001 1111 - mask3 = 0x0F // 0000 1111 - mask4 = 0x07 // 0000 0111 - - rune1Max = 1<<7 - 1 - rune2Max = 1<<11 - 1 - rune3Max = 1<<16 - 1 - - surrogateMin = 0xD800 - surrogateMax = 0xDFFF - - maxRune = '\U0010FFFF' // Maximum valid Unicode code point. - runeError = '\uFFFD' // the "error" Rune or "Unicode replacement character" -) - -func appendRune(p []byte, r rune) []byte { - // Negative values are erroneous. Making it unsigned addresses the problem. - switch i := uint32(r); { - case i <= rune1Max: - p = append(p, byte(r)) - return p - case i <= rune2Max: - p = append(p, t2|byte(r>>6)) - p = append(p, tx|byte(r)&maskx) - return p - case i > maxRune, surrogateMin <= i && i <= surrogateMax: - r = runeError - fallthrough - case i <= rune3Max: - p = append(p, t3|byte(r>>12)) - p = append(p, tx|byte(r>>6)&maskx) - p = append(p, tx|byte(r)&maskx) - return p - default: - p = append(p, t4|byte(r>>18)) - p = append(p, tx|byte(r>>12)&maskx) - p = append(p, tx|byte(r>>6)&maskx) - p = append(p, tx|byte(r)&maskx) - return p - } -} diff --git a/vendor/github.com/json-iterator/go/jsoniter.go b/vendor/github.com/json-iterator/go/jsoniter.go deleted file mode 100644 index c2934f916..000000000 --- a/vendor/github.com/json-iterator/go/jsoniter.go +++ /dev/null @@ -1,18 +0,0 @@ -// Package jsoniter implements encoding and decoding of JSON as defined in -// RFC 4627 and provides interfaces with identical syntax of standard lib encoding/json. -// Converting from encoding/json to jsoniter is no more than replacing the package with jsoniter -// and variable type declarations (if any). -// jsoniter interfaces gives 100% compatibility with code using standard lib. -// -// "JSON and Go" -// (https://golang.org/doc/articles/json_and_go.html) -// gives a description of how Marshal/Unmarshal operate -// between arbitrary or predefined json objects and bytes, -// and it applies to jsoniter.Marshal/Unmarshal as well. -// -// Besides, jsoniter.Iterator provides a different set of interfaces -// iterating given bytes/string/reader -// and yielding parsed elements one by one. -// This set of interfaces reads input as required and gives -// better performance. -package jsoniter diff --git a/vendor/github.com/json-iterator/go/pool.go b/vendor/github.com/json-iterator/go/pool.go deleted file mode 100644 index 735062684..000000000 --- a/vendor/github.com/json-iterator/go/pool.go +++ /dev/null @@ -1,41 +0,0 @@ -package jsoniter - -import ( - "io" -) - -// IteratorPool a thread safe pool of iterators with same configuration -type IteratorPool interface { - BorrowIterator(data []byte) *Iterator - ReturnIterator(iter *Iterator) -} - -// StreamPool a thread safe pool of streams with same configuration -type StreamPool interface { - BorrowStream(writer io.Writer) *Stream - ReturnStream(stream *Stream) -} - -func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream { - stream := cfg.streamPool.Get().(*Stream) - stream.Reset(writer) - return stream -} - -func (cfg *frozenConfig) ReturnStream(stream *Stream) { - stream.Error = nil - stream.Attachment = nil - cfg.streamPool.Put(stream) -} - -func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator { - iter := cfg.iteratorPool.Get().(*Iterator) - iter.ResetBytes(data) - return iter -} - -func (cfg *frozenConfig) ReturnIterator(iter *Iterator) { - iter.Error = nil - iter.Attachment = nil - cfg.iteratorPool.Put(iter) -} diff --git a/vendor/github.com/json-iterator/go/reflect.go b/vendor/github.com/json-iterator/go/reflect.go deleted file mode 100644 index 5c7d3a8a0..000000000 --- a/vendor/github.com/json-iterator/go/reflect.go +++ /dev/null @@ -1,321 +0,0 @@ -package jsoniter - -import ( - "fmt" - "github.com/modern-go/reflect2" - "reflect" - "unsafe" -) - -// ValDecoder is an internal type registered to cache as needed. -// Don't confuse jsoniter.ValDecoder with json.Decoder. -// For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link). -// -// Reflection on type to create decoders, which is then cached -// Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions -// 1. create instance of new value, for example *int will need a int to be allocated -// 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New -// 3. assignment to map, both key and value will be reflect.Value -// For a simple struct binding, it will be reflect.Value free and allocation free -type ValDecoder interface { - Decode(ptr unsafe.Pointer, iter *Iterator) -} - -// ValEncoder is an internal type registered to cache as needed. -// Don't confuse jsoniter.ValEncoder with json.Encoder. -// For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link). -type ValEncoder interface { - IsEmpty(ptr unsafe.Pointer) bool - Encode(ptr unsafe.Pointer, stream *Stream) -} - -type checkIsEmpty interface { - IsEmpty(ptr unsafe.Pointer) bool -} - -type ctx struct { - *frozenConfig - prefix string - encoders map[reflect2.Type]ValEncoder - decoders map[reflect2.Type]ValDecoder -} - -func (b *ctx) append(prefix string) *ctx { - return &ctx{ - frozenConfig: b.frozenConfig, - prefix: b.prefix + " " + prefix, - encoders: b.encoders, - decoders: b.decoders, - } -} - -// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal -func (iter *Iterator) ReadVal(obj interface{}) { - cacheKey := reflect2.RTypeOf(obj) - decoder := iter.cfg.getDecoderFromCache(cacheKey) - if decoder == nil { - typ := reflect2.TypeOf(obj) - if typ.Kind() != reflect.Ptr { - iter.ReportError("ReadVal", "can only unmarshal into pointer") - return - } - decoder = iter.cfg.DecoderOf(typ) - } - ptr := reflect2.PtrOf(obj) - if ptr == nil { - iter.ReportError("ReadVal", "can not read into nil pointer") - return - } - decoder.Decode(ptr, iter) -} - -// WriteVal copy the go interface into underlying JSON, same as json.Marshal -func (stream *Stream) WriteVal(val interface{}) { - if nil == val { - stream.WriteNil() - return - } - cacheKey := reflect2.RTypeOf(val) - encoder := stream.cfg.getEncoderFromCache(cacheKey) - if encoder == nil { - typ := reflect2.TypeOf(val) - encoder = stream.cfg.EncoderOf(typ) - } - encoder.Encode(reflect2.PtrOf(val), stream) -} - -func (cfg *frozenConfig) DecoderOf(typ reflect2.Type) ValDecoder { - cacheKey := typ.RType() - decoder := cfg.getDecoderFromCache(cacheKey) - if decoder != nil { - return decoder - } - ctx := &ctx{ - frozenConfig: cfg, - prefix: "", - decoders: map[reflect2.Type]ValDecoder{}, - encoders: map[reflect2.Type]ValEncoder{}, - } - ptrType := typ.(*reflect2.UnsafePtrType) - decoder = decoderOfType(ctx, ptrType.Elem()) - cfg.addDecoderToCache(cacheKey, decoder) - return decoder -} - -func decoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { - decoder := getTypeDecoderFromExtension(ctx, typ) - if decoder != nil { - return decoder - } - decoder = createDecoderOfType(ctx, typ) - for _, extension := range extensions { - decoder = extension.DecorateDecoder(typ, decoder) - } - for _, extension := range ctx.extensions { - decoder = extension.DecorateDecoder(typ, decoder) - } - return decoder -} - -func createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { - decoder := ctx.decoders[typ] - if decoder != nil { - return decoder - } - placeholder := &placeholderDecoder{} - ctx.decoders[typ] = placeholder - decoder = _createDecoderOfType(ctx, typ) - placeholder.decoder = decoder - return decoder -} - -func _createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { - decoder := createDecoderOfJsonRawMessage(ctx, typ) - if decoder != nil { - return decoder - } - decoder = createDecoderOfJsonNumber(ctx, typ) - if decoder != nil { - return decoder - } - decoder = createDecoderOfMarshaler(ctx, typ) - if decoder != nil { - return decoder - } - decoder = createDecoderOfAny(ctx, typ) - if decoder != nil { - return decoder - } - decoder = createDecoderOfNative(ctx, typ) - if decoder != nil { - return decoder - } - switch typ.Kind() { - case reflect.Interface: - ifaceType, isIFace := typ.(*reflect2.UnsafeIFaceType) - if isIFace { - return &ifaceDecoder{valType: ifaceType} - } - return &efaceDecoder{} - case reflect.Struct: - return decoderOfStruct(ctx, typ) - case reflect.Array: - return decoderOfArray(ctx, typ) - case reflect.Slice: - return decoderOfSlice(ctx, typ) - case reflect.Map: - return decoderOfMap(ctx, typ) - case reflect.Ptr: - return decoderOfOptional(ctx, typ) - default: - return &lazyErrorDecoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} - } -} - -func (cfg *frozenConfig) EncoderOf(typ reflect2.Type) ValEncoder { - cacheKey := typ.RType() - encoder := cfg.getEncoderFromCache(cacheKey) - if encoder != nil { - return encoder - } - ctx := &ctx{ - frozenConfig: cfg, - prefix: "", - decoders: map[reflect2.Type]ValDecoder{}, - encoders: map[reflect2.Type]ValEncoder{}, - } - encoder = encoderOfType(ctx, typ) - if typ.LikePtr() { - encoder = &onePtrEncoder{encoder} - } - cfg.addEncoderToCache(cacheKey, encoder) - return encoder -} - -type onePtrEncoder struct { - encoder ValEncoder -} - -func (encoder *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) -} - -func (encoder *onePtrEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) -} - -func encoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { - encoder := getTypeEncoderFromExtension(ctx, typ) - if encoder != nil { - return encoder - } - encoder = createEncoderOfType(ctx, typ) - for _, extension := range extensions { - encoder = extension.DecorateEncoder(typ, encoder) - } - for _, extension := range ctx.extensions { - encoder = extension.DecorateEncoder(typ, encoder) - } - return encoder -} - -func createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { - encoder := ctx.encoders[typ] - if encoder != nil { - return encoder - } - placeholder := &placeholderEncoder{} - ctx.encoders[typ] = placeholder - encoder = _createEncoderOfType(ctx, typ) - placeholder.encoder = encoder - return encoder -} -func _createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { - encoder := createEncoderOfJsonRawMessage(ctx, typ) - if encoder != nil { - return encoder - } - encoder = createEncoderOfJsonNumber(ctx, typ) - if encoder != nil { - return encoder - } - encoder = createEncoderOfMarshaler(ctx, typ) - if encoder != nil { - return encoder - } - encoder = createEncoderOfAny(ctx, typ) - if encoder != nil { - return encoder - } - encoder = createEncoderOfNative(ctx, typ) - if encoder != nil { - return encoder - } - kind := typ.Kind() - switch kind { - case reflect.Interface: - return &dynamicEncoder{typ} - case reflect.Struct: - return encoderOfStruct(ctx, typ) - case reflect.Array: - return encoderOfArray(ctx, typ) - case reflect.Slice: - return encoderOfSlice(ctx, typ) - case reflect.Map: - return encoderOfMap(ctx, typ) - case reflect.Ptr: - return encoderOfOptional(ctx, typ) - default: - return &lazyErrorEncoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} - } -} - -type lazyErrorDecoder struct { - err error -} - -func (decoder *lazyErrorDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if iter.WhatIsNext() != NilValue { - if iter.Error == nil { - iter.Error = decoder.err - } - } else { - iter.Skip() - } -} - -type lazyErrorEncoder struct { - err error -} - -func (encoder *lazyErrorEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - if ptr == nil { - stream.WriteNil() - } else if stream.Error == nil { - stream.Error = encoder.err - } -} - -func (encoder *lazyErrorEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return false -} - -type placeholderDecoder struct { - decoder ValDecoder -} - -func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - decoder.decoder.Decode(ptr, iter) -} - -type placeholderEncoder struct { - encoder ValEncoder -} - -func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - encoder.encoder.Encode(ptr, stream) -} - -func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.encoder.IsEmpty(ptr) -} diff --git a/vendor/github.com/json-iterator/go/reflect_array.go b/vendor/github.com/json-iterator/go/reflect_array.go deleted file mode 100644 index 13a0b7b08..000000000 --- a/vendor/github.com/json-iterator/go/reflect_array.go +++ /dev/null @@ -1,104 +0,0 @@ -package jsoniter - -import ( - "fmt" - "github.com/modern-go/reflect2" - "io" - "unsafe" -) - -func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder { - arrayType := typ.(*reflect2.UnsafeArrayType) - decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem()) - return &arrayDecoder{arrayType, decoder} -} - -func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder { - arrayType := typ.(*reflect2.UnsafeArrayType) - if arrayType.Len() == 0 { - return emptyArrayEncoder{} - } - encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem()) - return &arrayEncoder{arrayType, encoder} -} - -type emptyArrayEncoder struct{} - -func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteEmptyArray() -} - -func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return true -} - -type arrayEncoder struct { - arrayType *reflect2.UnsafeArrayType - elemEncoder ValEncoder -} - -func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteArrayStart() - elemPtr := unsafe.Pointer(ptr) - encoder.elemEncoder.Encode(elemPtr, stream) - for i := 1; i < encoder.arrayType.Len(); i++ { - stream.WriteMore() - elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i) - encoder.elemEncoder.Encode(elemPtr, stream) - } - stream.WriteArrayEnd() - if stream.Error != nil && stream.Error != io.EOF { - stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error()) - } -} - -func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return false -} - -type arrayDecoder struct { - arrayType *reflect2.UnsafeArrayType - elemDecoder ValDecoder -} - -func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - decoder.doDecode(ptr, iter) - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error()) - } -} - -func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { - c := iter.nextToken() - arrayType := decoder.arrayType - if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - return - } - if c != '[' { - iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c})) - return - } - c = iter.nextToken() - if c == ']' { - return - } - iter.unreadByte() - elemPtr := arrayType.UnsafeGetIndex(ptr, 0) - decoder.elemDecoder.Decode(elemPtr, iter) - length := 1 - for c = iter.nextToken(); c == ','; c = iter.nextToken() { - if length >= arrayType.Len() { - iter.Skip() - continue - } - idx := length - length += 1 - elemPtr = arrayType.UnsafeGetIndex(ptr, idx) - decoder.elemDecoder.Decode(elemPtr, iter) - } - if c != ']' { - iter.ReportError("decode array", "expect ], but found "+string([]byte{c})) - return - } -} diff --git a/vendor/github.com/json-iterator/go/reflect_dynamic.go b/vendor/github.com/json-iterator/go/reflect_dynamic.go deleted file mode 100644 index 8b6bc8b43..000000000 --- a/vendor/github.com/json-iterator/go/reflect_dynamic.go +++ /dev/null @@ -1,70 +0,0 @@ -package jsoniter - -import ( - "github.com/modern-go/reflect2" - "reflect" - "unsafe" -) - -type dynamicEncoder struct { - valType reflect2.Type -} - -func (encoder *dynamicEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - obj := encoder.valType.UnsafeIndirect(ptr) - stream.WriteVal(obj) -} - -func (encoder *dynamicEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.valType.UnsafeIndirect(ptr) == nil -} - -type efaceDecoder struct { -} - -func (decoder *efaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - pObj := (*interface{})(ptr) - obj := *pObj - if obj == nil { - *pObj = iter.Read() - return - } - typ := reflect2.TypeOf(obj) - if typ.Kind() != reflect.Ptr { - *pObj = iter.Read() - return - } - ptrType := typ.(*reflect2.UnsafePtrType) - ptrElemType := ptrType.Elem() - if iter.WhatIsNext() == NilValue { - if ptrElemType.Kind() != reflect.Ptr { - iter.skipFourBytes('n', 'u', 'l', 'l') - *pObj = nil - return - } - } - if reflect2.IsNil(obj) { - obj := ptrElemType.New() - iter.ReadVal(obj) - *pObj = obj - return - } - iter.ReadVal(obj) -} - -type ifaceDecoder struct { - valType *reflect2.UnsafeIFaceType -} - -func (decoder *ifaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if iter.ReadNil() { - decoder.valType.UnsafeSet(ptr, decoder.valType.UnsafeNew()) - return - } - obj := decoder.valType.UnsafeIndirect(ptr) - if reflect2.IsNil(obj) { - iter.ReportError("decode non empty interface", "can not unmarshal into nil") - return - } - iter.ReadVal(obj) -} diff --git a/vendor/github.com/json-iterator/go/reflect_extension.go b/vendor/github.com/json-iterator/go/reflect_extension.go deleted file mode 100644 index 917bbe84e..000000000 --- a/vendor/github.com/json-iterator/go/reflect_extension.go +++ /dev/null @@ -1,471 +0,0 @@ -package jsoniter - -import ( - "fmt" - "github.com/modern-go/reflect2" - "reflect" - "sort" - "strings" - "unicode" - "unsafe" -) - -var typeDecoders = map[string]ValDecoder{} -var fieldDecoders = map[string]ValDecoder{} -var typeEncoders = map[string]ValEncoder{} -var fieldEncoders = map[string]ValEncoder{} -var extensions = []Extension{} - -// StructDescriptor describe how should we encode/decode the struct -type StructDescriptor struct { - Type reflect2.Type - Fields []*Binding -} - -// GetField get one field from the descriptor by its name. -// Can not use map here to keep field orders. -func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding { - for _, binding := range structDescriptor.Fields { - if binding.Field.Name() == fieldName { - return binding - } - } - return nil -} - -// Binding describe how should we encode/decode the struct field -type Binding struct { - levels []int - Field reflect2.StructField - FromNames []string - ToNames []string - Encoder ValEncoder - Decoder ValDecoder -} - -// Extension the one for all SPI. Customize encoding/decoding by specifying alternate encoder/decoder. -// Can also rename fields by UpdateStructDescriptor. -type Extension interface { - UpdateStructDescriptor(structDescriptor *StructDescriptor) - CreateMapKeyDecoder(typ reflect2.Type) ValDecoder - CreateMapKeyEncoder(typ reflect2.Type) ValEncoder - CreateDecoder(typ reflect2.Type) ValDecoder - CreateEncoder(typ reflect2.Type) ValEncoder - DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder - DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder -} - -// DummyExtension embed this type get dummy implementation for all methods of Extension -type DummyExtension struct { -} - -// UpdateStructDescriptor No-op -func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { -} - -// CreateMapKeyDecoder No-op -func (extension *DummyExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { - return nil -} - -// CreateMapKeyEncoder No-op -func (extension *DummyExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { - return nil -} - -// CreateDecoder No-op -func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder { - return nil -} - -// CreateEncoder No-op -func (extension *DummyExtension) CreateEncoder(typ reflect2.Type) ValEncoder { - return nil -} - -// DecorateDecoder No-op -func (extension *DummyExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { - return decoder -} - -// DecorateEncoder No-op -func (extension *DummyExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { - return encoder -} - -type EncoderExtension map[reflect2.Type]ValEncoder - -// UpdateStructDescriptor No-op -func (extension EncoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { -} - -// CreateDecoder No-op -func (extension EncoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { - return nil -} - -// CreateEncoder get encoder from map -func (extension EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { - return extension[typ] -} - -// CreateMapKeyDecoder No-op -func (extension EncoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { - return nil -} - -// CreateMapKeyEncoder No-op -func (extension EncoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { - return nil -} - -// DecorateDecoder No-op -func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { - return decoder -} - -// DecorateEncoder No-op -func (extension EncoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { - return encoder -} - -type DecoderExtension map[reflect2.Type]ValDecoder - -// UpdateStructDescriptor No-op -func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { -} - -// CreateMapKeyDecoder No-op -func (extension DecoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { - return nil -} - -// CreateMapKeyEncoder No-op -func (extension DecoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { - return nil -} - -// CreateDecoder get decoder from map -func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { - return extension[typ] -} - -// CreateEncoder No-op -func (extension DecoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { - return nil -} - -// DecorateDecoder No-op -func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { - return decoder -} - -// DecorateEncoder No-op -func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { - return encoder -} - -type funcDecoder struct { - fun DecoderFunc -} - -func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - decoder.fun(ptr, iter) -} - -type funcEncoder struct { - fun EncoderFunc - isEmptyFunc func(ptr unsafe.Pointer) bool -} - -func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - encoder.fun(ptr, stream) -} - -func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool { - if encoder.isEmptyFunc == nil { - return false - } - return encoder.isEmptyFunc(ptr) -} - -// DecoderFunc the function form of TypeDecoder -type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator) - -// EncoderFunc the function form of TypeEncoder -type EncoderFunc func(ptr unsafe.Pointer, stream *Stream) - -// RegisterTypeDecoderFunc register TypeDecoder for a type with function -func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) { - typeDecoders[typ] = &funcDecoder{fun} -} - -// RegisterTypeDecoder register TypeDecoder for a typ -func RegisterTypeDecoder(typ string, decoder ValDecoder) { - typeDecoders[typ] = decoder -} - -// RegisterFieldDecoderFunc register TypeDecoder for a struct field with function -func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) { - RegisterFieldDecoder(typ, field, &funcDecoder{fun}) -} - -// RegisterFieldDecoder register TypeDecoder for a struct field -func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) { - fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder -} - -// RegisterTypeEncoderFunc register TypeEncoder for a type with encode/isEmpty function -func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { - typeEncoders[typ] = &funcEncoder{fun, isEmptyFunc} -} - -// RegisterTypeEncoder register TypeEncoder for a type -func RegisterTypeEncoder(typ string, encoder ValEncoder) { - typeEncoders[typ] = encoder -} - -// RegisterFieldEncoderFunc register TypeEncoder for a struct field with encode/isEmpty function -func RegisterFieldEncoderFunc(typ string, field string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { - RegisterFieldEncoder(typ, field, &funcEncoder{fun, isEmptyFunc}) -} - -// RegisterFieldEncoder register TypeEncoder for a struct field -func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) { - fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder -} - -// RegisterExtension register extension -func RegisterExtension(extension Extension) { - extensions = append(extensions, extension) -} - -func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { - decoder := _getTypeDecoderFromExtension(ctx, typ) - if decoder != nil { - for _, extension := range extensions { - decoder = extension.DecorateDecoder(typ, decoder) - } - for _, extension := range ctx.extensions { - decoder = extension.DecorateDecoder(typ, decoder) - } - } - return decoder -} -func _getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { - for _, extension := range extensions { - decoder := extension.CreateDecoder(typ) - if decoder != nil { - return decoder - } - } - for _, extension := range ctx.extensions { - decoder := extension.CreateDecoder(typ) - if decoder != nil { - return decoder - } - } - typeName := typ.String() - decoder := typeDecoders[typeName] - if decoder != nil { - return decoder - } - if typ.Kind() == reflect.Ptr { - ptrType := typ.(*reflect2.UnsafePtrType) - decoder := typeDecoders[ptrType.Elem().String()] - if decoder != nil { - return &OptionalDecoder{ptrType.Elem(), decoder} - } - } - return nil -} - -func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { - encoder := _getTypeEncoderFromExtension(ctx, typ) - if encoder != nil { - for _, extension := range extensions { - encoder = extension.DecorateEncoder(typ, encoder) - } - for _, extension := range ctx.extensions { - encoder = extension.DecorateEncoder(typ, encoder) - } - } - return encoder -} - -func _getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { - for _, extension := range extensions { - encoder := extension.CreateEncoder(typ) - if encoder != nil { - return encoder - } - } - for _, extension := range ctx.extensions { - encoder := extension.CreateEncoder(typ) - if encoder != nil { - return encoder - } - } - typeName := typ.String() - encoder := typeEncoders[typeName] - if encoder != nil { - return encoder - } - if typ.Kind() == reflect.Ptr { - typePtr := typ.(*reflect2.UnsafePtrType) - encoder := typeEncoders[typePtr.Elem().String()] - if encoder != nil { - return &OptionalEncoder{encoder} - } - } - return nil -} - -func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor { - structType := typ.(*reflect2.UnsafeStructType) - embeddedBindings := []*Binding{} - bindings := []*Binding{} - for i := 0; i < structType.NumField(); i++ { - field := structType.Field(i) - tag, hastag := field.Tag().Lookup(ctx.getTagKey()) - if ctx.onlyTaggedField && !hastag { - continue - } - tagParts := strings.Split(tag, ",") - if tag == "-" { - continue - } - if field.Anonymous() && (tag == "" || tagParts[0] == "") { - if field.Type().Kind() == reflect.Struct { - structDescriptor := describeStruct(ctx, field.Type()) - for _, binding := range structDescriptor.Fields { - binding.levels = append([]int{i}, binding.levels...) - omitempty := binding.Encoder.(*structFieldEncoder).omitempty - binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} - binding.Decoder = &structFieldDecoder{field, binding.Decoder} - embeddedBindings = append(embeddedBindings, binding) - } - continue - } else if field.Type().Kind() == reflect.Ptr { - ptrType := field.Type().(*reflect2.UnsafePtrType) - if ptrType.Elem().Kind() == reflect.Struct { - structDescriptor := describeStruct(ctx, ptrType.Elem()) - for _, binding := range structDescriptor.Fields { - binding.levels = append([]int{i}, binding.levels...) - omitempty := binding.Encoder.(*structFieldEncoder).omitempty - binding.Encoder = &dereferenceEncoder{binding.Encoder} - binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} - binding.Decoder = &dereferenceDecoder{ptrType.Elem(), binding.Decoder} - binding.Decoder = &structFieldDecoder{field, binding.Decoder} - embeddedBindings = append(embeddedBindings, binding) - } - continue - } - } - } - fieldNames := calcFieldNames(field.Name(), tagParts[0], tag) - fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name()) - decoder := fieldDecoders[fieldCacheKey] - if decoder == nil { - decoder = decoderOfType(ctx.append(field.Name()), field.Type()) - } - encoder := fieldEncoders[fieldCacheKey] - if encoder == nil { - encoder = encoderOfType(ctx.append(field.Name()), field.Type()) - } - binding := &Binding{ - Field: field, - FromNames: fieldNames, - ToNames: fieldNames, - Decoder: decoder, - Encoder: encoder, - } - binding.levels = []int{i} - bindings = append(bindings, binding) - } - return createStructDescriptor(ctx, typ, bindings, embeddedBindings) -} -func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor { - structDescriptor := &StructDescriptor{ - Type: typ, - Fields: bindings, - } - for _, extension := range extensions { - extension.UpdateStructDescriptor(structDescriptor) - } - for _, extension := range ctx.extensions { - extension.UpdateStructDescriptor(structDescriptor) - } - processTags(structDescriptor, ctx.frozenConfig) - // merge normal & embedded bindings & sort with original order - allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...)) - sort.Sort(allBindings) - structDescriptor.Fields = allBindings - return structDescriptor -} - -type sortableBindings []*Binding - -func (bindings sortableBindings) Len() int { - return len(bindings) -} - -func (bindings sortableBindings) Less(i, j int) bool { - left := bindings[i].levels - right := bindings[j].levels - k := 0 - for { - if left[k] < right[k] { - return true - } else if left[k] > right[k] { - return false - } - k++ - } -} - -func (bindings sortableBindings) Swap(i, j int) { - bindings[i], bindings[j] = bindings[j], bindings[i] -} - -func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) { - for _, binding := range structDescriptor.Fields { - shouldOmitEmpty := false - tagParts := strings.Split(binding.Field.Tag().Get(cfg.getTagKey()), ",") - for _, tagPart := range tagParts[1:] { - if tagPart == "omitempty" { - shouldOmitEmpty = true - } else if tagPart == "string" { - if binding.Field.Type().Kind() == reflect.String { - binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg} - binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg} - } else { - binding.Decoder = &stringModeNumberDecoder{binding.Decoder} - binding.Encoder = &stringModeNumberEncoder{binding.Encoder} - } - } - } - binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder} - binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty} - } -} - -func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string { - // ignore? - if wholeTag == "-" { - return []string{} - } - // rename? - var fieldNames []string - if tagProvidedFieldName == "" { - fieldNames = []string{originalFieldName} - } else { - fieldNames = []string{tagProvidedFieldName} - } - // private? - isNotExported := unicode.IsLower(rune(originalFieldName[0])) - if isNotExported { - fieldNames = []string{} - } - return fieldNames -} diff --git a/vendor/github.com/json-iterator/go/reflect_json_number.go b/vendor/github.com/json-iterator/go/reflect_json_number.go deleted file mode 100644 index 98d45c1ec..000000000 --- a/vendor/github.com/json-iterator/go/reflect_json_number.go +++ /dev/null @@ -1,112 +0,0 @@ -package jsoniter - -import ( - "encoding/json" - "github.com/modern-go/reflect2" - "strconv" - "unsafe" -) - -type Number string - -// String returns the literal text of the number. -func (n Number) String() string { return string(n) } - -// Float64 returns the number as a float64. -func (n Number) Float64() (float64, error) { - return strconv.ParseFloat(string(n), 64) -} - -// Int64 returns the number as an int64. -func (n Number) Int64() (int64, error) { - return strconv.ParseInt(string(n), 10, 64) -} - -func CastJsonNumber(val interface{}) (string, bool) { - switch typedVal := val.(type) { - case json.Number: - return string(typedVal), true - case Number: - return string(typedVal), true - } - return "", false -} - -var jsonNumberType = reflect2.TypeOfPtr((*json.Number)(nil)).Elem() -var jsoniterNumberType = reflect2.TypeOfPtr((*Number)(nil)).Elem() - -func createDecoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValDecoder { - if typ.AssignableTo(jsonNumberType) { - return &jsonNumberCodec{} - } - if typ.AssignableTo(jsoniterNumberType) { - return &jsoniterNumberCodec{} - } - return nil -} - -func createEncoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValEncoder { - if typ.AssignableTo(jsonNumberType) { - return &jsonNumberCodec{} - } - if typ.AssignableTo(jsoniterNumberType) { - return &jsoniterNumberCodec{} - } - return nil -} - -type jsonNumberCodec struct { -} - -func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - switch iter.WhatIsNext() { - case StringValue: - *((*json.Number)(ptr)) = json.Number(iter.ReadString()) - case NilValue: - iter.skipFourBytes('n', 'u', 'l', 'l') - *((*json.Number)(ptr)) = "" - default: - *((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString())) - } -} - -func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - number := *((*json.Number)(ptr)) - if len(number) == 0 { - stream.writeByte('0') - } else { - stream.WriteRaw(string(number)) - } -} - -func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { - return len(*((*json.Number)(ptr))) == 0 -} - -type jsoniterNumberCodec struct { -} - -func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - switch iter.WhatIsNext() { - case StringValue: - *((*Number)(ptr)) = Number(iter.ReadString()) - case NilValue: - iter.skipFourBytes('n', 'u', 'l', 'l') - *((*Number)(ptr)) = "" - default: - *((*Number)(ptr)) = Number([]byte(iter.readNumberAsString())) - } -} - -func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - number := *((*Number)(ptr)) - if len(number) == 0 { - stream.writeByte('0') - } else { - stream.WriteRaw(string(number)) - } -} - -func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { - return len(*((*Number)(ptr))) == 0 -} diff --git a/vendor/github.com/json-iterator/go/reflect_json_raw_message.go b/vendor/github.com/json-iterator/go/reflect_json_raw_message.go deleted file mode 100644 index f2619936c..000000000 --- a/vendor/github.com/json-iterator/go/reflect_json_raw_message.go +++ /dev/null @@ -1,60 +0,0 @@ -package jsoniter - -import ( - "encoding/json" - "github.com/modern-go/reflect2" - "unsafe" -) - -var jsonRawMessageType = reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem() -var jsoniterRawMessageType = reflect2.TypeOfPtr((*RawMessage)(nil)).Elem() - -func createEncoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValEncoder { - if typ == jsonRawMessageType { - return &jsonRawMessageCodec{} - } - if typ == jsoniterRawMessageType { - return &jsoniterRawMessageCodec{} - } - return nil -} - -func createDecoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValDecoder { - if typ == jsonRawMessageType { - return &jsonRawMessageCodec{} - } - if typ == jsoniterRawMessageType { - return &jsoniterRawMessageCodec{} - } - return nil -} - -type jsonRawMessageCodec struct { -} - -func (codec *jsonRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*json.RawMessage)(ptr)) = json.RawMessage(iter.SkipAndReturnBytes()) -} - -func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteRaw(string(*((*json.RawMessage)(ptr)))) -} - -func (codec *jsonRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { - return len(*((*json.RawMessage)(ptr))) == 0 -} - -type jsoniterRawMessageCodec struct { -} - -func (codec *jsoniterRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*RawMessage)(ptr)) = RawMessage(iter.SkipAndReturnBytes()) -} - -func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteRaw(string(*((*RawMessage)(ptr)))) -} - -func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { - return len(*((*RawMessage)(ptr))) == 0 -} diff --git a/vendor/github.com/json-iterator/go/reflect_map.go b/vendor/github.com/json-iterator/go/reflect_map.go deleted file mode 100644 index 8812f0850..000000000 --- a/vendor/github.com/json-iterator/go/reflect_map.go +++ /dev/null @@ -1,318 +0,0 @@ -package jsoniter - -import ( - "fmt" - "github.com/modern-go/reflect2" - "io" - "reflect" - "sort" - "unsafe" -) - -func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder { - mapType := typ.(*reflect2.UnsafeMapType) - keyDecoder := decoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()) - elemDecoder := decoderOfType(ctx.append("[mapElem]"), mapType.Elem()) - return &mapDecoder{ - mapType: mapType, - keyType: mapType.Key(), - elemType: mapType.Elem(), - keyDecoder: keyDecoder, - elemDecoder: elemDecoder, - } -} - -func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder { - mapType := typ.(*reflect2.UnsafeMapType) - if ctx.sortMapKeys { - return &sortKeysMapEncoder{ - mapType: mapType, - keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()), - elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()), - } - } - return &mapEncoder{ - mapType: mapType, - keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()), - elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()), - } -} - -func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder { - for _, extension := range ctx.extensions { - decoder := extension.CreateMapKeyDecoder(typ) - if decoder != nil { - return decoder - } - } - switch typ.Kind() { - case reflect.String: - return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String)) - case reflect.Bool, - reflect.Uint8, reflect.Int8, - reflect.Uint16, reflect.Int16, - reflect.Uint32, reflect.Int32, - reflect.Uint64, reflect.Int64, - reflect.Uint, reflect.Int, - reflect.Float32, reflect.Float64, - reflect.Uintptr: - typ = reflect2.DefaultTypeOfKind(typ.Kind()) - return &numericMapKeyDecoder{decoderOfType(ctx, typ)} - default: - ptrType := reflect2.PtrTo(typ) - if ptrType.Implements(textMarshalerType) { - return &referenceDecoder{ - &textUnmarshalerDecoder{ - valType: ptrType, - }, - } - } - if typ.Implements(textMarshalerType) { - return &textUnmarshalerDecoder{ - valType: typ, - } - } - return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)} - } -} - -func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder { - for _, extension := range ctx.extensions { - encoder := extension.CreateMapKeyEncoder(typ) - if encoder != nil { - return encoder - } - } - switch typ.Kind() { - case reflect.String: - return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String)) - case reflect.Bool, - reflect.Uint8, reflect.Int8, - reflect.Uint16, reflect.Int16, - reflect.Uint32, reflect.Int32, - reflect.Uint64, reflect.Int64, - reflect.Uint, reflect.Int, - reflect.Float32, reflect.Float64, - reflect.Uintptr: - typ = reflect2.DefaultTypeOfKind(typ.Kind()) - return &numericMapKeyEncoder{encoderOfType(ctx, typ)} - default: - if typ == textMarshalerType { - return &directTextMarshalerEncoder{ - stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), - } - } - if typ.Implements(textMarshalerType) { - return &textMarshalerEncoder{ - valType: typ, - stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), - } - } - if typ.Kind() == reflect.Interface { - return &dynamicMapKeyEncoder{ctx, typ} - } - return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)} - } -} - -type mapDecoder struct { - mapType *reflect2.UnsafeMapType - keyType reflect2.Type - elemType reflect2.Type - keyDecoder ValDecoder - elemDecoder ValDecoder -} - -func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - mapType := decoder.mapType - c := iter.nextToken() - if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - *(*unsafe.Pointer)(ptr) = nil - mapType.UnsafeSet(ptr, mapType.UnsafeNew()) - return - } - if mapType.UnsafeIsNil(ptr) { - mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0)) - } - if c != '{' { - iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) - return - } - c = iter.nextToken() - if c == '}' { - return - } - if c != '"' { - iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c})) - return - } - iter.unreadByte() - key := decoder.keyType.UnsafeNew() - decoder.keyDecoder.Decode(key, iter) - c = iter.nextToken() - if c != ':' { - iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) - return - } - elem := decoder.elemType.UnsafeNew() - decoder.elemDecoder.Decode(elem, iter) - decoder.mapType.UnsafeSetIndex(ptr, key, elem) - for c = iter.nextToken(); c == ','; c = iter.nextToken() { - key := decoder.keyType.UnsafeNew() - decoder.keyDecoder.Decode(key, iter) - c = iter.nextToken() - if c != ':' { - iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) - return - } - elem := decoder.elemType.UnsafeNew() - decoder.elemDecoder.Decode(elem, iter) - decoder.mapType.UnsafeSetIndex(ptr, key, elem) - } - if c != '}' { - iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c})) - } -} - -type numericMapKeyDecoder struct { - decoder ValDecoder -} - -func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - c := iter.nextToken() - if c != '"' { - iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c})) - return - } - decoder.decoder.Decode(ptr, iter) - c = iter.nextToken() - if c != '"' { - iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c})) - return - } -} - -type numericMapKeyEncoder struct { - encoder ValEncoder -} - -func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.writeByte('"') - encoder.encoder.Encode(ptr, stream) - stream.writeByte('"') -} - -func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return false -} - -type dynamicMapKeyEncoder struct { - ctx *ctx - valType reflect2.Type -} - -func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - obj := encoder.valType.UnsafeIndirect(ptr) - encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream) -} - -func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { - obj := encoder.valType.UnsafeIndirect(ptr) - return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj)) -} - -type mapEncoder struct { - mapType *reflect2.UnsafeMapType - keyEncoder ValEncoder - elemEncoder ValEncoder -} - -func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteObjectStart() - iter := encoder.mapType.UnsafeIterate(ptr) - for i := 0; iter.HasNext(); i++ { - if i != 0 { - stream.WriteMore() - } - key, elem := iter.UnsafeNext() - encoder.keyEncoder.Encode(key, stream) - if stream.indention > 0 { - stream.writeTwoBytes(byte(':'), byte(' ')) - } else { - stream.writeByte(':') - } - encoder.elemEncoder.Encode(elem, stream) - } - stream.WriteObjectEnd() -} - -func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool { - iter := encoder.mapType.UnsafeIterate(ptr) - return !iter.HasNext() -} - -type sortKeysMapEncoder struct { - mapType *reflect2.UnsafeMapType - keyEncoder ValEncoder - elemEncoder ValEncoder -} - -func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - if *(*unsafe.Pointer)(ptr) == nil { - stream.WriteNil() - return - } - stream.WriteObjectStart() - mapIter := encoder.mapType.UnsafeIterate(ptr) - subStream := stream.cfg.BorrowStream(nil) - subIter := stream.cfg.BorrowIterator(nil) - keyValues := encodedKeyValues{} - for mapIter.HasNext() { - subStream.buf = make([]byte, 0, 64) - key, elem := mapIter.UnsafeNext() - encoder.keyEncoder.Encode(key, subStream) - if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil { - stream.Error = subStream.Error - } - encodedKey := subStream.Buffer() - subIter.ResetBytes(encodedKey) - decodedKey := subIter.ReadString() - if stream.indention > 0 { - subStream.writeTwoBytes(byte(':'), byte(' ')) - } else { - subStream.writeByte(':') - } - encoder.elemEncoder.Encode(elem, subStream) - keyValues = append(keyValues, encodedKV{ - key: decodedKey, - keyValue: subStream.Buffer(), - }) - } - sort.Sort(keyValues) - for i, keyValue := range keyValues { - if i != 0 { - stream.WriteMore() - } - stream.Write(keyValue.keyValue) - } - stream.WriteObjectEnd() - stream.cfg.ReturnStream(subStream) - stream.cfg.ReturnIterator(subIter) -} - -func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool { - iter := encoder.mapType.UnsafeIterate(ptr) - return !iter.HasNext() -} - -type encodedKeyValues []encodedKV - -type encodedKV struct { - key string - keyValue []byte -} - -func (sv encodedKeyValues) Len() int { return len(sv) } -func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } -func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key } diff --git a/vendor/github.com/json-iterator/go/reflect_marshaler.go b/vendor/github.com/json-iterator/go/reflect_marshaler.go deleted file mode 100644 index 58ac959ad..000000000 --- a/vendor/github.com/json-iterator/go/reflect_marshaler.go +++ /dev/null @@ -1,218 +0,0 @@ -package jsoniter - -import ( - "encoding" - "encoding/json" - "github.com/modern-go/reflect2" - "unsafe" -) - -var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem() -var unmarshalerType = reflect2.TypeOfPtr((*json.Unmarshaler)(nil)).Elem() -var textMarshalerType = reflect2.TypeOfPtr((*encoding.TextMarshaler)(nil)).Elem() -var textUnmarshalerType = reflect2.TypeOfPtr((*encoding.TextUnmarshaler)(nil)).Elem() - -func createDecoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValDecoder { - ptrType := reflect2.PtrTo(typ) - if ptrType.Implements(unmarshalerType) { - return &referenceDecoder{ - &unmarshalerDecoder{ptrType}, - } - } - if ptrType.Implements(textUnmarshalerType) { - return &referenceDecoder{ - &textUnmarshalerDecoder{ptrType}, - } - } - return nil -} - -func createEncoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValEncoder { - if typ == marshalerType { - checkIsEmpty := createCheckIsEmpty(ctx, typ) - var encoder ValEncoder = &directMarshalerEncoder{ - checkIsEmpty: checkIsEmpty, - } - return encoder - } - if typ.Implements(marshalerType) { - checkIsEmpty := createCheckIsEmpty(ctx, typ) - var encoder ValEncoder = &marshalerEncoder{ - valType: typ, - checkIsEmpty: checkIsEmpty, - } - return encoder - } - ptrType := reflect2.PtrTo(typ) - if ctx.prefix != "" && ptrType.Implements(marshalerType) { - checkIsEmpty := createCheckIsEmpty(ctx, ptrType) - var encoder ValEncoder = &marshalerEncoder{ - valType: ptrType, - checkIsEmpty: checkIsEmpty, - } - return &referenceEncoder{encoder} - } - if typ == textMarshalerType { - checkIsEmpty := createCheckIsEmpty(ctx, typ) - var encoder ValEncoder = &directTextMarshalerEncoder{ - checkIsEmpty: checkIsEmpty, - stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), - } - return encoder - } - if typ.Implements(textMarshalerType) { - checkIsEmpty := createCheckIsEmpty(ctx, typ) - var encoder ValEncoder = &textMarshalerEncoder{ - valType: typ, - stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), - checkIsEmpty: checkIsEmpty, - } - return encoder - } - // if prefix is empty, the type is the root type - if ctx.prefix != "" && ptrType.Implements(textMarshalerType) { - checkIsEmpty := createCheckIsEmpty(ctx, ptrType) - var encoder ValEncoder = &textMarshalerEncoder{ - valType: ptrType, - stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), - checkIsEmpty: checkIsEmpty, - } - return &referenceEncoder{encoder} - } - return nil -} - -type marshalerEncoder struct { - checkIsEmpty checkIsEmpty - valType reflect2.Type -} - -func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - obj := encoder.valType.UnsafeIndirect(ptr) - if encoder.valType.IsNullable() && reflect2.IsNil(obj) { - stream.WriteNil() - return - } - marshaler := obj.(json.Marshaler) - bytes, err := marshaler.MarshalJSON() - if err != nil { - stream.Error = err - } else { - stream.Write(bytes) - } -} - -func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.checkIsEmpty.IsEmpty(ptr) -} - -type directMarshalerEncoder struct { - checkIsEmpty checkIsEmpty -} - -func (encoder *directMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - marshaler := *(*json.Marshaler)(ptr) - if marshaler == nil { - stream.WriteNil() - return - } - bytes, err := marshaler.MarshalJSON() - if err != nil { - stream.Error = err - } else { - stream.Write(bytes) - } -} - -func (encoder *directMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.checkIsEmpty.IsEmpty(ptr) -} - -type textMarshalerEncoder struct { - valType reflect2.Type - stringEncoder ValEncoder - checkIsEmpty checkIsEmpty -} - -func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - obj := encoder.valType.UnsafeIndirect(ptr) - if encoder.valType.IsNullable() && reflect2.IsNil(obj) { - stream.WriteNil() - return - } - marshaler := (obj).(encoding.TextMarshaler) - bytes, err := marshaler.MarshalText() - if err != nil { - stream.Error = err - } else { - str := string(bytes) - encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream) - } -} - -func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.checkIsEmpty.IsEmpty(ptr) -} - -type directTextMarshalerEncoder struct { - stringEncoder ValEncoder - checkIsEmpty checkIsEmpty -} - -func (encoder *directTextMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - marshaler := *(*encoding.TextMarshaler)(ptr) - if marshaler == nil { - stream.WriteNil() - return - } - bytes, err := marshaler.MarshalText() - if err != nil { - stream.Error = err - } else { - str := string(bytes) - encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream) - } -} - -func (encoder *directTextMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.checkIsEmpty.IsEmpty(ptr) -} - -type unmarshalerDecoder struct { - valType reflect2.Type -} - -func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - valType := decoder.valType - obj := valType.UnsafeIndirect(ptr) - unmarshaler := obj.(json.Unmarshaler) - iter.nextToken() - iter.unreadByte() // skip spaces - bytes := iter.SkipAndReturnBytes() - err := unmarshaler.UnmarshalJSON(bytes) - if err != nil { - iter.ReportError("unmarshalerDecoder", err.Error()) - } -} - -type textUnmarshalerDecoder struct { - valType reflect2.Type -} - -func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - valType := decoder.valType - obj := valType.UnsafeIndirect(ptr) - if reflect2.IsNil(obj) { - ptrType := valType.(*reflect2.UnsafePtrType) - elemType := ptrType.Elem() - elem := elemType.UnsafeNew() - ptrType.UnsafeSet(ptr, unsafe.Pointer(&elem)) - obj = valType.UnsafeIndirect(ptr) - } - unmarshaler := (obj).(encoding.TextUnmarshaler) - str := iter.ReadString() - err := unmarshaler.UnmarshalText([]byte(str)) - if err != nil { - iter.ReportError("textUnmarshalerDecoder", err.Error()) - } -} diff --git a/vendor/github.com/json-iterator/go/reflect_native.go b/vendor/github.com/json-iterator/go/reflect_native.go deleted file mode 100644 index 7f1e2464d..000000000 --- a/vendor/github.com/json-iterator/go/reflect_native.go +++ /dev/null @@ -1,455 +0,0 @@ -package jsoniter - -import ( - "encoding/base64" - "github.com/modern-go/reflect2" - "reflect" - "strconv" - "unsafe" -) - -const ptrSize = 32 << uintptr(^uintptr(0)>>63) - -func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder { - if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 { - sliceDecoder := decoderOfSlice(ctx, typ) - return &base64Codec{sliceDecoder: sliceDecoder} - } - typeName := typ.String() - kind := typ.Kind() - switch kind { - case reflect.String: - if typeName != "string" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem()) - } - return &stringCodec{} - case reflect.Int: - if typeName != "int" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem()) - } - if strconv.IntSize == 32 { - return &int32Codec{} - } - return &int64Codec{} - case reflect.Int8: - if typeName != "int8" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem()) - } - return &int8Codec{} - case reflect.Int16: - if typeName != "int16" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem()) - } - return &int16Codec{} - case reflect.Int32: - if typeName != "int32" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem()) - } - return &int32Codec{} - case reflect.Int64: - if typeName != "int64" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem()) - } - return &int64Codec{} - case reflect.Uint: - if typeName != "uint" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem()) - } - if strconv.IntSize == 32 { - return &uint32Codec{} - } - return &uint64Codec{} - case reflect.Uint8: - if typeName != "uint8" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem()) - } - return &uint8Codec{} - case reflect.Uint16: - if typeName != "uint16" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem()) - } - return &uint16Codec{} - case reflect.Uint32: - if typeName != "uint32" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem()) - } - return &uint32Codec{} - case reflect.Uintptr: - if typeName != "uintptr" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem()) - } - if ptrSize == 32 { - return &uint32Codec{} - } - return &uint64Codec{} - case reflect.Uint64: - if typeName != "uint64" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem()) - } - return &uint64Codec{} - case reflect.Float32: - if typeName != "float32" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem()) - } - return &float32Codec{} - case reflect.Float64: - if typeName != "float64" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem()) - } - return &float64Codec{} - case reflect.Bool: - if typeName != "bool" { - return encoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem()) - } - return &boolCodec{} - } - return nil -} - -func createDecoderOfNative(ctx *ctx, typ reflect2.Type) ValDecoder { - if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 { - sliceDecoder := decoderOfSlice(ctx, typ) - return &base64Codec{sliceDecoder: sliceDecoder} - } - typeName := typ.String() - switch typ.Kind() { - case reflect.String: - if typeName != "string" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem()) - } - return &stringCodec{} - case reflect.Int: - if typeName != "int" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem()) - } - if strconv.IntSize == 32 { - return &int32Codec{} - } - return &int64Codec{} - case reflect.Int8: - if typeName != "int8" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem()) - } - return &int8Codec{} - case reflect.Int16: - if typeName != "int16" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem()) - } - return &int16Codec{} - case reflect.Int32: - if typeName != "int32" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem()) - } - return &int32Codec{} - case reflect.Int64: - if typeName != "int64" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem()) - } - return &int64Codec{} - case reflect.Uint: - if typeName != "uint" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem()) - } - if strconv.IntSize == 32 { - return &uint32Codec{} - } - return &uint64Codec{} - case reflect.Uint8: - if typeName != "uint8" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem()) - } - return &uint8Codec{} - case reflect.Uint16: - if typeName != "uint16" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem()) - } - return &uint16Codec{} - case reflect.Uint32: - if typeName != "uint32" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem()) - } - return &uint32Codec{} - case reflect.Uintptr: - if typeName != "uintptr" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem()) - } - if ptrSize == 32 { - return &uint32Codec{} - } - return &uint64Codec{} - case reflect.Uint64: - if typeName != "uint64" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem()) - } - return &uint64Codec{} - case reflect.Float32: - if typeName != "float32" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem()) - } - return &float32Codec{} - case reflect.Float64: - if typeName != "float64" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem()) - } - return &float64Codec{} - case reflect.Bool: - if typeName != "bool" { - return decoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem()) - } - return &boolCodec{} - } - return nil -} - -type stringCodec struct { -} - -func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - *((*string)(ptr)) = iter.ReadString() -} - -func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - str := *((*string)(ptr)) - stream.WriteString(str) -} - -func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*string)(ptr)) == "" -} - -type int8Codec struct { -} - -func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*int8)(ptr)) = iter.ReadInt8() - } -} - -func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteInt8(*((*int8)(ptr))) -} - -func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*int8)(ptr)) == 0 -} - -type int16Codec struct { -} - -func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*int16)(ptr)) = iter.ReadInt16() - } -} - -func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteInt16(*((*int16)(ptr))) -} - -func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*int16)(ptr)) == 0 -} - -type int32Codec struct { -} - -func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*int32)(ptr)) = iter.ReadInt32() - } -} - -func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteInt32(*((*int32)(ptr))) -} - -func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*int32)(ptr)) == 0 -} - -type int64Codec struct { -} - -func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*int64)(ptr)) = iter.ReadInt64() - } -} - -func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteInt64(*((*int64)(ptr))) -} - -func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*int64)(ptr)) == 0 -} - -type uint8Codec struct { -} - -func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*uint8)(ptr)) = iter.ReadUint8() - } -} - -func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteUint8(*((*uint8)(ptr))) -} - -func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*uint8)(ptr)) == 0 -} - -type uint16Codec struct { -} - -func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*uint16)(ptr)) = iter.ReadUint16() - } -} - -func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteUint16(*((*uint16)(ptr))) -} - -func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*uint16)(ptr)) == 0 -} - -type uint32Codec struct { -} - -func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*uint32)(ptr)) = iter.ReadUint32() - } -} - -func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteUint32(*((*uint32)(ptr))) -} - -func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*uint32)(ptr)) == 0 -} - -type uint64Codec struct { -} - -func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*uint64)(ptr)) = iter.ReadUint64() - } -} - -func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteUint64(*((*uint64)(ptr))) -} - -func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*uint64)(ptr)) == 0 -} - -type float32Codec struct { -} - -func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*float32)(ptr)) = iter.ReadFloat32() - } -} - -func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteFloat32(*((*float32)(ptr))) -} - -func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*float32)(ptr)) == 0 -} - -type float64Codec struct { -} - -func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*float64)(ptr)) = iter.ReadFloat64() - } -} - -func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteFloat64(*((*float64)(ptr))) -} - -func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool { - return *((*float64)(ptr)) == 0 -} - -type boolCodec struct { -} - -func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.ReadNil() { - *((*bool)(ptr)) = iter.ReadBool() - } -} - -func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteBool(*((*bool)(ptr))) -} - -func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool { - return !(*((*bool)(ptr))) -} - -type base64Codec struct { - sliceType *reflect2.UnsafeSliceType - sliceDecoder ValDecoder -} - -func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { - if iter.ReadNil() { - codec.sliceType.UnsafeSetNil(ptr) - return - } - switch iter.WhatIsNext() { - case StringValue: - encoding := base64.StdEncoding - src := iter.SkipAndReturnBytes() - src = src[1 : len(src)-1] - decodedLen := encoding.DecodedLen(len(src)) - dst := make([]byte, decodedLen) - len, err := encoding.Decode(dst, src) - if err != nil { - iter.ReportError("decode base64", err.Error()) - } else { - dst = dst[:len] - codec.sliceType.UnsafeSet(ptr, unsafe.Pointer(&dst)) - } - case ArrayValue: - codec.sliceDecoder.Decode(ptr, iter) - default: - iter.ReportError("base64Codec", "invalid input") - } -} - -func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { - src := *((*[]byte)(ptr)) - if len(src) == 0 { - stream.WriteNil() - return - } - encoding := base64.StdEncoding - stream.writeByte('"') - size := encoding.EncodedLen(len(src)) - buf := make([]byte, size) - encoding.Encode(buf, src) - stream.buf = append(stream.buf, buf...) - stream.writeByte('"') -} - -func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool { - return len(*((*[]byte)(ptr))) == 0 -} diff --git a/vendor/github.com/json-iterator/go/reflect_optional.go b/vendor/github.com/json-iterator/go/reflect_optional.go deleted file mode 100644 index 43ec71d6d..000000000 --- a/vendor/github.com/json-iterator/go/reflect_optional.go +++ /dev/null @@ -1,133 +0,0 @@ -package jsoniter - -import ( - "github.com/modern-go/reflect2" - "reflect" - "unsafe" -) - -func decoderOfOptional(ctx *ctx, typ reflect2.Type) ValDecoder { - ptrType := typ.(*reflect2.UnsafePtrType) - elemType := ptrType.Elem() - decoder := decoderOfType(ctx, elemType) - if ctx.prefix == "" && elemType.Kind() == reflect.Ptr { - return &dereferenceDecoder{elemType, decoder} - } - return &OptionalDecoder{elemType, decoder} -} - -func encoderOfOptional(ctx *ctx, typ reflect2.Type) ValEncoder { - ptrType := typ.(*reflect2.UnsafePtrType) - elemType := ptrType.Elem() - elemEncoder := encoderOfType(ctx, elemType) - encoder := &OptionalEncoder{elemEncoder} - return encoder -} - -type OptionalDecoder struct { - ValueType reflect2.Type - ValueDecoder ValDecoder -} - -func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if iter.ReadNil() { - *((*unsafe.Pointer)(ptr)) = nil - } else { - if *((*unsafe.Pointer)(ptr)) == nil { - //pointer to null, we have to allocate memory to hold the value - newPtr := decoder.ValueType.UnsafeNew() - decoder.ValueDecoder.Decode(newPtr, iter) - *((*unsafe.Pointer)(ptr)) = newPtr - } else { - //reuse existing instance - decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) - } - } -} - -type dereferenceDecoder struct { - // only to deference a pointer - valueType reflect2.Type - valueDecoder ValDecoder -} - -func (decoder *dereferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if *((*unsafe.Pointer)(ptr)) == nil { - //pointer to null, we have to allocate memory to hold the value - newPtr := decoder.valueType.UnsafeNew() - decoder.valueDecoder.Decode(newPtr, iter) - *((*unsafe.Pointer)(ptr)) = newPtr - } else { - //reuse existing instance - decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) - } -} - -type OptionalEncoder struct { - ValueEncoder ValEncoder -} - -func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - if *((*unsafe.Pointer)(ptr)) == nil { - stream.WriteNil() - } else { - encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) - } -} - -func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return *((*unsafe.Pointer)(ptr)) == nil -} - -type dereferenceEncoder struct { - ValueEncoder ValEncoder -} - -func (encoder *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - if *((*unsafe.Pointer)(ptr)) == nil { - stream.WriteNil() - } else { - encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) - } -} - -func (encoder *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { - dePtr := *((*unsafe.Pointer)(ptr)) - if dePtr == nil { - return true - } - return encoder.ValueEncoder.IsEmpty(dePtr) -} - -func (encoder *dereferenceEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { - deReferenced := *((*unsafe.Pointer)(ptr)) - if deReferenced == nil { - return true - } - isEmbeddedPtrNil, converted := encoder.ValueEncoder.(IsEmbeddedPtrNil) - if !converted { - return false - } - fieldPtr := unsafe.Pointer(deReferenced) - return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr) -} - -type referenceEncoder struct { - encoder ValEncoder -} - -func (encoder *referenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) -} - -func (encoder *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) -} - -type referenceDecoder struct { - decoder ValDecoder -} - -func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - decoder.decoder.Decode(unsafe.Pointer(&ptr), iter) -} diff --git a/vendor/github.com/json-iterator/go/reflect_slice.go b/vendor/github.com/json-iterator/go/reflect_slice.go deleted file mode 100644 index 9441d79df..000000000 --- a/vendor/github.com/json-iterator/go/reflect_slice.go +++ /dev/null @@ -1,99 +0,0 @@ -package jsoniter - -import ( - "fmt" - "github.com/modern-go/reflect2" - "io" - "unsafe" -) - -func decoderOfSlice(ctx *ctx, typ reflect2.Type) ValDecoder { - sliceType := typ.(*reflect2.UnsafeSliceType) - decoder := decoderOfType(ctx.append("[sliceElem]"), sliceType.Elem()) - return &sliceDecoder{sliceType, decoder} -} - -func encoderOfSlice(ctx *ctx, typ reflect2.Type) ValEncoder { - sliceType := typ.(*reflect2.UnsafeSliceType) - encoder := encoderOfType(ctx.append("[sliceElem]"), sliceType.Elem()) - return &sliceEncoder{sliceType, encoder} -} - -type sliceEncoder struct { - sliceType *reflect2.UnsafeSliceType - elemEncoder ValEncoder -} - -func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - if encoder.sliceType.UnsafeIsNil(ptr) { - stream.WriteNil() - return - } - length := encoder.sliceType.UnsafeLengthOf(ptr) - if length == 0 { - stream.WriteEmptyArray() - return - } - stream.WriteArrayStart() - encoder.elemEncoder.Encode(encoder.sliceType.UnsafeGetIndex(ptr, 0), stream) - for i := 1; i < length; i++ { - stream.WriteMore() - elemPtr := encoder.sliceType.UnsafeGetIndex(ptr, i) - encoder.elemEncoder.Encode(elemPtr, stream) - } - stream.WriteArrayEnd() - if stream.Error != nil && stream.Error != io.EOF { - stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error()) - } -} - -func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.sliceType.UnsafeLengthOf(ptr) == 0 -} - -type sliceDecoder struct { - sliceType *reflect2.UnsafeSliceType - elemDecoder ValDecoder -} - -func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - decoder.doDecode(ptr, iter) - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error()) - } -} - -func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { - c := iter.nextToken() - sliceType := decoder.sliceType - if c == 'n' { - iter.skipThreeBytes('u', 'l', 'l') - sliceType.UnsafeSetNil(ptr) - return - } - if c != '[' { - iter.ReportError("decode slice", "expect [ or n, but found "+string([]byte{c})) - return - } - c = iter.nextToken() - if c == ']' { - sliceType.UnsafeSet(ptr, sliceType.UnsafeMakeSlice(0, 0)) - return - } - iter.unreadByte() - sliceType.UnsafeGrow(ptr, 1) - elemPtr := sliceType.UnsafeGetIndex(ptr, 0) - decoder.elemDecoder.Decode(elemPtr, iter) - length := 1 - for c = iter.nextToken(); c == ','; c = iter.nextToken() { - idx := length - length += 1 - sliceType.UnsafeGrow(ptr, length) - elemPtr = sliceType.UnsafeGetIndex(ptr, idx) - decoder.elemDecoder.Decode(elemPtr, iter) - } - if c != ']' { - iter.ReportError("decode slice", "expect ], but found "+string([]byte{c})) - return - } -} diff --git a/vendor/github.com/json-iterator/go/reflect_struct_decoder.go b/vendor/github.com/json-iterator/go/reflect_struct_decoder.go deleted file mode 100644 index e718722af..000000000 --- a/vendor/github.com/json-iterator/go/reflect_struct_decoder.go +++ /dev/null @@ -1,1034 +0,0 @@ -package jsoniter - -import ( - "fmt" - "github.com/modern-go/reflect2" - "io" - "strings" - "unsafe" -) - -func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder { - bindings := map[string]*Binding{} - structDescriptor := describeStruct(ctx, typ) - for _, binding := range structDescriptor.Fields { - for _, fromName := range binding.FromNames { - old := bindings[fromName] - if old == nil { - bindings[fromName] = binding - continue - } - ignoreOld, ignoreNew := resolveConflictBinding(ctx.frozenConfig, old, binding) - if ignoreOld { - delete(bindings, fromName) - } - if !ignoreNew { - bindings[fromName] = binding - } - } - } - fields := map[string]*structFieldDecoder{} - for k, binding := range bindings { - fields[k] = binding.Decoder.(*structFieldDecoder) - } - return createStructDecoder(ctx, typ, fields) -} - -func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structFieldDecoder) ValDecoder { - if ctx.disallowUnknownFields { - return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true} - } - knownHash := map[int64]struct{}{ - 0: {}, - } - switch len(fields) { - case 0: - return &skipObjectDecoder{typ} - case 1: - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder} - } - case 2: - var fieldHash1 int64 - var fieldHash2 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldHash1 == 0 { - fieldHash1 = fieldHash - fieldDecoder1 = fieldDecoder - } else { - fieldHash2 = fieldHash - fieldDecoder2 = fieldDecoder - } - } - return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2} - case 3: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } - } - return &threeFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3} - case 4: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldName4 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - var fieldDecoder4 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else if fieldName3 == 0 { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } else { - fieldName4 = fieldHash - fieldDecoder4 = fieldDecoder - } - } - return &fourFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4} - case 5: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldName4 int64 - var fieldName5 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - var fieldDecoder4 *structFieldDecoder - var fieldDecoder5 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else if fieldName3 == 0 { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } else if fieldName4 == 0 { - fieldName4 = fieldHash - fieldDecoder4 = fieldDecoder - } else { - fieldName5 = fieldHash - fieldDecoder5 = fieldDecoder - } - } - return &fiveFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, - fieldName5, fieldDecoder5} - case 6: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldName4 int64 - var fieldName5 int64 - var fieldName6 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - var fieldDecoder4 *structFieldDecoder - var fieldDecoder5 *structFieldDecoder - var fieldDecoder6 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else if fieldName3 == 0 { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } else if fieldName4 == 0 { - fieldName4 = fieldHash - fieldDecoder4 = fieldDecoder - } else if fieldName5 == 0 { - fieldName5 = fieldHash - fieldDecoder5 = fieldDecoder - } else { - fieldName6 = fieldHash - fieldDecoder6 = fieldDecoder - } - } - return &sixFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, - fieldName5, fieldDecoder5, - fieldName6, fieldDecoder6} - case 7: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldName4 int64 - var fieldName5 int64 - var fieldName6 int64 - var fieldName7 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - var fieldDecoder4 *structFieldDecoder - var fieldDecoder5 *structFieldDecoder - var fieldDecoder6 *structFieldDecoder - var fieldDecoder7 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else if fieldName3 == 0 { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } else if fieldName4 == 0 { - fieldName4 = fieldHash - fieldDecoder4 = fieldDecoder - } else if fieldName5 == 0 { - fieldName5 = fieldHash - fieldDecoder5 = fieldDecoder - } else if fieldName6 == 0 { - fieldName6 = fieldHash - fieldDecoder6 = fieldDecoder - } else { - fieldName7 = fieldHash - fieldDecoder7 = fieldDecoder - } - } - return &sevenFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, - fieldName5, fieldDecoder5, - fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7} - case 8: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldName4 int64 - var fieldName5 int64 - var fieldName6 int64 - var fieldName7 int64 - var fieldName8 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - var fieldDecoder4 *structFieldDecoder - var fieldDecoder5 *structFieldDecoder - var fieldDecoder6 *structFieldDecoder - var fieldDecoder7 *structFieldDecoder - var fieldDecoder8 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else if fieldName3 == 0 { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } else if fieldName4 == 0 { - fieldName4 = fieldHash - fieldDecoder4 = fieldDecoder - } else if fieldName5 == 0 { - fieldName5 = fieldHash - fieldDecoder5 = fieldDecoder - } else if fieldName6 == 0 { - fieldName6 = fieldHash - fieldDecoder6 = fieldDecoder - } else if fieldName7 == 0 { - fieldName7 = fieldHash - fieldDecoder7 = fieldDecoder - } else { - fieldName8 = fieldHash - fieldDecoder8 = fieldDecoder - } - } - return &eightFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, - fieldName5, fieldDecoder5, - fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7, - fieldName8, fieldDecoder8} - case 9: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldName4 int64 - var fieldName5 int64 - var fieldName6 int64 - var fieldName7 int64 - var fieldName8 int64 - var fieldName9 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - var fieldDecoder4 *structFieldDecoder - var fieldDecoder5 *structFieldDecoder - var fieldDecoder6 *structFieldDecoder - var fieldDecoder7 *structFieldDecoder - var fieldDecoder8 *structFieldDecoder - var fieldDecoder9 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else if fieldName3 == 0 { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } else if fieldName4 == 0 { - fieldName4 = fieldHash - fieldDecoder4 = fieldDecoder - } else if fieldName5 == 0 { - fieldName5 = fieldHash - fieldDecoder5 = fieldDecoder - } else if fieldName6 == 0 { - fieldName6 = fieldHash - fieldDecoder6 = fieldDecoder - } else if fieldName7 == 0 { - fieldName7 = fieldHash - fieldDecoder7 = fieldDecoder - } else if fieldName8 == 0 { - fieldName8 = fieldHash - fieldDecoder8 = fieldDecoder - } else { - fieldName9 = fieldHash - fieldDecoder9 = fieldDecoder - } - } - return &nineFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, - fieldName5, fieldDecoder5, - fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7, - fieldName8, fieldDecoder8, - fieldName9, fieldDecoder9} - case 10: - var fieldName1 int64 - var fieldName2 int64 - var fieldName3 int64 - var fieldName4 int64 - var fieldName5 int64 - var fieldName6 int64 - var fieldName7 int64 - var fieldName8 int64 - var fieldName9 int64 - var fieldName10 int64 - var fieldDecoder1 *structFieldDecoder - var fieldDecoder2 *structFieldDecoder - var fieldDecoder3 *structFieldDecoder - var fieldDecoder4 *structFieldDecoder - var fieldDecoder5 *structFieldDecoder - var fieldDecoder6 *structFieldDecoder - var fieldDecoder7 *structFieldDecoder - var fieldDecoder8 *structFieldDecoder - var fieldDecoder9 *structFieldDecoder - var fieldDecoder10 *structFieldDecoder - for fieldName, fieldDecoder := range fields { - fieldHash := calcHash(fieldName) - _, known := knownHash[fieldHash] - if known { - return &generalStructDecoder{typ, fields, false} - } - knownHash[fieldHash] = struct{}{} - if fieldName1 == 0 { - fieldName1 = fieldHash - fieldDecoder1 = fieldDecoder - } else if fieldName2 == 0 { - fieldName2 = fieldHash - fieldDecoder2 = fieldDecoder - } else if fieldName3 == 0 { - fieldName3 = fieldHash - fieldDecoder3 = fieldDecoder - } else if fieldName4 == 0 { - fieldName4 = fieldHash - fieldDecoder4 = fieldDecoder - } else if fieldName5 == 0 { - fieldName5 = fieldHash - fieldDecoder5 = fieldDecoder - } else if fieldName6 == 0 { - fieldName6 = fieldHash - fieldDecoder6 = fieldDecoder - } else if fieldName7 == 0 { - fieldName7 = fieldHash - fieldDecoder7 = fieldDecoder - } else if fieldName8 == 0 { - fieldName8 = fieldHash - fieldDecoder8 = fieldDecoder - } else if fieldName9 == 0 { - fieldName9 = fieldHash - fieldDecoder9 = fieldDecoder - } else { - fieldName10 = fieldHash - fieldDecoder10 = fieldDecoder - } - } - return &tenFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, - fieldName2, fieldDecoder2, - fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, - fieldName5, fieldDecoder5, - fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7, - fieldName8, fieldDecoder8, - fieldName9, fieldDecoder9, - fieldName10, fieldDecoder10} - } - return &generalStructDecoder{typ, fields, false} -} - -type generalStructDecoder struct { - typ reflect2.Type - fields map[string]*structFieldDecoder - disallowUnknownFields bool -} - -func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - decoder.decodeOneField(ptr, iter) - for iter.nextToken() == ',' { - decoder.decodeOneField(ptr, iter) - } - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } -} - -func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *Iterator) { - var field string - var fieldDecoder *structFieldDecoder - if iter.cfg.objectFieldMustBeSimpleString { - fieldBytes := iter.ReadStringAsSlice() - field = *(*string)(unsafe.Pointer(&fieldBytes)) - fieldDecoder = decoder.fields[field] - if fieldDecoder == nil { - fieldDecoder = decoder.fields[strings.ToLower(field)] - } - } else { - field = iter.ReadString() - fieldDecoder = decoder.fields[field] - if fieldDecoder == nil { - fieldDecoder = decoder.fields[strings.ToLower(field)] - } - } - if fieldDecoder == nil { - msg := "found unknown field: " + field - if decoder.disallowUnknownFields { - iter.ReportError("ReadObject", msg) - } - c := iter.nextToken() - if c != ':' { - iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) - } - iter.Skip() - return - } - c := iter.nextToken() - if c != ':' { - iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) - } - fieldDecoder.Decode(ptr, iter) -} - -type skipObjectDecoder struct { - typ reflect2.Type -} - -func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - valueType := iter.WhatIsNext() - if valueType != ObjectValue && valueType != NilValue { - iter.ReportError("skipObjectDecoder", "expect object or null") - return - } - iter.Skip() -} - -type oneFieldStructDecoder struct { - typ reflect2.Type - fieldHash int64 - fieldDecoder *structFieldDecoder -} - -func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - for { - if iter.readFieldHash() == decoder.fieldHash { - decoder.fieldDecoder.Decode(ptr, iter) - } else { - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } -} - -type twoFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder -} - -func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } -} - -type threeFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder -} - -func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } -} - -type fourFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder - fieldHash4 int64 - fieldDecoder4 *structFieldDecoder -} - -func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - case decoder.fieldHash4: - decoder.fieldDecoder4.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } -} - -type fiveFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder - fieldHash4 int64 - fieldDecoder4 *structFieldDecoder - fieldHash5 int64 - fieldDecoder5 *structFieldDecoder -} - -func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - case decoder.fieldHash4: - decoder.fieldDecoder4.Decode(ptr, iter) - case decoder.fieldHash5: - decoder.fieldDecoder5.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } -} - -type sixFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder - fieldHash4 int64 - fieldDecoder4 *structFieldDecoder - fieldHash5 int64 - fieldDecoder5 *structFieldDecoder - fieldHash6 int64 - fieldDecoder6 *structFieldDecoder -} - -func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - case decoder.fieldHash4: - decoder.fieldDecoder4.Decode(ptr, iter) - case decoder.fieldHash5: - decoder.fieldDecoder5.Decode(ptr, iter) - case decoder.fieldHash6: - decoder.fieldDecoder6.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } -} - -type sevenFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder - fieldHash4 int64 - fieldDecoder4 *structFieldDecoder - fieldHash5 int64 - fieldDecoder5 *structFieldDecoder - fieldHash6 int64 - fieldDecoder6 *structFieldDecoder - fieldHash7 int64 - fieldDecoder7 *structFieldDecoder -} - -func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - case decoder.fieldHash4: - decoder.fieldDecoder4.Decode(ptr, iter) - case decoder.fieldHash5: - decoder.fieldDecoder5.Decode(ptr, iter) - case decoder.fieldHash6: - decoder.fieldDecoder6.Decode(ptr, iter) - case decoder.fieldHash7: - decoder.fieldDecoder7.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } -} - -type eightFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder - fieldHash4 int64 - fieldDecoder4 *structFieldDecoder - fieldHash5 int64 - fieldDecoder5 *structFieldDecoder - fieldHash6 int64 - fieldDecoder6 *structFieldDecoder - fieldHash7 int64 - fieldDecoder7 *structFieldDecoder - fieldHash8 int64 - fieldDecoder8 *structFieldDecoder -} - -func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - case decoder.fieldHash4: - decoder.fieldDecoder4.Decode(ptr, iter) - case decoder.fieldHash5: - decoder.fieldDecoder5.Decode(ptr, iter) - case decoder.fieldHash6: - decoder.fieldDecoder6.Decode(ptr, iter) - case decoder.fieldHash7: - decoder.fieldDecoder7.Decode(ptr, iter) - case decoder.fieldHash8: - decoder.fieldDecoder8.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } -} - -type nineFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder - fieldHash4 int64 - fieldDecoder4 *structFieldDecoder - fieldHash5 int64 - fieldDecoder5 *structFieldDecoder - fieldHash6 int64 - fieldDecoder6 *structFieldDecoder - fieldHash7 int64 - fieldDecoder7 *structFieldDecoder - fieldHash8 int64 - fieldDecoder8 *structFieldDecoder - fieldHash9 int64 - fieldDecoder9 *structFieldDecoder -} - -func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - case decoder.fieldHash4: - decoder.fieldDecoder4.Decode(ptr, iter) - case decoder.fieldHash5: - decoder.fieldDecoder5.Decode(ptr, iter) - case decoder.fieldHash6: - decoder.fieldDecoder6.Decode(ptr, iter) - case decoder.fieldHash7: - decoder.fieldDecoder7.Decode(ptr, iter) - case decoder.fieldHash8: - decoder.fieldDecoder8.Decode(ptr, iter) - case decoder.fieldHash9: - decoder.fieldDecoder9.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } -} - -type tenFieldsStructDecoder struct { - typ reflect2.Type - fieldHash1 int64 - fieldDecoder1 *structFieldDecoder - fieldHash2 int64 - fieldDecoder2 *structFieldDecoder - fieldHash3 int64 - fieldDecoder3 *structFieldDecoder - fieldHash4 int64 - fieldDecoder4 *structFieldDecoder - fieldHash5 int64 - fieldDecoder5 *structFieldDecoder - fieldHash6 int64 - fieldDecoder6 *structFieldDecoder - fieldHash7 int64 - fieldDecoder7 *structFieldDecoder - fieldHash8 int64 - fieldDecoder8 *structFieldDecoder - fieldHash9 int64 - fieldDecoder9 *structFieldDecoder - fieldHash10 int64 - fieldDecoder10 *structFieldDecoder -} - -func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - if !iter.readObjectStart() { - return - } - for { - switch iter.readFieldHash() { - case decoder.fieldHash1: - decoder.fieldDecoder1.Decode(ptr, iter) - case decoder.fieldHash2: - decoder.fieldDecoder2.Decode(ptr, iter) - case decoder.fieldHash3: - decoder.fieldDecoder3.Decode(ptr, iter) - case decoder.fieldHash4: - decoder.fieldDecoder4.Decode(ptr, iter) - case decoder.fieldHash5: - decoder.fieldDecoder5.Decode(ptr, iter) - case decoder.fieldHash6: - decoder.fieldDecoder6.Decode(ptr, iter) - case decoder.fieldHash7: - decoder.fieldDecoder7.Decode(ptr, iter) - case decoder.fieldHash8: - decoder.fieldDecoder8.Decode(ptr, iter) - case decoder.fieldHash9: - decoder.fieldDecoder9.Decode(ptr, iter) - case decoder.fieldHash10: - decoder.fieldDecoder10.Decode(ptr, iter) - default: - iter.Skip() - } - if iter.isObjectEnd() { - break - } - } - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) - } -} - -type structFieldDecoder struct { - field reflect2.StructField - fieldDecoder ValDecoder -} - -func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - fieldPtr := decoder.field.UnsafeGet(ptr) - decoder.fieldDecoder.Decode(fieldPtr, iter) - if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%s: %s", decoder.field.Name(), iter.Error.Error()) - } -} - -type stringModeStringDecoder struct { - elemDecoder ValDecoder - cfg *frozenConfig -} - -func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - decoder.elemDecoder.Decode(ptr, iter) - str := *((*string)(ptr)) - tempIter := decoder.cfg.BorrowIterator([]byte(str)) - defer decoder.cfg.ReturnIterator(tempIter) - *((*string)(ptr)) = tempIter.ReadString() -} - -type stringModeNumberDecoder struct { - elemDecoder ValDecoder -} - -func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { - c := iter.nextToken() - if c != '"' { - iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) - return - } - decoder.elemDecoder.Decode(ptr, iter) - if iter.Error != nil { - return - } - c = iter.readByte() - if c != '"' { - iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) - return - } -} diff --git a/vendor/github.com/json-iterator/go/reflect_struct_encoder.go b/vendor/github.com/json-iterator/go/reflect_struct_encoder.go deleted file mode 100644 index d0759cf64..000000000 --- a/vendor/github.com/json-iterator/go/reflect_struct_encoder.go +++ /dev/null @@ -1,210 +0,0 @@ -package jsoniter - -import ( - "fmt" - "github.com/modern-go/reflect2" - "io" - "reflect" - "unsafe" -) - -func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder { - type bindingTo struct { - binding *Binding - toName string - ignored bool - } - orderedBindings := []*bindingTo{} - structDescriptor := describeStruct(ctx, typ) - for _, binding := range structDescriptor.Fields { - for _, toName := range binding.ToNames { - new := &bindingTo{ - binding: binding, - toName: toName, - } - for _, old := range orderedBindings { - if old.toName != toName { - continue - } - old.ignored, new.ignored = resolveConflictBinding(ctx.frozenConfig, old.binding, new.binding) - } - orderedBindings = append(orderedBindings, new) - } - } - if len(orderedBindings) == 0 { - return &emptyStructEncoder{} - } - finalOrderedFields := []structFieldTo{} - for _, bindingTo := range orderedBindings { - if !bindingTo.ignored { - finalOrderedFields = append(finalOrderedFields, structFieldTo{ - encoder: bindingTo.binding.Encoder.(*structFieldEncoder), - toName: bindingTo.toName, - }) - } - } - return &structEncoder{typ, finalOrderedFields} -} - -func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty { - encoder := createEncoderOfNative(ctx, typ) - if encoder != nil { - return encoder - } - kind := typ.Kind() - switch kind { - case reflect.Interface: - return &dynamicEncoder{typ} - case reflect.Struct: - return &structEncoder{typ: typ} - case reflect.Array: - return &arrayEncoder{} - case reflect.Slice: - return &sliceEncoder{} - case reflect.Map: - return encoderOfMap(ctx, typ) - case reflect.Ptr: - return &OptionalEncoder{} - default: - return &lazyErrorEncoder{err: fmt.Errorf("unsupported type: %v", typ)} - } -} - -func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) { - newTagged := new.Field.Tag().Get(cfg.getTagKey()) != "" - oldTagged := old.Field.Tag().Get(cfg.getTagKey()) != "" - if newTagged { - if oldTagged { - if len(old.levels) > len(new.levels) { - return true, false - } else if len(new.levels) > len(old.levels) { - return false, true - } else { - return true, true - } - } else { - return true, false - } - } else { - if oldTagged { - return true, false - } - if len(old.levels) > len(new.levels) { - return true, false - } else if len(new.levels) > len(old.levels) { - return false, true - } else { - return true, true - } - } -} - -type structFieldEncoder struct { - field reflect2.StructField - fieldEncoder ValEncoder - omitempty bool -} - -func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - fieldPtr := encoder.field.UnsafeGet(ptr) - encoder.fieldEncoder.Encode(fieldPtr, stream) - if stream.Error != nil && stream.Error != io.EOF { - stream.Error = fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error.Error()) - } -} - -func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool { - fieldPtr := encoder.field.UnsafeGet(ptr) - return encoder.fieldEncoder.IsEmpty(fieldPtr) -} - -func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { - isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil) - if !converted { - return false - } - fieldPtr := encoder.field.UnsafeGet(ptr) - return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr) -} - -type IsEmbeddedPtrNil interface { - IsEmbeddedPtrNil(ptr unsafe.Pointer) bool -} - -type structEncoder struct { - typ reflect2.Type - fields []structFieldTo -} - -type structFieldTo struct { - encoder *structFieldEncoder - toName string -} - -func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteObjectStart() - isNotFirst := false - for _, field := range encoder.fields { - if field.encoder.omitempty && field.encoder.IsEmpty(ptr) { - continue - } - if field.encoder.IsEmbeddedPtrNil(ptr) { - continue - } - if isNotFirst { - stream.WriteMore() - } - stream.WriteObjectField(field.toName) - field.encoder.Encode(ptr, stream) - isNotFirst = true - } - stream.WriteObjectEnd() - if stream.Error != nil && stream.Error != io.EOF { - stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error()) - } -} - -func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return false -} - -type emptyStructEncoder struct { -} - -func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteEmptyObject() -} - -func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return false -} - -type stringModeNumberEncoder struct { - elemEncoder ValEncoder -} - -func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - stream.writeByte('"') - encoder.elemEncoder.Encode(ptr, stream) - stream.writeByte('"') -} - -func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.elemEncoder.IsEmpty(ptr) -} - -type stringModeStringEncoder struct { - elemEncoder ValEncoder - cfg *frozenConfig -} - -func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - tempStream := encoder.cfg.BorrowStream(nil) - defer encoder.cfg.ReturnStream(tempStream) - encoder.elemEncoder.Encode(ptr, tempStream) - stream.WriteString(string(tempStream.Buffer())) -} - -func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.elemEncoder.IsEmpty(ptr) -} diff --git a/vendor/github.com/json-iterator/go/stream.go b/vendor/github.com/json-iterator/go/stream.go deleted file mode 100644 index 17662fded..000000000 --- a/vendor/github.com/json-iterator/go/stream.go +++ /dev/null @@ -1,211 +0,0 @@ -package jsoniter - -import ( - "io" -) - -// stream is a io.Writer like object, with JSON specific write functions. -// Error is not returned as return value, but stored as Error member on this stream instance. -type Stream struct { - cfg *frozenConfig - out io.Writer - buf []byte - Error error - indention int - Attachment interface{} // open for customized encoder -} - -// NewStream create new stream instance. -// cfg can be jsoniter.ConfigDefault. -// out can be nil if write to internal buffer. -// bufSize is the initial size for the internal buffer in bytes. -func NewStream(cfg API, out io.Writer, bufSize int) *Stream { - return &Stream{ - cfg: cfg.(*frozenConfig), - out: out, - buf: make([]byte, 0, bufSize), - Error: nil, - indention: 0, - } -} - -// Pool returns a pool can provide more stream with same configuration -func (stream *Stream) Pool() StreamPool { - return stream.cfg -} - -// Reset reuse this stream instance by assign a new writer -func (stream *Stream) Reset(out io.Writer) { - stream.out = out - stream.buf = stream.buf[:0] -} - -// Available returns how many bytes are unused in the buffer. -func (stream *Stream) Available() int { - return cap(stream.buf) - len(stream.buf) -} - -// Buffered returns the number of bytes that have been written into the current buffer. -func (stream *Stream) Buffered() int { - return len(stream.buf) -} - -// Buffer if writer is nil, use this method to take the result -func (stream *Stream) Buffer() []byte { - return stream.buf -} - -// SetBuffer allows to append to the internal buffer directly -func (stream *Stream) SetBuffer(buf []byte) { - stream.buf = buf -} - -// Write writes the contents of p into the buffer. -// It returns the number of bytes written. -// If nn < len(p), it also returns an error explaining -// why the write is short. -func (stream *Stream) Write(p []byte) (nn int, err error) { - stream.buf = append(stream.buf, p...) - if stream.out != nil { - nn, err = stream.out.Write(stream.buf) - stream.buf = stream.buf[nn:] - return - } - return len(p), nil -} - -// WriteByte writes a single byte. -func (stream *Stream) writeByte(c byte) { - stream.buf = append(stream.buf, c) -} - -func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) { - stream.buf = append(stream.buf, c1, c2) -} - -func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) { - stream.buf = append(stream.buf, c1, c2, c3) -} - -func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) { - stream.buf = append(stream.buf, c1, c2, c3, c4) -} - -func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) { - stream.buf = append(stream.buf, c1, c2, c3, c4, c5) -} - -// Flush writes any buffered data to the underlying io.Writer. -func (stream *Stream) Flush() error { - if stream.out == nil { - return nil - } - if stream.Error != nil { - return stream.Error - } - n, err := stream.out.Write(stream.buf) - if err != nil { - if stream.Error == nil { - stream.Error = err - } - return err - } - stream.buf = stream.buf[n:] - return nil -} - -// WriteRaw write string out without quotes, just like []byte -func (stream *Stream) WriteRaw(s string) { - stream.buf = append(stream.buf, s...) -} - -// WriteNil write null to stream -func (stream *Stream) WriteNil() { - stream.writeFourBytes('n', 'u', 'l', 'l') -} - -// WriteTrue write true to stream -func (stream *Stream) WriteTrue() { - stream.writeFourBytes('t', 'r', 'u', 'e') -} - -// WriteFalse write false to stream -func (stream *Stream) WriteFalse() { - stream.writeFiveBytes('f', 'a', 'l', 's', 'e') -} - -// WriteBool write true or false into stream -func (stream *Stream) WriteBool(val bool) { - if val { - stream.WriteTrue() - } else { - stream.WriteFalse() - } -} - -// WriteObjectStart write { with possible indention -func (stream *Stream) WriteObjectStart() { - stream.indention += stream.cfg.indentionStep - stream.writeByte('{') - stream.writeIndention(0) -} - -// WriteObjectField write "field": with possible indention -func (stream *Stream) WriteObjectField(field string) { - stream.WriteString(field) - if stream.indention > 0 { - stream.writeTwoBytes(':', ' ') - } else { - stream.writeByte(':') - } -} - -// WriteObjectEnd write } with possible indention -func (stream *Stream) WriteObjectEnd() { - stream.writeIndention(stream.cfg.indentionStep) - stream.indention -= stream.cfg.indentionStep - stream.writeByte('}') -} - -// WriteEmptyObject write {} -func (stream *Stream) WriteEmptyObject() { - stream.writeByte('{') - stream.writeByte('}') -} - -// WriteMore write , with possible indention -func (stream *Stream) WriteMore() { - stream.writeByte(',') - stream.writeIndention(0) - stream.Flush() -} - -// WriteArrayStart write [ with possible indention -func (stream *Stream) WriteArrayStart() { - stream.indention += stream.cfg.indentionStep - stream.writeByte('[') - stream.writeIndention(0) -} - -// WriteEmptyArray write [] -func (stream *Stream) WriteEmptyArray() { - stream.writeTwoBytes('[', ']') -} - -// WriteArrayEnd write ] with possible indention -func (stream *Stream) WriteArrayEnd() { - stream.writeIndention(stream.cfg.indentionStep) - stream.indention -= stream.cfg.indentionStep - stream.writeByte(']') -} - -func (stream *Stream) writeIndention(delta int) { - if stream.indention == 0 { - return - } - stream.writeByte('\n') - toWrite := stream.indention - delta - for i := 0; i < toWrite; i++ { - stream.buf = append(stream.buf, ' ') - } -} diff --git a/vendor/github.com/json-iterator/go/stream_float.go b/vendor/github.com/json-iterator/go/stream_float.go deleted file mode 100644 index f318d2c59..000000000 --- a/vendor/github.com/json-iterator/go/stream_float.go +++ /dev/null @@ -1,94 +0,0 @@ -package jsoniter - -import ( - "math" - "strconv" -) - -var pow10 []uint64 - -func init() { - pow10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000} -} - -// WriteFloat32 write float32 to stream -func (stream *Stream) WriteFloat32(val float32) { - abs := math.Abs(float64(val)) - fmt := byte('f') - // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. - if abs != 0 { - if float32(abs) < 1e-6 || float32(abs) >= 1e21 { - fmt = 'e' - } - } - stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 32) -} - -// WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster -func (stream *Stream) WriteFloat32Lossy(val float32) { - if val < 0 { - stream.writeByte('-') - val = -val - } - if val > 0x4ffffff { - stream.WriteFloat32(val) - return - } - precision := 6 - exp := uint64(1000000) // 6 - lval := uint64(float64(val)*float64(exp) + 0.5) - stream.WriteUint64(lval / exp) - fval := lval % exp - if fval == 0 { - return - } - stream.writeByte('.') - for p := precision - 1; p > 0 && fval < pow10[p]; p-- { - stream.writeByte('0') - } - stream.WriteUint64(fval) - for stream.buf[len(stream.buf)-1] == '0' { - stream.buf = stream.buf[:len(stream.buf)-1] - } -} - -// WriteFloat64 write float64 to stream -func (stream *Stream) WriteFloat64(val float64) { - abs := math.Abs(val) - fmt := byte('f') - // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. - if abs != 0 { - if abs < 1e-6 || abs >= 1e21 { - fmt = 'e' - } - } - stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 64) -} - -// WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster -func (stream *Stream) WriteFloat64Lossy(val float64) { - if val < 0 { - stream.writeByte('-') - val = -val - } - if val > 0x4ffffff { - stream.WriteFloat64(val) - return - } - precision := 6 - exp := uint64(1000000) // 6 - lval := uint64(val*float64(exp) + 0.5) - stream.WriteUint64(lval / exp) - fval := lval % exp - if fval == 0 { - return - } - stream.writeByte('.') - for p := precision - 1; p > 0 && fval < pow10[p]; p-- { - stream.writeByte('0') - } - stream.WriteUint64(fval) - for stream.buf[len(stream.buf)-1] == '0' { - stream.buf = stream.buf[:len(stream.buf)-1] - } -} diff --git a/vendor/github.com/json-iterator/go/stream_int.go b/vendor/github.com/json-iterator/go/stream_int.go deleted file mode 100644 index d1059ee4c..000000000 --- a/vendor/github.com/json-iterator/go/stream_int.go +++ /dev/null @@ -1,190 +0,0 @@ -package jsoniter - -var digits []uint32 - -func init() { - digits = make([]uint32, 1000) - for i := uint32(0); i < 1000; i++ { - digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0' - if i < 10 { - digits[i] += 2 << 24 - } else if i < 100 { - digits[i] += 1 << 24 - } - } -} - -func writeFirstBuf(space []byte, v uint32) []byte { - start := v >> 24 - if start == 0 { - space = append(space, byte(v>>16), byte(v>>8)) - } else if start == 1 { - space = append(space, byte(v>>8)) - } - space = append(space, byte(v)) - return space -} - -func writeBuf(buf []byte, v uint32) []byte { - return append(buf, byte(v>>16), byte(v>>8), byte(v)) -} - -// WriteUint8 write uint8 to stream -func (stream *Stream) WriteUint8(val uint8) { - stream.buf = writeFirstBuf(stream.buf, digits[val]) -} - -// WriteInt8 write int8 to stream -func (stream *Stream) WriteInt8(nval int8) { - var val uint8 - if nval < 0 { - val = uint8(-nval) - stream.buf = append(stream.buf, '-') - } else { - val = uint8(nval) - } - stream.buf = writeFirstBuf(stream.buf, digits[val]) -} - -// WriteUint16 write uint16 to stream -func (stream *Stream) WriteUint16(val uint16) { - q1 := val / 1000 - if q1 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[val]) - return - } - r1 := val - q1*1000 - stream.buf = writeFirstBuf(stream.buf, digits[q1]) - stream.buf = writeBuf(stream.buf, digits[r1]) - return -} - -// WriteInt16 write int16 to stream -func (stream *Stream) WriteInt16(nval int16) { - var val uint16 - if nval < 0 { - val = uint16(-nval) - stream.buf = append(stream.buf, '-') - } else { - val = uint16(nval) - } - stream.WriteUint16(val) -} - -// WriteUint32 write uint32 to stream -func (stream *Stream) WriteUint32(val uint32) { - q1 := val / 1000 - if q1 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[val]) - return - } - r1 := val - q1*1000 - q2 := q1 / 1000 - if q2 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[q1]) - stream.buf = writeBuf(stream.buf, digits[r1]) - return - } - r2 := q1 - q2*1000 - q3 := q2 / 1000 - if q3 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[q2]) - } else { - r3 := q2 - q3*1000 - stream.buf = append(stream.buf, byte(q3+'0')) - stream.buf = writeBuf(stream.buf, digits[r3]) - } - stream.buf = writeBuf(stream.buf, digits[r2]) - stream.buf = writeBuf(stream.buf, digits[r1]) -} - -// WriteInt32 write int32 to stream -func (stream *Stream) WriteInt32(nval int32) { - var val uint32 - if nval < 0 { - val = uint32(-nval) - stream.buf = append(stream.buf, '-') - } else { - val = uint32(nval) - } - stream.WriteUint32(val) -} - -// WriteUint64 write uint64 to stream -func (stream *Stream) WriteUint64(val uint64) { - q1 := val / 1000 - if q1 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[val]) - return - } - r1 := val - q1*1000 - q2 := q1 / 1000 - if q2 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[q1]) - stream.buf = writeBuf(stream.buf, digits[r1]) - return - } - r2 := q1 - q2*1000 - q3 := q2 / 1000 - if q3 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[q2]) - stream.buf = writeBuf(stream.buf, digits[r2]) - stream.buf = writeBuf(stream.buf, digits[r1]) - return - } - r3 := q2 - q3*1000 - q4 := q3 / 1000 - if q4 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[q3]) - stream.buf = writeBuf(stream.buf, digits[r3]) - stream.buf = writeBuf(stream.buf, digits[r2]) - stream.buf = writeBuf(stream.buf, digits[r1]) - return - } - r4 := q3 - q4*1000 - q5 := q4 / 1000 - if q5 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[q4]) - stream.buf = writeBuf(stream.buf, digits[r4]) - stream.buf = writeBuf(stream.buf, digits[r3]) - stream.buf = writeBuf(stream.buf, digits[r2]) - stream.buf = writeBuf(stream.buf, digits[r1]) - return - } - r5 := q4 - q5*1000 - q6 := q5 / 1000 - if q6 == 0 { - stream.buf = writeFirstBuf(stream.buf, digits[q5]) - } else { - stream.buf = writeFirstBuf(stream.buf, digits[q6]) - r6 := q5 - q6*1000 - stream.buf = writeBuf(stream.buf, digits[r6]) - } - stream.buf = writeBuf(stream.buf, digits[r5]) - stream.buf = writeBuf(stream.buf, digits[r4]) - stream.buf = writeBuf(stream.buf, digits[r3]) - stream.buf = writeBuf(stream.buf, digits[r2]) - stream.buf = writeBuf(stream.buf, digits[r1]) -} - -// WriteInt64 write int64 to stream -func (stream *Stream) WriteInt64(nval int64) { - var val uint64 - if nval < 0 { - val = uint64(-nval) - stream.buf = append(stream.buf, '-') - } else { - val = uint64(nval) - } - stream.WriteUint64(val) -} - -// WriteInt write int to stream -func (stream *Stream) WriteInt(val int) { - stream.WriteInt64(int64(val)) -} - -// WriteUint write uint to stream -func (stream *Stream) WriteUint(val uint) { - stream.WriteUint64(uint64(val)) -} diff --git a/vendor/github.com/json-iterator/go/stream_str.go b/vendor/github.com/json-iterator/go/stream_str.go deleted file mode 100644 index 54c2ba0b3..000000000 --- a/vendor/github.com/json-iterator/go/stream_str.go +++ /dev/null @@ -1,372 +0,0 @@ -package jsoniter - -import ( - "unicode/utf8" -) - -// htmlSafeSet holds the value true if the ASCII character with the given -// array position can be safely represented inside a JSON string, embedded -// inside of HTML