Skip to content

Commit

Permalink
Merge branch 'master' into integrate-apply-command2
Browse files Browse the repository at this point in the history
  • Loading branch information
bmonkman committed Jun 23, 2020
2 parents 46cb194 + 325a6c4 commit d86950a
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 59 deletions.
9 changes: 8 additions & 1 deletion cmd/init.go
@@ -1,8 +1,11 @@
package cmd

import (
"fmt"

"github.com/commitdev/zero/internal/config/projectconfig"
initPrompts "github.com/commitdev/zero/internal/init"
"github.com/commitdev/zero/pkg/util/exit"
"github.com/spf13/cobra"
)

Expand All @@ -15,6 +18,10 @@ var initCmd = &cobra.Command{
Short: "Create new project with provided name and initialize configuration based on user input.",
Run: func(cmd *cobra.Command, args []string) {
projectContext := initPrompts.Init(projectconfig.RootDir)
projectconfig.Init(projectconfig.RootDir, projectContext.Name, projectContext)
projectConfigErr := projectconfig.CreateProjectConfigFile(projectconfig.RootDir, projectContext.Name, projectContext)

if projectConfigErr != nil {
exit.Fatal(fmt.Sprintf(" Init failed while creating the zero project config file %s", projectConfigErr.Error()))
}
},
}
81 changes: 48 additions & 33 deletions internal/config/projectconfig/init.go
@@ -1,43 +1,25 @@
package projectconfig

import (
"bytes"
"fmt"
"io/ioutil"
"path"
"text/template"

"github.com/commitdev/zero/internal/constants"
"github.com/commitdev/zero/pkg/util/exit"
"github.com/commitdev/zero/internal/util"
"gopkg.in/yaml.v2"
)

