From 44b59961e33edf8b3ecfab95ca69417ca4aa8f72 Mon Sep 17 00:00:00 2001 From: Randall Lough Date: Sat, 23 May 2020 13:34:33 -0700 Subject: [PATCH 1/4] support for using modules and outside of GOPATH --- convert.go | 71 ++++++++++++++++++++++++++++++++++++++++++++++--- convert_test.go | 26 ++++++++++++++++++ 2 files changed, 94 insertions(+), 3 deletions(-) diff --git a/convert.go b/convert.go index 29a1c98..2ff91b9 100755 --- a/convert.go +++ b/convert.go @@ -1,9 +1,11 @@ package gqlgen_sqlboiler import ( + "bufio" "fmt" "go/types" "io/ioutil" + "os" "path" "path/filepath" "regexp" @@ -149,12 +151,75 @@ func copyConfig(cfg config.Config) *config.Config { } func getGoImportFromFile(dir string) string { + dir = strings.TrimPrefix(dir, "/") + projectPath, err := getProjectPath(dir) + if err != nil { + // TODO: adhering to your original error handling + // should consider doing something here rather than continuing + // since this step occurs during generation, panicing or fatal error should be okay + fmt.Println("error while creating project path %w", err) + } + var importPath string + if hasGoMod(projectPath) { + modulePath, err := getModulePath(projectPath) + if err != nil { + // TODO: adhering to your original error handling + // should consider doing something here rather than continuing + // since this step occurs during generation, panicing or fatal error should be okay + fmt.Println("error while creating module path %w", err) + } + importPath = modulePath + "/" + dir + } else { + importPath = gopathImport(projectPath + "/" + dir) + } + + return importPath +} +func getProjectPath(dir string) (string, error) { longPath, err := filepath.Abs(dir) if err != nil { - fmt.Println("error while trying to convert folder to gopath", err) + return "", fmt.Errorf("error while trying to convert folder to gopath %w", err) } - // src/Users/.../go/src/gitlab.com/.../app/backend/graphql_models - return strings.TrimPrefix(pathRegex.FindString(longPath), "src/") + return strings.TrimSuffix(longPath, dir), nil +} + +func hasGoMod(projectPath string) bool { + return fileExists(projectPath + "go.mod") +} + +func fileExists(filename string) bool { + info, err := os.Stat(filename) + if os.IsNotExist(err) { + return false + } + return !info.IsDir() +} +func getModulePath(projectPath string) (string, error) { + file, err := os.Open(projectPath + "go.mod") + if err != nil { + return "", fmt.Errorf("error while trying to read go mods path %w", err) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + // normalize to ensure readability + line := strings.TrimSpace(scanner.Text()) + + // look for the starting module statement + if strings.HasPrefix(line, "module") { + split := strings.Split(line, "module") + return strings.TrimSpace(split[1]), nil + } + } + + if err := scanner.Err(); err != nil { + return "", fmt.Errorf("error while trying to read go mods path %w", err) + } + return "", nil +} +func gopathImport(dir string) string { + return strings.TrimPrefix(pathRegex.FindString(dir), "src/") } func GetModelsWithInformation(enums []*Enum, cfg *config.Config, boilerModels []*BoilerModel) []*Model { diff --git a/convert_test.go b/convert_test.go index ad2661a..39321fe 100644 --- a/convert_test.go +++ b/convert_test.go @@ -21,3 +21,29 @@ func testShortType(t *testing.T, input, output string) { t.Errorf("%v should result in %v but did result in %v", input, output, result) } } + +func Test_gopathImport(t *testing.T) { + type args struct { + dir string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "in GOPATH", + args: args{ + dir: "/Users/someonefamous/go/src/github.com/someonefamous/famous-project", + }, + want: "github.com/someonefamous/famous-project", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := gopathImport(tt.args.dir); got != tt.want { + t.Errorf("gopathImport() = %v, want %v", got, tt.want) + } + }) + } +} From edd4796d5688d1f1b8ed9a260992d78b9c0ef95d Mon Sep 17 00:00:00 2001 From: Randall Lough Date: Sat, 23 May 2020 13:36:22 -0700 Subject: [PATCH 2/4] adding .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..496ee2c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store \ No newline at end of file From 6c9115af908eb4b938dd781b5f77b8b14f34b3cb Mon Sep 17 00:00:00 2001 From: Randall Lough Date: Sun, 24 May 2020 08:36:14 -0700 Subject: [PATCH 3/4] Set root import path on instantiation --- convert.go | 87 ++++---------------------------------- convert_test.go | 26 ------------ helpers.go | 109 ++++++++++++++++++++++++++++++++++++++++++++++++ helpers_test.go | 29 +++++++++++++ resolver.go | 18 ++++---- 5 files changed, 155 insertions(+), 114 deletions(-) create mode 100644 helpers.go create mode 100644 helpers_test.go diff --git a/convert.go b/convert.go index 2ff91b9..b7f19ee 100755 --- a/convert.go +++ b/convert.go @@ -1,11 +1,9 @@ package gqlgen_sqlboiler import ( - "bufio" "fmt" "go/types" "io/ioutil" - "os" "path" "path/filepath" "regexp" @@ -126,13 +124,14 @@ type EnumValue struct { } func NewConvertPlugin(output, backend, frontend Config) plugin.Plugin { - return &ConvertPlugin{Output: output, Backend: backend, Frontend: frontend} + return &ConvertPlugin{Output: output, Backend: backend, Frontend: frontend, rootImportPath: getRootImportPath()} } type ConvertPlugin struct { - Output Config - Backend Config - Frontend Config + Output Config + Backend Config + Frontend Config + rootImportPath string } type Config struct { @@ -150,78 +149,6 @@ func copyConfig(cfg config.Config) *config.Config { return &cfg } -func getGoImportFromFile(dir string) string { - dir = strings.TrimPrefix(dir, "/") - projectPath, err := getProjectPath(dir) - if err != nil { - // TODO: adhering to your original error handling - // should consider doing something here rather than continuing - // since this step occurs during generation, panicing or fatal error should be okay - fmt.Println("error while creating project path %w", err) - } - var importPath string - if hasGoMod(projectPath) { - modulePath, err := getModulePath(projectPath) - if err != nil { - // TODO: adhering to your original error handling - // should consider doing something here rather than continuing - // since this step occurs during generation, panicing or fatal error should be okay - fmt.Println("error while creating module path %w", err) - } - importPath = modulePath + "/" + dir - } else { - importPath = gopathImport(projectPath + "/" + dir) - } - - return importPath -} -func getProjectPath(dir string) (string, error) { - longPath, err := filepath.Abs(dir) - if err != nil { - return "", fmt.Errorf("error while trying to convert folder to gopath %w", err) - } - return strings.TrimSuffix(longPath, dir), nil -} - -func hasGoMod(projectPath string) bool { - return fileExists(projectPath + "go.mod") -} - -func fileExists(filename string) bool { - info, err := os.Stat(filename) - if os.IsNotExist(err) { - return false - } - return !info.IsDir() -} -func getModulePath(projectPath string) (string, error) { - file, err := os.Open(projectPath + "go.mod") - if err != nil { - return "", fmt.Errorf("error while trying to read go mods path %w", err) - } - defer file.Close() - - scanner := bufio.NewScanner(file) - for scanner.Scan() { - // normalize to ensure readability - line := strings.TrimSpace(scanner.Text()) - - // look for the starting module statement - if strings.HasPrefix(line, "module") { - split := strings.Split(line, "module") - return strings.TrimSpace(split[1]), nil - } - } - - if err := scanner.Err(); err != nil { - return "", fmt.Errorf("error while trying to read go mods path %w", err) - } - return "", nil -} -func gopathImport(dir string) string { - return strings.TrimPrefix(pathRegex.FindString(dir), "src/") -} - func GetModelsWithInformation(enums []*Enum, cfg *config.Config, boilerModels []*BoilerModel) []*Model { // get models based on the schema and sqlboiler structs @@ -245,11 +172,11 @@ func (m *ConvertPlugin) MutateConfig(originalCfg *config.Config) error { b := &ModelBuild{ PackageName: m.Output.PackageName, Backend: Config{ - Directory: getGoImportFromFile(m.Backend.Directory), + Directory: path.Join(m.rootImportPath, m.Backend.Directory), PackageName: m.Backend.PackageName, }, Frontend: Config{ - Directory: getGoImportFromFile(m.Frontend.Directory), + Directory: path.Join(m.rootImportPath, m.Frontend.Directory), PackageName: m.Frontend.PackageName, }, } diff --git a/convert_test.go b/convert_test.go index 39321fe..ad2661a 100644 --- a/convert_test.go +++ b/convert_test.go @@ -21,29 +21,3 @@ func testShortType(t *testing.T, input, output string) { t.Errorf("%v should result in %v but did result in %v", input, output, result) } } - -func Test_gopathImport(t *testing.T) { - type args struct { - dir string - } - tests := []struct { - name string - args args - want string - }{ - { - name: "in GOPATH", - args: args{ - dir: "/Users/someonefamous/go/src/github.com/someonefamous/famous-project", - }, - want: "github.com/someonefamous/famous-project", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := gopathImport(tt.args.dir); got != tt.want { - t.Errorf("gopathImport() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/helpers.go b/helpers.go new file mode 100644 index 0000000..e89016d --- /dev/null +++ b/helpers.go @@ -0,0 +1,109 @@ +package gqlgen_sqlboiler + +import ( + "bufio" + "fmt" + "os" + "path" + "path/filepath" + "strings" +) + +func getRootImportPath() string { + importPath, err := rootImportPath() + if err != nil { + fmt.Printf("error while getting root import path %v", err) + return "" + } + return importPath +} + +func getGoImportFromFile(dir string) string { + dir = strings.TrimPrefix(dir, "/") + importPath, err := rootImportPath() + if err != nil { + fmt.Printf("error while getting root import path %v", err) + return "" + } + return path.Join(importPath, dir) +} + +func rootImportPath() (string, error) { + projectPath, err := getWorkingPath() + if err != nil { + // TODO: adhering to your original error handling + // should consider doing something here rather than continuing + // since this step occurs during generation, panicing or fatal error should be okay + return "", fmt.Errorf("error while getting working directory %w", err) + } + if hasGoMod(projectPath) { + modulePath, err := getModulePath(projectPath) + if err != nil { + // TODO: adhering to your original error handling + // should consider doing something here rather than continuing + // since this step occurs during generation, panicing or fatal error should be okay + return "", fmt.Errorf("error while getting module path %w", err) + } + return modulePath, nil + } + + return gopathImport(projectPath), nil +} +func getProjectPath(dir string) (string, error) { + longPath, err := filepath.Abs(dir) + if err != nil { + return "", fmt.Errorf("error while trying to convert folder to gopath %w", err) + } + return strings.TrimSuffix(longPath, dir), nil +} + +// getWorkingPath gets the current working directory +func getWorkingPath() (string, error) { + wd, err := os.Getwd() + if err != nil { + return "", err + } + return wd, nil +} +func hasGoMod(projectPath string) bool { + filePath := path.Join(projectPath, "go.mod") + return fileExists(filePath) +} + +func fileExists(filename string) bool { + info, err := os.Stat(filename) + if os.IsNotExist(err) { + return false + } + return !info.IsDir() +} + +func getModulePath(projectPath string) (string, error) { + filePath := path.Join(projectPath, "go.mod") + file, err := os.Open(filePath) + if err != nil { + return "", fmt.Errorf("error while trying to read go mods path %w", err) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + // normalize to ensure readability + line := strings.TrimSpace(scanner.Text()) + + // look for the starting module statement + if strings.HasPrefix(line, "module") { + split := strings.Split(line, "module") + return strings.TrimSpace(split[1]), nil + } + } + + if err := scanner.Err(); err != nil { + return "", fmt.Errorf("error while trying to read go mods path %w", err) + } + return "", nil +} + +func gopathImport(dir string) string { + return strings.TrimPrefix(pathRegex.FindString(dir), "src/") +} diff --git a/helpers_test.go b/helpers_test.go new file mode 100644 index 0000000..80134c1 --- /dev/null +++ b/helpers_test.go @@ -0,0 +1,29 @@ +package gqlgen_sqlboiler + +import "testing" + +func Test_gopathImport(t *testing.T) { + type args struct { + dir string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "in GOPATH", + args: args{ + dir: "/Users/someonefamous/go/src/github.com/someonefamous/famous-project", + }, + want: "github.com/someonefamous/famous-project", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := gopathImport(tt.args.dir); got != tt.want { + t.Errorf("gopathImport() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/resolver.go b/resolver.go index 6336e6f..a9aaf1e 100644 --- a/resolver.go +++ b/resolver.go @@ -3,6 +3,7 @@ package gqlgen_sqlboiler import ( "fmt" "os" + "path" "path/filepath" "strings" @@ -16,14 +17,15 @@ import ( ) func NewResolverPlugin(output, backend, frontend Config, authImport string) plugin.Plugin { - return &ResolverPlugin{output: output, backend: backend, frontend: frontend, authImport: authImport} + return &ResolverPlugin{output: output, backend: backend, frontend: frontend, authImport: authImport, rootImportPath: getRootImportPath()} } type ResolverPlugin struct { - output Config - backend Config - frontend Config - authImport string + output Config + backend Config + frontend Config + authImport string + rootImportPath string } var _ plugin.CodeGenerator = &ResolverPlugin{} @@ -61,16 +63,16 @@ func (m *ResolverPlugin) generateSingleFile(data *codegen.Data, models []*Model, file.imports = append(file.imports, Import{ Alias: ".", - ImportPath: getGoImportFromFile(m.output.Directory), + ImportPath: path.Join(m.rootImportPath, m.output.Directory), }) file.imports = append(file.imports, Import{ Alias: "dm", - ImportPath: getGoImportFromFile(m.backend.Directory), + ImportPath: path.Join(m.rootImportPath, m.backend.Directory), }) file.imports = append(file.imports, Import{ Alias: "fm", - ImportPath: getGoImportFromFile(m.frontend.Directory), + ImportPath: path.Join(m.rootImportPath, m.frontend.Directory), }) if m.authImport != "" { From 3a079d105533813ad721990ffb7a02186eed316d Mon Sep 17 00:00:00 2001 From: Randall Lough Date: Sun, 24 May 2020 15:00:11 -0700 Subject: [PATCH 4/4] Leverage Golangs builtin GoMod Path func instead of custom built one --- go.mod | 1 + go.sum | 2 ++ helpers.go | 25 +++++++------------------ 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 8c74420..a44a652 100644 --- a/go.mod +++ b/go.mod @@ -8,5 +8,6 @@ require ( github.com/pkg/errors v0.9.1 github.com/vektah/gqlparser/v2 v2.0.1 github.com/web-ridge/go-pluralize v0.1.5 + golang.org/x/mod v0.3.0 // indirect golang.org/x/tools v0.0.0-20200507205054-480da3ebd79c ) diff --git a/go.sum b/go.sum index 4923fea..26ecd0e 100644 --- a/go.sum +++ b/go.sum @@ -63,6 +63,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= diff --git a/helpers.go b/helpers.go index e89016d..6793b22 100644 --- a/helpers.go +++ b/helpers.go @@ -1,8 +1,9 @@ package gqlgen_sqlboiler import ( - "bufio" "fmt" + "golang.org/x/mod/modfile" + "io/ioutil" "os" "path" "path/filepath" @@ -80,28 +81,16 @@ func fileExists(filename string) bool { func getModulePath(projectPath string) (string, error) { filePath := path.Join(projectPath, "go.mod") - file, err := os.Open(filePath) + file, err := ioutil.ReadFile(filePath) if err != nil { return "", fmt.Errorf("error while trying to read go mods path %w", err) } - defer file.Close() - scanner := bufio.NewScanner(file) - for scanner.Scan() { - // normalize to ensure readability - line := strings.TrimSpace(scanner.Text()) - - // look for the starting module statement - if strings.HasPrefix(line, "module") { - split := strings.Split(line, "module") - return strings.TrimSpace(split[1]), nil - } - } - - if err := scanner.Err(); err != nil { - return "", fmt.Errorf("error while trying to read go mods path %w", err) + modPath := modfile.ModulePath(file) + if modPath == "" { + return "", fmt.Errorf("could not determine mod path \n") } - return "", nil + return modPath, nil } func gopathImport(dir string) string {