179 lines
4.2 KiB
Go
179 lines
4.2 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"os"
|
||
|
"os/exec"
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
if len(os.Args) != 3 {
|
||
|
fmt.Println("Usage: go run main.go <input_directory> <output_directory>")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
inputDir := os.Args[1]
|
||
|
outputDir := os.Args[2]
|
||
|
files, err := getGoFiles(inputDir)
|
||
|
if err != nil {
|
||
|
fmt.Println(err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
for _, file := range files {
|
||
|
typeDecls, importDecls, err := extractTypes(file)
|
||
|
if err != nil {
|
||
|
fmt.Println(err)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
// Filter out structs with "Nullable" at the beginning of their names.
|
||
|
typeDecls = filterNullableTypes(typeDecls)
|
||
|
|
||
|
// Generate the adapted file name by inserting the "_adapted" string before the ".go" extension of the original file name.
|
||
|
adaptedFile := strings.Replace(filepath.Base(file), ".go", "_adapted.go", 1)
|
||
|
adaptedFile = filepath.Join(outputDir, adaptedFile)
|
||
|
// Write the struct declarations and import declarations to the adapted file.
|
||
|
err = writeStruct(typeDecls, importDecls, adaptedFile)
|
||
|
if err != nil {
|
||
|
fmt.Println(err)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
// Reformat the adapted file using gofmt.
|
||
|
err = runGoImports(adaptedFile)
|
||
|
if err != nil {
|
||
|
fmt.Println(err)
|
||
|
continue
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// getGoFiles returns a list of .go files in the given directory.
|
||
|
func getGoFiles(dir string) ([]string, error) {
|
||
|
var files []string
|
||
|
|
||
|
f, err := os.Open(dir)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
defer f.Close()
|
||
|
|
||
|
fi, err := f.Readdir(-1)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
for _, file := range fi {
|
||
|
if !file.IsDir() && strings.HasSuffix(file.Name(), ".go") {
|
||
|
// Concatenate the directory path and the file name to get the full path.
|
||
|
files = append(files, dir+"/"+file.Name())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return files, nil
|
||
|
}
|
||
|
|
||
|
// filterNullableTypes filters out structs with "Nullable" at the beginning of their names.
|
||
|
func filterNullableTypes(structDecls []string) []string {
|
||
|
var filteredStructDecls []string
|
||
|
for _, s := range structDecls {
|
||
|
// Check if the struct name starts with "Nullable".
|
||
|
if !strings.HasPrefix(s, "type Nullable") {
|
||
|
filteredStructDecls = append(filteredStructDecls, s)
|
||
|
}
|
||
|
}
|
||
|
return filteredStructDecls
|
||
|
}
|
||
|
|
||
|
// extractTypes reads a .go file and returns a list of type declarations and a list of import declarations.
|
||
|
func extractTypes(file string) ([]string, []string, error) {
|
||
|
var typeDecls []string
|
||
|
var importDecls []string
|
||
|
|
||
|
f, err := os.Open(file)
|
||
|
if err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
defer f.Close()
|
||
|
|
||
|
scanner := bufio.NewScanner(f)
|
||
|
var typeDecl, importDecl string
|
||
|
inStruct, inImport := false, false
|
||
|
for scanner.Scan() {
|
||
|
line := scanner.Text()
|
||
|
if strings.HasPrefix(line, "import") {
|
||
|
inImport = true
|
||
|
importDecl = line + "\n"
|
||
|
} else if inImport && (line == "" || strings.HasPrefix(line, ")")) {
|
||
|
importDecl += line + "\n"
|
||
|
inImport = false
|
||
|
importDecls = append(importDecls, importDecl)
|
||
|
} else if inImport {
|
||
|
importDecl += line + "\n"
|
||
|
} else if strings.HasPrefix(line, "type") {
|
||
|
inStruct = true
|
||
|
typeDecl = line + "\n"
|
||
|
} else if inStruct && strings.HasPrefix(line, "}") {
|
||
|
typeDecl += line + "\n"
|
||
|
typeDecls = append(typeDecls, typeDecl)
|
||
|
inStruct = false
|
||
|
} else if inStruct {
|
||
|
typeDecl += line + "\n"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if err := scanner.Err(); err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
|
||
|
return typeDecls, importDecls, nil
|
||
|
}
|
||
|
|
||
|
// writeStruct writes the given struct declarations and import declarations to a new file with the given name.
|
||
|
func writeStruct(structDecls []string, importDecls []string, file string) error {
|
||
|
f, err := os.Create(file)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer f.Close()
|
||
|
|
||
|
// Add the package dto declaration at the top of the file.
|
||
|
_, err = io.WriteString(f, "package dto\n\n")
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// Write the import declarations to the file.
|
||
|
for _, importDecl := range importDecls {
|
||
|
_, err = io.WriteString(f, importDecl)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Write the struct declarations to the file.
|
||
|
for _, s := range structDecls {
|
||
|
_, err = io.WriteString(f, s)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// runimports reformats the given file using the goimports tool.
|
||
|
func runGoImports(file string) error {
|
||
|
cmd := exec.Command("goimports", "-w", file)
|
||
|
output, err := cmd.CombinedOutput()
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("%s: %s", err, output)
|
||
|
}
|
||
|
return nil
|
||
|
}
|