const exampleConfig = `name: %s
const zeroProjectConfigTemplate = `
# Templated zero-project.yml file
name: {{.Name}}
# Context is normally populated automatically but could be used to inject global params
context:
shouldPushRepositories: {{.ShouldPushRepositories | printf "%v"}}
# module can be in any format the go-getter supports (path, github, url, etc.)
# supports https://github.com/hashicorp/go-getter#url-format
# Example:
# - repo: "../development/modules/ci"
# - dir: "github-actions"
modules:
aws-eks-stack:
parameters:
repoName: infrastructure
region: us-east-1
accountId: 12345
productionHost: something.com
files:
dir: infrastructure
repo: https://github.com/myorg/infrastructure
some-other-module:
parameters:
repoName: api
files:
dir: api
repo: https://github.com/myorg/api
{{.Modules}}
`

var RootDir = "./"
Expand All @@ -46,16 +28,49 @@ func SetRootDir(dir string) {
RootDir = dir
}

func Init(dir string, projectName string, projectContext *ZeroProjectConfig) {
// TODO: template the zero-project.yml with projectContext
// content := []byte(fmt.Sprintf(exampleConfig, projectName))
content, err := yaml.Marshal(projectContext)
// CreateProjectConfigFile extracts the required content for zero project config file then write to disk.
func CreateProjectConfigFile(dir string, projectName string, projectContext *ZeroProjectConfig) error {
content, err := getProjectFileContent(*projectContext)
if err != nil {
exit.Fatal(fmt.Sprintf("Failed to serialize configuration file %s", constants.ZeroProjectYml))
return err
}

writeErr := ioutil.WriteFile(path.Join(dir, projectName, constants.ZeroProjectYml), content, 0644)
writeErr := ioutil.WriteFile(path.Join(dir, projectName, constants.ZeroProjectYml), []byte(content), 0644)
if writeErr != nil {
exit.Fatal(fmt.Sprintf("Failed to create config file %s", constants.ZeroProjectYml))
return err
}

return nil
}

func getProjectFileContent(projectConfig ZeroProjectConfig) (string, error) {
var tplBuffer bytes.Buffer
tmpl, err := template.New("projectConfig").Parse(zeroProjectConfigTemplate)
if err != nil {
return "", err
}

if len(projectConfig.Modules) == 0 {
return "", fmt.Errorf("Invalid project config, expected config modules to be non-empty")
}

pConfigModules, err := yaml.Marshal(projectConfig.Modules)
if err != nil {
return "", err
}

t := struct {
Name string
ShouldPushRepositories bool
Modules string
}{
Name: projectConfig.Name,
ShouldPushRepositories: projectConfig.ShouldPushRepositories,
Modules: util.IndentString(string(pConfigModules), 2),
}

if err := tmpl.Execute(&tplBuffer, t); err != nil {
return "", err
}
return tplBuffer.String(), nil
}
29 changes: 26 additions & 3 deletions internal/config/projectconfig/init_test.go
Expand Up @@ -7,26 +7,49 @@ import (

"github.com/commitdev/zero/internal/config/projectconfig"
"github.com/commitdev/zero/internal/constants"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/stretchr/testify/assert"
)

func TestInit(t *testing.T) {
func TestCreateProjectConfigFile(t *testing.T) {
const testDir = "../../test-sandbox"
projectName := "test-project"

projectconfig.SetRootDir(testDir)
defer os.RemoveAll(testDir)

testDirPath := path.Join(projectconfig.RootDir, projectName)

// create sandbox dir
err := os.MkdirAll(testDirPath, os.ModePerm)
if err != nil {
t.Fatal(err)
}

config := projectconfig.ZeroProjectConfig{}
projectconfig.Init(projectconfig.RootDir, projectName, &config)
expectedConfig := &projectconfig.ZeroProjectConfig{
Name: projectName,
ShouldPushRepositories: false,
Modules: eksGoReactSampleModules(),
}
assert.NoError(t, projectconfig.CreateProjectConfigFile(projectconfig.RootDir, projectName, expectedConfig))

// make sure the file exists
if _, err := os.Stat(path.Join(testDirPath, constants.ZeroProjectYml)); err != nil {
t.Fatal(err)
}

t.Run("Should return a valid project config", func(t *testing.T) {
resultConfig := projectconfig.LoadConfig(path.Join(testDirPath, constants.ZeroProjectYml))

if !cmp.Equal(expectedConfig, resultConfig, cmpopts.EquateEmpty()) {
t.Errorf("projectconfig.ZeroProjectConfig.Unmarshal mismatch (-expected +result):\n%s", cmp.Diff(expectedConfig, resultConfig))
}
})

t.Run("Should fail if modules are missing from project config", func(t *testing.T) {
expectedConfig.Modules = nil
assert.Error(t, projectconfig.CreateProjectConfigFile(projectconfig.RootDir, projectName, expectedConfig))
})

}
2 changes: 1 addition & 1 deletion internal/config/projectconfig/project_config.go
Expand Up @@ -34,7 +34,7 @@ type Modules map[string]Module

type Module struct {
Parameters Parameters `yaml:"parameters,omitempty"`
Files Files
Files Files `yaml:"files,omitempty"`
}

type Parameters map[string]string
Expand Down
45 changes: 24 additions & 21 deletions internal/config/projectconfig/project_config_test.go
Expand Up @@ -45,29 +45,32 @@ func eksGoReactSampleModules() projectconfig.Modules {

func validConfigContent() string {
return `
# Templated zero-project.yml file
name: abc
shouldPushRepositories: false
modules:
aws-eks-stack:
parameters:
a: b
files:
dir: zero-aws-eks-stack
repo: github.com/something/repo1
source: github.com/commitdev/zero-aws-eks-stack
deployable-backend:
parameters:
a: b
files:
dir: zero-deployable-backend
repo: github.com/something/repo2
source: github.com/commitdev/zero-deployable-backend
deployable-react-frontend:
parameters:
a: b
files:
dir: zero-deployable-react-frontend
repo: github.com/something/repo3
source: github.com/commitdev/zero-deployable-react-frontend
aws-eks-stack:
parameters:
a: b
files:
dir: zero-aws-eks-stack
repo: github.com/something/repo1
source: github.com/commitdev/zero-aws-eks-stack
deployable-backend:
parameters:
a: b
files:
dir: zero-deployable-backend
repo: github.com/something/repo2
source: github.com/commitdev/zero-deployable-backend
deployable-react-frontend:
parameters:
a: b
files:
dir: zero-deployable-react-frontend
repo: github.com/something/repo3
source: github.com/commitdev/zero-deployable-react-frontend
`
}
11 changes: 11 additions & 0 deletions internal/util/util.go
Expand Up @@ -10,6 +10,7 @@ import (
"os/exec"
"path"
"path/filepath"
"strconv"
"strings"
"text/template"

Expand Down Expand Up @@ -122,3 +123,13 @@ func AppendProjectEnvToCmdEnv(envMap map[string]string, envList []string) []stri
}
return envList
}

// IndentString will Add x space char padding at the beginging of each line.
func IndentString(content string, spaces int) string {
var result string
subStr := strings.Split(content, "\n")
for _, s := range subStr {
result += fmt.Sprintf("%"+strconv.Itoa(spaces)+"s%s\n", "", s)
}
return result
}

0 comments on commit d86950a

Please sign in to comment.