diff --git a/cmd/apiregister-gen/generators/parser.go b/cmd/apiregister-gen/generators/parser.go index 76ca378647..d7a2d765fa 100644 --- a/cmd/apiregister-gen/generators/parser.go +++ b/cmd/apiregister-gen/generators/parser.go @@ -651,28 +651,43 @@ func (apigroup *APIGroup) DoType(t *types.Type) (*Struct, []*types.Type) { if !samepkg { parts := strings.Split(base, ".") if len(parts) > 1 { - switch member.Type.Name.Package { - case "k8s.io/apimachinery/pkg/apis/meta/v1": - // Use versioned types for meta/v1 - uImport = fmt.Sprintf("%s \"%s\"", "metav1", "k8s.io/apimachinery/pkg/apis/meta/v1") - uType = "metav1." + parts[1] - default: - // Use unversioned types for everything else - t := member.Type - hasElem := false - if t.Elem != nil { - // Handle Pointers, Maps, Slices correctly - t = t.Elem - hasElem = true - } - uImportName := path.Base(path.Dir(t.Name.Package)) - uImport = path.Dir(t.Name.Package) - uType = uImportName + "." + t.Name.Name + // Don't generate unversioned types for core types, just use the versioned types + if strings.HasPrefix(mSubType.Name.Package, "k8s.io/api/") { + // Import the package under an alias so it doesn't conflict with other groups + // having the same version + importAlias := path.Base(path.Dir(mSubType.Name.Package)) + path.Base(mSubType.Name.Package) + uImport = fmt.Sprintf("%s \"%s\"", importAlias, mSubType.Name.Package) if hasElem { - uType = strings.Replace(member.Type.String(), path.Dir(uImport)+"/", "", 1) - uType = strings.Replace(uType, "/"+path.Base(t.Name.Package), "", 1) + // Replace the full package with the alias when referring to the type + uType = strings.Replace(member.Type.String(), mSubType.Name.Package, importAlias, 1) + } else { + // Replace the full package with the alias when referring to the type + uType = fmt.Sprintf("%s.%s", importAlias, parts[1]) + } + } else { + switch member.Type.Name.Package { + case "k8s.io/apimachinery/pkg/apis/meta/v1": + // Use versioned types for meta/v1 + uImport = fmt.Sprintf("%s \"%s\"", "metav1", "k8s.io/apimachinery/pkg/apis/meta/v1") + uType = "metav1." + parts[1] + default: + // Use unversioned types for everything else + t := member.Type + hasElem := false + if t.Elem != nil { + // Handle Pointers, Maps, Slices correctly + t = t.Elem + hasElem = true + } + uImportName := path.Base(path.Dir(t.Name.Package)) + uImport = path.Dir(t.Name.Package) + uType = uImportName + "." + t.Name.Name + if hasElem { + uType = strings.Replace(member.Type.String(), path.Dir(uImport)+"/", "", 1) + uType = strings.Replace(uType, "/"+path.Base(t.Name.Package), "", 1) + } + fmt.Printf("\nDifferent Package Parent Package: %s Child Package: %s Name: %s : %s : %s\n%s : %s\n\n", t.Name.Package, member.Type.Name.Package, member.Type.Kind, member.Type.String(), path.Dir(uImport), uImport, uType) } - fmt.Printf("\nDifferent Package Parent Package: %s Child Package: %s Name: %s : %s : %s\n%s : %s\n\n", t.Name.Package, member.Type.Name.Package, member.Type.Kind, member.Type.String(), path.Dir(uImport), uImport, uType) } } } diff --git a/cmd/apiserver-boot/boot/build/build_executables.go b/cmd/apiserver-boot/boot/build/build_executables.go index 4bbbfe2cea..86dfb12535 100644 --- a/cmd/apiserver-boot/boot/build/build_executables.go +++ b/cmd/apiserver-boot/boot/build/build_executables.go @@ -48,6 +48,7 @@ apiserver-boot build --goos linux --goarch amd64 --output linux/`, func AddBuildExecutables(cmd *cobra.Command) { cmd.AddCommand(createBuildExecutablesCmd) + createBuildExecutablesCmd.Flags().StringVar(&vendorDir, "vendor-dir", "", "Location of directory containing vendor files.") createBuildExecutablesCmd.Flags().BoolVar(&GenerateForBuild, "generate", true, "if true, generate code before building") createBuildExecutablesCmd.Flags().StringVar(&goos, "goos", "", "if specified, set this GOOS") createBuildExecutablesCmd.Flags().StringVar(&goarch, "goarch", "", "if specified, set this GOARCH") diff --git a/cmd/apiserver-boot/boot/build/generate.go b/cmd/apiserver-boot/boot/build/generate.go index 3cee3d950a..7202cf0c6d 100644 --- a/cmd/apiserver-boot/boot/build/generate.go +++ b/cmd/apiserver-boot/boot/build/generate.go @@ -37,6 +37,7 @@ var unversionedAPIs []string var codegenerators []string var copyright string var generators = sets.String{} +var vendorDir string var generateCmd = &cobra.Command{ Use: "generated", @@ -55,6 +56,7 @@ var extraAPI = strings.Join([]string{ func AddGenerate(cmd *cobra.Command) { cmd.AddCommand(generateCmd) generateCmd.Flags().StringVar(©right, "copyright", "boilerplate.go.txt", "Location of copyright boilerplate file.") + generateCmd.Flags().StringVar(&vendorDir, "vendor-dir", "", "Location of directory containing vendor files.") generateCmd.Flags().StringArrayVar(&versionedAPIs, "api-versions", []string{}, "API version to generate code for. Can be specified multiple times. e.g. --api-versions foo/v1beta1 --api-versions bar/v1 defaults to all versions found under directories pkg/apis//") generateCmd.Flags().StringArrayVar(&codegenerators, "generator", []string{}, "list of generators to run. e.g. --generator apiregister --generator conversion Valid values: [apiregister,conversion,client,deepcopy,defaulter,openapi]") generateCmd.AddCommand(generateCleanCmd) @@ -174,6 +176,10 @@ func RunGenerate(cmd *cobra.Command, args []string) { apis = append(apis, filepath.Join("k8s.io", "client-go", "pkg", "api", "v1")) } + if _, err := os.Stat(filepath.Join("vendor", "k8s.io", "api", "core", "v1", "doc.go")); err == nil { + apis = append(apis, filepath.Join("k8s.io", "api", "core", "v1")) + } + c := exec.Command(filepath.Join(root, "openapi-gen"), append(all, "-o", util.GoSrc, @@ -267,6 +273,9 @@ func RunGenerate(cmd *cobra.Command, args []string) { func getVendorApis(pkg string) []string { dir := filepath.Join("vendor", pkg) + if len(vendorDir) >= 0 { + dir = filepath.Join(vendorDir, dir) + } apis := []string{} if groups, err := ioutil.ReadDir(dir); err == nil { for _, g := range groups { diff --git a/example/Makefile b/example/Makefile index bfc544be1b..23a06fae59 100644 --- a/example/Makefile +++ b/example/Makefile @@ -21,7 +21,7 @@ test: build bash -c "find pkg/apis/ -name apiserver.local.config | xargs rm -rf" build: cmds - bin/apiserver-boot build executables + bin/apiserver-boot build executables --vendor-dir ../ # Build docs docs: cleandocs build diff --git a/example/pkg/apis/miskatonic/v1beta1/university_types.go b/example/pkg/apis/miskatonic/v1beta1/university_types.go index 46bfd61a48..004598e3c7 100644 --- a/example/pkg/apis/miskatonic/v1beta1/university_types.go +++ b/example/pkg/apis/miskatonic/v1beta1/university_types.go @@ -20,11 +20,12 @@ import ( "log" "github.com/kubernetes-incubator/apiserver-builder/example/pkg/apis/miskatonic" + corev1 "k8s.io/api/core/v1" + extensionsv1beta1 "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apiserver/pkg/endpoints/request" - //extensionsv1beta1 "k8s.io/client-go/pkg/apis/extensions/v1beta1" ) // Generating code from university_types.go file will generate storage and status REST endpoints for @@ -59,20 +60,11 @@ type UniversitySpec struct { // The unversioned struct definition for this field is automatically generated in the group package Automatic AutomaticCreateUnversionedType - //// WARNING: Using types from client-go as fields does not work outside this example - //// This example hacked the vendored client-go to add the openapi generation directives - //// to make this work - //Template *apiv1.PodSpec `json:"template,omitempty"` - // - //// WARNING: Using types from client-go as fields does not work outside this example - //// This example hacked the vendored client-go to add the openapi generation directives - //// to make this work - //ServiceSpec apiv1.ServiceSpec `json:"service_spec,omitempty"` - // - //// WARNING: Using types from client-go as fields does not work outside this example - //// This example hacked the vendored client-go to add the openapi generation directives - //// to make this work - //Rollout []extensionsv1beta1.Deployment `json:"rollout,omitempty"` + Template *corev1.PodSpec `json:"template,omitempty"` + + ServiceSpec corev1.ServiceSpec `json:"service_spec,omitempty"` + + Rollout []extensionsv1beta1.Deployment `json:"rollout,omitempty"` } // Require that the unversioned struct is manually created. This is *NOT* the default behavior for diff --git a/example/pkg/apis/miskatonic/v1beta1/university_types_test.go b/example/pkg/apis/miskatonic/v1beta1/university_types_test.go index 84d5e34502..1257f04fdd 100644 --- a/example/pkg/apis/miskatonic/v1beta1/university_types_test.go +++ b/example/pkg/apis/miskatonic/v1beta1/university_types_test.go @@ -19,8 +19,8 @@ package v1beta1_test import ( . "github.com/kubernetes-incubator/apiserver-builder/example/pkg/apis/miskatonic/v1beta1" . "github.com/kubernetes-incubator/apiserver-builder/example/pkg/client/clientset_generated/clientset/typed/miskatonic/v1beta1" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - //"k8s.io/client-go/pkg/api/v1" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -35,15 +35,14 @@ var _ = Describe("University", func() { instance = University{} instance.Name = "miskatonic-university" instance.Spec.FacultySize = 7 - //instance.Spec.ServiceSpec = v1.ServiceSpec{} - //instance.Spec.ServiceSpec.ClusterIP = "1.1.1.1" + instance.Spec.ServiceSpec = corev1.ServiceSpec{} + instance.Spec.ServiceSpec.ClusterIP = "1.1.1.1" expected = instance val := 15 expected.Spec.MaxStudents = &val - //expected.Spec.ServiceSpec = v1.ServiceSpec{} - //expected.Spec.ServiceSpec.ClusterIP = "1.1.1.1" - + expected.Spec.ServiceSpec = corev1.ServiceSpec{} + expected.Spec.ServiceSpec.ClusterIP = "1.1.1.1" }) AfterEach(func() {