From c97498dfc9a328c2fbb0cbd478a57e39098429db Mon Sep 17 00:00:00 2001 From: Jessica Yuen <im.jessicayuen@gmail.com> Date: Thu, 28 Sep 2017 10:32:36 -0700 Subject: [PATCH] Construct base components object In order to support environment heirarchy, we need to be able to reference all components. This commit will implement component imports as k-v pairs ex: foo: "import/foo.jsonnet" as a Jsonnet object. This jsonnet object will then be assigned as an ExtCode so that it can be referenced by a base.libsonnet file which environments can build / override upon. --- cmd/root.go | 28 ++++++++++++++++- cmd/root_test.go | 75 ++++++++++++++++++++++++++++++++++++++++++++ template/expander.go | 16 ++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 cmd/root_test.go diff --git a/cmd/root.go b/cmd/root.go index 8c4b074e..c429c6bb 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -22,6 +22,7 @@ import ( "fmt" "io" "os" + "path" "path/filepath" "reflect" "strings" @@ -58,6 +59,8 @@ const ( // environment or the -f flag. flagFile = "file" flagFileShort = "f" + + componentsExtCodeKey = "__ksonnet/components" ) var clientConfig clientcmd.ClientConfig @@ -369,8 +372,9 @@ func expandEnvCmdObjs(cmd *cobra.Command, envSpec *envSpec, cwd metadata.AbsPath if err != nil { return nil, err } + baseObjExtCode := fmt.Sprintf("%s=%s", componentsExtCodeKey, constructBaseObj(fileNames)) + expander.ExtCodes = append([]string{baseObjExtCode}) } - } // @@ -379,3 +383,25 @@ func expandEnvCmdObjs(cmd *cobra.Command, envSpec *envSpec, cwd metadata.AbsPath return expander.Expand(fileNames) } + +// constructBaseObj constructs the base Jsonnet object that represents k-v +// pairs of component name -> component imports. For example, +// +// { +// foo: import "components/foo.jsonnet" +// } +func constructBaseObj(paths []string) string { + var obj bytes.Buffer + obj.WriteString("{\n") + for _, p := range paths { + ext := path.Ext(p) + if path.Ext(p) != ".jsonnet" { + continue + } + + name := strings.TrimSuffix(path.Base(p), ext) + fmt.Fprintf(&obj, " %s: import \"%s\",\n", name, p) + } + obj.WriteString("}\n") + return obj.String() +} diff --git a/cmd/root_test.go b/cmd/root_test.go new file mode 100644 index 00000000..3ee755b6 --- /dev/null +++ b/cmd/root_test.go @@ -0,0 +1,75 @@ +// Copyright 2017 The kubecfg 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 cmd + +import ( + "testing" +) + +func TestConstructBaseObj(t *testing.T) { + tests := []struct { + inputPaths []string + expected string + }{ + // test simple case with 1 .jsonnet path + { + []string{ + "some/fake/path/foo.jsonnet", + }, + `{ + foo: import "some/fake/path/foo.jsonnet", +} +`, + }, + // test multiple .jsonnet path case + { + []string{ + "some/fake/path/foo.jsonnet", + "another/fake/path/bar.jsonnet", + }, + `{ + foo: import "some/fake/path/foo.jsonnet", + bar: import "another/fake/path/bar.jsonnet", +} +`, + }, + // test zero path case + { + []string{}, + `{ +} +`, + }, + // test non-jsonnet extension case + { + []string{ + "some/fake/path/foo.libsonnet", + "another/fake/path/bar.jsonnet", + }, + `{ + bar: import "another/fake/path/bar.jsonnet", +} +`, + }, + } + + for _, s := range tests { + res := constructBaseObj(s.inputPaths) + if res != s.expected { + t.Errorf("Wrong object constructed\n expected: %v\n got: %v", s.expected, res) + } + } +} diff --git a/template/expander.go b/template/expander.go index d414db8c..4c7fbe00 100644 --- a/template/expander.go +++ b/template/expander.go @@ -20,6 +20,7 @@ type Expander struct { ExtVarFiles []string TlaVars []string TlaVarFiles []string + ExtCodes []string Resolver string FailAction string @@ -112,6 +113,21 @@ func (spec *Expander) jsonnetVM() (*jsonnet.VM, error) { vm.TlaVar(kv[0], string(v)) } + for _, extcode := range spec.ExtCodes { + kv := strings.SplitN(extcode, "=", 2) + switch len(kv) { + case 1: + v, present := os.LookupEnv(kv[0]) + if present { + vm.ExtCode(kv[0], v) + } else { + return nil, fmt.Errorf("Missing environment variable: %s", kv[0]) + } + case 2: + vm.ExtCode(kv[0], kv[1]) + } + } + resolver, err := spec.buildResolver() if err != nil { return nil, err -- GitLab