Skip to content

Commit

Permalink
CLI implementation (#19)
Browse files Browse the repository at this point in the history
1. CLI impelmentation which will take the input location as well as
optional output location (if not passed it will create .ast folder
within the input location).
2. Little code refactor
3. Changed code to add file information only inside root node of type
ast.File
4. Unit tests for different use cases for CLI inputs.
  • Loading branch information
pandurangpatil authored Jun 15, 2023
1 parent fe66677 commit def385a
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: echo tag
run: |
echo "The current tag is: ${{ steps.taggerDryRun.outputs.tag }}"
- name: Build C-Shared Libraries
- name: Build
run: |
GOOS=linux GOARCH=amd64 go build -o build/goastgen-linux
GOOS=linux GOARCH=arm64 go build -o build/goastgen-linux-arm64
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ module privado.ai/goastgen

go 1.18

require github.com/stretchr/testify v1.8.4
require (
github.com/google/uuid v1.3.0
github.com/stretchr/testify v1.8.4
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
Expand Down
5 changes: 4 additions & 1 deletion goastgen/libgoastgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,10 @@ func processStruct(node interface{}, objPtrValue reflect.Value, fset *token.File
if astNode, ok := objPtrValue.Interface().(ast.Node); ok && fset != nil {
if pos := astNode.Pos(); pos.IsValid() {
position := fset.Position(pos)
objectMap["node_filename"] = position.Filename
//Add file information only inside ast.File node which is the root node for a file AST.
if elementValueObj.Type().String() == "ast.File" {
objectMap["node_filename"] = position.Filename
}
objectMap["node_line_no"] = position.Line
objectMap["node_col_no"] = position.Column
}
Expand Down
97 changes: 92 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,103 @@
package main

import (
"flag"
"fmt"
"os"
"path/filepath"
"privado.ai/goastgen/goastgen"
"strings"
)

func main() {
args := os.Args[1:]
path := args[0]
resultJson := goastgen.ParseAstFromFile(path)
fmt.Println(resultJson)
out, inputPath := parseArguments()
processRequest(out, inputPath)
}

// go build -buildmode=c-shared -o lib-goastgen.dylib main.go
func processRequest(out string, inputPath string) {
if strings.HasSuffix(inputPath, ".go") {
fileInfo, err := os.Stat(inputPath)
if err != nil {
fmt.Println("Failed to get file info:", err)
return
}
directory := filepath.Dir(inputPath)
var outFile = ""
if out == ".ast" {
outFile = filepath.Join(directory, out, fileInfo.Name()+".json")
} else {
outFile = filepath.Join(out, fileInfo.Name()+".json")
}
writeFileContents(outFile, goastgen.ParseAstFromFile(inputPath))
} else {
err := filepath.Walk(inputPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
fmt.Printf("Error accessing path %s: %v\n", path, err)
return err
}
if !info.IsDir() && strings.HasSuffix(info.Name(), ".go") {
var outFile = ""
directory := filepath.Dir(path)
if out == ".ast" {
outFile = filepath.Join(inputPath, out, strings.ReplaceAll(directory, inputPath, ""), info.Name()+".json")
} else {
outFile = filepath.Join(out, strings.ReplaceAll(directory, inputPath, ""), info.Name()+".json")
}
writeFileContents(outFile, goastgen.ParseAstFromFile(path))
}
return nil
})

if err != nil {
fmt.Printf("Error walking the path %s: %v\n", inputPath, err)
}
}
}

func parseArguments() (string, string) {
var (
out string
inputPath string = ""
)
flag.StringVar(&out, "out", ".ast", "Out put location of ast")
flag.Parse()
// Check if positional arguments exist
if flag.NArg() > 0 {
// Retrieve positional arguments
inputPath = flag.Arg(0)
}
if inputPath == "" {
fmt.Println("Usage:")
fmt.Println("\tgoastgen [falgs] <source location>")
fmt.Println()
fmt.Println("Flags:")
flag.PrintDefaults()
os.Exit(1)
}
return out, inputPath
}

func writeFileContents(location string, contents string) {
// Open the file for writing (creates a new file if it doesn't exist)
dir := filepath.Dir(location)

// Create all directories recursively
err := os.MkdirAll(dir, 0755)
if err != nil {
fmt.Println("Failed to create file:", err)
return
}
file, err := os.Create(location)
if err != nil {
fmt.Println("Failed to create file:", err)
return
}
defer file.Close()

// Write the contents to the file
_, err = file.WriteString(contents)
if err != nil {
fmt.Println("Failed to write to file:", err)
return
}
}
99 changes: 99 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package main

import (
"fmt"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"os"
"path/filepath"
"testing"
)

func TestProcessRequestWithSingleFileUseCase(t *testing.T) {
// Get the temporary directory path
tempDir := os.TempDir()

// Create a new folder in the temporary directory
newFolder := filepath.Join(tempDir, uuid.New().String())
err := os.Mkdir(newFolder, 0755)
if err != nil {
fmt.Println("Failed to create folder:", err)
return
}
srcFile := filepath.Join(newFolder, "hello.go")
file, errf := os.Create(srcFile)
if errf != nil {
fmt.Println("Failed to create file:", errf)
return
}
code := "package main \n" +
"import \"fmt\"\n" +
"func main() {\n" +
"fmt.Println(\"Hello World\")\n" +
"}"
file.WriteString(code)
processRequest(".ast", srcFile)
expectedJsonFileLocation := filepath.Join(newFolder, ".ast", "hello.go.json")
_, err = os.Stat(expectedJsonFileLocation)
assert.Nil(t, err, "check the ast output is generated at expected location")

diffOutLocation := filepath.Join(tempDir, uuid.New().String())
processRequest(diffOutLocation, srcFile)
expectedJsonFileLocation = filepath.Join(diffOutLocation, "hello.go.json")
_, err = os.Stat(expectedJsonFileLocation)
assert.Nil(t, err, "check the ast output is generated at expected location")
}

func TestProcessRequestWithMultipleFileDiffFolderStructureUsecase(t *testing.T) {
// Get the temporary directory path
tempDir := os.TempDir()

// Create a new folder in the temporary directory
newFolder := filepath.Join(tempDir, uuid.New().String())
err := os.Mkdir(newFolder, 0755)
if err != nil {
fmt.Println("Failed to create folder:", err)
return
}
srcFile := filepath.Join(newFolder, "hello.go")
file, errf := os.Create(srcFile)
if errf != nil {
fmt.Println("Failed to create file:", errf)
return
}
code := "package main \n" +
"import \"fmt\"\n" +
"func main() {\n" +
"fmt.Println(\"Hello World\")\n" +
"}"
file.WriteString(code)
subDir := filepath.Join(newFolder, "subdir")
err = os.Mkdir(subDir, 0755)
if err != nil {
fmt.Println("Failed to create folder:", err)
return
}
subSrcFile := filepath.Join(subDir, "hellosub.go")
file, errf = os.Create(subSrcFile)
if errf != nil {
fmt.Println("Failed to create file:", errf)
return
}
file.WriteString(code)
processRequest(".ast", newFolder)
expectedJsonFileLocationone := filepath.Join(newFolder, ".ast", "hello.go.json")
_, err = os.Stat(expectedJsonFileLocationone)
assert.Nil(t, err, "check the ast output is generated at expected location")
expectedJsonFileLocationtwo := filepath.Join(newFolder, ".ast", "subdir", "hellosub.go.json")
_, err = os.Stat(expectedJsonFileLocationtwo)
assert.Nil(t, err, "check the ast output is generated at expected location")

diffOutLocation := filepath.Join(tempDir, uuid.New().String())
processRequest(diffOutLocation, newFolder)
expectedJsonFileLocationone = filepath.Join(diffOutLocation, "hello.go.json")
_, err = os.Stat(expectedJsonFileLocationone)
assert.Nil(t, err, "check the ast output is generated at expected location")
expectedJsonFileLocationtwo = filepath.Join(diffOutLocation, "subdir", "hellosub.go.json")
_, err = os.Stat(expectedJsonFileLocationtwo)
assert.Nil(t, err, "check the ast output is generated at expected location")
}

0 comments on commit def385a

Please sign in to comment.