Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ $ zero init
## Sample project initilization
✔ Project Name: myapp-infra
🎉 Initializing project
✔ EKS + Go + React
✔ EKS + Go + React + Gatsby
✔ Should the created projects be checked into github automatically? (y/n): y
✔ What's the root of the github org to create repositories in?: github.com/myapp-org
✔ Existing AWS Profiles
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ require (
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v2 v2.2.2
github.com/gabriel-vasile/mimetype v1.1.1

)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gabriel-vasile/mimetype v1.1.1 h1:qbN9MPuRf3bstHu9zkI9jDWNfH//9+9kHxr9oRBBBOA=
github.com/gabriel-vasile/mimetype v1.1.1/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
Expand Down
92 changes: 74 additions & 18 deletions internal/generate/generate_modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package generate

import (
"fmt"
"io"
"log"
"os"
"path"
"path/filepath"
"regexp"
"strings"
"sync"
"text/template"

Expand All @@ -15,8 +16,9 @@ import (
"github.com/commitdev/zero/internal/module"
"github.com/commitdev/zero/internal/util"
"github.com/commitdev/zero/pkg/util/flog"

"github.com/commitdev/zero/pkg/util/fs"

"github.com/gabriel-vasile/mimetype"
)

// Generate accepts a projectconfig struct and renders the templates for all referenced modules
Expand Down Expand Up @@ -52,22 +54,23 @@ func Generate(projectConfig projectconfig.ZeroProjectConfig) error {
mod.Parameters,
}

fileTemplates := newTemplates(moduleDir, outputDir, false)
txtTypeFiles, binTypeFiles := sortFileType(moduleDir, outputDir, false)

executeTemplates(fileTemplates, templateData, delimiters)
executeTemplates(txtTypeFiles, templateData, delimiters)
copyBinFiles(binTypeFiles)
}
return nil
}

type TemplateConfig struct {
type fileConfig struct {
source string
destination string
isTemplate bool
}

// newTemplates walks the module directory to find all to be templated
func newTemplates(moduleDir string, outputDir string, overwrite bool) []*TemplateConfig {
templates := []*TemplateConfig{}
// sortFileType walks the module directory to find and classify all files into bin / text/plain (non-bin) types.
func sortFileType(moduleDir string, outputDir string, overwrite bool) ([]*fileConfig, []*fileConfig) {
binTypeFiles := []*fileConfig{}
txtTypeFiles := []*fileConfig{}

paths, err := getAllFilePathsInDirectory(moduleDir)
if err != nil {
Expand All @@ -80,11 +83,6 @@ func newTemplates(moduleDir string, outputDir string, overwrite bool) []*Templat
continue
}

_, file := filepath.Split(path)
hasTmpltSuffix := strings.HasSuffix(file, constants.TemplateExtn)
if hasTmpltSuffix {
file = strings.Replace(file, constants.TemplateExtn, "", -1)
}
outputPath := fs.ReplacePath(path, moduleDir, outputDir)

if !overwrite {
Expand All @@ -94,13 +92,34 @@ func newTemplates(moduleDir string, outputDir string, overwrite bool) []*Templat
}
}

templates = append(templates, &TemplateConfig{
// detect the file type
detectedMIME, err := mimetype.DetectFile(path)
if err != nil {
panic(err)
}

// detect root file type
isBinary := true
for mime := detectedMIME; mime != nil; mime = mime.Parent() {
if mime.Is("text/plain") {
isBinary = false
}
}

if isBinary {
binTypeFiles = append(binTypeFiles, &fileConfig{
source: path,
destination: outputPath,
})
continue
}

txtTypeFiles = append(txtTypeFiles, &fileConfig{
source: path,
destination: outputPath,
isTemplate: hasTmpltSuffix,
})
}
return templates
return txtTypeFiles, binTypeFiles
}

// getAllFilePathsInDirectory Recursively get all file paths in directory, including sub-directories.
Expand All @@ -122,7 +141,7 @@ func getAllFilePathsInDirectory(moduleDir string) ([]string, error) {
return paths, nil
}

func executeTemplates(templates []*TemplateConfig, data interface{}, delimiters []string) {
func executeTemplates(templates []*fileConfig, data interface{}, delimiters []string) {
var wg sync.WaitGroup
leftDelim := delimiters[0]
rightDelim := delimiters[1]
Expand Down Expand Up @@ -162,3 +181,40 @@ func executeTemplates(templates []*TemplateConfig, data interface{}, delimiters

wg.Wait()
}

func copyBinFiles(binTypeFiles []*fileConfig) {

for _, binFile := range binTypeFiles {
source := binFile.source
dest := binFile.destination

// create dir
outputDirPath, _ := path.Split(dest)
err := fs.CreateDirs(outputDirPath)
if err != nil {
flog.Errorf("Error creating directory '%s': %v", source, err)
}

// create refs to src and dest
from, err := os.Open(source)
if err != nil {
flog.Errorf("Error opening file to read '%s' : %v", source, err)
}
defer from.Close()

to, err := os.OpenFile(dest, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
log.Fatal(err)
flog.Errorf("Error creating file '%s': %v", dest, err)
}
defer to.Close()

// copy file
_, err = io.Copy(to, from)
if err != nil {
flog.Errorf("Error copying file '%s' : %v", source, err)
} else {
flog.Successf("Finished copying file : %s", dest)
}
}
}
3 changes: 2 additions & 1 deletion internal/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ func GetRegistry() Registry {
return Registry{
// TODO: better place to store these options as configuration file or any source
{
"EKS + Go + React",
"EKS + Go + React + Gatsby",
[]string{
"github.com/commitdev/zero-aws-eks-stack",
"github.com/commitdev/zero-deployable-landing-page",
"github.com/commitdev/zero-deployable-backend",
"github.com/commitdev/zero-deployable-react-frontend",
},
Expand Down
6 changes: 3 additions & 3 deletions internal/registry/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func TestAvailableLabels(t *testing.T) {
t.Run("should be same order as declared", func(t *testing.T) {
labels := registry.AvailableLabels(reg)
assert.Equal(t, labels, []string{
"EKS + Go + React",
"EKS + Go + React + Gatsby",
"foo",
"bar",
"lorem",
Expand All @@ -27,7 +27,7 @@ func TestGetModulesByName(t *testing.T) {
reg := testRegistry()
t.Run("should return modules of specified stack", func(t *testing.T) {

assert.Equal(t, registry.GetModulesByName(reg, "EKS + Go + React"),
assert.Equal(t, registry.GetModulesByName(reg, "EKS + Go + React + Gatsby"),
[]string{"module-source 1", "module-source 2"})
assert.Equal(t, registry.GetModulesByName(reg, "lorem"), []string{"module-source 5"})
assert.Equal(t, registry.GetModulesByName(reg, "ipsum"), []string{"module-source 6"})
Expand All @@ -37,7 +37,7 @@ func TestGetModulesByName(t *testing.T) {

func testRegistry() registry.Registry {
return registry.Registry{
{"EKS + Go + React", []string{"module-source 1", "module-source 2"}},
{"EKS + Go + React + Gatsby", []string{"module-source 1", "module-source 2"}},
{"foo", []string{"module-source 3"}},
{"bar", []string{"module-source 4"}},
{"lorem", []string{"module-source 5"}},
Expand Down