diff --git a/private/apigen/common.go b/private/apigen/common.go index 53d27d9ae..7d2c2ff21 100644 --- a/private/apigen/common.go +++ b/private/apigen/common.go @@ -30,7 +30,11 @@ type API struct { Version string Description string // The package name to use for the Go generated code. + // If omitted, the last segment of the PackagePath will be used as the package name. PackageName string + // The path of the package that will use the generated Go code. + // This is used to prevent the code from importing its own package. + PackagePath string // BasePath is the base path for the API endpoints. E.g. "/api". // It doesn't require to begin with "/". When empty, "/" is used. BasePath string diff --git a/private/apigen/example/gen.go b/private/apigen/example/gen.go index 4bf21ece5..39345f3d0 100644 --- a/private/apigen/example/gen.go +++ b/private/apigen/example/gen.go @@ -16,7 +16,11 @@ import ( ) func main() { - a := &apigen.API{PackageName: "example", Version: "v0", BasePath: "/api"} + a := &apigen.API{ + PackagePath: "storj.io/storj/private/apigen/example", + Version: "v0", + BasePath: "/api", + } g := a.Group("Documents", "docs") diff --git a/private/apigen/gogen.go b/private/apigen/gogen.go index 58a18d4aa..0ce3c86e0 100644 --- a/private/apigen/gogen.go +++ b/private/apigen/gogen.go @@ -4,6 +4,7 @@ package apigen import ( + "fmt" "go/format" "os" "reflect" @@ -38,14 +39,14 @@ func (a *API) generateGo() ([]byte, error) { result := &StringBuilder{} pf := result.Writelnf - getPackageName := func(path string) string { - pathPackages := strings.Split(path, "/") - name := pathPackages[len(pathPackages)-1] - if name == "main" { - panic(errs.New(`invalid package name. Your types cannot be defined in a package named "main"`)) - } + if a.PackagePath == "" { + return nil, errs.New("Package path must be defined") + } - return name + packageName := a.PackageName + if packageName == "" { + parts := strings.Split(a.PackagePath, "/") + packageName = parts[len(parts)-1] } imports := struct { @@ -59,7 +60,7 @@ func (a *API) generateGo() ([]byte, error) { i := func(paths ...string) { for _, path := range paths { - if path == "" || getPackageName(path) == a.PackageName { + if path == "" || path == a.PackagePath { continue } @@ -107,7 +108,7 @@ func (a *API) generateGo() ([]byte, error) { pf( "var Err%sAPI = errs.Class(\"%s %s api\")", capitalize(group.Prefix), - a.PackageName, + packageName, strings.ToLower(group.Prefix), ) } @@ -286,7 +287,7 @@ func (a *API) generateGo() ([]byte, error) { pf("// DO NOT EDIT.") pf("") - pf("package %s", a.PackageName) + pf("package %s", packageName) pf("") pf("import (") @@ -322,8 +323,17 @@ func (a *API) generateGo() ([]byte, error) { // If type is from the same package then we use only type's name. // If type is from external package then we use type along with its appropriate package name. func (a *API) handleTypesPackage(t reflect.Type) string { - if strings.HasPrefix(t.String(), a.PackageName) { - return t.Elem().Name() + switch t.Kind() { + case reflect.Array: + return fmt.Sprintf("[%d]%s", t.Len(), a.handleTypesPackage(t.Elem())) + case reflect.Slice: + return "[]" + a.handleTypesPackage(t.Elem()) + case reflect.Pointer: + return "*" + a.handleTypesPackage(t.Elem()) + } + + if t.PkgPath() == a.PackagePath { + return t.Name() } return t.String() diff --git a/satellite/admin/back-office/gen/main.go b/satellite/admin/back-office/gen/main.go index f5b5b9aef..73f68349a 100644 --- a/satellite/admin/back-office/gen/main.go +++ b/satellite/admin/back-office/gen/main.go @@ -13,7 +13,12 @@ import ( ) func main() { - api := &apigen.API{PackageName: "admin", Version: "v1", BasePath: "/api"} + api := &apigen.API{ + PackageName: "admin", + PackagePath: "storj.io/storj/satellite/admin/back-office", + Version: "v1", + BasePath: "/api", + } // This is an example and must be deleted when we define the first real endpoint. group := api.Group("Example", "example") diff --git a/satellite/console/consoleweb/consoleapi/gen/main.go b/satellite/console/consoleweb/consoleapi/gen/main.go index baba9520e..db097fa69 100644 --- a/satellite/console/consoleweb/consoleapi/gen/main.go +++ b/satellite/console/consoleweb/consoleapi/gen/main.go @@ -24,7 +24,7 @@ func main() { Version: "v0", BasePath: "/api", Description: "Interacts with projects", - PackageName: "consoleapi", + PackagePath: "storj.io/storj/satellite/console/consoleweb/consoleapi", } {