Repository: kubernetes-sigs/controller-tools
Pull request #268 (2019-07-19 03:25:57)

🐛 Handle the error type in crd gen
So this fixes a very niche parsing issue:

```go
type noNotify struct{ error }
```

That parses as a field, but it has no package because it's a core type I think? Not 100% sure but it definitely causes a segfault :)

k8s-ci-robot: Welcome @coderanger! <br><br>It looks like this is your first PR to <a href='https://github.com/kubernetes-sigs/controller-tools'>kubernetes-sigs/controller-tools</a> 🎉. Please refer to our [pull request process documentation](https://git.k8s.io/community/contributors/guide/pull-requests.md) to help your PR have a smooth ride to approval. <br><br>You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. [Here is the bot commands documentation](https://go.k8s.io/bot-commands). <br><br>You can also check if kubernetes-sigs/controller-tools has [its own contribution guidelines](https://github.com/kubernetes-sigs/controller-tools/tree/master/CONTRIBUTING.md). <br><br>You may want to refer to our [testing guide](https://git.k8s.io/community/contributors/devel/sig-testing/testing.md) if you run into trouble with your tests not passing. <br><br>If you are having difficulty getting your pull request seen, please follow the [recommended escalation practices](https://github.com/kubernetes/community/blob/master/contributors/guide/pull-requests.md#why-is-my-pull-request-not-getting-reviewed). Also, for tips and tricks in the contribution process you may want to read the [Kubernetes contributor cheat sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet/README.md). We want to make sure your contribution gets all the attention it needs! <br><br>Thank you, and welcome to Kubernetes. :smiley:
k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/controller-tools/pull/268#" title="Author self-approved">coderanger</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **pwittrock**
You can assign the PR to them by writing `/assign @pwittrock` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fcontroller-tools).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubernetes-sigs/controller-tools/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["pwittrock"]} -->
munnerz: Huh, how come you're embedding an `error` type into your API? What're you trying to achieve with this?

Avoiding segfaults sounds like a good plan regardless, but I'm curious as to why you're doing this 😅

/lgtm
coderanger: @munnerz It's a extension to pkg/errors to basically tag an error as "please don't generate a notification for this" so when it propagates up to my error handlers, they can check and not push a Slack message.
DirectXMan12: ah, the universe types.  They're weird an need explicit handling, but the rest are builtins.  `error` is weird.

Patch:
diff --git a/Gopkg.lock b/Gopkg.lock
index 426702a2..704ad198 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -290,10 +290,9 @@
   version = "kubernetes-1.14.1"
 
 [[projects]]
