Skip to content

Commit

Permalink
feat: add in features module when module is imported
Browse files Browse the repository at this point in the history
  • Loading branch information
mukezhz committed Nov 30, 2023
1 parent 569cc03 commit ff1218d
Showing 1 changed file with 114 additions and 0 deletions.
114 changes: 114 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ package main

import (
"bufio"
"bytes"
"embed"
"fmt"
"github.com/spf13/cobra"
"go/ast"
"go/format"
"go/parser"
"go/token"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"io"
Expand Down Expand Up @@ -111,6 +116,17 @@ func getModuleNameFromGoModFile() (string, error) {

func createModule(cmd *cobra.Command, args []string) {
projectModuleName, err := getModuleNameFromGoModFile()
currentDir, err := os.Getwd()
if err != nil {
fmt.Println("Error getting current directory:", err)
return
}
projectPath, err := findGitRoot(currentDir)
if err != nil {
fmt.Println("Error finding Git root:", err)
return
}
mainModulePath := filepath.Join(projectPath, "domain", "features", "module.go")
if err != nil {
panic(err)
}
Expand All @@ -123,6 +139,10 @@ func createModule(cmd *cobra.Command, args []string) {
templatePath := filepath.Join(".", "templates", "wesionary", "module")

generateFiles(templatePath, targetRoot, data)

updatedCode := AddAnotherFxOptionsInModule(mainModulePath, data.PackageName, data.ProjectModuleName)
writeContentToPath(mainModulePath, updatedCode)

}

func createProject(cmd *cobra.Command, args []string) {
Expand Down Expand Up @@ -253,3 +273,97 @@ func checkVersion(goVersion string) string {
}
return goVersion
}

func AddAnotherFxOptionsInModule(path, module, projectModule string) string {
fset := token.NewFileSet()
node, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
if err != nil {
log.Fatal(err)
}
importPackage(node, projectModule, module)

// Traverse the AST and find the fx.Options call
ast.Inspect(node, func(n ast.Node) bool {
switch x := n.(type) {
case *ast.CallExpr:
if sel, ok := x.Fun.(*ast.SelectorExpr); ok {
if sel.Sel.Name == "Module" {
x.Args = append(x.Args, &ast.CallExpr{
Fun: &ast.SelectorExpr{
X: ast.NewIdent("fx"),
Sel: ast.NewIdent("Options"),
},
Args: []ast.Expr{
ast.NewIdent(module + ".Module"),
},
})
}
}
}
return true
})

// Add the source code in buffer
var buf bytes.Buffer
if err := format.Node(&buf, fset, node); err != nil {
log.Fatal(err)
}
formattedCode := buf.String()
providerToInsert := fmt.Sprintf("fx.Options(%v.Module),", module)
formattedCode = strings.Replace(formattedCode, providerToInsert, "\n\t"+providerToInsert, 1)
return formattedCode
}

func findGitRoot(path string) (string, error) {
if path == "/" {
return "", fmt.Errorf("reached root directory, .git not found")
}

// Check if .git directory exists in the current path
if _, err := os.Stat(filepath.Join(path, ".git")); err == nil {
return path, nil
} else if !os.IsNotExist(err) {
return "", err
}

parentDir := filepath.Dir(path)
return findGitRoot(parentDir)
}

func writeContentToPath(path, content string) {
err := os.WriteFile(path, []byte(content), os.ModePerm)
if err != nil {
panic(err)
}
}

func importPackage(node *ast.File, projectModule, packageName string) {
importSpec := &ast.ImportSpec{
Path: &ast.BasicLit{
Kind: token.STRING,
Value: fmt.Sprintf(`"%v/domain/features/%v"`, projectModule, packageName),
},
}

importDecl := &ast.GenDecl{
Tok: token.IMPORT,
Lparen: token.Pos(1), // for grouping
Specs: []ast.Spec{importSpec},
}

// Check if there are existing imports, and if so, add to them
found := false
for _, decl := range node.Decls {
genDecl, ok := decl.(*ast.GenDecl)
if ok && genDecl.Tok == token.IMPORT {
genDecl.Specs = append(genDecl.Specs, importSpec)
found = true
break
}
}

// If no import declaration exists, add the new one to Decls
if !found {
node.Decls = append([]ast.Decl{importDecl}, node.Decls...)
}
}

0 comments on commit ff1218d

Please sign in to comment.