Skip to content

Commit

Permalink
Merge pull request #5 from wesionaryTEAM/refactor/project-gen
Browse files Browse the repository at this point in the history
Refactor: Modularize generate project command
  • Loading branch information
mukezhz committed May 8, 2024
2 parents c8dfe40 + 09ebe3f commit 2234dce
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 53 deletions.
78 changes: 26 additions & 52 deletions cmd/create_project.go
Original file line number Diff line number Diff line change
@@ -1,40 +1,37 @@
package cmd

import (
"fmt"
"path/filepath"
"strings"

"github.com/gookit/color"
"github.com/mukezhz/geng/pkg/constant"
"github.com/mukezhz/geng/pkg/gen"
"github.com/mukezhz/geng/pkg/terminal"
"github.com/mukezhz/geng/pkg/utility"
"github.com/mukezhz/geng/templates"
"github.com/spf13/cobra"
)

var newProjectCmd = &cobra.Command{
var projectCmd = &cobra.Command{
Use: "new [project name]",
Short: "Create a new project",
Args: cobra.MaximumNArgs(1),
Run: createProject,
}

var projectGen = gen.ProjectGenerator{}

func init() {
newProjectCmd.Flags().StringP("mod", "m", "", "module name")
newProjectCmd.Flags().StringP("dir", "d", "", "target directory")
newProjectCmd.Flags().StringP("version", "v", "", "version support: Default: 1.20")
projectCmd.Flags().StringVarP(&projectGen.ModuleName, "mod", "m", "", "module name")
projectCmd.Flags().StringVarP(&projectGen.Directory, "dir", "d", "", "target directory")
projectCmd.Flags().StringVarP(&projectGen.GoVersion, "version", "v", "", "version support: Default: 1.20")
}

func createProject(cmd *cobra.Command, args []string) {
var projectName string
var projectModuleName string
var goVersion string
var projectDescription string
var author string
var directory string
var questions []terminal.ProjectQuestion

// TODO: update using infrastructure generator
templateInfraPath := utility.IgnoreWindowsPath(filepath.Join(".", "templates", "wesionary", "infrastructure"))
infrasTmpl := utility.ListDirectory(templates.FS, templateInfraPath)
infras := utility.Map[string, string](infrasTmpl, func(q string) string {
Expand All @@ -51,69 +48,46 @@ func createProject(cmd *cobra.Command, args []string) {
terminal.NewShortQuestion(constant.DirectoryKEY, constant.Directory+" [Optional]", "Enter Project Directory (Default: package_name) [Optional]"),
terminal.NewCheckboxQuestion(constant.InfrastructureNameKEY, "Select the infrastructure? [<space> to select] [Optional]", infras),
}

terminal.StartInteractiveTerminal(questions)

questionMap := make(map[string]string)

for _, q := range questions {
switch q.Key {
case constant.ProjectNameKEY:
projectName = q.Answer
case constant.ProjectDescriptionKEY:
projectDescription = q.Answer
case constant.AuthorKEY:
author = q.Answer
case constant.ProjectModuleNameKEY:
projectModuleName = q.Answer
case constant.GoVersionKEY:
goVersion = q.Answer
case constant.DirectoryKEY:
directory = q.Answer
}
questionMap[q.Key] = q.Answer
if q.Input.Exited() {
color.Redln("exited without completing...")
return
}
}

projectGen.Fill(questionMap)

} else {
projectName = args[0]
projectModuleName, _ = cmd.Flags().GetString("mod")
goVersion, _ = cmd.Flags().GetString("version")
directory, _ = cmd.Flags().GetString("dir")
projectGen.Name = args[0]
projectGen.ModuleName, _ = cmd.Flags().GetString("mod")
projectGen.GoVersion, _ = cmd.Flags().GetString("version")
projectGen.Directory, _ = cmd.Flags().GetString("dir")
}

goVersion = utility.CheckVersion(goVersion)
if projectName == "" {
color.Redln("Error: project name is required")
if err := projectGen.Validate(); err != nil {
color.Redln(err.Error())
return
}
if projectModuleName == "" {
color.Redln("Error: golang module name is required")
return
}

data := utility.GetModuleDataFromModuleName(projectName, projectModuleName, goVersion)
data.ProjectDescription = projectDescription
data.Author = author

data.Directory = directory
if data.Directory == "" {
data.Directory = filepath.Join(data.Directory, data.PackageName)
}
targetRoot := data.Directory

templatePath := utility.IgnoreWindowsPath(filepath.Join("templates", "wesionary", "project"))
err := utility.GenerateFiles(templates.FS, templatePath, targetRoot, data)
data, err := projectGen.Generate()
if err != nil {
color.Redln("Error generate file", err)
color.Redln(err.Error())
return
}

// TODO: update using infrastructure generator
for _, q := range questions {
switch q.Key {
case constant.InfrastructureNameKEY:
infrastructureModulePath := filepath.Join(data.PackageName, "pkg", "infrastructure", "module.go")
addInfrastructure(questions, infrasTmpl, infrastructureModulePath, data, true, templates.FS)
addInfrastructure(questions, infrasTmpl, infrastructureModulePath, *data, true, templates.FS)
}
}

utility.PrintColorizeProjectDetail(data)
fmt.Println("")
}
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var Root = &cobra.Command{
func init() {
Root.AddCommand(
newModuleCmd,
newProjectCmd,
projectCmd,
runProjectCmd,
addInfrastructureCmd,
addServiceCmd,
Expand Down
69 changes: 69 additions & 0 deletions pkg/gen/project.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package gen

import (
"errors"
"fmt"
"path/filepath"

"github.com/mukezhz/geng/pkg/constant"
"github.com/mukezhz/geng/pkg/model"
"github.com/mukezhz/geng/pkg/utility"
"github.com/mukezhz/geng/templates"
)

// ProjectGenerator is argument for project generator
type ProjectGenerator struct {
Name string
ModuleName string
Description string
Author string
Directory string
GoVersion string
}

// Fill fills up items from map to the struct
func (p *ProjectGenerator) Fill(d map[string]string) {
p.Name, _ = d[constant.ProjectNameKEY]
p.ModuleName, _ = d[constant.ProjectModuleNameKEY]
p.Author, _ = d[constant.AuthorKEY]
p.Description, _ = d[constant.ProjectDescriptionKEY]
p.GoVersion, _ = d[constant.GoVersionKEY]
p.Directory, _ = d[constant.DirectoryKEY]
}

// Validate validates generated project arguments
func (p *ProjectGenerator) Validate() error {
p.GoVersion = utility.CheckVersion(p.GoVersion)
if p.Name == "" {
return errors.New("Error: project name is required")
}
if p.ModuleName == "" {
return errors.New("Error: golang module name is required")
}
return nil
}

// Generate genrates the project given the arguments in the struct
func (p *ProjectGenerator) Generate() (*model.ModuleData, error) {
data := utility.GetModuleDataFromModuleName(p.Name, p.ModuleName, p.GoVersion)
data.ProjectDescription = p.Description
data.Author = p.Author

data.Directory = p.Directory
if data.Directory == "" {
data.Directory = filepath.Join(data.Directory, data.PackageName)
}

targetRoot := data.Directory

templatePath := utility.IgnoreWindowsPath(filepath.Join("templates", "wesionary", "project"))
err := utility.GenerateFiles(templates.FS, templatePath, targetRoot, data)
if err != nil {
return nil, fmt.Errorf("Error generating file: %v", err)
}

utility.PrintColorizeProjectDetail(data)
fmt.Println("")

return &data, nil
}

0 comments on commit 2234dce

Please sign in to comment.