-  digest = "0:"
+  digest = "1:2949c401dc3fabc93e6688d3d65e63600778ce706e2eb0ad0c702cddb319c124"
   name = "k8s.io/apimachinery"
   packages = [
-    "pkg/api/equality",
     "pkg/api/resource",
     "pkg/apis/meta/v1",
     "pkg/conversion",
@@ -353,7 +352,6 @@
     "k8s.io/api/admissionregistration/v1beta1",
     "k8s.io/api/rbac/v1",
     "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1",
-    "k8s.io/apimachinery/pkg/api/equality",
     "k8s.io/apimachinery/pkg/apis/meta/v1",
     "k8s.io/apimachinery/pkg/runtime/schema",
     "sigs.k8s.io/yaml",
diff --git a/PROJECT b/PROJECT
new file mode 100644
index 00000000..b5137fea
--- /dev/null
+++ b/PROJECT
@@ -0,0 +1,2 @@
+domain: k8s.io
+repo: sigs.k8s.io/controller-tools
diff --git a/cmd/controller-gen/main.go b/cmd/controller-gen/main.go
index 5bdaa420..389476bb 100644
--- a/cmd/controller-gen/main.go
+++ b/cmd/controller-gen/main.go
@@ -20,7 +20,6 @@ import (
 	"fmt"
 	"io"
 	"os"
-	"strings"
 
 	"github.com/spf13/cobra"
 
@@ -114,15 +113,9 @@ func init() {
 	}
 }
 
-// noUsageError suppresses usage printing when it occurs
-// (since cobra doesn't provide a good way to avoid printing
-// out usage in only certain situations).
-type noUsageError struct{ error }
-
 func main() {
 	helpLevel := 0
 	whichLevel := 0
-
 	cmd := &cobra.Command{
 		Use:   "controller-gen",
 		Short: "Generate Kubernetes API extension resources and code.",
@@ -131,45 +124,21 @@ func main() {
 	# outputting crds to /tmp/crds and everything else to stdout
 	controller-gen rbac:roleName=<role name> crd paths=./apis/... output:crd:dir=/tmp/crds output:stdout
 
-	# Generate deepcopy/runtime.Object implementations for a particular file
-	controller-gen object paths=./apis/v1beta1/some_types.go
+	# Generate deepcopy implementations for a particular file
+	controller-gen deepcopy paths=./apis/v1beta1/some_types.go
 
 	# Run all the generators for a given project
 	controller-gen paths=./apis/...
-
-	# Explain the markers for generating CRDs, and their arguments
-	controller-gen crd -ww
 `,
 		RunE: func(c *cobra.Command, rawOpts []string) error {
-			// print the help if we asked for it (since we've got a different help flag :-/), then bail
 			if helpLevel > 0 {
 				return c.Usage()
 			}
-
-			// print the marker docs if we asked for them, then bail
-			if whichLevel > 0 {
-				return printMarkerDocs(c, rawOpts, whichLevel)
-			}
-
-			// otherwise, set up the runtime for actually running the generators
-			rt, err := genall.FromOptions(optionsRegistry, rawOpts)
-			if err != nil {
-				return err
-			}
-			if len(rt.Generators) == 0 {
-				return fmt.Errorf("no generators specified")
-			}
-
-			if hadErrs := rt.Run(); hadErrs {
-				// don't obscure the actual error with a bunch of usage
-				return noUsageError{fmt.Errorf("not all generators ran successfully")}
-			}
-			return nil
+			return runGenerators(c, rawOpts, whichLevel)
 		},
-		SilenceUsage: true, // silence the usage, then print it out ourselves if it wasn't suppressed
 	}
-	cmd.Flags().CountVarP(&whichLevel, "which-markers", "w", "print out all markers available with the requested generators\n(up to -www for the most detailed output, or -wwww for json output)")
-	cmd.Flags().CountVarP(&helpLevel, "detailed-help", "h", "print out more detailed help\n(up to -hhh for the most detailed output, or -hhhh for json output)")
+	cmd.Flags().CountVarP(&whichLevel, "which-markers", "w", "print out all markers available with the requested generators (passing more times yields more detailed information)")
+	cmd.Flags().CountVarP(&helpLevel, "detailed-help", "h", "print out more detailed help (passing more times yields more detailed information about options)")
 	cmd.Flags().Bool("help", false, "print out usage and a summary of options")
 	oldUsage := cmd.UsageFunc()
 	cmd.SetUsageFunc(func(c *cobra.Command) error {
@@ -184,28 +153,33 @@ func main() {
 	})
 
 	if err := cmd.Execute(); err != nil {
-		if _, noUsage := err.(noUsageError); !noUsage {
-			// print the usage unless we suppressed it
-			if err := cmd.Usage(); err != nil {
-				panic(err)
-			}
-		}
-		fmt.Fprintf(cmd.OutOrStderr(), "run `%[1]s %[2]s -w` to see all available markers, or `%[1]s %[2]s -h` for usage\n", cmd.CalledAs(), strings.Join(os.Args[1:], " "))
+		fmt.Fprintln(os.Stderr, err)
 		os.Exit(1)
 	}
 }
 
-// printMarkerDocs prints out marker help for the given generators specified in
-// the rawOptions, at the given level.
-func printMarkerDocs(c *cobra.Command, rawOptions []string, whichLevel int) error {
-	// just grab a registry so we don't lag while trying to load roots
-	// (like we'd do if we just constructed the full runtime).
-	reg, err := genall.RegistryFromOptions(optionsRegistry, rawOptions)
+func runGenerators(c *cobra.Command, rawOptions []string, whichLevel int) error {
+	if whichLevel > 0 {
+		// just grab a registry so we don't lag while trying to load roots
+		// (like we'd do if we just constructed the full runtime).
+		reg, err := genall.RegistryFromOptions(optionsRegistry, rawOptions)
+		if err != nil {
+			return err
+		}
+
+		return helpForLevels(c.OutOrStdout(), c.OutOrStderr(), whichLevel, reg, help.SortByCategory)
+	}
+
+	rt, err := genall.FromOptions(optionsRegistry, rawOptions)
 	if err != nil {
 		return err
 	}
 
-	return helpForLevels(c.OutOrStdout(), c.OutOrStderr(), whichLevel, reg, help.SortByCategory)
+	if hadErrs := rt.Run(); hadErrs {
+		return fmt.Errorf("not all generators ran successfully")
+	}
+
+	return nil
 }
 
 func helpForLevels(mainOut io.Writer, errOut io.Writer, whichLevel int, reg *markers.Registry, sorter help.SortGroup) error {
diff --git a/pkg/crd/gen.go b/pkg/crd/gen.go
index 5e78ab58..ce5acbcd 100644
--- a/pkg/crd/gen.go
+++ b/pkg/crd/gen.go
@@ -148,6 +148,11 @@ func findKubeKinds(parser *Parser, metav1Pkg *loader.Package) []schema.GroupKind
 				// ObjectMeta and TypeMeta are named types
 				continue
 			}
+			if namedField.Obj().Pkg() == nil {
+				// Embedded non-builtin universe type (specifically, it's probably `error`),
+				// so it can't be ObjectMeta or TypeMeta
+				continue
+			}
 			fieldPkgPath := loader.NonVendorPath(namedField.Obj().Pkg().Path())
 			fieldPkg := pkg.Imports()[fieldPkgPath]
 			if fieldPkg != metav1Pkg {
diff --git a/pkg/crd/known_types.go b/pkg/crd/known_types.go
index 4a5bca92..639f6836 100644
--- a/pkg/crd/known_types.go
+++ b/pkg/crd/known_types.go
@@ -35,10 +35,6 @@ var KnownPackages = map[string]PackageOverride{
 			Type:   "string",
 			Format: "date-time",
 		}
-		p.Schemata[TypeIdent{Name: "MicroTime", Package: pkg}] = apiext.JSONSchemaProps{
-			Type:   "string",
-			Format: "date-time",
-		}
 		p.Schemata[TypeIdent{Name: "Duration", Package: pkg}] = apiext.JSONSchemaProps{
 			// TODO(directxman12): regexp validation for this (or get kube to support it as a format value)
 			Type: "string",
diff --git a/pkg/crd/markers/validation.go b/pkg/crd/markers/validation.go
index 9f7fbca7..bf71f5ee 100644
--- a/pkg/crd/markers/validation.go
+++ b/pkg/crd/markers/validation.go
@@ -78,12 +78,7 @@ func init() {
 	AllDefinitions = append(AllDefinitions, ValidationMarkers...)
 
 	for _, def := range ValidationMarkers {
-		newDef := *def.Definition
-		// copy both parts so we don't change the definition
-		typDef := definitionWithHelp{
-			Definition: &newDef,
-			Help:       def.Help,
-		}
+		typDef := *def
 		typDef.Target = markers.DescribesType
 		AllDefinitions = append(AllDefinitions, &typDef)
 	}
diff --git a/pkg/crd/schema.go b/pkg/crd/schema.go
index ab969a18..a68a2841 100644
--- a/pkg/crd/schema.go
+++ b/pkg/crd/schema.go
@@ -328,7 +328,7 @@ func structToSchema(ctx *schemaContext, structType *ast.StructType) *v1beta1.JSO
 		jsonTag, hasTag := field.Tag.Lookup("json")
 		if !hasTag {
 			// if the field doesn't have a JSON tag, it doesn't belong in output (and shouldn't exist in a serialized type)
-			ctx.pkg.AddError(loader.ErrFromNode(fmt.Errorf("encountered struct field %q without JSON tag in type %q", field.Name, ctx.info.Name), field.RawField))
+			ctx.pkg.AddError(loader.ErrFromNode(fmt.Errorf("enountered struct field %q without JSON tag in type %q", field.Name, ctx.info.Name), field.RawField))
 			continue
 		}
 		jsonOpts := strings.Split(jsonTag, ",")
diff --git a/pkg/crd/spec.go b/pkg/crd/spec.go
index f6017f45..94fa2220 100644
--- a/pkg/crd/spec.go
+++ b/pkg/crd/spec.go
@@ -17,13 +17,11 @@ package crd
 
 import (
 	"fmt"
-	"sort"
 	"strings"
 
 	"github.com/gobuffalo/flect"
 
 	apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
-	"k8s.io/apimachinery/pkg/api/equality"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 
@@ -38,86 +36,6 @@ type SpecMarker interface {
 	ApplyToCRD(crd *apiext.CustomResourceDefinitionSpec, version string) error
 }
 
-// mergeIdenticalSubresources checks to see if subresources are identical across
-// all versions, and if so, merges them into a top-level version.
-//
-// This assumes you're not using trivial versions.
-func mergeIdenticalSubresources(crd *apiext.CustomResourceDefinition) {
-	subres := crd.Spec.Versions[0].Subresources
-	for _, ver := range crd.Spec.Versions {
-		if ver.Subresources == nil || !equality.Semantic.DeepEqual(subres, ver.Subresources) {
-			// either all nil, or not identical
-			return
-		}
-	}
-
-	// things are identical if we've gotten this far, so move the subresources up
-	// and discard the identical per-version ones
-	crd.Spec.Subresources = subres
-	for i := range crd.Spec.Versions {
-		crd.Spec.Versions[i].Subresources = nil
-	}
-}
-
-// mergeIdenticalSchemata checks to see if schemata are identical across
-// all versions, and if so, merges them into a top-level version.
-//
-// This assumes you're not using trivial versions.
-func mergeIdenticalSchemata(crd *apiext.CustomResourceDefinition) {
-	schema := crd.Spec.Versions[0].Schema
-	for _, ver := range crd.Spec.Versions {
-		if ver.Schema == nil || !equality.Semantic.DeepEqual(schema, ver.Schema) {
-			// either all nil, or not identical
-			return
-		}
-	}
-
-	// things are identical if we've gotten this far, so move the schemata up
-	// to a single schema and discard the identical per-version ones
-	crd.Spec.Validation = schema
-	for i := range crd.Spec.Versions {
-		crd.Spec.Versions[i].Schema = nil
-	}
-}
-
-// mergeIdenticalPrinterColumns checks to see if schemata are identical across
-// all versions, and if so, merges them into a top-level version.
-//
-// This assumes you're not using trivial versions.
-func mergeIdenticalPrinterColumns(crd *apiext.CustomResourceDefinition) {
-	cols := crd.Spec.Versions[0].AdditionalPrinterColumns
-	for _, ver := range crd.Spec.Versions {
-		if len(ver.AdditionalPrinterColumns) == 0 || !equality.Semantic.DeepEqual(cols, ver.AdditionalPrinterColumns) {
-			// either all nil, or not identical
-			return
-		}
-	}
-
-	// things are identical if we've gotten this far, so move the printer columns up
-	// and discard the identical per-version ones
-	crd.Spec.AdditionalPrinterColumns = cols
-	for i := range crd.Spec.Versions {
-		crd.Spec.Versions[i].AdditionalPrinterColumns = nil
-	}
-}
-
-// MergeIdenticalVersionInfo makes sure that components of the Versions field that are identical
-// across all versions get merged into the top-level fields in v1beta1.
-//
-// This is required by the Kubernetes API server validation.
-//
-// The reason is that a v1beta1 -> v1 -> v1beta1 conversion cycle would need to
-// round-trip identically, v1 doesn't have top-level subresources, and without
-// this restriction it would be ambiguous how a v1-with-identical-subresources
-// converts into a v1beta1).
-func MergeIdenticalVersionInfo(crd *apiext.CustomResourceDefinition) {
-	if len(crd.Spec.Versions) > 1 {
-		mergeIdenticalSubresources(crd)
-		mergeIdenticalSchemata(crd)
-		mergeIdenticalPrinterColumns(crd)
-	}
-}
-
 // NeedCRDFor requests the full CRD for the given group-kind.  It requires
 // that the packages containing the Go structs for that CRD have already
 // been loaded with NeedPackage.
@@ -201,11 +119,6 @@ func (p *Parser) NeedCRDFor(groupKind schema.GroupKind) {
 		return
 	}
 
-	// it is necessary to make sure the order of CRD versions in crd.Spec.Versions is stable and explicitly set crd.Spec.Version.
-	// Otherwise, crd.Spec.Version may point to different CRD versions across different runs.
-	sort.Slice(crd.Spec.Versions, func(i, j int) bool { return crd.Spec.Versions[i].Name < crd.Spec.Versions[j].Name })
-	crd.Spec.Version = crd.Spec.Versions[0].Name
-
 	// make sure we have *a* storage version
 	// (default it if we only have one, otherwise, bail)
 	if len(crd.Spec.Versions) == 1 {
@@ -231,9 +144,5 @@ func (p *Parser) NeedCRDFor(groupKind schema.GroupKind) {
 	crd.Status.Conditions = []apiext.CustomResourceDefinitionCondition{}
 	crd.Status.StoredVersions = []string{}
 
-	// make sure we merge identical per-version parts, to avoid validation errors
-	// (see the reasoning near the top of the file).
-	MergeIdenticalVersionInfo(&crd)
-
 	p.CustomResourceDefinitions[groupKind] = crd
 }
diff --git a/pkg/deepcopy/gen.go b/pkg/deepcopy/gen.go
index 371af3d6..3121da33 100644
--- a/pkg/deepcopy/gen.go
+++ b/pkg/deepcopy/gen.go
@@ -128,6 +128,8 @@ func genObjectInterface(info *markers.TypeInfo) bool {
 func (d Generator) Generate(ctx *genall.GenerationContext) error {
 	var headerText string
 
+	checker := ctx.Checker
+
 	if d.HeaderFile != "" {
 		headerBytes, err := ctx.ReadFile(d.HeaderFile)
 		if err != nil {
@@ -135,35 +137,77 @@ func (d Generator) Generate(ctx *genall.GenerationContext) error {
 		}
 		headerText = string(headerBytes)
 	}
-	headerText = strings.ReplaceAll(headerText, " YEAR", " "+d.Year)
-
-	objGenCtx := ObjectGenCtx{
-		Collector:  ctx.Collector,
-		Checker:    ctx.Checker,
-		HeaderText: headerText,
-	}
+	headerText = strings.ReplaceAll(headerText, " YEAR", d.Year)
 
 	for _, root := range ctx.Roots {
-		outContents := objGenCtx.GenerateForPackage(root)
-		if outContents == nil {
+		allTypes, err := enabledOnPackage(ctx.Collector, root)
+		if err != nil {
+			root.AddError(err)
 			continue
 		}
 
-		writeOut(ctx, root, outContents)
+		checker.Check(root, func(node ast.Node) bool {
+			// ignore interfaces
+			_, isIface := node.(*ast.InterfaceType)
+			return !isIface
+		})
+
+		root.NeedTypesInfo()
+
+		byType := make(map[string][]byte)
+		imports := &importsList{
+			byPath:  make(map[string]string),
+			byAlias: make(map[string]string),
+			pkg:     root,
+		}
+		// avoid confusing aliases by "reserving" the root package's name as an alias
+		imports.byAlias[root.Name] = ""
+
+		if err := markers.EachType(ctx.Collector, root, func(info *markers.TypeInfo) {
+			outContent := new(bytes.Buffer)
+
+			// copy when nabled for all types and not disabled, or enabled
+			// specifically on this type
+			if !enabledOnType(allTypes, info) {
+				return
+			}
+
+			// avoid copying non-exported types, etc
+			if !shouldBeCopied(root, info) {
+				return
+			}
+
+			copyCtx := &copyMethodMaker{
+				pkg:         root,
+				importsList: imports,
+				codeWriter:  &codeWriter{out: outContent},
+			}
+
+			copyCtx.GenerateMethodsFor(root, info)
+
+			outBytes := outContent.Bytes()
+			if len(outBytes) > 0 {
+				byType[info.Name] = outBytes
+			}
+		}); err != nil {
+			root.AddError(err)
+			continue
+		}
+
+		if len(byType) == 0 {
+			continue
+		}
+
+		outContent := new(bytes.Buffer)
+		writeHeader(root, outContent, root.Name, imports, headerText)
+		writeMethods(root, outContent, byType)
+
+		writeFormatted(ctx, root, outContent.Bytes())
 	}
 
 	return nil
 }
 
-// ObjectGenCtx contains the common info for generating deepcopy implementations.
-// It mostly exists so that generating for a package can be easily tested without
-// requiring a full set of output rules, etc.
-type ObjectGenCtx struct {
-	Collector  *markers.Collector
-	Checker    *loader.TypeChecker
-	HeaderText string
-}
-
 // writeHeader writes out the build tag, package declaration, and imports
 func writeHeader(pkg *loader.Package, out io.Writer, packageName string, imports *importsList, headerText string) {
 	// NB(directxman12): blank line after build tags to distinguish them from comments
@@ -186,84 +230,6 @@ import (
 
 }
 
-// GenerateForPackage generates DeepCopy and runtime.Object implementations for
-// types in the given package, writing the formatted result to given writer.
-// May return nil if source could not be generated.
-func (ctx *ObjectGenCtx) GenerateForPackage(root *loader.Package) []byte {
-	allTypes, err := enabledOnPackage(ctx.Collector, root)
-	if err != nil {
-		root.AddError(err)
-		return nil
-	}
-
-	ctx.Checker.Check(root, func(node ast.Node) bool {
-		// ignore interfaces
-		_, isIface := node.(*ast.InterfaceType)
-		return !isIface
-	})
-
-	root.NeedTypesInfo()
-
-	byType := make(map[string][]byte)
-	imports := &importsList{
-		byPath:  make(map[string]string),
-		byAlias: make(map[string]string),
-		pkg:     root,
-	}
-	// avoid confusing aliases by "reserving" the root package's name as an alias
-	imports.byAlias[root.Name] = ""
-
-	if err := markers.EachType(ctx.Collector, root, func(info *markers.TypeInfo) {
-		outContent := new(bytes.Buffer)
-
-		// copy when nabled for all types and not disabled, or enabled
-		// specifically on this type
-		if !enabledOnType(allTypes, info) {
-			return
-		}
-
-		// avoid copying non-exported types, etc
-		if !shouldBeCopied(root, info) {
-			return
-		}
-
-		copyCtx := &copyMethodMaker{
-			pkg:         root,
-			importsList: imports,
-			codeWriter:  &codeWriter{out: outContent},
-		}
-
-		copyCtx.GenerateMethodsFor(root, info)
-
-		outBytes := outContent.Bytes()
-		if len(outBytes) > 0 {
-			byType[info.Name] = outBytes
-		}
-	}); err != nil {
-		root.AddError(err)
-		return nil
-	}
-
-	if len(byType) == 0 {
-		return nil
-	}
-
-	outContent := new(bytes.Buffer)
-	writeHeader(root, outContent, root.Name, imports, ctx.HeaderText)
-	writeMethods(root, outContent, byType)
-
-	outBytes := outContent.Bytes()
-	formattedBytes, err := format.Source(outBytes)
-	if err != nil {
-		root.AddError(err)
-		// we still write the invalid source to disk to figure out what went wrong
-	} else {
-		outBytes = formattedBytes
-	}
-
-	return outBytes
-}
-
 // writeMethods writes each method to the file, sorted by type name.
 func writeMethods(pkg *loader.Package, out io.Writer, byType map[string][]byte) {
 	sortedNames := make([]string, 0, len(byType))
@@ -282,7 +248,15 @@ func writeMethods(pkg *loader.Package, out io.Writer, byType map[string][]byte)
 
 // writeFormatted outputs the given code, after gofmt-ing it.  If we couldn't gofmt,
 // we write the unformatted code for debugging purposes.
-func writeOut(ctx *genall.GenerationContext, root *loader.Package, outBytes []byte) {
+func writeFormatted(ctx *genall.GenerationContext, root *loader.Package, outBytes []byte) {
+	formattedBytes, err := format.Source(outBytes)
+	if err != nil {
+		root.AddError(err)
+		// we still write the invalid source to disk to figure out what went wrong
+	} else {
+		outBytes = formattedBytes
+	}
+
 	outputFile, err := ctx.Open(root, "zz_generated.deepcopy.go")
 	if err != nil {
 		root.AddError(err)
diff --git a/pkg/deepcopy/traverse.go b/pkg/deepcopy/traverse.go
index 1c92e48a..96e09be9 100644
--- a/pkg/deepcopy/traverse.go
+++ b/pkg/deepcopy/traverse.go
@@ -34,9 +34,6 @@ import (
 // I've tried to clean it up a bit from the original in deepcopy-gen,
 // but parts remain a bit convoluted.  Exercise caution when changing.
 // It's perhaps a tad over-commented now, but better safe than sorry.
-// It also seriously needs auditing for sanity -- there's parts where we
-// copy the original deepcopy-gen's output just to be safe, but some of that
-// could be simplified away if we're careful.
 
 // codeWriter assists in writing out Go code lines and blocks to a writer.
 type codeWriter struct {
@@ -155,53 +152,6 @@ func (l *importsList) ImportSpecs() []string {
 	return res
 }
 
-// namingInfo holds package and syntax for referencing a field, type,
-// etc.  It's used to allow lazily marking import usage.
-// You should generally retrieve the syntax using Syntax.
-type namingInfo struct {
-	// typeInfo is the type being named.
-	typeInfo     types.Type
-	nameOverride string
-}
-
-// Syntax calculates the code representation of the given type or name,
-// and marks that is used (potentially marking an import as used).
-func (n *namingInfo) Syntax(basePkg *loader.Package, imports *importsList) string {
-	if n.nameOverride != "" {
-		return n.nameOverride
-	}
-
-	// NB(directxman12): typeInfo.String gets us most of the way there,
-	// but fails (for us) on named imports, since it uses the full package path.
-	switch typeInfo := n.typeInfo.(type) {
-	case *types.Named:
-		// register that we need an import for this type,
-		// so we can get the appropriate alias to use.
-		typeName := typeInfo.Obj()
-		otherPkg := typeName.Pkg()
-		if otherPkg == basePkg.Types {
-			// local import
-			return typeName.Name()
-		}
-		alias := imports.NeedImport(loader.NonVendorPath(otherPkg.Path()))
-		return alias + "." + typeName.Name()
-	case *types.Basic:
-		return typeInfo.String()
-	case *types.Pointer:
-		return "*" + (&namingInfo{typeInfo: typeInfo.Elem()}).Syntax(basePkg, imports)
-	case *types.Slice:
-		return "[]" + (&namingInfo{typeInfo: typeInfo.Elem()}).Syntax(basePkg, imports)
-	case *types.Map:
-		return fmt.Sprintf(
-			"map[%s]%s",
-			(&namingInfo{typeInfo: typeInfo.Key()}).Syntax(basePkg, imports),
-			(&namingInfo{typeInfo: typeInfo.Elem()}).Syntax(basePkg, imports))
-	default:
-		basePkg.AddError(fmt.Errorf("name requested for invalid type %s", typeInfo))
-		return typeInfo.String()
-	}
-}
-
 // copyMethodMakers makes DeepCopy (and related) methods for Go types,
 // writing them to its codeWriter.
 type copyMethodMaker struct {
@@ -213,7 +163,7 @@ type copyMethodMaker struct {
 // GenerateMethodsFor makes DeepCopy, DeepCopyInto, and DeepCopyObject methods
 // for the given type, when appropriate
 func (c *copyMethodMaker) GenerateMethodsFor(root *loader.Package, info *markers.TypeInfo) {
-	typeInfo := root.TypesInfo.TypeOf(info.RawSpec.Name)
+	typeInfo := root.TypesInfo.TypeOf(info.RawSpec.Type)
 	if typeInfo == types.Typ[types.Invalid] {
 		root.AddError(loader.ErrFromNode(fmt.Errorf("unknown type %s", info.Name), info.RawSpec))
 	}
@@ -233,24 +183,21 @@ func (c *copyMethodMaker) GenerateMethodsFor(root *loader.Package, info *markers
 			c.Linef("func (in *%s) DeepCopyInto(out *%s) {", info.Name, info.Name)
 		} else {
 			c.Linef("func (in %s) DeepCopyInto(out *%s) {", info.Name, info.Name)
-			c.Line("{in := &in") // add an extra block so that we can redefine `in` without type issues
+			c.Line("in := &in")
 		}
 
 		// just wrap the existing deepcopy if present
 		if hasManualDeepCopy {
 			if deepCopyOnPtr {
 				c.Line("clone := in.DeepCopy()")
-				c.Line("*out = *clone")
+				c.Line("*out := *clone")
 			} else {
-				c.Line("*out = in.DeepCopy()")
+				c.Line("*out := in.DeepCopy()")
 			}
 		} else {
-			c.genDeepCopyIntoBlock(&namingInfo{nameOverride: info.Name}, typeInfo)
+			c.genDeepCopyIntoBlock(info.Name, typeInfo)
 		}
 
-		if !ptrReceiver {
-			c.Line("}") // close our extra "in redefinition" block
-		}
 		c.Line("}")
 	}
 
@@ -277,20 +224,18 @@ func (c *copyMethodMaker) GenerateMethodsFor(root *loader.Package, info *markers
 
 // genDeepCopyBody generates a DeepCopyInto block for the given type.  The
 // block is *not* wrapped in curly braces.
-func (c *copyMethodMaker) genDeepCopyIntoBlock(actualName *namingInfo, typeInfo types.Type) {
-	// we calculate *how* we should copy mostly based on the "eventual" type of
-	// a given type (i.e. the type that results from following all aliases)
-	last := eventualUnderlyingType(typeInfo)
-
+func (c *copyMethodMaker) genDeepCopyIntoBlock(actualName string, typeInfo types.Type) {
 	// we might hit a type that has a manual deepcopy method written on non-root types
-	// (this case is handled for root types in GenerateMethodFor).
-	// In that case (when we're not dealing with a pointer, since those need special handling
-	// to match 1-to-1 with k8s deepcopy-gen), just use that.
-	if _, isPtr := last.(*types.Pointer); !isPtr && hasAnyDeepCopyMethod(c.pkg, typeInfo) {
+	// (this case is handled for root types in GenerateMethodFor)
+	if hasAnyDeepCopyMethod(c.pkg, typeInfo) {
 		c.Line("*out = in.DeepCopy()")
 		return
 	}
 
+	// we calculate *how* we should copy mostly based on the "eventual" type of
+	// a given type (i.e. the type that results from following all aliases)
+	last := eventualUnderlyingType(typeInfo)
+
 	switch last := last.(type) {
 	case *types.Basic:
 		// basic types themselves can be "shallow" copied, so all we need
@@ -318,7 +263,7 @@ func (c *copyMethodMaker) genDeepCopyIntoBlock(actualName *namingInfo, typeInfo
 
 // genMapDeepCopy generates DeepCopy code for the given named type whose eventual
 // type is the given map type.
-func (c *copyMethodMaker) genMapDeepCopy(actualName *namingInfo, mapType *types.Map) {
+func (c *copyMethodMaker) genMapDeepCopy(actualName string, mapType *types.Map) {
 	// maps *must* have shallow-copiable types, since we just iterate
 	// through the keys, only trying to deepcopy the values.
 	if !fineToShallowCopy(mapType.Key()) {
@@ -327,7 +272,7 @@ func (c *copyMethodMaker) genMapDeepCopy(actualName *namingInfo, mapType *types.
 	}
 
 	// make our actual type (not the underlying one)...
-	c.Linef("*out = make(%[1]s, len(*in))", actualName.Syntax(c.pkg, c.importsList))
+	c.Linef("*out = make(%[1]s, len(*in))", actualName)
 
 	// ...and copy each element appropriately
 	c.For("key, val := range *in", func() {
@@ -338,19 +283,17 @@ func (c *copyMethodMaker) genMapDeepCopy(actualName *namingInfo, mapType *types.
 		switch {
 		case hasDeepCopyInto || hasDeepCopy:
 			// use the manually-written methods
-			_, fieldIsPtr := mapType.Elem().(*types.Pointer)                       // is "out" actually a pointer
-			inIsPtr := resultWillBePointer(mapType.Elem(), hasDeepCopy, copyOnPtr) // does copying "in" produce a pointer
+			_, outNeedsPtr := mapType.Elem().(*types.Pointer) // is "out" actually a pointer
+			inIsPtr := usePtrReceiver(mapType.Elem())         // does copying "in" produce a pointer
 			if hasDeepCopy {
 				// If we're calling DeepCopy, check if it's receiver needs a pointer
 				inIsPtr = copyOnPtr
 			}
-			if inIsPtr == fieldIsPtr {
+			if inIsPtr == outNeedsPtr {
 				c.Line("(*out)[key] = val.DeepCopy()")
-			} else if fieldIsPtr {
-				c.Line("{") // use a block because we use `x` as a temporary
+			} else if outNeedsPtr {
 				c.Line("x := val.DeepCopy()")
 				c.Line("(*out)[key] = &x")
-				c.Line("}")
 			} else {
 				c.Line("(*out)[key] = *val.DeepCopy()")
 			}
@@ -365,12 +308,12 @@ func (c *copyMethodMaker) genMapDeepCopy(actualName *namingInfo, mapType *types.
 
 			// if it passes by reference, let the main switch handle it
 			if passesByReference(underlyingElem) {
-				c.Linef("var outVal %[1]s", (&namingInfo{typeInfo: underlyingElem}).Syntax(c.pkg, c.importsList))
+				c.Linef("var outVal %[1]s", c.syntaxFor(underlyingElem))
 				c.IfElse("val == nil", func() {
 					c.Line("(*out)[key] = nil")
 				}, func() {
 					c.Line("in, out := &val, &outVal")
-					c.genDeepCopyIntoBlock(&namingInfo{typeInfo: mapType.Elem()}, mapType.Elem())
+					c.genDeepCopyIntoBlock(c.syntaxFor(mapType.Elem()), mapType.Elem())
 				})
 				c.Line("(*out)[key] = outVal")
 
@@ -392,18 +335,18 @@ func (c *copyMethodMaker) genMapDeepCopy(actualName *namingInfo, mapType *types.
 
 // genSliceDeepCopy generates DeepCopy code for the given named type whose
 // underlying type is the given slice.
-func (c *copyMethodMaker) genSliceDeepCopy(actualName *namingInfo, sliceType *types.Slice) {
+func (c *copyMethodMaker) genSliceDeepCopy(actualName string, sliceType *types.Slice) {
 	underlyingElem := eventualUnderlyingType(sliceType.Elem())
 
 	// make the actual type (not the underlying)
-	c.Linef("*out = make(%[1]s, len(*in))", actualName.Syntax(c.pkg, c.importsList))
+	c.Linef("*out = make(%[1]s, len(*in))", actualName)
 
 	// check if we need to do anything special, or just copy each element appropriately
 	switch {
 	case hasAnyDeepCopyMethod(c.pkg, sliceType.Elem()):
 		// just use deepcopy if it's present (deepcopyinto will be filled in by our code)
 		c.For("i := range *in", func() {
-			c.Line("(*in)[i].DeepCopyInto(&(*out)[i])")
+			c.Line("(*in)[1].DeepCopyInto(&(*out)[i]")
 		})
 	case fineToShallowCopy(underlyingElem):
 		// shallow copy if ok
@@ -415,7 +358,7 @@ func (c *copyMethodMaker) genSliceDeepCopy(actualName *namingInfo, sliceType *ty
 			if passesByReference(underlyingElem) || hasAnyDeepCopyMethod(c.pkg, sliceType.Elem()) {
 				c.If("(*in)[i] != nil", func() {
 					c.Line("in, out := &(*in)[i], &(*out)[i]")
-					c.genDeepCopyIntoBlock(&namingInfo{typeInfo: sliceType.Elem()}, sliceType.Elem())
+					c.genDeepCopyIntoBlock(c.syntaxFor(sliceType.Elem()), sliceType.Elem())
 				})
 				return
 			}
@@ -433,7 +376,7 @@ func (c *copyMethodMaker) genSliceDeepCopy(actualName *namingInfo, sliceType *ty
 
 // genStructDeepCopy generates DeepCopy code for the given named type whose
 // underlying type is the given struct.
-func (c *copyMethodMaker) genStructDeepCopy(_ *namingInfo, structType *types.Struct) {
+func (c *copyMethodMaker) genStructDeepCopy(_ string, structType *types.Struct) {
 	c.Line("*out = *in")
 
 	for i := 0; i < structType.NumFields(); i++ {
@@ -443,29 +386,18 @@ func (c *copyMethodMaker) genStructDeepCopy(_ *namingInfo, structType *types.Str
 		hasDeepCopy, copyOnPtr := hasDeepCopyMethod(c.pkg, field.Type())
 		hasDeepCopyInto := hasDeepCopyIntoMethod(c.pkg, field.Type())
 		if hasDeepCopyInto || hasDeepCopy {
-			// NB(directxman12): yes, I know this is kind-of weird that we
-			// have all this special-casing here, but it's nice for testing
-			// purposes to be 1-to-1 with deepcopy-gen, which does all sorts of
-			// stuff like this (I'm pretty sure I found some codepaths that
-			// never execute there, because they're pretty clearly invalid
-			// syntax).
-
-			_, fieldIsPtr := field.Type().(*types.Pointer)
-			inIsPtr := resultWillBePointer(field.Type(), hasDeepCopy, copyOnPtr)
-			if fieldIsPtr {
-				// we'll need a if block to check for nilness
-				// we'll let genDeepCopyIntoBlock handle the details, we just needed the setup
-				c.If(fmt.Sprintf("in.%s != nil", field.Name()), func() {
-					c.Linef("in, out := &in.%[1]s, &out.%[1]s", field.Name())
-					c.genDeepCopyIntoBlock(&namingInfo{typeInfo: field.Type()}, field.Type())
-				})
+			_, outNeedsPtr := field.Type().(*types.Pointer)
+			inIsPtr := usePtrReceiver(field.Type())
+			if hasDeepCopy {
+				inIsPtr = copyOnPtr
+			}
+			if inIsPtr == outNeedsPtr {
+				c.Linef("out.%[1]s = in.%[1]s.DeepCopy()", field.Name())
+			} else if outNeedsPtr {
+				c.Linef("x := in.%[1]s.DeepCopy()", field.Name())
+				c.Linef("out.%[1]s = &x", field.Name())
 			} else {
-				// special-case for compatibility with deepcopy-gen
-				if inIsPtr == fieldIsPtr {
-					c.Linef("out.%[1]s = in.%[1]s.DeepCopy()", field.Name())
-				} else {
-					c.Linef("in.%[1]s.DeepCopyInto(&out.%[1]s)", field.Name())
-				}
+				c.Linef("in.%[1]s.DeepCopyInto(&out.%[1]s)", field.Name())
 			}
 			continue
 		}
@@ -475,7 +407,7 @@ func (c *copyMethodMaker) genStructDeepCopy(_ *namingInfo, structType *types.Str
 		if passesByReference(underlyingField) {
 			c.If(fmt.Sprintf("in.%s != nil", field.Name()), func() {
 				c.Linef("in, out := &in.%[1]s, &out.%[1]s", field.Name())
-				c.genDeepCopyIntoBlock(&namingInfo{typeInfo: field.Type()}, field.Type())
+				c.genDeepCopyIntoBlock(c.syntaxFor(field.Type()), field.Type())
 			})
 			continue
 		}
@@ -499,14 +431,14 @@ func (c *copyMethodMaker) genStructDeepCopy(_ *namingInfo, structType *types.Str
 
 // genPointerDeepCopy generates DeepCopy code for the given named type whose
 // underlying type is the given struct.
-func (c *copyMethodMaker) genPointerDeepCopy(_ *namingInfo, pointerType *types.Pointer) {
+func (c *copyMethodMaker) genPointerDeepCopy(_ string, pointerType *types.Pointer) {
 	underlyingElem := eventualUnderlyingType(pointerType.Elem())
 
 	// if we have a manually written deepcopy, just use that
 	hasDeepCopy, copyOnPtr := hasDeepCopyMethod(c.pkg, pointerType.Elem())
 	hasDeepCopyInto := hasDeepCopyIntoMethod(c.pkg, pointerType.Elem())
 	if hasDeepCopyInto || hasDeepCopy {
-		outNeedsPtr := resultWillBePointer(pointerType.Elem(), hasDeepCopy, copyOnPtr)
+		outNeedsPtr := usePtrReceiver(pointerType.Elem())
 		if hasDeepCopy {
 			outNeedsPtr = copyOnPtr
 		}
@@ -521,17 +453,17 @@ func (c *copyMethodMaker) genPointerDeepCopy(_ *namingInfo, pointerType *types.P
 
 	// shallow-copiable types are pretty easy
 	if fineToShallowCopy(underlyingElem) {
-		c.Linef("*out = new(%[1]s)", (&namingInfo{typeInfo: pointerType.Elem()}).Syntax(c.pkg, c.importsList))
+		c.Linef("*out = new(%[1]s)", c.syntaxFor(pointerType.Elem()))
 		c.Line("**out = **in")
 		return
 	}
 
 	// pass-by-reference types get delegated to the main switch
 	if passesByReference(underlyingElem) {
-		c.Linef("*out = new(%s)", (&namingInfo{typeInfo: underlyingElem}).Syntax(c.pkg, c.importsList))
+		c.Linef("*out = new(%s)", c.syntaxFor(underlyingElem))
 		c.If("**in != nil", func() {
 			c.Line("in, out := *in, *out")
-			c.genDeepCopyIntoBlock(&namingInfo{typeInfo: underlyingElem}, eventualUnderlyingType(underlyingElem))
+			c.genDeepCopyIntoBlock(c.syntaxFor(underlyingElem), eventualUnderlyingType(underlyingElem))
 		})
 		return
 	}
@@ -539,7 +471,7 @@ func (c *copyMethodMaker) genPointerDeepCopy(_ *namingInfo, pointerType *types.P
 	// otherwise...
 	switch underlyingElem := underlyingElem.(type) {
 	case *types.Struct:
-		c.Linef("*out = new(%[1]s)", (&namingInfo{typeInfo: pointerType.Elem()}).Syntax(c.pkg, c.importsList))
+		c.Linef("*out = new(%[1]s)", c.syntaxFor(pointerType.Elem()))
 		c.Line("(*in).DeepCopyInto(*out)")
 	default:
 		c.pkg.AddError(fmt.Errorf("invalid pointer element type %s", underlyingElem))
@@ -547,43 +479,48 @@ func (c *copyMethodMaker) genPointerDeepCopy(_ *namingInfo, pointerType *types.P
 	}
 }
 
-// usePtrReceiver checks if we need a pointer receiver on methods for the given type
-// Pass-by-reference types don't get pointer receivers.
-func usePtrReceiver(typeInfo types.Type) bool {
-	switch typeInfo.(type) {
+// syntaxFor returns the Go syntax-utal representation of the given type.
+func (c *copyMethodMaker) syntaxFor(typeInfo types.Type) string {
+	// NB(directxman12): typeInfo.String gets us most of the way there,
+	// but fails (for us) on named imports, since it uses the full package path.
+	switch typeInfo := typeInfo.(type) {
+	case *types.Named:
+		// register that we need an import for this type,
+		// so we can get the appropriate alias to use.
+		typeName := typeInfo.Obj()
+		otherPkg := typeName.Pkg()
+		if otherPkg == c.pkg.Types {
+			// local import
+			return typeName.Name()
+		}
+		alias := c.NeedImport(loader.NonVendorPath(otherPkg.Path()))
+		return alias + "." + typeName.Name()
+	case *types.Basic:
+		return typeInfo.String()
 	case *types.Pointer:
-		return false
-	case *types.Map:
-		return false
+		return "*" + c.syntaxFor(typeInfo.Elem())
 	case *types.Slice:
-		return false
-	case *types.Named:
-		return usePtrReceiver(typeInfo.Underlying())
+		return "[]" + c.syntaxFor(typeInfo.Elem())
+	case *types.Map:
+		return fmt.Sprintf("map[%s]%s", c.syntaxFor(typeInfo.Key()), c.syntaxFor(typeInfo.Elem()))
 	default:
-		return true
+		c.pkg.AddError(fmt.Errorf("name requested for invalid type %s", typeInfo))
+		return typeInfo.String()
 	}
 }
 
-func resultWillBePointer(typeInfo types.Type, hasDeepCopy, deepCopyOnPtr bool) bool {
-	// if we have a manual deepcopy, we can just check what that returns
-	if hasDeepCopy {
-		return deepCopyOnPtr
-	}
-
-	// otherwise, we'll need to check its type
-	switch typeInfo := typeInfo.(type) {
+// usePtrReceiver checks if we need a pointer receiver on methods for the given type
+// Pass-by-reference types don't get pointer receivers.
+func usePtrReceiver(typeInfo types.Type) bool {
+	switch typeInfo.(type) {
 	case *types.Pointer:
-		// NB(directxman12): we don't have to worry about the elem having a deepcopy,
-		// since hasManualDeepCopy would've caught that.
-
-		// we'll be calling on the elem, so check that
-		return resultWillBePointer(typeInfo.Elem(), false, false)
+		return false
 	case *types.Map:
 		return false
 	case *types.Slice:
 		return false
 	case *types.Named:
-		return resultWillBePointer(typeInfo.Underlying(), false, false)
+		return usePtrReceiver(typeInfo.Underlying())
 	default:
 		return true
 	}
@@ -600,36 +537,22 @@ func shouldBeCopied(pkg *loader.Package, info *markers.TypeInfo) bool {
 		return false
 	}
 
-	typeInfo := pkg.TypesInfo.TypeOf(info.RawSpec.Name)
+	typeInfo := pkg.TypesInfo.TypeOf(info.RawSpec.Type)
 	if typeInfo == types.Typ[types.Invalid] {
 		pkg.AddError(loader.ErrFromNode(fmt.Errorf("unknown type %s", info.Name), info.RawSpec))
 		return false
 	}
-
-	// according to gengo, everything named is an alias, except for an alias to a pointer,
-	// which is just a pointer, afaict.  Just roll with it.
-	if asPtr, isPtr := typeInfo.(*types.Named).Underlying().(*types.Pointer); isPtr {
-		typeInfo = asPtr
-	}
-
-	lastType := typeInfo
-	if _, isNamed := typeInfo.(*types.Named); isNamed {
-		// if it has a manual deepcopy or deepcopyinto, we're fine
-		if hasAnyDeepCopyMethod(pkg, typeInfo) {
+	var lastType types.Type
+	for underlyingType := typeInfo; underlyingType != lastType; lastType, underlyingType = underlyingType, underlyingType.Underlying() {
+		// aliases to other things besides basics need copy methods
+		// (basics can be straight-up shallow-copied)
+		if _, isBasic := underlyingType.(*types.Basic); !isBasic {
 			return true
 		}
 
-		for underlyingType := typeInfo.Underlying(); underlyingType != lastType; lastType, underlyingType = underlyingType, underlyingType.Underlying() {
-			// if it has a manual deepcopy or deepcopyinto, we're fine
-			if hasAnyDeepCopyMethod(pkg, underlyingType) {
-				return true
-			}
-
-			// aliases to other things besides basics need copy methods
-			// (basics can be straight-up shallow-copied)
-			if _, isBasic := underlyingType.(*types.Basic); !isBasic {
-				return true
-			}
+		// if it has a manual deepcopy or deepcopyinto, we're fine
+		if hasAnyDeepCopyMethod(pkg, underlyingType) {
+			return true
 		}
 	}
 
@@ -641,11 +564,8 @@ func shouldBeCopied(pkg *loader.Package, info *markers.TypeInfo) bool {
 // hasDeepCopyMethod checks if this type has a manual DeepCopy method and if
 // the method has a pointer receiver.
 func hasDeepCopyMethod(pkg *loader.Package, typeInfo types.Type) (bool, bool) {
-	deepCopyMethod, ind, _ := types.LookupFieldOrMethod(typeInfo, true /* check pointers too */, pkg.Types, "DeepCopy")
-	if len(ind) != 1 {
-		// ignore embedded methods
-		return false, false
-	}
+	methods := types.NewMethodSet(typeInfo)
+	deepCopyMethod := methods.Lookup(pkg.Types, "DeepCopy")
 	if deepCopyMethod == nil {
 		return false, false
 	}
@@ -657,37 +577,18 @@ func hasDeepCopyMethod(pkg *loader.Package, typeInfo types.Type) (bool, bool) {
 	if methodSig.Results() == nil || methodSig.Results().Len() != 1 {
 		return false, false
 	}
-
-	recvAsPtr, recvIsPtr := methodSig.Recv().Type().(*types.Pointer)
-	if recvIsPtr {
-		// NB(directxman12): the pointer type returned here isn't comparable even though they
-		// have the same underlying type, for some reason (probably that
-		// LookupFieldOrMethod calls types.NewPointer for us), so check the
-		// underlying values.
-
-		resultPtr, resultIsPtr := methodSig.Results().At(0).Type().(*types.Pointer)
-		if !resultIsPtr {
-			// pointer vs non-pointer are different types
-			return false, false
-		}
-
-		if recvAsPtr.Elem() != resultPtr.Elem() {
-			return false, false
-		}
-	} else if methodSig.Results().At(0).Type() != methodSig.Recv().Type() {
+	if methodSig.Results().At(0).Type() != methodSig.Recv().Type() {
 		return false, false
 	}
 
+	_, recvIsPtr := methodSig.Results().At(0).Type().(*types.Pointer)
 	return true, recvIsPtr
 }
 
 // hasDeepCopyIntoMethod checks if this type has a manual DeepCopyInto method.
 func hasDeepCopyIntoMethod(pkg *loader.Package, typeInfo types.Type) bool {
-	deepCopyMethod, ind, _ := types.LookupFieldOrMethod(typeInfo, true /* check pointers too */, pkg.Types, "DeepCopyInto")
-	if len(ind) != 1 {
-		// ignore embedded methods
-		return false
-	}
+	methods := types.NewMethodSet(typeInfo) // todo: recalculating this could be slow, keep across both invocations
+	deepCopyMethod := methods.Lookup(pkg.Types, "DeepCopyInto")
 	if deepCopyMethod == nil {
 		return false
 	}
@@ -705,13 +606,9 @@ func hasDeepCopyIntoMethod(pkg *loader.Package, typeInfo types.Type) bool {
 	}
 
 	if recvPtr, recvIsPtr := methodSig.Recv().Type().(*types.Pointer); recvIsPtr {
-		// NB(directxman12): the pointer type returned here isn't comparable even though they
-		// have the same underlying type, for some reason (probably that
-		// LookupFieldOrMethod calls types.NewPointer for us), so check the
-		// underlying values.
-		return paramPtr.Elem() == recvPtr.Elem()
+		return methodSig.Params().At(0).Type() == recvPtr
 	}
-	return methodSig.Recv().Type() == paramPtr.Elem()
+	return methodSig.Params().At(0).Type() == paramPtr.Elem()
 }
 
 // hasAnyDeepCopyMethod checks if the given method has DeepCopy or DeepCopyInto
diff --git a/pkg/genall/help/pretty/help.go b/pkg/genall/help/pretty/help.go
index 3e34cc0d..5cf4c762 100644
--- a/pkg/genall/help/pretty/help.go
+++ b/pkg/genall/help/pretty/help.go
@@ -164,7 +164,6 @@ func MarkerSyntaxHelp(def help.MarkerDoc) Span {
 
 	for _, arg := range def.Fields {
 		out.Print(fieldStyle.Containing(fieldSyntaxHelp(arg, sep)))
-		sep = ","
 	}
 
 	return out
diff --git a/pkg/rbac/parser.go b/pkg/rbac/parser.go
index 88ae805d..a0388236 100644
--- a/pkg/rbac/parser.go
+++ b/pkg/rbac/parser.go
@@ -52,10 +52,6 @@ type Rule struct {
 	Verbs []string
 	// URL specifies the non-resource URLs that this rule encompasses.
 	URLs []string `marker:"urls,optional"`
-	// Namespace specifies the scope of the Rule.
-	// If not set, the Rule belongs to the generated ClusterRole.
-	// If set, the Rule belongs to a Role, whose namespace is specified by this field.
-	Namespace string `marker:",optional"`
 }
 
 // ruleKey represents the resources and non-resources a Rule applies.
@@ -150,109 +146,69 @@ func (Generator) RegisterMarkers(into *markers.Registry) error {
 	return nil
 }
 
-// GenerateRoles generate a slice of objs representing either a ClusterRole or a Role object
-// The order of the objs in the returned slice is stable and determined by their namespaces.
-func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{}, error) {
-	rulesByNS := make(map[string][]*Rule)
+// GenerateClusterRole generates a rbacv1.ClusterRole object
+func GenerateClusterRole(ctx *genall.GenerationContext, roleName string) (*rbacv1.ClusterRole, error) {
+	rules := make(map[ruleKey]*Rule)
 	for _, root := range ctx.Roots {
 		markerSet, err := markers.PackageMarkers(ctx.Collector, root)
 		if err != nil {
 			root.AddError(err)
 		}
 
-		// group RBAC markers by namespace
+		// all the Rules having the same ruleKey will be merged into the first Rule
 		for _, markerValue := range markerSet[RuleDefinition.Name] {
 			rule := markerValue.(Rule)
-			namespace := rule.Namespace
-			if _, ok := rulesByNS[namespace]; !ok {
-				rules := make([]*Rule, 0)
-				rulesByNS[namespace] = rules
-			}
-			rulesByNS[namespace] = append(rulesByNS[namespace], &rule)
-		}
-	}
-
-	// NormalizeRules merge Rule with the same ruleKey and sort the Rules
-	NormalizeRules := func(rules []*Rule) []rbacv1.PolicyRule {
-		ruleMap := make(map[ruleKey]*Rule)
-		// all the Rules having the same ruleKey will be merged into the first Rule
-		for _, rule := range rules {
 			key := rule.key()
-			if _, ok := ruleMap[key]; !ok {
-				ruleMap[key] = rule
+			if _, ok := rules[key]; !ok {
+				rules[key] = &rule
 				continue
 			}
-			ruleMap[key].addVerbs(rule.Verbs)
-		}
-
-		// sort the Rules in rules according to their ruleKeys
-		keys := make([]ruleKey, 0, len(ruleMap))
-		for key := range ruleMap {
-			keys = append(keys, key)
+			rules[key].addVerbs(rule.Verbs)
 		}
-		sort.Sort(ruleKeys(keys))
-
-		var policyRules []rbacv1.PolicyRule
-		for _, key := range keys {
-			policyRules = append(policyRules, ruleMap[key].ToRule())
+	}
 
-		}
-		return policyRules
+	if len(rules) == 0 {
+		return nil, nil
 	}
 
-	// collect all the namespaces and sort them
-	var namespaces []string
-	for ns := range rulesByNS {
-		namespaces = append(namespaces, ns)
+	// sort the Rules in rules according to their ruleKeys
+	keys := make([]ruleKey, 0)
+	for key := range rules {
+		keys = append(keys, key)
 	}
-	sort.Strings(namespaces)
-
-	// process the items in rulesByNS by the order specified in `namespaces` to make sure that the Role order is stable
-	var objs []interface{}
-	for _, ns := range namespaces {
-		rules := rulesByNS[ns]
-		policyRules := NormalizeRules(rules)
-		if len(policyRules) == 0 {
-			continue
-		}
-		if ns == "" {
-			objs = append(objs, rbacv1.ClusterRole{
-				TypeMeta: metav1.TypeMeta{
-					Kind:       "ClusterRole",
-					APIVersion: rbacv1.SchemeGroupVersion.String(),
-				},
-				ObjectMeta: metav1.ObjectMeta{
-					Name: roleName,
-				},
-				Rules: policyRules,
-			})
-		} else {
-			objs = append(objs, rbacv1.Role{
-				TypeMeta: metav1.TypeMeta{
-					Kind:       "Role",
-					APIVersion: rbacv1.SchemeGroupVersion.String(),
-				},
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      roleName,
-					Namespace: ns,
-				},
-				Rules: policyRules,
-			})
-		}
+	sort.Sort(ruleKeys(keys))
+
+	var policyRules []rbacv1.PolicyRule
+	for _, key := range keys {
+		policyRules = append(policyRules, rules[key].ToRule())
+
 	}
 
-	return objs, nil
+	return &rbacv1.ClusterRole{
+		TypeMeta: metav1.TypeMeta{
+			Kind:       "ClusterRole",
+			APIVersion: rbacv1.SchemeGroupVersion.String(),
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Name: roleName,
+		},
+		Rules: policyRules,
+	}, nil
 }
 
 func (g Generator) Generate(ctx *genall.GenerationContext) error {
-	objs, err := GenerateRoles(ctx, g.RoleName)
+	clusterRole, err := GenerateClusterRole(ctx, g.RoleName)
 	if err != nil {
 		return err
 	}
 
-	if len(objs) == 0 {
+	if clusterRole == nil {
 		return nil
 	}
 
-	return ctx.WriteYAML("role.yaml", objs...)
+	if err := ctx.WriteYAML("role.yaml", *clusterRole); err != nil {
+		return err
+	}
+
+	return nil
 }
diff --git a/pkg/rbac/zz_generated.markerhelp.go b/pkg/rbac/zz_generated.markerhelp.go
index 1aa81a01..bd8a3251 100644
--- a/pkg/rbac/zz_generated.markerhelp.go
+++ b/pkg/rbac/zz_generated.markerhelp.go
@@ -64,10 +64,6 @@ func (Rule) Help() *markers.DefinitionHelp {
 				Summary: "URL specifies the non-resource URLs that this rule encompasses.",
 				Details: "",
 			},
-			"Namespace": markers.DetailedHelp{
-				Summary: "specifies the scope of the Rule. If not set, the Rule belongs to the generated ClusterRole. If set, the Rule belongs to a Role, whose namespace is specified by this field.",
-				Details: "",
-			},
 		},
 	}
 }


Test patch:
diff --git a/pkg/crd/crd_spec_test.go b/pkg/crd/crd_spec_test.go
deleted file mode 100644
index 5f7b09de..00000000
--- a/pkg/crd/crd_spec_test.go
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
-Copyright 2019 The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package crd_test
-
-import (
-	. "github.com/onsi/ginkgo"
-	. "github.com/onsi/gomega"
-	apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
-
-	"sigs.k8s.io/controller-tools/pkg/crd"
-)
-
-var _ = Describe("CRD Generation", func() {
-	Describe("Utilities", func() {
-		Describe("MergeIdenticalVersionInfo", func() {
-			It("should replace per-version schemata with a top-level schema if all are identical", func() {
-				spec := &apiext.CustomResourceDefinition{
-					Spec: apiext.CustomResourceDefinitionSpec{
-						Versions: []apiext.CustomResourceDefinitionVersion{
-							{
-								Name: "v1",
-								Schema: &apiext.CustomResourceValidation{
-									OpenAPIV3Schema: &apiext.JSONSchemaProps{
-										Required:   []string{"foo"},
-										Type:       "object",
-										Properties: map[string]apiext.JSONSchemaProps{"foo": apiext.JSONSchemaProps{Type: "string"}},
-									},
-								},
-							},
-							{
-								Name:    "v2",
-								Storage: true,
-								Schema: &apiext.CustomResourceValidation{
-									OpenAPIV3Schema: &apiext.JSONSchemaProps{
-										Required:   []string{"foo"},
-										Type:       "object",
-										Properties: map[string]apiext.JSONSchemaProps{"foo": apiext.JSONSchemaProps{Type: "string"}},
-									},
-								},
-							},
-						},
-					},
-				}
-				crd.MergeIdenticalVersionInfo(spec)
-				Expect(spec.Spec.Validation).To(Equal(&apiext.CustomResourceValidation{
-					OpenAPIV3Schema: &apiext.JSONSchemaProps{
-						Required:   []string{"foo"},
-						Type:       "object",
-						Properties: map[string]apiext.JSONSchemaProps{"foo": apiext.JSONSchemaProps{Type: "string"}},
-					},
-				}))
-				Expect(spec.Spec.Versions).To(Equal([]apiext.CustomResourceDefinitionVersion{
-					{Name: "v1"}, {Name: "v2", Storage: true},
-				}))
-			})
-
-			It("shouldn't merge different schemata", func() {
-				spec := &apiext.CustomResourceDefinition{
-					Spec: apiext.CustomResourceDefinitionSpec{
-						Versions: []apiext.CustomResourceDefinitionVersion{
-							{
-								Name: "v1",
-								Schema: &apiext.CustomResourceValidation{
-									OpenAPIV3Schema: &apiext.JSONSchemaProps{
-										Type:       "object",
-										Properties: map[string]apiext.JSONSchemaProps{"foo": apiext.JSONSchemaProps{Type: "string"}},
-									},
-								},
-							},
-							{
-								Name:    "v2",
-								Storage: true,
-								Schema: &apiext.CustomResourceValidation{
-									OpenAPIV3Schema: &apiext.JSONSchemaProps{
-										Required:   []string{"foo"},
-										Type:       "object",
-										Properties: map[string]apiext.JSONSchemaProps{"foo": apiext.JSONSchemaProps{Type: "string"}},
-									},
-								},
-							},
-						},
-					},
-				}
-				orig := spec.DeepCopy()
-				crd.MergeIdenticalVersionInfo(spec)
-				Expect(spec).To(Equal(orig))
-			})
-
-			It("should replace per-version subresources with top-level subresources if all are identical", func() {
-				spec := &apiext.CustomResourceDefinition{
-					Spec: apiext.CustomResourceDefinitionSpec{
-						Versions: []apiext.CustomResourceDefinitionVersion{
-							{
-								Name: "v1",
-								Subresources: &apiext.CustomResourceSubresources{
-									Status: &apiext.CustomResourceSubresourceStatus{},
-								},
-							},
-							{
-								Name:    "v2",
-								Storage: true,
-								Subresources: &apiext.CustomResourceSubresources{
-									Status: &apiext.CustomResourceSubresourceStatus{},
-								},
-							},
-						},
-					},
-				}
-
-				crd.MergeIdenticalVersionInfo(spec)
-				Expect(spec.Spec.Subresources).To(Equal(&apiext.CustomResourceSubresources{
-					Status: &apiext.CustomResourceSubresourceStatus{},
-				}))
-				Expect(spec.Spec.Versions).To(Equal([]apiext.CustomResourceDefinitionVersion{
-					{Name: "v1"}, {Name: "v2", Storage: true},
-				}))
-			})
-
-			It("shouldn't merge different subresources", func() {
-				spec := &apiext.CustomResourceDefinition{
-					Spec: apiext.CustomResourceDefinitionSpec{
-						Versions: []apiext.CustomResourceDefinitionVersion{
-							{
-								Name: "v1",
-								Subresources: &apiext.CustomResourceSubresources{
-									Status: &apiext.CustomResourceSubresourceStatus{},
-								},
-							},
-							{
-								Name:    "v2",
-								Storage: true,
-							},
-						},
-					},
-				}
-				orig := spec.DeepCopy()
-				crd.MergeIdenticalVersionInfo(spec)
-				Expect(spec).To(Equal(orig))
-			})
-
-			It("should replace per-version printer columns with top-level printer columns if all are identical", func() {
-				spec := &apiext.CustomResourceDefinition{
-					Spec: apiext.CustomResourceDefinitionSpec{
-						Versions: []apiext.CustomResourceDefinitionVersion{
-							{
-								Name: "v1",
-								AdditionalPrinterColumns: []apiext.CustomResourceColumnDefinition{
-									{Name: "Cheddar", JSONPath: ".spec.cheddar"},
-									{Name: "Parmesan", JSONPath: ".status.parmesan"},
-								},
-							},
-							{
-								Name:    "v2",
-								Storage: true,
-								AdditionalPrinterColumns: []apiext.CustomResourceColumnDefinition{
-									{Name: "Cheddar", JSONPath: ".spec.cheddar"},
-									{Name: "Parmesan", JSONPath: ".status.parmesan"},
-								},
-							},
-						},
-					},
-				}
-
-				crd.MergeIdenticalVersionInfo(spec)
-				Expect(spec.Spec.AdditionalPrinterColumns).To(Equal([]apiext.CustomResourceColumnDefinition{
-					{Name: "Cheddar", JSONPath: ".spec.cheddar"},
-					{Name: "Parmesan", JSONPath: ".status.parmesan"},
-				}))
-				Expect(spec.Spec.Versions).To(Equal([]apiext.CustomResourceDefinitionVersion{
-					{Name: "v1"}, {Name: "v2", Storage: true},
-				}))
-			})
-
-			It("shouldn't merge different printer columns", func() {
-				spec := &apiext.CustomResourceDefinition{
-					Spec: apiext.CustomResourceDefinitionSpec{
-						Versions: []apiext.CustomResourceDefinitionVersion{
-							{
-								Name: "v1",
-								AdditionalPrinterColumns: []apiext.CustomResourceColumnDefinition{
-									{Name: "Cheddar", JSONPath: ".spec.cheddar"},
-									{Name: "Parmesan", JSONPath: ".status.parmesan"},
-								},
-							},
-							{
-								Name:    "v2",
-								Storage: true,
-							},
-						},
-					},
-				}
-				orig := spec.DeepCopy()
-				crd.MergeIdenticalVersionInfo(spec)
-				Expect(spec).To(Equal(orig))
-			})
-		})
-	})
-})
diff --git a/pkg/crd/parser_integration_test.go b/pkg/crd/parser_integration_test.go
index dd0e3200..57389286 100644
--- a/pkg/crd/parser_integration_test.go
+++ b/pkg/crd/parser_integration_test.go
@@ -1,19 +1,3 @@
-/*
-Copyright 2019 The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
 package crd_test
 
 import (
diff --git a/pkg/crd/testdata/README.md b/pkg/crd/testdata/README.md
index a97347fd..4192e808 100644
--- a/pkg/crd/testdata/README.md
+++ b/pkg/crd/testdata/README.md
@@ -10,14 +10,7 @@ Book](https://book.kubebuilder.io/cronjob-tutorial.html), but with added
 fields to test additional markers and generation behavior.
 
 If you add a new marker, re-generate the golden output file,
-`testdata.kubebuilder.io_cronjobs.yaml`, with (if you have the latest
-controller-gen on your path):
-
-```bash
-go generate
-```
-
-or, if you don't have the latest controller-gen on your path, use:
+`testdata.kubebuilder.io_cronjobs.yaml`, with:
 
 ```bash
 $ /path/to/current/build/of/controller-gen crd paths=. output:dir=.
diff --git a/pkg/crd/testdata/cronjob_types.go b/pkg/crd/testdata/cronjob_types.go
index 972f7572..3e882d4e 100644
--- a/pkg/crd/testdata/cronjob_types.go
+++ b/pkg/crd/testdata/cronjob_types.go
@@ -13,8 +13,6 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-//go:generate controller-gen crd paths=. output:dir=.
-
 // +groupName=testdata.kubebuilder.io
 // +versionName=v1
 package cronjob
@@ -86,19 +84,8 @@ type CronJobSpec struct {
 
 	// This tests string slices are allowed as map values.
 	StringSliceData map[string][]string `json:"stringSliceData,omitempty"`
-
-	// This tests that markers that are allowed on both fields and types are applied to fields
-	// +kubebuilder:validation:MinLength=4
-	TwoOfAKindPart0 string `json:"twoOfAKindPart0"`
-
-	// This tests that markers that are allowed on both fields and types are applied to types
-	TwoOfAKindPart1 LongerString `json:"twoOfAKindPart1"`
 }
 
-// +kubebuilder:validation:MinLength=4
-// This tests that markers that are allowed on both fields and types are applied to types
-type LongerString string
-
 // use an explicit type marker to verify that apply-first markers generate properly
 
 // +kubebuilder:validation:Type=string
@@ -155,11 +142,6 @@ type CronJobStatus struct {
 	// Information when was the last time the job was successfully scheduled.
 	// +optional
 	LastScheduleTime *metav1.Time `json:"lastScheduleTime,omitempty"`
-
-	// Information about the last time the job was successfully scheduled,
-	// with microsecond precision.
-	// +optional
-	LastScheduleMicroTime *metav1.MicroTime `json:"lastScheduleMicroTime,omitempty"`
 }
 
 // +kubebuilder:object:root=true
diff --git a/pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml b/pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml
index 20d4cec0..84d98e5a 100644
--- a/pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml
+++ b/pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml
@@ -11,7 +11,6 @@ spec:
     kind: CronJob
     plural: cronjobs
   scope: Namespaced
-  version: v1
   versions:
   - name: v1
     schema:
@@ -4930,23 +4929,11 @@ spec:
                   executions, it does not apply to already started executions.  Defaults
                   to false.
                 type: boolean
-              twoOfAKindPart0:
-                description: This tests that markers that are allowed on both fields
-                  and types are applied to fields
-                minLength: 4
-                type: string
-              twoOfAKindPart1:
-                description: This tests that markers that are allowed on both fields
-                  and types are applied to types
-                minLength: 4
-                type: string
             required:
             - binaryName
             - canBeNull
             - jobTemplate
             - schedule
-            - twoOfAKindPart0
-            - twoOfAKindPart1
             type: object
           status:
             description: CronJobStatus defines the observed state of CronJob
@@ -4991,11 +4978,6 @@ spec:
                       type: string
                   type: object
                 type: array
-              lastScheduleMicroTime:
-                description: Information about the last time the job was successfully
-                  scheduled, with microsecond precision.
-                format: date-time
-                type: string
               lastScheduleTime:
                 description: Information when was the last time the job was successfully
                   scheduled.
diff --git a/pkg/deepcopy/deepcopy_integration_test.go b/pkg/deepcopy/deepcopy_integration_test.go
deleted file mode 100644
index 77e848c9..00000000
--- a/pkg/deepcopy/deepcopy_integration_test.go
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-Copyright 2019 The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package deepcopy_test
-
-import (
-	"io/ioutil"
-	"os"
-
-	"github.com/google/go-cmp/cmp"
-	. "github.com/onsi/ginkgo"
-	. "github.com/onsi/gomega"
-	"golang.org/x/tools/go/packages"
-
-	"sigs.k8s.io/controller-tools/pkg/deepcopy"
-	"sigs.k8s.io/controller-tools/pkg/loader"
-	"sigs.k8s.io/controller-tools/pkg/markers"
-)
-
-func packageErrors(pkg *loader.Package, filterKinds ...packages.ErrorKind) error {
-	toSkip := make(map[packages.ErrorKind]struct{})
-	for _, errKind := range filterKinds {
-		toSkip[errKind] = struct{}{}
-	}
-	var outErr error
-	packages.Visit([]*packages.Package{pkg.Package}, nil, func(pkgRaw *packages.Package) {
-		for _, err := range pkgRaw.Errors {
-			if _, skip := toSkip[err.Kind]; skip {
-				continue
-			}
-			outErr = err
-		}
-	})
-	return outErr
-}
-
-var _ = Describe("CRD Generation From Parsing to CustomResourceDefinition", func() {
-	It("should properly generate and flatten the rewritten CronJob schema", func() {
-		By("switching into testdata to appease go modules")
-		cwd, err := os.Getwd()
-		Expect(err).NotTo(HaveOccurred())
-		Expect(os.Chdir("./testdata")).To(Succeed()) // go modules are directory-sensitive
-		defer func() { Expect(os.Chdir(cwd)).To(Succeed()) }()
-
-		By("loading the roots")
-		pkgs, err := loader.LoadRoots(".")
-		Expect(err).NotTo(HaveOccurred())
-		Expect(pkgs).To(HaveLen(1))
-		cronJobPkg := pkgs[0]
-
-		By("setting up the generation context")
-		collector := &markers.Collector{Registry: &markers.Registry{}}
-		Expect(deepcopy.Generator{}.RegisterMarkers(collector.Registry)).To(Succeed())
-		checker := &loader.TypeChecker{}
-		ctx := &deepcopy.ObjectGenCtx{
-			Collector: collector,
-			Checker:   checker,
-		}
-
-		By("requesting that types be generated")
-		outContents := ctx.GenerateForPackage(cronJobPkg)
-
-		By("checking that no errors occurred along the way (expect for type errors)")
-		Expect(packageErrors(cronJobPkg, packages.TypeError)).NotTo(HaveOccurred())
-
-		By("checking that we got output contents")
-		Expect(outContents).NotTo(BeNil())
-
-		By("loading the desired code")
-		expectedFile, err := ioutil.ReadFile("zz_generated.deepcopy.go")
-		Expect(err).NotTo(HaveOccurred())
-
-		By("comparing the two")
-		Expect(outContents).To(Equal(expectedFile), "generated code not as expected, check pkg/deepcopy/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(outContents, expectedFile))
-	})
-})
diff --git a/pkg/deepcopy/deepcopy_suite_test.go b/pkg/deepcopy/deepcopy_suite_test.go
deleted file mode 100644
index 63492787..00000000
--- a/pkg/deepcopy/deepcopy_suite_test.go
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-Copyright 2019 The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package deepcopy_test
-
-import (
-	"testing"
-
-	. "github.com/onsi/ginkgo"
-	. "github.com/onsi/gomega"
-)
-
-func TestObjectGeneration(t *testing.T) {
-	RegisterFailHandler(Fail)
-	RunSpecs(t, "DeepCopy/runtime.Object Generation Suite")
-}
diff --git a/pkg/deepcopy/testdata/README.md b/pkg/deepcopy/testdata/README.md
deleted file mode 100644
index 90898237..00000000
--- a/pkg/deepcopy/testdata/README.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# DeepCopy Integration Test testdata
-
-This contains a tiny module used for testdata for the DeepCopy integration
-test. The directory should always be called testdata, so Go treats it
-specially.
-
-The `cronjob_types.go` file contains the input types, and is loosely based
-on the CronJob tutorial from the [KubeBuilder
-Book](https://book.kubebuilder.io/cronjob-tutorial.html), but with added
-fields to test additional DeepCopy cases.
-
-If you for some reason need to change deepcopy generation, you can
-re-generate the golden output file,
-`zz_generated.deepcopy.go`, with (if you have the latest
-controller-gen on your path):
-
-```bash
-go generate
-```
-
-or, if you don't have the latest controller-gen on your path, use:
-
-```bash
-$ /path/to/current/build/of/controller-gen object paths=.
-```
-
-
-Make sure you review the diff to ensure that it only contains the desired
-changes!
-
-If you didn't add a new marker and this output changes, make sure you have
-a good explanation for why generated output needs to change!
diff --git a/pkg/deepcopy/testdata/cronjob_types.go b/pkg/deepcopy/testdata/cronjob_types.go
deleted file mode 100644
index 3a49368d..00000000
--- a/pkg/deepcopy/testdata/cronjob_types.go
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-//go:generate controller-gen object paths=.
-
-// +kubebuilder:object:generate=true
-// +groupName=testdata.kubebuilder.io
-// +versionName=v1
-package cronjob
-
-import (
-	batchv1beta1 "k8s.io/api/batch/v1beta1"
-	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-// EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
-// NOTE: json tags are required.  Any new fields you add must have json tags for the fields to be serialized.
-
-// CronJobSpec defines the desired state of CronJob
-// Real-world test:
-type CronJobSpec struct {
-	// The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
-	Schedule string `json:"schedule"`
-
-	// Optional deadline in seconds for starting the job if it misses scheduled
-	// time for any reason.  Missed jobs executions will be counted as failed ones.
-	// +optional
-	StartingDeadlineSeconds *int64 `json:"startingDeadlineSeconds,omitempty"`
-
-	// Specifies how to treat concurrent executions of a Job.
-	// Valid values are:
-	// - "Allow" (default): allows CronJobs to run concurrently;
-	// - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet;
-	// - "Replace": cancels currently running job and replaces it with a new one
-	// +optional
-	ConcurrencyPolicy ConcurrencyPolicy `json:"concurrencyPolicy,omitempty"`
-
-	// This flag tells the controller to suspend subsequent executions, it does
-	// not apply to already started executions.  Defaults to false.
-	// +optional
-	Suspend *bool `json:"suspend,omitempty"`
-
-	// Specifies the job that will be created when executing a CronJob.
-	JobTemplate batchv1beta1.JobTemplateSpec `json:"jobTemplate"`
-
-	// The number of successful finished jobs to retain.
-	// This is a pointer to distinguish between explicit zero and not specified.
-	// +optional
-	SuccessfulJobsHistoryLimit *int32 `json:"successfulJobsHistoryLimit,omitempty"`
-
-	// The number of failed finished jobs to retain.
-	// This is a pointer to distinguish between explicit zero and not specified.
-	// +optional
-	FailedJobsHistoryLimit *int32 `json:"failedJobsHistoryLimit,omitempty"`
-
-	// Specific cases
-	SpecificCases SpecificCases `json:"specificCases"`
-}
-
-// SpecificCases excercises specific paths and/or regressions in the deepcopy machinery
-type SpecificCases struct {
-	// "Normal" Cases:
-
-	// Reference type receiver: covered by SomePointers/StringMap
-	// Non-reference-type receiver: covered by this struct
-
-	// has manual deepcopy w/ pointer receiver
-	ManualDeepCopyPtr DeepCopyPtr `json:"manualDeepCopyPtr"`
-	// has manual deepcopy w/ non-pointer receiver
-	ManualDeepCopyNonPtr DeepCopyNonPtr `json:"manualDeepCopyNonPtr"`
-
-	// has manual deepcopyinto w/ pointer receiver
-	ManualIntoPtr DeepCopyIntoPtr `json:"manualIntoPtr"`
-	// has manual deepcopyinto w/ non-pointer receiver
-	ManualIntoNonPtr DeepCopyIntoNonPtr `json:"manualIntoNonPtr"`
-
-	// built-in types in fields
-	BuiltInField string `json:"builtInField"`
-
-	// non-quite deepcopies
-	BadDeepCopyHasParams `json:"badDeepCopyHasParams"`
-	BadDeepCopyNoReturn `json:"badDeepCopyNoReturn"`
-	BadDeepCopyPtrVal `json:"badDeepCopyPtrVal"`
-	BadDeepCopyNonPtrVal `json:"badDeepCopyNonPtrVal"`
-	BadDeepCopyPtrMismatch `json:"badDeepCopyPtrMismatch"`
-
-	// not-quite-deepcopyintos
-	BadDeepCopyIntoNoParams `json:"badDeepCopyIntoNoParams"`
-	BadDeepCopyIntoNonPtrParam `json:"badDeepCopyIntoNonPtrParam"`
-	BadDeepCopyIntoHasResult `json:"badDeepCopyIntoHasResult"`
-
-	// compound types in fields
-
-	// also tests maps/slices/etc of built-in types
-	MapInField map[string]string `json:"mapInField"`
-	SliceInField []string `json:"sliceInField"`
-	BuiltInPointer *string `json:"pointerInField"`
-	NamedTypeInField TotallyAString `json:"namedTypeInField"`
-	// named types to struct are tested via the reference to this object
-	// named types to others are tested via the SomePointers/StringMap cases
-
-	// other map types
-	MapToDeepCopyPtr map[string]DeepCopyPtr `json:"mapToDeepCopyPtr"`
-	MapToDeepCopyNonPtr map[string]DeepCopyPtr `json:"mapToDeepCopyNonPtr"`
-	MapToDeepCopyIntoPtr map[string]DeepCopyIntoPtr `json:"mapToDeepCopyIntoPtr"`
-	MapToDeepCopyIntoNonPtr map[string]DeepCopyIntoNonPtr `json:"mapToDeepCopyIntoNonPtr"`
-	MapToShallowNamedType map[string]TotallyAString `json:"mapToShallowNamedType"`
-	MapToReferenceType map[string][]string `json:"mapToReferenceType"`
-	MapToStruct map[string]CronJobSpec `json:"mapToStruct"`
-	MapWithNamedKeys map[TotallyAString]int `json:"mapWithNamedKeys"`
-	MapToPtrToDeepCopyIntoRefType map[string]*DeepCopyIntoRef `json:"mapToPtrToDeepCopyIntoRefType"`
-	MapToDeepCopyIntoRefType map[string]DeepCopyIntoRef `json:"mapToDeepCopyIntoRefType"`
-
-	// other slice types
-	SliceToDeepCopyPtr []DeepCopyPtr `json:"sliceToDeepCopyPtr"`
-	SliceToDeepCopyNonPtr []DeepCopyPtr `json:"sliceToDeepCopyNonPtr"`
-	SliceToDeepCopyIntoPtr []DeepCopyIntoPtr `json:"sliceToDeepCopyIntoPtr"`
-	SliceToDeepCopyIntoNonPtr []DeepCopyIntoNonPtr `json:"sliceToDeepCopyIntoNonPtr"`
-	SliceToShallowNamedType []TotallyAString `json:"sliceToShallowNamedType"`
-	SliceToReferenceType [][]string `json:"sliceToReferenceType"`
-	SliceToStruct []CronJobSpec `json:"sliceToStruct"`
-
-	// other pointer types
-	PtrToDeepCopyPtr *DeepCopyPtr `json:"ptrToDeepCopyPtr"`
-	PtrToDeepCopyNonPtr *DeepCopyPtr `json:"ptrToDeepCopyNonPtr"`
-	PtrToDeepCopyIntoPtr *DeepCopyIntoPtr `json:"ptrToDeepCopyIntoPtr"`
-	PtrToDeepCopyIntoNonPtr *DeepCopyIntoNonPtr `json:"ptrToDeepCopyIntoNonPtr"`
-	PtrToShallowNamedType *TotallyAString `json:"ptrToShallowNamedType"`
-	PtrToReferenceType *[]string `json:"ptrToReferenceType"`
-	PtrToStruct *CronJobSpec `json:"ptrToStruct"`
-	PtrToDeepCopyIntoRef *DeepCopyIntoRef `json:"ptrToDeepCopyIntoRef"`
-
-
-	// Regression Tests:
-
-	// Case: kubernetes-sigs/controller-tools#262 part 1 (see type definition)
-	SomePointers SliceOfPointers `json:"somePointers"`
-
-	// Case: kubernetes-sigs/controller-tools#262 part 2 (see type definition)
-	StringMap MapOfStrings `json:"stringMap"`
-}
-
-// Test aliases to basic types
-type TotallyAString string
-
-// Tests manual DeepCopy with a pointer receiver
-type DeepCopyPtr struct {}
-func (d *DeepCopyPtr) DeepCopy() *DeepCopyPtr {
-	return &DeepCopyPtr{}
-}
-
-// Tests manual DeepCopy with a non-pointer receiver
-type DeepCopyNonPtr struct {}
-func (d DeepCopyNonPtr) DeepCopy() DeepCopyNonPtr {
-	return DeepCopyNonPtr{}
-}
-
-// Tests manual DeepCopyInto with a pointer receiver
-type DeepCopyIntoPtr struct {}
-func (d *DeepCopyIntoPtr) DeepCopyInto(out *DeepCopyIntoPtr) {
-	*out = DeepCopyIntoPtr{}
-}
-
-// Tests manual DeepCopyInto with a non-pointer receiver
-type DeepCopyIntoNonPtr struct {}
-func (d DeepCopyIntoNonPtr) DeepCopyInto(out *DeepCopyIntoNonPtr) {
-	*out = DeepCopyIntoNonPtr{}
-}
-
-// Tests manual DeepCopyInto with a reference type receiver
-type DeepCopyIntoRef map[string]string
-func (d DeepCopyIntoRef) DeepCopyInto(out *DeepCopyIntoRef) {
-	*out = make(DeepCopyIntoRef)
-}
-
-// Case: kubernetes-sigs/controller-tools#262 part 1:
-// Type renames of slices to pointers.
-type SliceOfPointers []*SomeStruct
-type SomeStruct struct {
-	Foo string `json:"foo"`
-}
-
-// Case: kubernetes-sigs/controller-tools#262 part 2:
-// Type renames on "allowable" maps
-type MapOfStrings map[string]string
-
-// tests bad deep copy methods
-
-type BadDeepCopyHasParams struct{}
-func (d *BadDeepCopyHasParams) DeepCopy(out string) *BadDeepCopyHasParams {
-	return nil
-} 
-
-type BadDeepCopyNoReturn struct{}
-func (d *BadDeepCopyNoReturn) DeepCopy() {}
-
-type BadDeepCopyPtrVal struct {}
-func (d *BadDeepCopyPtrVal) DeepCopy() *BadDeepCopyNoReturn {
-	return nil
-}
-
-type BadDeepCopyNonPtrVal struct {}
-func (d BadDeepCopyNonPtrVal) DeepCopy() BadDeepCopyNoReturn {
-	return BadDeepCopyNoReturn{}
-}
-
-type BadDeepCopyPtrMismatch struct {}
-func (d BadDeepCopyPtrMismatch) DeepCopy() *BadDeepCopyPtrMismatch {
-	return nil
-}
-
-type BadDeepCopyIntoNoParams struct {}
-func (d BadDeepCopyIntoNoParams) DeepCopyInto() {}
-
-type BadDeepCopyIntoNonPtrParam struct {}
-func (d BadDeepCopyIntoNonPtrParam) DeepCopyInto(out BadDeepCopyIntoNonPtrParam) {}
-
-type BadDeepCopyIntoHasResult struct {}
-func (d BadDeepCopyIntoHasResult) DeepCopyInto(out *BadDeepCopyIntoHasResult) error {
-	return nil
-}
-
-// ConcurrencyPolicy describes how the job will be handled.
-// Only one of the following concurrent policies may be specified.
-// If none of the following policies is specified, the default one
-// is AllowConcurrent.
-// +kubebuilder:validation:Enum=Allow;Forbid;Replace
-type ConcurrencyPolicy string
-
-const (
-	// AllowConcurrent allows CronJobs to run concurrently.
-	AllowConcurrent ConcurrencyPolicy = "Allow"
-
-	// ForbidConcurrent forbids concurrent runs, skipping next run if previous
-	// hasn't finished yet.
-	ForbidConcurrent ConcurrencyPolicy = "Forbid"
-
-	// ReplaceConcurrent cancels currently running job and replaces it with a new one.
-	ReplaceConcurrent ConcurrencyPolicy = "Replace"
-)
-
-// CronJobStatus defines the observed state of CronJob
-type CronJobStatus struct {
-	// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
-	// Important: Run "make" to regenerate code after modifying this file
-
-	// A list of pointers to currently running jobs.
-	// +optional
-	Active []corev1.ObjectReference `json:"active,omitempty"`
-
-	// Information when was the last time the job was successfully scheduled.
-	// +optional
-	LastScheduleTime *metav1.Time `json:"lastScheduleTime,omitempty"`
-}
-
-// +kubebuilder:object:root=true
-// +kubebuilder:subresource:status
-// +kubebuilder:resource
-
-// CronJob is the Schema for the cronjobs API
-type CronJob struct {
-	/*
-	 */
-	metav1.TypeMeta   `json:",inline"`
-	metav1.ObjectMeta `json:"metadata,omitempty"`
-
-	Spec   CronJobSpec   `json:"spec,omitempty"`
-	Status CronJobStatus `json:"status,omitempty"`
-}
-
-// +kubebuilder:object:root=true
-
-// CronJobList contains a list of CronJob
-type CronJobList struct {
-	metav1.TypeMeta `json:",inline"`
-	metav1.ListMeta `json:"metadata,omitempty"`
-	Items           []CronJob `json:"items"`
-}
diff --git a/pkg/deepcopy/testdata/go.mod b/pkg/deepcopy/testdata/go.mod
deleted file mode 100644
index 879b8b8d..00000000
--- a/pkg/deepcopy/testdata/go.mod
+++ /dev/null
@@ -1,8 +0,0 @@
-module testdata.kubebuilder.io/cronjob
-
-go 1.12
-
-require (
-	k8s.io/api v0.0.0-20190722141453-b90922c02518
-	k8s.io/apimachinery v0.0.0-20190719140911-bfcf53abc9f8
-)
diff --git a/pkg/deepcopy/testdata/go.sum b/pkg/deepcopy/testdata/go.sum
deleted file mode 100644
index 703670a9..00000000
--- a/pkg/deepcopy/testdata/go.sum
+++ /dev/null
@@ -1,89 +0,0 @@
-github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
-github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
-github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
-github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
-github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
-github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
-github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
-github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
-github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
-github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
-github.com/gogo/protobuf v1.0.0 h1:2jyBKDKU/8v3v2xVR2PtiWQviFUyiaGk2rpfyFT8rTM=
-github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
-github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
-github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
-github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
-github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
-github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
-github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o=
-gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
-gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-k8s.io/api v0.0.0-20190722141453-b90922c02518 h1:mShu41WQl4VJGAd7fbhhH0tsy+KMjZRnC/OcFYF8RVc=
-k8s.io/api v0.0.0-20190722141453-b90922c02518/go.mod h1:1O0xzX/RAtnm7l+5VEUxZ1ysO2ghatfq/OZED4zM9kA=
-k8s.io/apimachinery v0.0.0-20190719140911-bfcf53abc9f8 h1:fVMoqaOPZ6KTeszBSBO8buFmXaR2JlnMn53eEBeganU=
-k8s.io/apimachinery v0.0.0-20190719140911-bfcf53abc9f8/go.mod h1:sBJWIJZfxLhp7mRsRyuAE/NfKTr3kXGR1iaqg8O0gJo=
-k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
-k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68=
-k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
-k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4=
-sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
-sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
diff --git a/pkg/deepcopy/testdata/legacy_deepcopy_cases.go b/pkg/deepcopy/testdata/legacy_deepcopy_cases.go
deleted file mode 100644
index 97ba12d2..00000000
--- a/pkg/deepcopy/testdata/legacy_deepcopy_cases.go
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
-Copyright 2019 The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package cronjob
-
-// NB(directxman12): this file contains tests copied over from the legacy deepcopy-gen
-// They should all continue to pass -- non-covered cases have already been pruned.
-
-// +kubebuilder:object:root=true
-type Foo struct {
-	X int
-}
-
-type Builtin int
-type Slice []int
-type Pointer *int
-type PointerAlias *Builtin
-type Struct Foo
-type Map map[string]int
-
-type FooAlias Foo
-type FooSlice []Foo
-type FooPointer *Foo
-type FooMap map[string]Foo
-
-type AliasBuiltin Builtin
-type AliasSlice Slice
-type AliasPointer Pointer
-type AliasStruct Struct
-type AliasMap Map
-
-// Aliases
-type Ttest struct {
-	Builtin      Builtin
-	Slice        Slice
-	Pointer      Pointer
-	PointerAlias PointerAlias
-	Struct       Struct
-	Map          Map
-	SliceSlice   []Slice
-	MapSlice     map[string]Slice
-
-	FooAlias   FooAlias
-	FooSlice   FooSlice
-	FooPointer FooPointer
-	FooMap     FooMap
-
-	AliasBuiltin AliasBuiltin
-	AliasSlice   AliasSlice
-	AliasPointer AliasPointer
-	AliasStruct  AliasStruct
-	AliasMap     AliasMap
-}
-
-type TestBuiltins struct {
-	Byte byte
-	Int8    int8
-	Int16   int16
-	Int32   int32
-	Int64   int64
-	Uint8   uint8
-	Uint16  uint16
-	Uint32  uint32
-	Uint64  uint64
-	Float32 float32
-	Float64 float64
-	String  string
-}
-
-type TestMaps struct {
-	Byte map[string]byte
-	Int8    map[string]int8
-	Int16        map[string]int16
-	Int32        map[string]int32
-	Int64        map[string]int64
-	Uint8        map[string]uint8
-	Uint16       map[string]uint16
-	Uint32       map[string]uint32
-	Uint64       map[string]uint64
-	Float32      map[string]float32
-	Float64      map[string]float64
-	String       map[string]string
-	StringPtr    map[string]*string
-	StringPtrPtr map[string]**string
-	Map          map[string]map[string]string
-	MapPtr       map[string]*map[string]string
-	Slice        map[string][]string
-	SlicePtr     map[string]*[]string
-	Struct       map[string]Ttest
-	StructPtr    map[string]*Ttest
-}
-
-
-type TestPointers struct {
-	Builtin   *string
-	Ptr       **string
-	Map       *map[string]string
-	Slice     *[]string
-	MapPtr    **map[string]string
-	SlicePtr  **[]string
-	Struct    *Ttest
-	StructPtr **Ttest
-}
-
-type TestSlices struct {
-	Byte []byte
-	Int8    []int8 //TODO: int8 becomes byte in SnippetWriter
-	Int16        []int16
-	Int32        []int32
-	Int64        []int64
-	Uint8        []uint8
-	Uint16       []uint16
-	Uint32       []uint32
-	Uint64       []uint64
-	Float32      []float32
-	Float64      []float64
-	String       []string
-	StringPtr    []*string
-	StringPtrPtr []**string
-	Map          []map[string]string
-	MapPtr       []*map[string]string
-	Slice        [][]string
-	SlicePtr     []*[]string
-	Struct       []Ttest
-	StructPtr    []*Ttest
-}
-
-type Inner struct {
-	Byte byte
-	Int8    int8 //TODO: int8 becomes byte in SnippetWriter
-	Int16   int16
-	Int32   int32
-	Int64   int64
-	Uint8   uint8
-	Uint16  uint16
-	Uint32  uint32
-	Uint64  uint64
-	Float32 float32
-	Float64 float64
-	String  string
-}
-
-type TestInner struct {
-	Inner1 Inner
-	Inner2 Inner
-}
-
-// Trivial
-type Struct_Empty struct{}
-
-// Only primitives
-type Struct_Primitives struct {
-	BoolField   bool
-	IntField    int
-	StringField string
-	FloatField  float64
-}
-type Struct_Primitives_Alias Struct_Primitives
-type Struct_Embed_Struct_Primitives struct {
-	Struct_Primitives
-}
-type Struct_Embed_Int struct {
-	int
-}
-type Struct_Struct_Primitives struct {
-	StructField Struct_Primitives
-}
-
-// Manual DeepCopy method
-type ManualStruct struct {
-	StringField string
-}
-
-func (m ManualStruct) DeepCopy() ManualStruct {
-	return m
-}
-
-type ManualStruct_Alias ManualStruct
-
-type Struct_Embed_ManualStruct struct {
-	ManualStruct
-}
-
-// Only pointers to primitives
-type Struct_PrimitivePointers struct {
-	BoolPtrField   *bool
-	IntPtrField    *int
-	StringPtrField *string
-	FloatPtrField  *float64
-}
-type Struct_PrimitivePointers_Alias Struct_PrimitivePointers
-type Struct_Embed_Struct_PrimitivePointers struct {
-	Struct_PrimitivePointers
-}
-type Struct_Embed_Pointer struct {
-	*int
-}
-type Struct_Struct_PrimitivePointers struct {
-	StructField Struct_PrimitivePointers
-}
-
-// Manual DeepCopy method
-type ManualSlice []string
-
-func (m ManualSlice) DeepCopy() ManualSlice {
-	r := make(ManualSlice, len(m))
-	copy(r, m)
-	return r
-}
-
-// Slices
-type Struct_Slices struct {
-	SliceBoolField                         []bool
-	SliceByteField                         []byte
-	SliceIntField                          []int
-	SliceStringField                       []string
-	SliceFloatField                        []float64
-	SliceStructPrimitivesField             []Struct_Primitives
-	SliceStructPrimitivesAliasField        []Struct_Primitives_Alias
-	SliceStructPrimitivePointersField      []Struct_PrimitivePointers
-	SliceStructPrimitivePointersAliasField []Struct_PrimitivePointers_Alias
-	SliceSliceIntField                     [][]int
-	SliceManualStructField                 []ManualStruct
-	ManualSliceField                       ManualSlice
-}
-type Struct_Slices_Alias Struct_Slices
-type Struct_Embed_Struct_Slices struct {
-	Struct_Slices
-}
-type Struct_Struct_Slices struct {
-	StructField Struct_Slices
-}
-
-// Everything
-type Struct_Everything struct {
-	BoolField                 bool
-	IntField                  int
-	StringField               string
-	FloatField                float64
-	StructField               Struct_Primitives
-	EmptyStructField          Struct_Empty
-	ManualStructField         ManualStruct
-	ManualStructAliasField    ManualStruct_Alias
-	BoolPtrField              *bool
-	IntPtrField               *int
-	StringPtrField            *string
-	FloatPtrField             *float64
-	PrimitivePointersField    Struct_PrimitivePointers
-	ManualStructPtrField      *ManualStruct
-	ManualStructAliasPtrField *ManualStruct_Alias
-	SliceBoolField            []bool
-	SliceByteField            []byte
-	SliceIntField             []int
-	SliceStringField          []string
-	SliceFloatField           []float64
-	SlicesField               Struct_Slices
-	SliceManualStructField    []ManualStruct
-	ManualSliceField          ManualSlice
-}
-
-// An Object
-// +kubebuilder:object:root=true
-type Struct_ExplicitObject struct {
-	x int
-}
-
-// +k8s:deepcopy-gen=false
-type Struct_TypeMeta struct {
-}
-
-// +kubebuilder:object:root=true
-type Struct_ExplicitSelectorExplicitObject struct {
-	Struct_TypeMeta
-}
-
-// Another type in another file.
-type Struct_B struct{}
diff --git a/pkg/deepcopy/testdata/zz_generated.deepcopy.go b/pkg/deepcopy/testdata/zz_generated.deepcopy.go
deleted file mode 100644
index 7e4a3f5a..00000000
--- a/pkg/deepcopy/testdata/zz_generated.deepcopy.go
+++ /dev/null
@@ -1,2016 +0,0 @@
-// +build !ignore_autogenerated
-
-// autogenerated by controller-gen object, do not modify manually
-
-package cronjob
-
-import (
-	"k8s.io/api/core/v1"
-	runtime "k8s.io/apimachinery/pkg/runtime"
-)
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in AliasMap) DeepCopyInto(out *AliasMap) {
-	{
-		in := &in
-		*out = make(AliasMap, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasMap.
-func (in AliasMap) DeepCopy() AliasMap {
-	if in == nil {
-		return nil
-	}
-	out := new(AliasMap)
-	in.DeepCopyInto(out)
-	return *out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in AliasSlice) DeepCopyInto(out *AliasSlice) {
-	{
-		in := &in
-		*out = make(AliasSlice, len(*in))
-		copy(*out, *in)
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasSlice.
-func (in AliasSlice) DeepCopy() AliasSlice {
-	if in == nil {
-		return nil
-	}
-	out := new(AliasSlice)
-	in.DeepCopyInto(out)
-	return *out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AliasStruct) DeepCopyInto(out *AliasStruct) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasStruct.
-func (in *AliasStruct) DeepCopy() *AliasStruct {
-	if in == nil {
-		return nil
-	}
-	out := new(AliasStruct)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *BadDeepCopyHasParams) DeepCopyInto(out *BadDeepCopyHasParams) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BadDeepCopyHasParams.
-func (in *BadDeepCopyHasParams) DeepCopy() *BadDeepCopyHasParams {
-	if in == nil {
-		return nil
-	}
-	out := new(BadDeepCopyHasParams)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *BadDeepCopyIntoHasResult) DeepCopyInto(out *BadDeepCopyIntoHasResult) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BadDeepCopyIntoHasResult.
-func (in *BadDeepCopyIntoHasResult) DeepCopy() *BadDeepCopyIntoHasResult {
-	if in == nil {
-		return nil
-	}
-	out := new(BadDeepCopyIntoHasResult)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *BadDeepCopyIntoNoParams) DeepCopyInto(out *BadDeepCopyIntoNoParams) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BadDeepCopyIntoNoParams.
-func (in *BadDeepCopyIntoNoParams) DeepCopy() *BadDeepCopyIntoNoParams {
-	if in == nil {
-		return nil
-	}
-	out := new(BadDeepCopyIntoNoParams)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *BadDeepCopyIntoNonPtrParam) DeepCopyInto(out *BadDeepCopyIntoNonPtrParam) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BadDeepCopyIntoNonPtrParam.
-func (in *BadDeepCopyIntoNonPtrParam) DeepCopy() *BadDeepCopyIntoNonPtrParam {
-	if in == nil {
-		return nil
-	}
-	out := new(BadDeepCopyIntoNonPtrParam)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *BadDeepCopyNoReturn) DeepCopyInto(out *BadDeepCopyNoReturn) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BadDeepCopyNoReturn.
-func (in *BadDeepCopyNoReturn) DeepCopy() *BadDeepCopyNoReturn {
-	if in == nil {
-		return nil
-	}
-	out := new(BadDeepCopyNoReturn)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *BadDeepCopyNonPtrVal) DeepCopyInto(out *BadDeepCopyNonPtrVal) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BadDeepCopyNonPtrVal.
-func (in *BadDeepCopyNonPtrVal) DeepCopy() *BadDeepCopyNonPtrVal {
-	if in == nil {
-		return nil
-	}
-	out := new(BadDeepCopyNonPtrVal)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *BadDeepCopyPtrMismatch) DeepCopyInto(out *BadDeepCopyPtrMismatch) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BadDeepCopyPtrMismatch.
-func (in *BadDeepCopyPtrMismatch) DeepCopy() *BadDeepCopyPtrMismatch {
-	if in == nil {
-		return nil
-	}
-	out := new(BadDeepCopyPtrMismatch)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *BadDeepCopyPtrVal) DeepCopyInto(out *BadDeepCopyPtrVal) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BadDeepCopyPtrVal.
-func (in *BadDeepCopyPtrVal) DeepCopy() *BadDeepCopyPtrVal {
-	if in == nil {
-		return nil
-	}
-	out := new(BadDeepCopyPtrVal)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *CronJob) DeepCopyInto(out *CronJob) {
-	*out = *in
-	out.TypeMeta = in.TypeMeta
-	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
-	in.Spec.DeepCopyInto(&out.Spec)
-	in.Status.DeepCopyInto(&out.Status)
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CronJob.
-func (in *CronJob) DeepCopy() *CronJob {
-	if in == nil {
-		return nil
-	}
-	out := new(CronJob)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *CronJob) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *CronJobList) DeepCopyInto(out *CronJobList) {
-	*out = *in
-	out.TypeMeta = in.TypeMeta
-	in.ListMeta.DeepCopyInto(&out.ListMeta)
-	if in.Items != nil {
-		in, out := &in.Items, &out.Items
-		*out = make([]CronJob, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CronJobList.
-func (in *CronJobList) DeepCopy() *CronJobList {
-	if in == nil {
-		return nil
-	}
-	out := new(CronJobList)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *CronJobList) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *CronJobSpec) DeepCopyInto(out *CronJobSpec) {
-	*out = *in
-	if in.StartingDeadlineSeconds != nil {
-		in, out := &in.StartingDeadlineSeconds, &out.StartingDeadlineSeconds
-		*out = new(int64)
-		**out = **in
-	}
-	if in.Suspend != nil {
-		in, out := &in.Suspend, &out.Suspend
-		*out = new(bool)
-		**out = **in
-	}
-	in.JobTemplate.DeepCopyInto(&out.JobTemplate)
-	if in.SuccessfulJobsHistoryLimit != nil {
-		in, out := &in.SuccessfulJobsHistoryLimit, &out.SuccessfulJobsHistoryLimit
-		*out = new(int32)
-		**out = **in
-	}
-	if in.FailedJobsHistoryLimit != nil {
-		in, out := &in.FailedJobsHistoryLimit, &out.FailedJobsHistoryLimit
-		*out = new(int32)
-		**out = **in
-	}
-	in.SpecificCases.DeepCopyInto(&out.SpecificCases)
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CronJobSpec.
-func (in *CronJobSpec) DeepCopy() *CronJobSpec {
-	if in == nil {
-		return nil
-	}
-	out := new(CronJobSpec)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *CronJobStatus) DeepCopyInto(out *CronJobStatus) {
-	*out = *in
-	if in.Active != nil {
-		in, out := &in.Active, &out.Active
-		*out = make([]v1.ObjectReference, len(*in))
-		copy(*out, *in)
-	}
-	if in.LastScheduleTime != nil {
-		in, out := &in.LastScheduleTime, &out.LastScheduleTime
-		*out = (*in).DeepCopy()
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CronJobStatus.
-func (in *CronJobStatus) DeepCopy() *CronJobStatus {
-	if in == nil {
-		return nil
-	}
-	out := new(CronJobStatus)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeepCopyIntoNonPtr.
-func (in *DeepCopyIntoNonPtr) DeepCopy() *DeepCopyIntoNonPtr {
-	if in == nil {
-		return nil
-	}
-	out := new(DeepCopyIntoNonPtr)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeepCopyIntoPtr.
-func (in *DeepCopyIntoPtr) DeepCopy() *DeepCopyIntoPtr {
-	if in == nil {
-		return nil
-	}
-	out := new(DeepCopyIntoPtr)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeepCopyIntoRef.
-func (in DeepCopyIntoRef) DeepCopy() DeepCopyIntoRef {
-	if in == nil {
-		return nil
-	}
-	out := new(DeepCopyIntoRef)
-	in.DeepCopyInto(out)
-	return *out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *DeepCopyNonPtr) DeepCopyInto(out *DeepCopyNonPtr) {
-	*out = in.DeepCopy()
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *DeepCopyPtr) DeepCopyInto(out *DeepCopyPtr) {
-	clone := in.DeepCopy()
-	*out = *clone
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Foo) DeepCopyInto(out *Foo) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Foo.
-func (in *Foo) DeepCopy() *Foo {
-	if in == nil {
-		return nil
-	}
-	out := new(Foo)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *Foo) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *FooAlias) DeepCopyInto(out *FooAlias) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FooAlias.
-func (in *FooAlias) DeepCopy() *FooAlias {
-	if in == nil {
-		return nil
-	}
-	out := new(FooAlias)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in FooMap) DeepCopyInto(out *FooMap) {
-	{
-		in := &in
-		*out = make(FooMap, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FooMap.
-func (in FooMap) DeepCopy() FooMap {
-	if in == nil {
-		return nil
-	}
-	out := new(FooMap)
-	in.DeepCopyInto(out)
-	return *out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in FooSlice) DeepCopyInto(out *FooSlice) {
-	{
-		in := &in
-		*out = make(FooSlice, len(*in))
-		copy(*out, *in)
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FooSlice.
-func (in FooSlice) DeepCopy() FooSlice {
-	if in == nil {
-		return nil
-	}
-	out := new(FooSlice)
-	in.DeepCopyInto(out)
-	return *out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Inner) DeepCopyInto(out *Inner) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Inner.
-func (in *Inner) DeepCopy() *Inner {
-	if in == nil {
-		return nil
-	}
-	out := new(Inner)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in ManualSlice) DeepCopyInto(out *ManualSlice) {
-	{
-		in := &in
-		*out = in.DeepCopy()
-	}
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ManualStruct) DeepCopyInto(out *ManualStruct) {
-	*out = in.DeepCopy()
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ManualStruct_Alias) DeepCopyInto(out *ManualStruct_Alias) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManualStruct_Alias.
-func (in *ManualStruct_Alias) DeepCopy() *ManualStruct_Alias {
-	if in == nil {
-		return nil
-	}
-	out := new(ManualStruct_Alias)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in Map) DeepCopyInto(out *Map) {
-	{
-		in := &in
-		*out = make(Map, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Map.
-func (in Map) DeepCopy() Map {
-	if in == nil {
-		return nil
-	}
-	out := new(Map)
-	in.DeepCopyInto(out)
-	return *out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in MapOfStrings) DeepCopyInto(out *MapOfStrings) {
-	{
-		in := &in
-		*out = make(MapOfStrings, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MapOfStrings.
-func (in MapOfStrings) DeepCopy() MapOfStrings {
-	if in == nil {
-		return nil
-	}
-	out := new(MapOfStrings)
-	in.DeepCopyInto(out)
-	return *out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in Slice) DeepCopyInto(out *Slice) {
-	{
-		in := &in
-		*out = make(Slice, len(*in))
-		copy(*out, *in)
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Slice.
-func (in Slice) DeepCopy() Slice {
-	if in == nil {
-		return nil
-	}
-	out := new(Slice)
-	in.DeepCopyInto(out)
-	return *out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in SliceOfPointers) DeepCopyInto(out *SliceOfPointers) {
-	{
-		in := &in
-		*out = make(SliceOfPointers, len(*in))
-		for i := range *in {
-			if (*in)[i] != nil {
-				in, out := &(*in)[i], &(*out)[i]
-				*out = new(SomeStruct)
-				**out = **in
-			}
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SliceOfPointers.
-func (in SliceOfPointers) DeepCopy() SliceOfPointers {
-	if in == nil {
-		return nil
-	}
-	out := new(SliceOfPointers)
-	in.DeepCopyInto(out)
-	return *out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SomeStruct) DeepCopyInto(out *SomeStruct) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SomeStruct.
-func (in *SomeStruct) DeepCopy() *SomeStruct {
-	if in == nil {
-		return nil
-	}
-	out := new(SomeStruct)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SpecificCases) DeepCopyInto(out *SpecificCases) {
-	*out = *in
-	in.ManualDeepCopyPtr.DeepCopyInto(&out.ManualDeepCopyPtr)
-	out.ManualDeepCopyNonPtr = in.ManualDeepCopyNonPtr.DeepCopy()
-	in.ManualIntoPtr.DeepCopyInto(&out.ManualIntoPtr)
-	in.ManualIntoNonPtr.DeepCopyInto(&out.ManualIntoNonPtr)
-	out.BadDeepCopyHasParams = in.BadDeepCopyHasParams
-	out.BadDeepCopyNoReturn = in.BadDeepCopyNoReturn
-	out.BadDeepCopyPtrVal = in.BadDeepCopyPtrVal
-	out.BadDeepCopyNonPtrVal = in.BadDeepCopyNonPtrVal
-	out.BadDeepCopyPtrMismatch = in.BadDeepCopyPtrMismatch
-	out.BadDeepCopyIntoNoParams = in.BadDeepCopyIntoNoParams
-	out.BadDeepCopyIntoNonPtrParam = in.BadDeepCopyIntoNonPtrParam
-	out.BadDeepCopyIntoHasResult = in.BadDeepCopyIntoHasResult
-	if in.MapInField != nil {
-		in, out := &in.MapInField, &out.MapInField
-		*out = make(map[string]string, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.SliceInField != nil {
-		in, out := &in.SliceInField, &out.SliceInField
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-	if in.BuiltInPointer != nil {
-		in, out := &in.BuiltInPointer, &out.BuiltInPointer
-		*out = new(string)
-		**out = **in
-	}
-	if in.MapToDeepCopyPtr != nil {
-		in, out := &in.MapToDeepCopyPtr, &out.MapToDeepCopyPtr
-		*out = make(map[string]DeepCopyPtr, len(*in))
-		for key, val := range *in {
-			(*out)[key] = *val.DeepCopy()
-		}
-	}
-	if in.MapToDeepCopyNonPtr != nil {
-		in, out := &in.MapToDeepCopyNonPtr, &out.MapToDeepCopyNonPtr
-		*out = make(map[string]DeepCopyPtr, len(*in))
-		for key, val := range *in {
-			(*out)[key] = *val.DeepCopy()
-		}
-	}
-	if in.MapToDeepCopyIntoPtr != nil {
-		in, out := &in.MapToDeepCopyIntoPtr, &out.MapToDeepCopyIntoPtr
-		*out = make(map[string]DeepCopyIntoPtr, len(*in))
-		for key, val := range *in {
-			(*out)[key] = *val.DeepCopy()
-		}
-	}
-	if in.MapToDeepCopyIntoNonPtr != nil {
-		in, out := &in.MapToDeepCopyIntoNonPtr, &out.MapToDeepCopyIntoNonPtr
-		*out = make(map[string]DeepCopyIntoNonPtr, len(*in))
-		for key, val := range *in {
-			(*out)[key] = *val.DeepCopy()
-		}
-	}
-	if in.MapToShallowNamedType != nil {
-		in, out := &in.MapToShallowNamedType, &out.MapToShallowNamedType
-		*out = make(map[string]TotallyAString, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.MapToReferenceType != nil {
-		in, out := &in.MapToReferenceType, &out.MapToReferenceType
-		*out = make(map[string][]string, len(*in))
-		for key, val := range *in {
-			var outVal []string
-			if val == nil {
-				(*out)[key] = nil
-			} else {
-				in, out := &val, &outVal
-				*out = make([]string, len(*in))
-				copy(*out, *in)
-			}
-			(*out)[key] = outVal
-		}
-	}
-	if in.MapToStruct != nil {
-		in, out := &in.MapToStruct, &out.MapToStruct
-		*out = make(map[string]CronJobSpec, len(*in))
-		for key, val := range *in {
-			(*out)[key] = *val.DeepCopy()
-		}
-	}
-	if in.MapWithNamedKeys != nil {
-		in, out := &in.MapWithNamedKeys, &out.MapWithNamedKeys
-		*out = make(map[TotallyAString]int, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.MapToPtrToDeepCopyIntoRefType != nil {
-		in, out := &in.MapToPtrToDeepCopyIntoRefType, &out.MapToPtrToDeepCopyIntoRefType
-		*out = make(map[string]*DeepCopyIntoRef, len(*in))
-		for key, val := range *in {
-			{
-				x := val.DeepCopy()
-				(*out)[key] = &x
-			}
-		}
-	}
-	if in.MapToDeepCopyIntoRefType != nil {
-		in, out := &in.MapToDeepCopyIntoRefType, &out.MapToDeepCopyIntoRefType
-		*out = make(map[string]DeepCopyIntoRef, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val.DeepCopy()
-		}
-	}
-	if in.SliceToDeepCopyPtr != nil {
-		in, out := &in.SliceToDeepCopyPtr, &out.SliceToDeepCopyPtr
-		*out = make([]DeepCopyPtr, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.SliceToDeepCopyNonPtr != nil {
-		in, out := &in.SliceToDeepCopyNonPtr, &out.SliceToDeepCopyNonPtr
-		*out = make([]DeepCopyPtr, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.SliceToDeepCopyIntoPtr != nil {
-		in, out := &in.SliceToDeepCopyIntoPtr, &out.SliceToDeepCopyIntoPtr
-		*out = make([]DeepCopyIntoPtr, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.SliceToDeepCopyIntoNonPtr != nil {
-		in, out := &in.SliceToDeepCopyIntoNonPtr, &out.SliceToDeepCopyIntoNonPtr
-		*out = make([]DeepCopyIntoNonPtr, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.SliceToShallowNamedType != nil {
-		in, out := &in.SliceToShallowNamedType, &out.SliceToShallowNamedType
-		*out = make([]TotallyAString, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceToReferenceType != nil {
-		in, out := &in.SliceToReferenceType, &out.SliceToReferenceType
-		*out = make([][]string, len(*in))
-		for i := range *in {
-			if (*in)[i] != nil {
-				in, out := &(*in)[i], &(*out)[i]
-				*out = make([]string, len(*in))
-				copy(*out, *in)
-			}
-		}
-	}
-	if in.SliceToStruct != nil {
-		in, out := &in.SliceToStruct, &out.SliceToStruct
-		*out = make([]CronJobSpec, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.PtrToDeepCopyPtr != nil {
-		in, out := &in.PtrToDeepCopyPtr, &out.PtrToDeepCopyPtr
-		*out = (*in).DeepCopy()
-	}
-	if in.PtrToDeepCopyNonPtr != nil {
-		in, out := &in.PtrToDeepCopyNonPtr, &out.PtrToDeepCopyNonPtr
-		*out = (*in).DeepCopy()
-	}
-	if in.PtrToDeepCopyIntoPtr != nil {
-		in, out := &in.PtrToDeepCopyIntoPtr, &out.PtrToDeepCopyIntoPtr
-		*out = (*in).DeepCopy()
-	}
-	if in.PtrToDeepCopyIntoNonPtr != nil {
-		in, out := &in.PtrToDeepCopyIntoNonPtr, &out.PtrToDeepCopyIntoNonPtr
-		*out = (*in).DeepCopy()
-	}
-	if in.PtrToShallowNamedType != nil {
-		in, out := &in.PtrToShallowNamedType, &out.PtrToShallowNamedType
-		*out = new(TotallyAString)
-		**out = **in
-	}
-	if in.PtrToReferenceType != nil {
-		in, out := &in.PtrToReferenceType, &out.PtrToReferenceType
-		*out = new([]string)
-		if **in != nil {
-			in, out := *in, *out
-			*out = make([]string, len(*in))
-			copy(*out, *in)
-		}
-	}
-	if in.PtrToStruct != nil {
-		in, out := &in.PtrToStruct, &out.PtrToStruct
-		*out = new(CronJobSpec)
-		(*in).DeepCopyInto(*out)
-	}
-	if in.PtrToDeepCopyIntoRef != nil {
-		in, out := &in.PtrToDeepCopyIntoRef, &out.PtrToDeepCopyIntoRef
-		x := (*in).DeepCopy()
-		*out = &x
-	}
-	if in.SomePointers != nil {
-		in, out := &in.SomePointers, &out.SomePointers
-		*out = make(SliceOfPointers, len(*in))
-		for i := range *in {
-			if (*in)[i] != nil {
-				in, out := &(*in)[i], &(*out)[i]
-				*out = new(SomeStruct)
-				**out = **in
-			}
-		}
-	}
-	if in.StringMap != nil {
-		in, out := &in.StringMap, &out.StringMap
-		*out = make(MapOfStrings, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SpecificCases.
-func (in *SpecificCases) DeepCopy() *SpecificCases {
-	if in == nil {
-		return nil
-	}
-	out := new(SpecificCases)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct) DeepCopyInto(out *Struct) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct.
-func (in *Struct) DeepCopy() *Struct {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_B) DeepCopyInto(out *Struct_B) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_B.
-func (in *Struct_B) DeepCopy() *Struct_B {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_B)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Embed_Int) DeepCopyInto(out *Struct_Embed_Int) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Embed_Int.
-func (in *Struct_Embed_Int) DeepCopy() *Struct_Embed_Int {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Embed_Int)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Embed_ManualStruct) DeepCopyInto(out *Struct_Embed_ManualStruct) {
-	*out = *in
-	out.ManualStruct = in.ManualStruct.DeepCopy()
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Embed_ManualStruct.
-func (in *Struct_Embed_ManualStruct) DeepCopy() *Struct_Embed_ManualStruct {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Embed_ManualStruct)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Embed_Pointer) DeepCopyInto(out *Struct_Embed_Pointer) {
-	*out = *in
-	if in.int != nil {
-		in, out := &in.int, &out.int
-		*out = new(int)
-		**out = **in
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Embed_Pointer.
-func (in *Struct_Embed_Pointer) DeepCopy() *Struct_Embed_Pointer {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Embed_Pointer)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Embed_Struct_PrimitivePointers) DeepCopyInto(out *Struct_Embed_Struct_PrimitivePointers) {
-	*out = *in
-	in.Struct_PrimitivePointers.DeepCopyInto(&out.Struct_PrimitivePointers)
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Embed_Struct_PrimitivePointers.
-func (in *Struct_Embed_Struct_PrimitivePointers) DeepCopy() *Struct_Embed_Struct_PrimitivePointers {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Embed_Struct_PrimitivePointers)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Embed_Struct_Primitives) DeepCopyInto(out *Struct_Embed_Struct_Primitives) {
-	*out = *in
-	out.Struct_Primitives = in.Struct_Primitives
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Embed_Struct_Primitives.
-func (in *Struct_Embed_Struct_Primitives) DeepCopy() *Struct_Embed_Struct_Primitives {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Embed_Struct_Primitives)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Embed_Struct_Slices) DeepCopyInto(out *Struct_Embed_Struct_Slices) {
-	*out = *in
-	in.Struct_Slices.DeepCopyInto(&out.Struct_Slices)
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Embed_Struct_Slices.
-func (in *Struct_Embed_Struct_Slices) DeepCopy() *Struct_Embed_Struct_Slices {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Embed_Struct_Slices)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Empty) DeepCopyInto(out *Struct_Empty) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Empty.
-func (in *Struct_Empty) DeepCopy() *Struct_Empty {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Empty)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Everything) DeepCopyInto(out *Struct_Everything) {
-	*out = *in
-	out.StructField = in.StructField
-	out.EmptyStructField = in.EmptyStructField
-	out.ManualStructField = in.ManualStructField.DeepCopy()
-	out.ManualStructAliasField = in.ManualStructAliasField
-	if in.BoolPtrField != nil {
-		in, out := &in.BoolPtrField, &out.BoolPtrField
-		*out = new(bool)
-		**out = **in
-	}
-	if in.IntPtrField != nil {
-		in, out := &in.IntPtrField, &out.IntPtrField
-		*out = new(int)
-		**out = **in
-	}
-	if in.StringPtrField != nil {
-		in, out := &in.StringPtrField, &out.StringPtrField
-		*out = new(string)
-		**out = **in
-	}
-	if in.FloatPtrField != nil {
-		in, out := &in.FloatPtrField, &out.FloatPtrField
-		*out = new(float64)
-		**out = **in
-	}
-	in.PrimitivePointersField.DeepCopyInto(&out.PrimitivePointersField)
-	if in.ManualStructPtrField != nil {
-		in, out := &in.ManualStructPtrField, &out.ManualStructPtrField
-		x := (*in).DeepCopy()
-		*out = &x
-	}
-	if in.ManualStructAliasPtrField != nil {
-		in, out := &in.ManualStructAliasPtrField, &out.ManualStructAliasPtrField
-		*out = new(ManualStruct_Alias)
-		**out = **in
-	}
-	if in.SliceBoolField != nil {
-		in, out := &in.SliceBoolField, &out.SliceBoolField
-		*out = make([]bool, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceByteField != nil {
-		in, out := &in.SliceByteField, &out.SliceByteField
-		*out = make([]byte, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceIntField != nil {
-		in, out := &in.SliceIntField, &out.SliceIntField
-		*out = make([]int, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceStringField != nil {
-		in, out := &in.SliceStringField, &out.SliceStringField
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceFloatField != nil {
-		in, out := &in.SliceFloatField, &out.SliceFloatField
-		*out = make([]float64, len(*in))
-		copy(*out, *in)
-	}
-	in.SlicesField.DeepCopyInto(&out.SlicesField)
-	if in.SliceManualStructField != nil {
-		in, out := &in.SliceManualStructField, &out.SliceManualStructField
-		*out = make([]ManualStruct, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	out.ManualSliceField = in.ManualSliceField.DeepCopy()
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Everything.
-func (in *Struct_Everything) DeepCopy() *Struct_Everything {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Everything)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_ExplicitObject) DeepCopyInto(out *Struct_ExplicitObject) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_ExplicitObject.
-func (in *Struct_ExplicitObject) DeepCopy() *Struct_ExplicitObject {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_ExplicitObject)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *Struct_ExplicitObject) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_ExplicitSelectorExplicitObject) DeepCopyInto(out *Struct_ExplicitSelectorExplicitObject) {
-	*out = *in
-	out.Struct_TypeMeta = in.Struct_TypeMeta
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_ExplicitSelectorExplicitObject.
-func (in *Struct_ExplicitSelectorExplicitObject) DeepCopy() *Struct_ExplicitSelectorExplicitObject {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_ExplicitSelectorExplicitObject)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *Struct_ExplicitSelectorExplicitObject) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_PrimitivePointers) DeepCopyInto(out *Struct_PrimitivePointers) {
-	*out = *in
-	if in.BoolPtrField != nil {
-		in, out := &in.BoolPtrField, &out.BoolPtrField
-		*out = new(bool)
-		**out = **in
-	}
-	if in.IntPtrField != nil {
-		in, out := &in.IntPtrField, &out.IntPtrField
-		*out = new(int)
-		**out = **in
-	}
-	if in.StringPtrField != nil {
-		in, out := &in.StringPtrField, &out.StringPtrField
-		*out = new(string)
-		**out = **in
-	}
-	if in.FloatPtrField != nil {
-		in, out := &in.FloatPtrField, &out.FloatPtrField
-		*out = new(float64)
-		**out = **in
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_PrimitivePointers.
-func (in *Struct_PrimitivePointers) DeepCopy() *Struct_PrimitivePointers {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_PrimitivePointers)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_PrimitivePointers_Alias) DeepCopyInto(out *Struct_PrimitivePointers_Alias) {
-	*out = *in
-	if in.BoolPtrField != nil {
-		in, out := &in.BoolPtrField, &out.BoolPtrField
-		*out = new(bool)
-		**out = **in
-	}
-	if in.IntPtrField != nil {
-		in, out := &in.IntPtrField, &out.IntPtrField
-		*out = new(int)
-		**out = **in
-	}
-	if in.StringPtrField != nil {
-		in, out := &in.StringPtrField, &out.StringPtrField
-		*out = new(string)
-		**out = **in
-	}
-	if in.FloatPtrField != nil {
-		in, out := &in.FloatPtrField, &out.FloatPtrField
-		*out = new(float64)
-		**out = **in
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_PrimitivePointers_Alias.
-func (in *Struct_PrimitivePointers_Alias) DeepCopy() *Struct_PrimitivePointers_Alias {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_PrimitivePointers_Alias)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Primitives) DeepCopyInto(out *Struct_Primitives) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Primitives.
-func (in *Struct_Primitives) DeepCopy() *Struct_Primitives {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Primitives)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Primitives_Alias) DeepCopyInto(out *Struct_Primitives_Alias) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Primitives_Alias.
-func (in *Struct_Primitives_Alias) DeepCopy() *Struct_Primitives_Alias {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Primitives_Alias)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Slices) DeepCopyInto(out *Struct_Slices) {
-	*out = *in
-	if in.SliceBoolField != nil {
-		in, out := &in.SliceBoolField, &out.SliceBoolField
-		*out = make([]bool, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceByteField != nil {
-		in, out := &in.SliceByteField, &out.SliceByteField
-		*out = make([]byte, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceIntField != nil {
-		in, out := &in.SliceIntField, &out.SliceIntField
-		*out = make([]int, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceStringField != nil {
-		in, out := &in.SliceStringField, &out.SliceStringField
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceFloatField != nil {
-		in, out := &in.SliceFloatField, &out.SliceFloatField
-		*out = make([]float64, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceStructPrimitivesField != nil {
-		in, out := &in.SliceStructPrimitivesField, &out.SliceStructPrimitivesField
-		*out = make([]Struct_Primitives, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceStructPrimitivesAliasField != nil {
-		in, out := &in.SliceStructPrimitivesAliasField, &out.SliceStructPrimitivesAliasField
-		*out = make([]Struct_Primitives_Alias, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceStructPrimitivePointersField != nil {
-		in, out := &in.SliceStructPrimitivePointersField, &out.SliceStructPrimitivePointersField
-		*out = make([]Struct_PrimitivePointers, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.SliceStructPrimitivePointersAliasField != nil {
-		in, out := &in.SliceStructPrimitivePointersAliasField, &out.SliceStructPrimitivePointersAliasField
-		*out = make([]Struct_PrimitivePointers_Alias, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.SliceSliceIntField != nil {
-		in, out := &in.SliceSliceIntField, &out.SliceSliceIntField
-		*out = make([][]int, len(*in))
-		for i := range *in {
-			if (*in)[i] != nil {
-				in, out := &(*in)[i], &(*out)[i]
-				*out = make([]int, len(*in))
-				copy(*out, *in)
-			}
-		}
-	}
-	if in.SliceManualStructField != nil {
-		in, out := &in.SliceManualStructField, &out.SliceManualStructField
-		*out = make([]ManualStruct, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	out.ManualSliceField = in.ManualSliceField.DeepCopy()
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Slices.
-func (in *Struct_Slices) DeepCopy() *Struct_Slices {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Slices)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Slices_Alias) DeepCopyInto(out *Struct_Slices_Alias) {
-	*out = *in
-	if in.SliceBoolField != nil {
-		in, out := &in.SliceBoolField, &out.SliceBoolField
-		*out = make([]bool, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceByteField != nil {
-		in, out := &in.SliceByteField, &out.SliceByteField
-		*out = make([]byte, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceIntField != nil {
-		in, out := &in.SliceIntField, &out.SliceIntField
-		*out = make([]int, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceStringField != nil {
-		in, out := &in.SliceStringField, &out.SliceStringField
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceFloatField != nil {
-		in, out := &in.SliceFloatField, &out.SliceFloatField
-		*out = make([]float64, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceStructPrimitivesField != nil {
-		in, out := &in.SliceStructPrimitivesField, &out.SliceStructPrimitivesField
-		*out = make([]Struct_Primitives, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceStructPrimitivesAliasField != nil {
-		in, out := &in.SliceStructPrimitivesAliasField, &out.SliceStructPrimitivesAliasField
-		*out = make([]Struct_Primitives_Alias, len(*in))
-		copy(*out, *in)
-	}
-	if in.SliceStructPrimitivePointersField != nil {
-		in, out := &in.SliceStructPrimitivePointersField, &out.SliceStructPrimitivePointersField
-		*out = make([]Struct_PrimitivePointers, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.SliceStructPrimitivePointersAliasField != nil {
-		in, out := &in.SliceStructPrimitivePointersAliasField, &out.SliceStructPrimitivePointersAliasField
-		*out = make([]Struct_PrimitivePointers_Alias, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.SliceSliceIntField != nil {
-		in, out := &in.SliceSliceIntField, &out.SliceSliceIntField
-		*out = make([][]int, len(*in))
-		for i := range *in {
-			if (*in)[i] != nil {
-				in, out := &(*in)[i], &(*out)[i]
-				*out = make([]int, len(*in))
-				copy(*out, *in)
-			}
-		}
-	}
-	if in.SliceManualStructField != nil {
-		in, out := &in.SliceManualStructField, &out.SliceManualStructField
-		*out = make([]ManualStruct, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	out.ManualSliceField = in.ManualSliceField.DeepCopy()
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Slices_Alias.
-func (in *Struct_Slices_Alias) DeepCopy() *Struct_Slices_Alias {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Slices_Alias)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Struct_PrimitivePointers) DeepCopyInto(out *Struct_Struct_PrimitivePointers) {
-	*out = *in
-	in.StructField.DeepCopyInto(&out.StructField)
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Struct_PrimitivePointers.
-func (in *Struct_Struct_PrimitivePointers) DeepCopy() *Struct_Struct_PrimitivePointers {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Struct_PrimitivePointers)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Struct_Primitives) DeepCopyInto(out *Struct_Struct_Primitives) {
-	*out = *in
-	out.StructField = in.StructField
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Struct_Primitives.
-func (in *Struct_Struct_Primitives) DeepCopy() *Struct_Struct_Primitives {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Struct_Primitives)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Struct_Struct_Slices) DeepCopyInto(out *Struct_Struct_Slices) {
-	*out = *in
-	in.StructField.DeepCopyInto(&out.StructField)
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct_Struct_Slices.
-func (in *Struct_Struct_Slices) DeepCopy() *Struct_Struct_Slices {
-	if in == nil {
-		return nil
-	}
-	out := new(Struct_Struct_Slices)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *TestBuiltins) DeepCopyInto(out *TestBuiltins) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestBuiltins.
-func (in *TestBuiltins) DeepCopy() *TestBuiltins {
-	if in == nil {
-		return nil
-	}
-	out := new(TestBuiltins)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *TestInner) DeepCopyInto(out *TestInner) {
-	*out = *in
-	out.Inner1 = in.Inner1
-	out.Inner2 = in.Inner2
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestInner.
-func (in *TestInner) DeepCopy() *TestInner {
-	if in == nil {
-		return nil
-	}
-	out := new(TestInner)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *TestMaps) DeepCopyInto(out *TestMaps) {
-	*out = *in
-	if in.Byte != nil {
-		in, out := &in.Byte, &out.Byte
-		*out = make(map[string]byte, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.Int8 != nil {
-		in, out := &in.Int8, &out.Int8
-		*out = make(map[string]int8, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.Int16 != nil {
-		in, out := &in.Int16, &out.Int16
-		*out = make(map[string]int16, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.Int32 != nil {
-		in, out := &in.Int32, &out.Int32
-		*out = make(map[string]int32, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.Int64 != nil {
-		in, out := &in.Int64, &out.Int64
-		*out = make(map[string]int64, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.Uint8 != nil {
-		in, out := &in.Uint8, &out.Uint8
-		*out = make(map[string]uint8, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.Uint16 != nil {
-		in, out := &in.Uint16, &out.Uint16
-		*out = make(map[string]uint16, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.Uint32 != nil {
-		in, out := &in.Uint32, &out.Uint32
-		*out = make(map[string]uint32, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.Uint64 != nil {
-		in, out := &in.Uint64, &out.Uint64
-		*out = make(map[string]uint64, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.Float32 != nil {
-		in, out := &in.Float32, &out.Float32
-		*out = make(map[string]float32, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.Float64 != nil {
-		in, out := &in.Float64, &out.Float64
-		*out = make(map[string]float64, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.String != nil {
-		in, out := &in.String, &out.String
-		*out = make(map[string]string, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.StringPtr != nil {
-		in, out := &in.StringPtr, &out.StringPtr
-		*out = make(map[string]*string, len(*in))
-		for key, val := range *in {
-			var outVal *string
-			if val == nil {
-				(*out)[key] = nil
-			} else {
-				in, out := &val, &outVal
-				*out = new(string)
-				**out = **in
-			}
-			(*out)[key] = outVal
-		}
-	}
-	if in.StringPtrPtr != nil {
-		in, out := &in.StringPtrPtr, &out.StringPtrPtr
-		*out = make(map[string]**string, len(*in))
-		for key, val := range *in {
-			var outVal **string
-			if val == nil {
-				(*out)[key] = nil
-			} else {
-				in, out := &val, &outVal
-				*out = new(*string)
-				if **in != nil {
-					in, out := *in, *out
-					*out = new(string)
-					**out = **in
-				}
-			}
-			(*out)[key] = outVal
-		}
-	}
-	if in.Map != nil {
-		in, out := &in.Map, &out.Map
-		*out = make(map[string]map[string]string, len(*in))
-		for key, val := range *in {
-			var outVal map[string]string
-			if val == nil {
-				(*out)[key] = nil
-			} else {
-				in, out := &val, &outVal
-				*out = make(map[string]string, len(*in))
-				for key, val := range *in {
-					(*out)[key] = val
-				}
-			}
-			(*out)[key] = outVal
-		}
-	}
-	if in.MapPtr != nil {
-		in, out := &in.MapPtr, &out.MapPtr
-		*out = make(map[string]*map[string]string, len(*in))
-		for key, val := range *in {
-			var outVal *map[string]string
-			if val == nil {
-				(*out)[key] = nil
-			} else {
-				in, out := &val, &outVal
-				*out = new(map[string]string)
-				if **in != nil {
-					in, out := *in, *out
-					*out = make(map[string]string, len(*in))
-					for key, val := range *in {
-						(*out)[key] = val
-					}
-				}
-			}
-			(*out)[key] = outVal
-		}
-	}
-	if in.Slice != nil {
-		in, out := &in.Slice, &out.Slice
-		*out = make(map[string][]string, len(*in))
-		for key, val := range *in {
-			var outVal []string
-			if val == nil {
-				(*out)[key] = nil
-			} else {
-				in, out := &val, &outVal
-				*out = make([]string, len(*in))
-				copy(*out, *in)
-			}
-			(*out)[key] = outVal
-		}
-	}
-	if in.SlicePtr != nil {
-		in, out := &in.SlicePtr, &out.SlicePtr
-		*out = make(map[string]*[]string, len(*in))
-		for key, val := range *in {
-			var outVal *[]string
-			if val == nil {
-				(*out)[key] = nil
-			} else {
-				in, out := &val, &outVal
-				*out = new([]string)
-				if **in != nil {
-					in, out := *in, *out
-					*out = make([]string, len(*in))
-					copy(*out, *in)
-				}
-			}
-			(*out)[key] = outVal
-		}
-	}
-	if in.Struct != nil {
-		in, out := &in.Struct, &out.Struct
-		*out = make(map[string]Ttest, len(*in))
-		for key, val := range *in {
-			(*out)[key] = *val.DeepCopy()
-		}
-	}
-	if in.StructPtr != nil {
-		in, out := &in.StructPtr, &out.StructPtr
-		*out = make(map[string]*Ttest, len(*in))
-		for key, val := range *in {
-			var outVal *Ttest
-			if val == nil {
-				(*out)[key] = nil
-			} else {
-				in, out := &val, &outVal
-				*out = new(Ttest)
-				(*in).DeepCopyInto(*out)
-			}
-			(*out)[key] = outVal
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestMaps.
-func (in *TestMaps) DeepCopy() *TestMaps {
-	if in == nil {
-		return nil
-	}
-	out := new(TestMaps)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *TestPointers) DeepCopyInto(out *TestPointers) {
-	*out = *in
-	if in.Builtin != nil {
-		in, out := &in.Builtin, &out.Builtin
-		*out = new(string)
-		**out = **in
-	}
-	if in.Ptr != nil {
-		in, out := &in.Ptr, &out.Ptr
-		*out = new(*string)
-		if **in != nil {
-			in, out := *in, *out
-			*out = new(string)
-			**out = **in
-		}
-	}
-	if in.Map != nil {
-		in, out := &in.Map, &out.Map
-		*out = new(map[string]string)
-		if **in != nil {
-			in, out := *in, *out
-			*out = make(map[string]string, len(*in))
-			for key, val := range *in {
-				(*out)[key] = val
-			}
-		}
-	}
-	if in.Slice != nil {
-		in, out := &in.Slice, &out.Slice
-		*out = new([]string)
-		if **in != nil {
-			in, out := *in, *out
-			*out = make([]string, len(*in))
-			copy(*out, *in)
-		}
-	}
-	if in.MapPtr != nil {
-		in, out := &in.MapPtr, &out.MapPtr
-		*out = new(*map[string]string)
-		if **in != nil {
-			in, out := *in, *out
-			*out = new(map[string]string)
-			if **in != nil {
-				in, out := *in, *out
-				*out = make(map[string]string, len(*in))
-				for key, val := range *in {
-					(*out)[key] = val
-				}
-			}
-		}
-	}
-	if in.SlicePtr != nil {
-		in, out := &in.SlicePtr, &out.SlicePtr
-		*out = new(*[]string)
-		if **in != nil {
-			in, out := *in, *out
-			*out = new([]string)
-			if **in != nil {
-				in, out := *in, *out
-				*out = make([]string, len(*in))
-				copy(*out, *in)
-			}
-		}
-	}
-	if in.Struct != nil {
-		in, out := &in.Struct, &out.Struct
-		*out = new(Ttest)
-		(*in).DeepCopyInto(*out)
-	}
-	if in.StructPtr != nil {
-		in, out := &in.StructPtr, &out.StructPtr
-		*out = new(*Ttest)
-		if **in != nil {
-			in, out := *in, *out
-			*out = new(Ttest)
-			(*in).DeepCopyInto(*out)
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestPointers.
-func (in *TestPointers) DeepCopy() *TestPointers {
-	if in == nil {
-		return nil
-	}
-	out := new(TestPointers)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *TestSlices) DeepCopyInto(out *TestSlices) {
-	*out = *in
-	if in.Byte != nil {
-		in, out := &in.Byte, &out.Byte
-		*out = make([]byte, len(*in))
-		copy(*out, *in)
-	}
-	if in.Int8 != nil {
-		in, out := &in.Int8, &out.Int8
-		*out = make([]int8, len(*in))
-		copy(*out, *in)
-	}
-	if in.Int16 != nil {
-		in, out := &in.Int16, &out.Int16
-		*out = make([]int16, len(*in))
-		copy(*out, *in)
-	}
-	if in.Int32 != nil {
-		in, out := &in.Int32, &out.Int32
-		*out = make([]int32, len(*in))
-		copy(*out, *in)
-	}
-	if in.Int64 != nil {
-		in, out := &in.Int64, &out.Int64
-		*out = make([]int64, len(*in))
-		copy(*out, *in)
-	}
-	if in.Uint8 != nil {
-		in, out := &in.Uint8, &out.Uint8
-		*out = make([]uint8, len(*in))
-		copy(*out, *in)
-	}
-	if in.Uint16 != nil {
-		in, out := &in.Uint16, &out.Uint16
-		*out = make([]uint16, len(*in))
-		copy(*out, *in)
-	}
-	if in.Uint32 != nil {
-		in, out := &in.Uint32, &out.Uint32
-		*out = make([]uint32, len(*in))
-		copy(*out, *in)
-	}
-	if in.Uint64 != nil {
-		in, out := &in.Uint64, &out.Uint64
-		*out = make([]uint64, len(*in))
-		copy(*out, *in)
-	}
-	if in.Float32 != nil {
-		in, out := &in.Float32, &out.Float32
-		*out = make([]float32, len(*in))
-		copy(*out, *in)
-	}
-	if in.Float64 != nil {
-		in, out := &in.Float64, &out.Float64
-		*out = make([]float64, len(*in))
-		copy(*out, *in)
-	}
-	if in.String != nil {
-		in, out := &in.String, &out.String
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-	if in.StringPtr != nil {
-		in, out := &in.StringPtr, &out.StringPtr
-		*out = make([]*string, len(*in))
-		for i := range *in {
-			if (*in)[i] != nil {
-				in, out := &(*in)[i], &(*out)[i]
-				*out = new(string)
-				**out = **in
-			}
-		}
-	}
-	if in.StringPtrPtr != nil {
-		in, out := &in.StringPtrPtr, &out.StringPtrPtr
-		*out = make([]**string, len(*in))
-		for i := range *in {
-			if (*in)[i] != nil {
-				in, out := &(*in)[i], &(*out)[i]
-				*out = new(*string)
-				if **in != nil {
-					in, out := *in, *out
-					*out = new(string)
-					**out = **in
-				}
-			}
-		}
-	}
-	if in.Map != nil {
-		in, out := &in.Map, &out.Map
-		*out = make([]map[string]string, len(*in))
-		for i := range *in {
-			if (*in)[i] != nil {
-				in, out := &(*in)[i], &(*out)[i]
-				*out = make(map[string]string, len(*in))
-				for key, val := range *in {
-					(*out)[key] = val
-				}
-			}
-		}
-	}
-	if in.MapPtr != nil {
-		in, out := &in.MapPtr, &out.MapPtr
-		*out = make([]*map[string]string, len(*in))
-		for i := range *in {
-			if (*in)[i] != nil {
-				in, out := &(*in)[i], &(*out)[i]
-				*out = new(map[string]string)
-				if **in != nil {
-					in, out := *in, *out
-					*out = make(map[string]string, len(*in))
-					for key, val := range *in {
-						(*out)[key] = val
-					}
-				}
-			}
-		}
-	}
-	if in.Slice != nil {
-		in, out := &in.Slice, &out.Slice
-		*out = make([][]string, len(*in))
-		for i := range *in {
-			if (*in)[i] != nil {
-				in, out := &(*in)[i], &(*out)[i]
-				*out = make([]string, len(*in))
-				copy(*out, *in)
-			}
-		}
-	}
-	if in.SlicePtr != nil {
-		in, out := &in.SlicePtr, &out.SlicePtr
-		*out = make([]*[]string, len(*in))
-		for i := range *in {
-			if (*in)[i] != nil {
-				in, out := &(*in)[i], &(*out)[i]
-				*out = new([]string)
-				if **in != nil {
-					in, out := *in, *out
-					*out = make([]string, len(*in))
-					copy(*out, *in)
-				}
-			}
-		}
-	}
-	if in.Struct != nil {
-		in, out := &in.Struct, &out.Struct
-		*out = make([]Ttest, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.StructPtr != nil {
-		in, out := &in.StructPtr, &out.StructPtr
-		*out = make([]*Ttest, len(*in))
-		for i := range *in {
-			if (*in)[i] != nil {
-				in, out := &(*in)[i], &(*out)[i]
-				*out = new(Ttest)
-				(*in).DeepCopyInto(*out)
-			}
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestSlices.
-func (in *TestSlices) DeepCopy() *TestSlices {
-	if in == nil {
-		return nil
-	}
-	out := new(TestSlices)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Ttest) DeepCopyInto(out *Ttest) {
-	*out = *in
-	if in.Slice != nil {
-		in, out := &in.Slice, &out.Slice
-		*out = make(Slice, len(*in))
-		copy(*out, *in)
-	}
-	if in.Pointer != nil {
-		in, out := &in.Pointer, &out.Pointer
-		*out = new(int)
-		**out = **in
-	}
-	if in.PointerAlias != nil {
-		in, out := &in.PointerAlias, &out.PointerAlias
-		*out = new(Builtin)
-		**out = **in
-	}
-	out.Struct = in.Struct
-	if in.Map != nil {
-		in, out := &in.Map, &out.Map
-		*out = make(Map, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.SliceSlice != nil {
-		in, out := &in.SliceSlice, &out.SliceSlice
-		*out = make([]Slice, len(*in))
-		for i := range *in {
-			if (*in)[i] != nil {
-				in, out := &(*in)[i], &(*out)[i]
-				*out = make(Slice, len(*in))
-				copy(*out, *in)
-			}
-		}
-	}
-	if in.MapSlice != nil {
-		in, out := &in.MapSlice, &out.MapSlice
-		*out = make(map[string]Slice, len(*in))
-		for key, val := range *in {
-			var outVal []int
-			if val == nil {
-				(*out)[key] = nil
-			} else {
-				in, out := &val, &outVal
-				*out = make(Slice, len(*in))
-				copy(*out, *in)
-			}
-			(*out)[key] = outVal
-		}
-	}
-	out.FooAlias = in.FooAlias
-	if in.FooSlice != nil {
-		in, out := &in.FooSlice, &out.FooSlice
-		*out = make(FooSlice, len(*in))
-		copy(*out, *in)
-	}
-	if in.FooPointer != nil {
-		in, out := &in.FooPointer, &out.FooPointer
-		*out = new(Foo)
-		**out = **in
-	}
-	if in.FooMap != nil {
-		in, out := &in.FooMap, &out.FooMap
-		*out = make(FooMap, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.AliasSlice != nil {
-		in, out := &in.AliasSlice, &out.AliasSlice
-		*out = make(AliasSlice, len(*in))
-		copy(*out, *in)
-	}
-	if in.AliasPointer != nil {
-		in, out := &in.AliasPointer, &out.AliasPointer
-		*out = new(int)
-		**out = **in
-	}
-	out.AliasStruct = in.AliasStruct
-	if in.AliasMap != nil {
-		in, out := &in.AliasMap, &out.AliasMap
-		*out = make(AliasMap, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
-func (in *Ttest) DeepCopy() *Ttest {
-	if in == nil {
-		return nil
-	}
-	out := new(Ttest)
-	in.DeepCopyInto(out)
-	return out
-}
diff --git a/pkg/rbac/parser_integration_test.go b/pkg/rbac/parser_integration_test.go
index a56c1ec6..240bbb52 100644
--- a/pkg/rbac/parser_integration_test.go
+++ b/pkg/rbac/parser_integration_test.go
@@ -1,8 +1,6 @@
 package rbac_test
 
 import (
-	"bytes"
-	"fmt"
 	"io/ioutil"
 	"os"
 
@@ -45,7 +43,7 @@ var _ = Describe("ClusterRole generated by the RBAC Generator", func() {
 			}
 
 			By("generating a ClusterRole")
-			objs, err := rbac.GenerateRoles(ctx, "manager-role")
+			clusterRole, err := rbac.GenerateClusterRole(ctx, "manager-role")
 			Expect(err).NotTo(HaveOccurred())
 
 			By("loading the desired YAML")
@@ -53,21 +51,11 @@ var _ = Describe("ClusterRole generated by the RBAC Generator", func() {
 			Expect(err).NotTo(HaveOccurred())
 
 			By("parsing the desired YAML")
-			for i, expectedRoleBytes := range bytes.Split(expectedFile, []byte("\n---\n"))[1:] {
-				By(fmt.Sprintf("comparing the generated Role and expected Role (Pair %d)", i))
-				obj := objs[i]
-				switch obj := obj.(type) {
-				case rbacv1.ClusterRole:
-					var expectedClusterRole rbacv1.ClusterRole
-					Expect(yaml.Unmarshal(expectedRoleBytes, &expectedClusterRole)).To(Succeed())
-					Expect(obj).To(Equal(expectedClusterRole), "type not as expected, check pkg/rbac/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(obj, expectedClusterRole))
-				default:
-					var expectedRole rbacv1.Role
-					Expect(yaml.Unmarshal(expectedRoleBytes, &expectedRole)).To(Succeed())
-					Expect(obj).To(Equal(expectedRole), "type not as expected, check pkg/rbac/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(obj, expectedRole))
-				}
-			}
+			var role rbacv1.ClusterRole
+			Expect(yaml.Unmarshal(expectedFile, &role)).To(Succeed())
 
+			By("comparing the two")
+			Expect(*clusterRole).To(Equal(role), "type not as expected, check pkg/rbac/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(*clusterRole, role))
 		})
 	}
 })
diff --git a/pkg/rbac/testdata/controller.go b/pkg/rbac/testdata/controller.go
index 6c2964dd..98ed3d5d 100644
--- a/pkg/rbac/testdata/controller.go
+++ b/pkg/rbac/testdata/controller.go
@@ -3,10 +3,7 @@ package controller
 // +kubebuilder:rbac:groups=batch.io,resources=cronjobs,verbs=get;watch;create
 // +kubebuilder:rbac:groups=batch.io,resources=cronjobs/status,verbs=get;update;patch
 // +kubebuilder:rbac:groups=art,resources=jobs,verbs=get
-// +kubebuilder:rbac:groups=wave,resources=jobs,verbs=get,namespace=zoo
 // +kubebuilder:rbac:groups=batch;batch;batch,resources=jobs/status,verbs=watch
 // +kubebuilder:rbac:groups=batch;cron,resources=jobs/status,verbs=create;get
-// +kubebuilder:rbac:groups=art,resources=jobs,verbs=get,namespace=zoo
 // +kubebuilder:rbac:groups=cron;batch,resources=jobs/status,verbs=get;create
 // +kubebuilder:rbac:groups=batch,resources=jobs/status,verbs=watch;watch
-// +kubebuilder:rbac:groups=art,resources=jobs,verbs=get,namespace=park
diff --git a/pkg/rbac/testdata/role.yaml b/pkg/rbac/testdata/role.yaml
index d7afab43..01fc94f1 100644
--- a/pkg/rbac/testdata/role.yaml
+++ b/pkg/rbac/testdata/role.yaml
@@ -42,39 +42,3 @@ rules:
   - get
   - patch
   - update
-
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: Role
-metadata:
-  creationTimestamp: null
-  name: manager-role
-  namespace: park
-rules:
-- apiGroups:
-  - art
-  resources:
-  - jobs
-  verbs:
-  - get
-
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: Role
-metadata:
-  creationTimestamp: null
-  name: manager-role
-  namespace: zoo
-rules:
-- apiGroups:
-  - art
-  resources:
-  - jobs
-  verbs:
-  - get
-- apiGroups:
-  - wave
-  resources:
-  - jobs
-  verbs:
-  - get
diff --git a/test.sh b/test.sh
index eaf71660..26d7e8b5 100755
--- a/test.sh
+++ b/test.sh
@@ -123,7 +123,6 @@ golangci-lint run --disable-all \
     --enable=misspell \
     --enable=gocyclo \
     --enable=gosec \
-    --deadline=5m \
     ./pkg/... ./cmd/...
 
 # --enable=structcheck \  # doesn't understand embedded structs