oapi-type-definitions-extra.../src/main.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
}