Skip to content

Commit

Permalink
Merge pull request #3 from wesionaryTEAM/BAC-62
Browse files Browse the repository at this point in the history
BAC62
  • Loading branch information
Denes-cilwal authored Apr 14, 2024
2 parents 539806c + 9f84b15 commit b5d9868
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 19 deletions.
8 changes: 7 additions & 1 deletion cmd/create_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ var newProjectCmd = &cobra.Command{
Run: createProject,
}

func setupFlagsForNewProject(cmd *cobra.Command) {
cmd.Flags().StringP("mod", "m", "", "module name")
cmd.Flags().StringP("dir", "d", "", "target directory")
cmd.Flags().StringP("version", "v", "", "version support: Default: 1.20")
}

func createProject(cmd *cobra.Command, args []string) {
var projectName string
var projectModuleName string
Expand Down Expand Up @@ -79,7 +85,7 @@ func createProject(cmd *cobra.Command, args []string) {
return
}
if projectModuleName == "" {
color.Redln("Error: module name is required")
color.Redln("Error: golang module name is required")
return
}

Expand Down
23 changes: 23 additions & 0 deletions cmd/generate_fx_module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package cmd

import (
"github.com/mukezhz/geng/pkg/utility"
"github.com/spf13/cobra"
)

var generateFxCmd = &cobra.Command{
Use: "fx",
Short: "Generate the fx configuration file for the project",
Long: `
Generate a module by reading comments from the source code.
Example:
geng fx
`,
Args: cobra.MaximumNArgs(2),
Run: generateFx,
}

func generateFx(_ *cobra.Command, _ []string) {
utility.GenerateFxModule()
}
34 changes: 27 additions & 7 deletions cmd/new_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,33 @@ import (

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

var newModuleCmd = &cobra.Command{
Use: "gen module [name]",
Use: "gen mod [name]",
Short: "Create a new domain",
Args: cobra.MaximumNArgs(2),
Run: createModule,
Long: `
Create a new module|service|middleware in the project.
Example:
geng gen mod [name]
geng gen srv [name]
geng gen mid [name]
Default:
geng gen -> geng gen mod
`,
Args: cobra.MaximumNArgs(2),
Run: generate,
}

func createModule(_ *cobra.Command, args []string) {
func generate(_ *cobra.Command, args []string) {
if len(args) == 0 {
args = append(args, "module")
}
projectModule, err := utility.GetModuleNameFromGoModFile()
if err != nil {
fmt.Println("Error finding Module name from go.mod:", err)
Expand All @@ -35,6 +49,12 @@ func createModule(_ *cobra.Command, args []string) {
fmt.Println("Error finding Git root:", err)
return
}
// Define the directory structure
generateModule(projectPath, args, projectModule)

}

func generateModule(projectPath string, args []string, projectModule model.GoMod) {
mainModulePath := filepath.Join(projectPath, "domain", "module.go")
var moduleName string
if len(args) == 1 {
Expand All @@ -50,7 +70,7 @@ func createModule(_ *cobra.Command, args []string) {
}
if q.Input.Exited() {
color.Redln("exited without completing...")
return

}
}
} else {
Expand All @@ -62,11 +82,10 @@ func createModule(_ *cobra.Command, args []string) {
}
data := utility.GetModuleDataFromModuleName(moduleName, projectModule.Module, projectModule.GoVersion)

// Define the directory structure
targetRoot := filepath.Join(".", "domain", data.PackageName)
templatePath := filepath.Join(".", "templates", "wesionary", "module")

err = utility.GenerateFiles(templatesFS, templatePath, targetRoot, data)
err := utility.GenerateFiles(templatesFS, templatePath, targetRoot, data)
if err != nil {
color.Redln("Error: generate file", err)
return
Expand All @@ -76,4 +95,5 @@ func createModule(_ *cobra.Command, args []string) {
utility.WriteContentToPath(mainModulePath, updatedCode)

utility.PrintColorizeModuleDetail(data)

}
10 changes: 2 additions & 8 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,10 @@ import (
)

var (
// Used for flags.
cfgFile string
userLicense string

rootCmd = &cobra.Command{
Use: "cobra-cli",
Use: "geng",
Short: "A generator for Cobra based Applications",
Long: `Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
Long: `geng is a CLI library for Go that empowers applications.`,
}
templatesFS embed.FS
)
Expand Down
5 changes: 2 additions & 3 deletions cmd/run_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@ func runProject(_ *cobra.Command, args []string) {
}

func init() {
newProjectCmd.Flags().StringP("mod", "m", "", "features name")
newProjectCmd.Flags().StringP("dir", "d", "", "target directory")
newProjectCmd.Flags().StringP("version", "v", "", "version support")
setupFlagsForNewProject(newProjectCmd)
rootCmd.AddCommand(newModuleCmd)
rootCmd.AddCommand(newProjectCmd)
rootCmd.AddCommand(runProjectCmd)
rootCmd.AddCommand(addInfrastructureCmd)
rootCmd.AddCommand(addServiceCmd)
rootCmd.AddCommand(generateFxCmd)
}
138 changes: 138 additions & 0 deletions pkg/utility/fx_generator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package utility

import (
"fmt"
"go/ast"
"go/parser"
"go/token"
"os"
"path/filepath"
"strings"
"text/template"

"golang.org/x/text/cases"
"golang.org/x/text/language"
)

func GenerateFxModule() {
fset := token.NewFileSet()
root := "./"
moduleMap := make(map[string][]string)

err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
if !strings.HasSuffix(info.Name(), ".go") {
return nil
}

file, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to parse file %s: %v\n", path, err)
return err
}

processedFile := processFile(file)
if len(processedFile) != 0 {
moduleMap[filepath.Dir(path)] = append(moduleMap[filepath.Dir(path)], processedFile...)
}

return nil
})
generateFile(moduleMap)

if err != nil {
fmt.Fprintf(os.Stderr, "Error walking through the directory: %v\n", err)
os.Exit(1)
}
}

func processFile(file *ast.File) []string {
providers := make([]string, 0)
ast.Inspect(file, func(n ast.Node) bool {
fn, ok := n.(*ast.FuncDecl)
if !ok || fn.Doc == nil {
return true
}

var provide bool
var asInterface string

for _, comment := range fn.Doc.List {
if strings.Contains(comment.Text, "@fxProvide") {
provide = true
}
if strings.HasPrefix(comment.Text, "// @fxAs ") {
parts := strings.SplitN(comment.Text, " ", 3)
if len(parts) > 2 {
asInterface = strings.TrimSpace(parts[2])
}
}
}

if provide {
if asInterface != "" {
providers = append(providers, fmt.Sprintf("fx.Provide(fx.Annotate(%s, fx.As(new(%s)))),", fn.Name.Name, asInterface))
} else {
providers = append(providers, fmt.Sprintf("fx.Provide(%s),", fn.Name.Name))
}
}
return true
})
return providers
}

type Module struct {
PackageName string
ModuleName string
Name string
Providers []string
}

const templateText = `package {{.PackageName}}
import "go.uber.org/fx"
// This file is generated by geng. DO NOT EDIT.
// File generated at: {{.Timestamp}}
// File will be overwritten when running geng again.
var {{.ModuleName}} = fx.Module("{{.Name}}",
{{- range .Providers}}
{{.}}
{{- end}}
)
`

func generateFile(dependencies map[string][]string) {
tmpl, err := template.New("module").Parse(templateText)
if err != nil {
panic(err)
}

for k, v := range dependencies {
module := Module{
PackageName: filepath.Base(k),
Name: filepath.Base(k),
ModuleName: cases.Title(language.English).String(filepath.Base(k)),
Providers: v,
}
filePath := filepath.Join(k, "module.go")
file, err := os.Create(filePath)
if err != nil {
panic(err)
}
defer file.Close()

err = tmpl.Execute(file, module)
if err != nil {
panic(err)
}
}
count := len(dependencies)
fmt.Printf("Generated %d module files\n", count)
}

0 comments on commit b5d9868

Please sign in to comment.