Skip to content

Commit

Permalink
Merge pull request #11 from wesionaryTEAM/main
Browse files Browse the repository at this point in the history
generate di config using comment
  • Loading branch information
mukezhz authored Apr 14, 2024
2 parents 30bd043 + b5d9868 commit 951923c
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 0 deletions.
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()
}
1 change: 1 addition & 0 deletions cmd/run_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ func init() {
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 951923c

Please sign in to comment.