From 6378e75ab8f5988a01c7f08ec2e9a8b1ad9e79f4 Mon Sep 17 00:00:00 2001
From: Jessica Yuen <im.jessicayuen@gmail.com>
Date: Tue, 3 Oct 2017 13:32:48 -0700
Subject: [PATCH] Expand environment .jsonnet file

Commands that take `env` as a param currently expand all files in the
`components` directory. This is no longer necessary with the
introduction of `base.libsonnet` and the per-environment override
`<env>.jsonnet` file.

This commit will simply expand the single `<env>.jsonnet` file (which
will implicitly expand all component files). The case of running
`ksonnet apply default`, is equivalent to running `ksonnet apply -f
environments/default/default.jsonnet`.
---
 cmd/root.go                  |  9 ++++-----
 metadata/environment.go      |  7 ++++---
 metadata/environment_test.go |  5 +++--
 metadata/interface.go        |  2 +-
 metadata/manager.go          | 11 +++++++----
 metadata/manager_test.go     |  6 +++++-
 6 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/cmd/root.go b/cmd/root.go
index b9175f00..372f8875 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -59,8 +59,6 @@ const (
 	// environment or the -f flag.
 	flagFile      = "file"
 	flagFileShort = "f"
-
-	componentsExtCodeKey = "__ksonnet/components"
 )
 
 var clientConfig clientcmd.ClientConfig
@@ -372,16 +370,17 @@ func expandEnvCmdObjs(cmd *cobra.Command, envSpec *envSpec, cwd metadata.AbsPath
 			return nil, err
 		}
 
-		libPath, envLibPath := manager.LibPaths(*envSpec.env)
+		libPath, envLibPath, envComponentPath := manager.LibPaths(*envSpec.env)
 		expander.FlagJpath = append([]string{string(libPath), string(envLibPath)}, expander.FlagJpath...)
 
 		if !filesPresent {
-			fileNames, err = manager.ComponentPaths()
+			componentPaths, err := manager.ComponentPaths()
 			if err != nil {
 				return nil, err
 			}
-			baseObjExtCode := fmt.Sprintf("%s=%s", componentsExtCodeKey, constructBaseObj(fileNames))
+			baseObjExtCode := fmt.Sprintf("%s=%s", metadata.ComponentsExtCodeKey, constructBaseObj(componentPaths))
 			expander.ExtCodes = append([]string{baseObjExtCode}, expander.ExtCodes...)
+			fileNames = []string{string(envComponentPath)}
 		}
 	}
 
diff --git a/metadata/environment.go b/metadata/environment.go
index 8d1e8ef7..850cbc3b 100644
--- a/metadata/environment.go
+++ b/metadata/environment.go
@@ -123,7 +123,7 @@ func (m *manager) createEnvironment(name, uri string, extensionsLibData, k8sLibD
 		return err
 	}
 
-	// Generate the base.libsonnet override file
+	// Generate the environment .jsonnet file
 	overrideFileName := path.Base(name) + ".jsonnet"
 	overrideData := m.generateOverrideData()
 	log.Debugf("Generating '%s', length: %d", overrideFileName, len(overrideData))
