Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#64 : Remove -l flag, move all configuration to yaml, a lot of refact… #65

Merged
merged 2 commits into from
Nov 5, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
55 changes: 27 additions & 28 deletions cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import (
"sync"

"github.com/commitdev/commit0/internal/config"
"github.com/commitdev/commit0/internal/generate/ci"
"github.com/commitdev/commit0/internal/generate/docker"
"github.com/commitdev/commit0/internal/generate/golang"
"github.com/commitdev/commit0/internal/generate/http"
"github.com/commitdev/commit0/internal/generate/kubernetes"
"github.com/commitdev/commit0/internal/generate/proto"
"github.com/commitdev/commit0/internal/generate/react"
Expand All @@ -19,7 +16,6 @@ import (
)

var configPath string
var language string

const (
Go = "go"
Expand All @@ -32,7 +28,6 @@ var supportedLanguages = [...]string{Go, React, Kubernetes}
func init() {

generateCmd.PersistentFlags().StringVarP(&configPath, "config", "c", "commit0.yml", "config path")
generateCmd.PersistentFlags().StringVarP(&language, "language", "l", "", "language to generate project in")

rootCmd.AddCommand(generateCmd)
}
Expand All @@ -41,54 +36,58 @@ var generateCmd = &cobra.Command{
Use: "generate",
Short: "Generate idl & application folders",
Run: func(cmd *cobra.Command, args []string) {
if !ValidLanguage() {
log.Fatalf("'%s' is not a supported language.", language)
}

templates := packr.New("templates", "../templates")
t := templator.NewTemplator(templates)

cfg := config.LoadConfig(configPath)
cfg.Language = language
cfg.Print()

var wg sync.WaitGroup
switch language {
case Go:
proto.Generate(t, cfg, &wg)
golang.Generate(t, cfg, &wg)
if !ValidLanguage(cfg.Frontend.Framework) {
log.Fatalf("'%s' is not a supported framework.", cfg.Frontend.Framework)
}

docker.GenerateGoAppDockerFile(t, cfg, &wg)
docker.GenerateGoDockerCompose(t, cfg, &wg)
case React:
react.Generate(t, cfg, &wg)
case Kubernetes:
kubernetes.Generate(t, cfg, &wg)
for _, s := range cfg.Services {
if !ValidLanguage(cfg.Frontend.Framework) {
log.Fatalf("'%s' in service '%s' is not a supported language.", s.Name, s.Language)
}
}

util.TemplateFileIfDoesNotExist("", "README.md", t.Readme, &wg, cfg)
for _, s := range cfg.Services {
switch s.Language {
case Go:
log.Printf("Creating Go service")
proto.Generate(t, cfg, s, &wg)
golang.Generate(t, cfg, s, &wg)
}
}

if cfg.CI.System != "" {
ci.Generate(t.CI, cfg, ".", &wg)
if cfg.Infrastructure.AWS.EKS.ClusterName != "" {
kubernetes.Generate(t, cfg, &wg)
}

if cfg.Network.Http.Enabled {
http.GenerateHTTPGW(t, cfg, &wg)
docker.GenerateGoHTTPGWDockerFile(t, cfg, &wg)
// @TODO : This strucuture probably needs to be adjusted. Probably too generic.
switch cfg.Frontend.Framework {
case React:
react.Generate(t, cfg, &wg)
}

util.TemplateFileIfDoesNotExist("", "README.md", t.Readme, &wg, cfg)

// Wait for all the templates to be generated
wg.Wait()

switch language {
case Kubernetes:
log.Println("Executing commands")
// @TODO : Move this stuff to another command? Or genericize it a bit.
if cfg.Infrastructure.AWS.EKS.Deploy {
kubernetes.Execute(cfg)
}

},
}

func ValidLanguage() bool {
func ValidLanguage(language string) bool {
for _, l := range supportedLanguages {
if l == language {
return true
Expand Down
73 changes: 41 additions & 32 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,71 +8,80 @@ import (
"gopkg.in/yaml.v2"
)

type Maintainers struct {
type maintainers struct {
Name string
Email string
}

type Grpc struct {
type grpc struct {
Host string
Port int
}

type Graphql struct {
type graphql struct {
Enabled bool
Port int
}

type Http struct {
type http struct {
Enabled bool
Port int
}

type Web struct {
type web struct {
Enabled bool
Port int
}

type Network struct {
Grpc Grpc
Http Http
Web Web
Graphql Graphql
type network struct {
Grpc grpc
Http http
Web web
Graphql graphql
}

type Service struct {
Name string
Description string
Language string
GitRepo string `yaml:"gitRepo"`
DockerRepo string `yaml:"dockerRepo"`
Network network
CI CI
}

type CI struct {
System string `yaml:"system"`
BuildImage string `yaml:"build-image"`
BuildCommand string `yaml:"build-command"`
TestCommand string `yaml:"test-command"`
LanguageVersion string `yaml:"language-version"`
System string
Language string
BuildImage string `yaml:"buildImage"`
BuildTag string `yaml:"buildTag"`
BuildCommand string `yaml:"buildCommand"`
TestCommand string `yaml:"testCommand"`
}

type Commit0Config struct {
Language string `yaml:"string"`
Organization string `yaml:"organization"`
Name string `yaml:"name"`
Description string `yaml:"description"`
GitRepo string `yaml:"git-repo"`
DockerRepo string `yaml:"docker-repo"`
Maintainers []Maintainers `yaml:"maintainers"`
Network Network `yaml:"network"`
Services []Service `yaml:"services"`
React React `yaml:"react"`
Kubernetes Kubernetes `yaml:"kubernetes"`
CI CI `yaml:"ci"`
Organization string
Name string
Description string
Maintainers []maintainers
Services []Service
Frontend frontend
Infrastructure infrastructure
}

type Kubernetes struct {
ClusterName string `yaml:"clusterName"`
Deploy bool `yaml:"deploy"`
AWSAccountId string `yaml:"awsAccountId"`
AWSRegion string `yaml:"awsRegion"`
type infrastructure struct {
AWS aws
}

type aws struct {
AccountId string `yaml:"accountId"`
Region string
EKS eks
}

type eks struct {
ClusterName string `yaml:"clusterName"`
Deploy bool
}

func LoadConfig(filePath string) *Commit0Config {
Expand Down
14 changes: 8 additions & 6 deletions internal/config/react.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ type reactView struct {
Component string
}

type React struct {
App reactApp
Account reactAccount
Header reactHeader
Sidenav reactSidenav
Views []reactView
type frontend struct {
Framework string
App reactApp
Account reactAccount
Header reactHeader
Sidenav reactSidenav
Views []reactView
CI CI
}
38 changes: 13 additions & 25 deletions internal/generate/ci/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,54 +19,42 @@ const (

type CIGenerationError struct {
err string
config *config.Commit0Config
config config.CI
}

func (e *CIGenerationError) Error() string {
return fmt.Sprintf("Error: %s. Unable to Generate CI/CD Pipeline with config:\n%v\n", e.err, e.config)
}

// Generate a CI configuration file based on your language and CI system
func Generate(templator *templator.CITemplator, config *config.Commit0Config, basePath string, wg *sync.WaitGroup) error {
switch config.Language {
case "go":
if config.CI.LanguageVersion == "" {
config.CI.LanguageVersion = defaultGoVersion
}
if config.CI.BuildImage == "" {
config.CI.BuildImage = fmt.Sprintf("%s:%s", defaultGoDockerImage, config.CI.LanguageVersion)
}
if config.CI.BuildCommand == "" {
config.CI.BuildCommand = defaultBuildCommand
}
if config.CI.TestCommand == "" {
config.CI.TestCommand = defaultTestCommand
}
default:
return &CIGenerationError{"Unsupported Language", config}
}
func Generate(t *templator.CITemplator, cfg *config.Commit0Config, ciConfig config.CI, basePath string, wg *sync.WaitGroup) error {

var ciConfigPath string
var ciFilename string
var ciTemp *template.Template

switch config.CI.System {
switch ciConfig.System {
case "jenkins":
ciConfigPath = basePath
ciFilename = "Jenkinsfile"
ciTemp = templator.Jenkins
ciTemp = t.Jenkins
case "circleci":
ciConfigPath = fmt.Sprintf("%s/%s", basePath, ".circleci/")
ciFilename = "config.yml"
ciTemp = templator.CircleCI
ciTemp = t.CircleCI
case "travisci":
ciConfigPath = basePath
ciFilename = ".travis.yml"
ciTemp = templator.TravisCI
ciTemp = t.TravisCI
default:
return &CIGenerationError{"Unsupported CI System", config}
return &CIGenerationError{"Unsupported CI System", ciConfig}
}

data := templator.CITemplateData{
*cfg,
ciConfig,
}
util.TemplateFileIfDoesNotExist(ciConfigPath, ciFilename, ciTemp, wg, config)
util.TemplateFileIfDoesNotExist(ciConfigPath, ciFilename, ciTemp, wg, data)

return nil
}
63 changes: 5 additions & 58 deletions internal/generate/ci/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,73 +10,20 @@ import (
"github.com/commitdev/commit0/internal/templator"
)

func TestGenerateJenkins(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess these cases are covered by the integration tests now anyway, plus the logic inside of the CI generator is much simpler now.

testConf := &config.Commit0Config{
Language: "go",
CI: config.CI{
System: "jenkins",
},
}
testTemp := &templator.CITemplator{
Jenkins: &template.Template{},
CircleCI: &template.Template{},
TravisCI: &template.Template{},
}
var wg sync.WaitGroup
err := ci.Generate(testTemp, testConf, "/dev/null", &wg)
if err != nil {
t.Errorf("Error when executing test. %s", err)
}

expectedBuildImage := "golang/golang:1.12"
actualBuildImage := testConf.CI.BuildImage
if actualBuildImage != expectedBuildImage {
t.Errorf("want: %s, got: %s", expectedBuildImage, actualBuildImage)
}

expectedBuildCommand := "make build"
actualBuildCommand := testConf.CI.BuildCommand
if actualBuildCommand != expectedBuildCommand {
t.Errorf("want: %s, got: %s", expectedBuildCommand, actualBuildCommand)
func TestGenerateInvalidCISystem(t *testing.T) {
testConf := &config.Commit0Config{}
testCI := config.CI{
System: "invalidCISystem",
}

expectedTestCommand := "make test"
actualTestCommand := testConf.CI.TestCommand
if actualTestCommand != expectedTestCommand {
t.Errorf("want: %s, got: %s", expectedTestCommand, actualTestCommand)
}
}

func TestGenerateInvalidLanguage(t *testing.T) {
testConf := &config.Commit0Config{
Language: "invalidLanguage",
}
testTemp := &templator.CITemplator{
Jenkins: &template.Template{},
CircleCI: &template.Template{},
TravisCI: &template.Template{},
}
var wg sync.WaitGroup
err := ci.Generate(testTemp, testConf, "/dev/null", &wg)
if err == nil {
t.Errorf("Error should be thrown with invalid language specified. %s", err.Error())
}
}

func TestGenerateInvalidCISystem(t *testing.T) {
testConf := &config.Commit0Config{
Language: "go",
CI: config.CI{
System: "invalidCISystem",
},
}
testTemp := &templator.CITemplator{
Jenkins: &template.Template{},
CircleCI: &template.Template{},
TravisCI: &template.Template{},
}
var wg sync.WaitGroup
err := ci.Generate(testTemp, testConf, "/dev/null", &wg)
err := ci.Generate(testTemp, testConf, testCI, "/dev/null", &wg)
if err == nil {
t.Errorf("Error should be thrown with invalid ci system specified. %s", err.Error())
}
Expand Down