@@ -350,9 +350,10 @@ func (m *manager) generateKsonnetLibData(spec ClusterSpec) ([]byte, []byte, []by
 func (m *manager) generateOverrideData() []byte {
 	var buf bytes.Buffer
 	buf.WriteString(fmt.Sprintf("local base = import \"%s\";\n", m.baseLibsonnetPath))
-	buf.WriteString(fmt.Sprintf("local k = import \"%s\";\n\n", path.Join(metadataDirName, extensionsLibFilename)))
+	buf.WriteString(fmt.Sprintf("local k = import \"%s\";\n\n", extensionsLibFilename))
 	buf.WriteString("base + {\n")
-	buf.WriteString("  // Insert user-specified overrides here.\n")
+	buf.WriteString("  // Insert user-specified overrides here. For example if a component is named \"nginx-deployment\", you might have something like:\n")
+	buf.WriteString("  //   \"nginx-deployment\"+: k.deployment.mixin.metadata.labels({foo: \"bar\"})\n")
 	buf.WriteString("}\n")
 	return buf.Bytes()
 }
diff --git a/metadata/environment_test.go b/metadata/environment_test.go
index d922b6fc..e4350417 100644
--- a/metadata/environment_test.go
+++ b/metadata/environment_test.go
@@ -185,10 +185,11 @@ func TestGenerateOverrideData(t *testing.T) {
 	m := mockEnvironments(t, "test-gen-override-data")
 
 	expected := `local base = import "test-gen-override-data/environments/base.libsonnet";
-local k = import ".metadata/k.libsonnet";
+local k = import "k.libsonnet";
 
 base + {
-  // Insert user-specified overrides here.
+  // Insert user-specified overrides here. For example if a component is named "nginx-deployment", you might have something like:
+  //   "nginx-deployment"+: k.deployment.mixin.metadata.labels({foo: "bar"})
 }
 `
 	result := m.generateOverrideData()
diff --git a/metadata/interface.go b/metadata/interface.go
index afdb46df..5c22265e 100644
--- a/metadata/interface.go
+++ b/metadata/interface.go
@@ -43,7 +43,7 @@ type Manager interface {
 	Root() AbsPath
 	ComponentPaths() (AbsPaths, error)
 	CreateComponent(name string, text string, templateType prototype.TemplateType) error
-	LibPaths(envName string) (libPath, envLibPath AbsPath)
+	LibPaths(envName string) (libPath, envLibPath, envComponentPath AbsPath)
 	CreateEnvironment(name, uri string, spec ClusterSpec) error
 	DeleteEnvironment(name string) error
 	GetEnvironments() ([]*Environment, error)
diff --git a/metadata/manager.go b/metadata/manager.go
index 31201447..2792d405 100644
--- a/metadata/manager.go
+++ b/metadata/manager.go
@@ -40,6 +40,9 @@ const (
 	vendorDir       = "vendor"
 
 	baseLibsonnetFile = "base.libsonnet"
+
+	// ComponentsExtCodeKey is the ExtCode key for component imports
+	ComponentsExtCodeKey = "__ksonnet/components"
 )
 
 type manager struct {
@@ -175,8 +178,9 @@ func (m *manager) CreateComponent(name string, text string, templateType prototy
 	return afero.WriteFile(m.appFS, componentPath, []byte(text), defaultFilePermissions)
 }
 
-func (m *manager) LibPaths(envName string) (libPath, envLibPath AbsPath) {
-	return m.libPath, appendToAbsPath(m.environmentsPath, envName, metadataDirName)
+func (m *manager) LibPaths(envName string) (libPath, envLibPath, envComponentPath AbsPath) {
+	envPath := appendToAbsPath(m.environmentsPath, envName)
+	return m.libPath, appendToAbsPath(envPath, metadataDirName), appendToAbsPath(envPath, path.Base(envName)+".jsonnet")
 }
 
 func (m *manager) createAppDirTree() error {
@@ -206,8 +210,7 @@ func (m *manager) createAppDirTree() error {
 }
 
 func genBaseLibsonnetContent() []byte {
-	// TODO replace with constant ref once #164 is merged
-	return []byte(`local components = std.extVar("__ksonnet/components");
+	return []byte(`local components = std.extVar("` + ComponentsExtCodeKey + `");
 components + {
   // Insert user-specified overrides here.
 }
diff --git a/metadata/manager_test.go b/metadata/manager_test.go
index 330778e8..c3f40ad2 100644
--- a/metadata/manager_test.go
+++ b/metadata/manager_test.go
@@ -215,15 +215,19 @@ func TestLibPaths(t *testing.T) {
 	appName := "test-lib-paths"
 	expectedLibPath := path.Join(appName, libDir)
 	expectedEnvLibPath := path.Join(appName, environmentsDir, mockEnvName, metadataDirName)
+	expectedEnvComponentPath := path.Join(appName, environmentsDir, mockEnvName, path.Base(mockEnvName)+".jsonnet")
 	m := mockEnvironments(t, appName)
 
-	libPath, envLibPath := m.LibPaths(mockEnvName)
+	libPath, envLibPath, envComponentPath := m.LibPaths(mockEnvName)
 	if string(libPath) != expectedLibPath {
 		t.Fatalf("Expected lib path to be:\n  '%s'\n, got:\n  '%s'", expectedLibPath, libPath)
 	}
 	if string(envLibPath) != expectedEnvLibPath {
 		t.Fatalf("Expected environment lib path to be:\n  '%s'\n, got:\n  '%s'", expectedEnvLibPath, envLibPath)
 	}
+	if string(envComponentPath) != expectedEnvComponentPath {
+		t.Fatalf("Expected environment component path to be:\n  '%s'\n, got:\n  '%s'", expectedEnvComponentPath, envComponentPath)
+	}
 }
 
 func TestFindFailure(t *testing.T) {
-- 
GitLab