Code Monkey home page Code Monkey logo

gengo's Introduction

gengo

Travis Widget GoDoc Widget GoReport

NOTE: k8s.io/gengo/v2 is the current development module.

A package for generating things based on go files. This mechanism was first used in Kubernetes code-generator and is split out here for ease of reuse and maintainability.

go get k8s.io/gengo/...

Examples

A set generator, deep-copy generator, defaulter generator and go-to-protobuf generator are included here. Also, import-boss will enforce arbitrary rules about import trees.

args/

Package args defines common arguments for a generator binary.

generator/

Package generator defines interfaces for code generators to implement, and machinery that will execute those code generators.

types/

Package types contains the type system definition. It is modeled after Go's type system, but it's intended that you could produce these types by parsing something else, if you want to write the parser/converter.

We don't directly use the go types in the go typecheck library because they are based on implementing differing interfaces. A struct-based format is more convenient input for template driven output.

parser/

Package parser parses go source files.

namer/

Package namer defines a naming system, for:

  • helping you reference go objects in a syntactically correct way
  • keeping track of what you reference, for importing the right packages
  • and defining parallel tracks of names, for making public interfaces and private implementations.

Contributing

Please see CONTRIBUTING.md for instructions on how to contribute.

gengo's People

Contributors

alexzielenski avatar alvaroaleman avatar asifdxtreme avatar danegsta avatar deads2k avatar dims avatar eloyekunle avatar fisherxu avatar goltermann avatar jefftree avatar jiangyuzhao avatar jianhuiz avatar joelsmith avatar jpbetz avatar jpeach avatar k8s-ci-robot avatar lavalamp avatar liggitt avatar markusthoemmes avatar mbssaiakhil avatar nikhita avatar rainest avatar simonbaeumer avatar smarterclayton avatar spzala avatar sttts avatar thockin avatar wojtek-t avatar wzshiming avatar zexi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gengo's Issues

feature request: cli tools

I am looking for the generator of proto file from golang struct,
the go-to-protobuf looks like related about this,
I have tried proteus, but does not works well,
this project will offer some cli tools for code gen?
thx!

Deep copy gen generates invalid code if struct has an `_` field

Running deepcopy-gen against structs that have _ fields in them generates invalid go code.

Source struct:

type CreateBucketConfiguration struct {
	_ struct{} `type:"structure"`

	LocationConstraint BucketLocationConstraint `type:"string" enum:"true"`
}
type BucketLocationConstraint string

doc.go directives to deepcopy:

// +k8s:deepcopy-gen=package,register

deepcopy directives above structs that the above struct is a child of (not sure if this makes a difference or not - this is autogenerated code from the operator sdk)

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

Output by deepcopy-gen:

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CreateBucketConfiguration) DeepCopyInto(out *CreateBucketConfiguration) {
	*out = *in
	out._ = in._
	return
}

Setting or accessing _ fields is invalid.

I applied the following patch locally and it outputs correct code (ie does not attempt to copy the _ field). No idea if this is the correct way to solve the problem though.

diff --git a/vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy.go b/vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy.go
index 4548108..1d90578 100644
--- a/vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy.go
+++ b/vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy.go
@@ -823,6 +823,9 @@ func (g *genDeepCopy) doStruct(t *types.Type, sw *generator.SnippetWriter) {

 	// Now fix-up fields as needed.
 	for _, m := range ut.Members {
+		if m.Name == "_" {
+			continue
+		}
 		ft := m.Type
 		uft := underlyingType(ft)

After applying this patch, output is as expected:

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CreateBucketConfiguration) DeepCopyInto(out *CreateBucketConfiguration) {
	*out = *in
	return
}

`k8s:deepcopy-gen` does not work when a struct has comments

The deepcopy generator cannot consider more than one line of comments
before the actual structure.

A part of my code was this:

import (
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:deepcopy-gen=true

// SkinnyPod is a stripped down version of k8s' Pod structure.
// By keeping only the parts we use from the pod in memory,
// we reduce the memory footprint of the application.
type SkinnyPod struct {
	metav1.ObjectMeta
	Spec   corev1.PodSpec
	Status corev1.PodStatus
}

Running the kubernetes generator, I had this error:

F0204 10:23:39.567087   91737 deepcopy.go:183] Type <redacted>/internal/types.SkinnyObject requests deepcopy generation but is not copyable

The error's stack pointed out to this line of code:

klog.Fatalf("Type %v requests deepcopy generation but is not copyable", t)
.

After reading the code, It made sense just to remove the comments from the struct and try again. It did work like this:

import (
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:deepcopy-gen=true

type SkinnyPod struct {
	metav1.ObjectMeta
	Spec   corev1.PodSpec
	Status corev1.PodStatus
}

Issue with Installing gengo on docker image without GO111MODULE

Im trying to install gengo on a docker image. This is Dockerfile that doesnt work

FROM golang:1.14.2-stretch
RUN go get k8s.io/gengo

Error produced:

Sending build context to Docker daemon   1.47GB
Step 1/2 : FROM golang:1.14.2-stretch
 ---> a58e31ece45e
Step 2/2 : RUN go get k8s.io/gengo
 ---> Running in 61735ad7dec3
package k8s.io/gengo: no Go files in /go/src/k8s.io/gengo
The command '/bin/sh -c go get k8s.io/gengo' returned a non-zero code: 1

The issue happens with 1.13.x base image of go also. I believe this is due to the latest klog v2 change that was made here: 565683f

There seems to be a fix for this. If i have GO111MODULE=on, the build succeeds.
This is Dockerfile that works:

FROM golang:1.14.2-stretch
ENV GO111MODULE=on
RUN go get k8s.io/gengo

Not sure if this is expected. It breaks some downstream users. If this is not a bug, does it warrant at least a documentation change?

Useless error report when hitting an unknown struct

Some type I had in my source code had a problem. Sadly the output of the generator is not very useful to pinpoint what type exactly:

go generate -v ./pkg/... ./cmd/...                                            
pkg/apis/apis.go                                          
F0305 17:48:56.504879  139794 deepcopy.go:873] Hit an unsupported type invalid type                              
Makefile:69: recipe for target 'generate' failed           

Int8 should not be byte type

Current builtin types in gengo

		Types: map[string]*Type{
			"bool":    Bool,
			"string":  String,
			"int":     Int,
			"int64":   Int64,
			"int32":   Int32,
			"int16":   Int16,
			"int8":    Byte,
			"uint":    Uint,
			"uint64":  Uint64,
			"uint32":  Uint32,
			"uint16":  Uint16,
			"uint8":   Byte,
			"uintptr": Uintptr,
			"byte":    Byte,
			"float":   Float,
			"float64": Float64,
			"float32": Float32,
		}

Description

int8 and uint8 are basic kind in go and defined as reflect.Kind (See https://golang.org/pkg/reflect/#Kind)

However byte which is uint8 kind actually is not basic kind

Expected

int8 is Int8 type, uint8 is Uint8 type and byte is Uint8 type

Actual

Now int8, uint8 and byte are Byte type

deepcopy-gen doesn't work on Windows

There are a couple of bugs which stop deepcopy-gen from working on Windows:

  • golangTrackerLocalName uses the path separator to split package names, but package names can contain forward-slashes as well (I'm not actually sure whether the package names which reach this function can actually contain back-slashes). I worked around this locally by using a split on either forward- or back-slashes.
  • In parser/parse.go: strings.HasSuffix(f.name, "/doc.go"). I just hacked this locally to have an || strings.HasSuffix(f.name, "\doc.go"), it seems like this one probably should be using path separator.

I can put together a PR if anyone has any rough suggestions about how to fix these more properly (I am not a Go expert).

Update for go modules

Let's begin publishing the module file.

Let's version this thing and start respecting the semver guarantees.

Capture the underlying value of constants.

When using gengo to generate API documentation, it would be pretty convenient to be able to get the underlying value of the constant. This could be used to generate documentation for the acceptable values of an enum.

Golint errors in generated files by `deepcopy-gen`

When I want to enable golint with pkg/scheduler in k8s kubernetes/kubernetes#58234, there are files generated by deepcopy-gen having lint errors. e.g.:

pkg/scheduler/api/zz_generated.deepcopy.go:265:9: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)

The code:

// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Policy) DeepCopyObject() runtime.Object {
	if c := in.DeepCopy(); c != nil {
		return c
	} else {
		return nil
	}
}

I think these errors should be fixed in deepcopy-gen so these files can pass the golint check.

master doesn't work with release-1.8 kubernetes/code-generator

kubernetes/code-generator/cmd/client-go is missing the --go-header and -o flags. @stts told me the issue was with the version of gengo I was using.

We should have a branch for kubernetes/gengo that matches the code vendored by kubernetes/kubernetes at the same branch.

To get the right version of gengo I need to pin it to a commit in my glide.yaml. I should be able to pin all kubernetes/* repos to a release-1.* and they should work together.

Support for JSONMap in CRDs

I have a CRD that I'm working on that is a wrapper around other objects, and so has the form

type UnstructuredJSON map[string]interface{}

type MyMessage struct {
  Objects []UnstructuredJSON
}

map[string]interface{} doesn't translate well with DeepCopy:

*out = make([]UnstructuredJSON, len(*in))
for i := range *in {
	if (*in)[i] != nil {
		in, out := &(*in)[i], &(*out)[i]
		*out = make(UnstructuredJSON, len(*in))
		for key, val := range *in {
			if val == nil {
				(*out)[key] = nil
			} else {
				(*out)[key] = val.DeepCopyinterface{}()
			}
		}
	}
}

(*out)[key] = val.DeepCopyinterface{}() is an error

I think some sort of UnstructuredJSON (called JSONMap in kubernetes Runtime) could be supported -- it's quite constrained on what can be in those interface{} values, but it would probably require custom copy logic.

What do you think?

Context: http://github.com/GoogleCloudPlatform/k8s-cluster-bundle

Unclear when strings are package names vs paths

I started some hacking this weekend in prep for other work, and I realized that it was unclear when string fields are package names ("foo") vs paths ("github.com/me/foo"). So I started making a strong type for them. I an not done with the work yet, but one thing that's clear is that at least some code (protobuf, I am looking at you) abuses types like Name to mean whatever it wants.

I am filing this for discussion. #13 is WIP

Generating non-go code

Hi, I'm looking into using gengo for generating ".adoc" files from go code.

Is it a valid use case? I see everything is built around code.

deepcopy-gen generates invalid code if package name is a reserved golang word

I have a CRD which I want to make use of the protobuf struct, which I build from types.proto: (pay attention to import "google/protobuf/struct.proto"; and google.protobuf.Struct settings)

syntax = 'proto3';

// ...
import "gogoproto/gogo.proto";
import "google/protobuf/struct.proto";
import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto";
// ...

option go_package = "v1";

// SomeSpec ...
message SomeSpec {
  // Somefield ...
  // +optional
  string somefield = 1;
  // Settings ...
  // +optional
  google.protobuf.Struct settings = 2;
}

// ...

which generation with protoc results to types.pb.go: (pay attention to _struct "github.com/golang/protobuf/ptypes/struct")

// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: types.proto

package v1

import (
	// ...
	_ "github.com/gogo/protobuf/gogoproto"
	proto "github.com/gogo/protobuf/proto"
	// ...
	_struct "github.com/golang/protobuf/ptypes/struct"
	// ...
	v11 "k8s.io/api/core/v1"
	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	// ...
)

// ...

which generation with generate-groups.sh all ... results to zz_generated.deepcopy.go: (pay attention to struct "github.com/golang/protobuf/ptypes/struct"

// +build !ignore_autogenerated

// Code generated by deepcopy-gen. DO NOT EDIT.

package v1

import (
	struct "github.com/golang/protobuf/ptypes/struct"
	corev1 "k8s.io/api/core/v1"
	runtime "k8s.io/apimachinery/pkg/runtime"
	net "net"
)

// ...

// and some usage of struct.Struct in the generated code
// ...
in, out := &in.Settings, &out.Settings
*out = new(struct.Struct)
(*in).DeepCopyInto(*out)
// ...

which is resulting into following error:

unable to format file ".../v1/zz_generated.deepcopy.go" (8:2: expected 'STRING', found 'struct' (and 10 more errors)).

And is obviously also not usable afterwards

Can you also add an underline _ to reserved golang words like gogoproto does with _struct?

Create a SECURITY_CONTACTS file.

As per the email sent to kubernetes-dev[1], please create a SECURITY_CONTACTS
file.

The template for the file can be found in the kubernetes-template repository[2].
A description for the file is in the steering-committee docs[3], you might need
to search that page for "Security Contacts".

Please feel free to ping me on the PR when you make it, otherwise I will see when
you close this issue. :)

Thanks so much, let me know if you have any questions.

(This issue was generated from a tool, apologies for any weirdness.)

[1] https://groups.google.com/forum/#!topic/kubernetes-dev/codeiIoQ6QE
[2] https://github.com/kubernetes/kubernetes-template-project/blob/master/SECURITY_CONTACTS
[3] https://github.com/kubernetes/community/blob/master/committee-steering/governance/sig-governance-template-short.md

deepcopy-gen generates invalid code for interface{}

Declaring a map[string]interface{} member in a struct handled by deepcopy-gen generates invalid code.
It seems there could be two options available:

  • for map[string]interface{}, generate code that leverages runtime.DeepCopyJSON
  • for any interface{}, error out instead of generating code that does not compile.

Related issues: #128, kubernetes-sigs/kubebuilder#528 and kubernetes-sigs/controller-tools#126

Example

  • foo.go
// +k8s:deepcopy-gen=true
type Foo struct {
  Data map[string]interface{}
}
  • zz_generated.deepcopy.go (DeepCopy function omitted for clarity as it basically calls DeepCopyInto)
// 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
	if in.Data != nil {
		in, out := &in.Data, &out.Data
		*out = make(map[string]interface{}, len(*in))
		for key, val := range *in {
			if val == nil {
				(*out)[key] = nil
			} else {
				// INVALID FUNCTION NAME
				(*out)[key] = val.DeepCopyinterface{}()
			}
		}
	}
	return
}

Gengo passes file path as package path to build.Context.Import().

In parse.go, the function Builder.importWithMode() calls build.Context.Import() with dir as the first argument. But dir is a filesystem path, as opposed to a package path, and Import expects a package path as its first argument.

On UNIX systems, this doesn't matter because the two turn out to be the same thing. On Windows, it is a huge problem because package paths are always slash separated while filesystem paths use backslashes.

deepcopy-gen doesn't handle pointer-to-slice correctly

If you have a struct with a pointer to a slice, eg:

Ports *[]NetworkPolicyPort `json:"ports,omitempty"`

(because you need to distinguish "field is not set" from "field is set to []") then deepcopy-gen generates incorrect code to copy it, resulting in:

../../apis/extensions/zz_generated.deepcopy.go:587: invalid argument *in (type *[]NetworkPolicyPort) for len

because it outputs code as though the field was a slice, not a pointer-to-slice. (Presumably pointer-to-map fields have the same problem.)

(kubernetes/kubernetes#25835 has more discussion of the use case.)

I don't have a simple reproducer, but, eg, changing NetworkPolicyIngressRule.Ports in kubernetes/pkg/apis/extensions/types.go from []NetworkPolicyPort to *[]NetworkPolicyPort and regenerating stuff will trigger the error above.

No comments are collected for string alias constants.

In service-apis, we use the following pattern:

type ListenerConditionType string

const (
	// ListenerConditionConflicted indicates that the controller
	// was unable to resolve conflicting specification requirements
	// for this Listener. If a Listener is conflicted, its network
	// port should not be configured on any network elements.
	//
	// Possible reasons for this condition to be true are:
	//
	// * "HostnameConflict"
	// * "ProtocolConflict"
	// * "RouteConflict"
	//
	// Controllers may raise this condition with other reasons,
	// but should prefer to use the reasons listed above to improve
	// interoperability.
	ListenerConditionConflicted ListenerConditionType = "Conflicted"

	// ListenerReasonHostnameConflict is used when the Listener
	// violates the Hostname match constraints that allow collapsing
	// Listeners. For example, this reason would be used when multiple
	// Listeners on the same port use the "Any" hostname match type.
	ListenerReasonHostnameConflict ListenerConditionReason = "HostnameConflict"
)

We also use a variation of this with eum validation:

// +kubebuilder:validation:Enum=Domain;Exact;Any
type HostnameMatchType string

const (
	// HostnameMatchExact specifies that the hostname provided
	// by the client must exactly match the specified value.
	//
	// This match type MUST be case-insensitive.
	HostnameMatchExact HostnameMatchType = "Exact"

	// HostnameMatchDomain specifies that the hostname provided
	// by the client should be matched against a DNS domain value.
	// The domain match removes the leftmost DNS label from the
	// hostname provided by the client and compares the resulting
	// value.
	//
	// For example, "example.com" is a "Domain" match for the host
	// name "foo.example.com", but not for "foo.bar.example.com"
	// or for "example.foo.com".
	//
	// This match type MUST be case-insensitive.
	HostnameMatchDomain HostnameMatchType = "Domain"

	// HostnameMatchAny specifies that this Listener accepts
	// all client traffic regardless of the presence or value of
	// any hostname supplied by the client.
	HostnameMatchAny HostnameMatchType = "Any"
)

What I would like to do is bubble the documentation from the constants up to the generated HTML documentation for the CRD (we are using https://github.com/ahmetb/gen-crd-api-reference-docs), but it looks like comments aren't collected for DeclarationOf types.

For example, here's the DeclarationOf type:

I1012 08:38:00.636089   32798 main.go:467] type -> &types.Type{Name:types.Name{Package:"sigs.k8s.io/service-apis/apis/v1alpha1", Name:"HostnameMatchExact", Path:""}, Kind:"DeclarationOf", CommentLines:[]string(nil), SecondClosestCommentLines:[]string(nil), Members:[]types.Member(nil), Elem:(*types.Type)(nil), Key:(*types.Type)(nil), Underlying:(*types.Type)(0xc009e70d10), Methods:map[string]*types.Type(nil), Signature:(*types.Signature)(nil)}

And here's its underlying type:

I1012 08:38:00.636102   32798 main.go:468] underlying -> &types.Type{Name:types.Name{Package:"sigs.k8s.io/service-apis/apis/v1alpha1", Name:"HostnameMatchType", Path:""}, Kind:"Alias", CommentLines:[]string{"HostnameMatchType specifies the types of matches that are valid", "for hostnames.", "Valid match types are:", "", "* \"Domain\"", "* \"Exact\"", "* \"Any\"", "", "+kubebuilder:validation:Enum=Domain;Exact;Any"}, SecondClosestCommentLines:[]string{""}, Members:[]types.Member(nil), Elem:(*types.Type)(nil), Key:(*types.Type)(nil), Underlying:(*types.Type)(0x17ef600), Methods:map[string]*types.Type(nil), Signature:(*types.Signature)(nil)}

The alias has comments, but the constant doesn't.

Type aliases are flattened to the underlying type.

Over in service-apis , I used https://github.com/ahmetb/gen-crd-api-reference-docs to generate the CRD API documentation. This project uses gengo to parse the Go types for the CRD, and generates HTML documentation.

In the service-apis CRD, we use type aliases like this:

type ConfigMapsDefaultLocalObjectReference struct {
...
}

type GatewayClassParametersObjectReference = ConfigMapsDefaultLocalObjectReference
type RouteHostExtensionObjectReference = ConfigMapsDefaultLocalObjectReference
type RouteActionExtensionObjectReference = ConfigMapsDefaultLocalObjectReference

The end result of this is that all the aliases get flattened to the underlying type ConfigMapsDefaultLocalObjectReference.

I'm not at all familiar with any of the machinery underlying this, but the only way I could see to detect the alias was using IsAlias on the type name before walking the type. Once you do this, it might be reasonable to emit the type alias as a type of Kind "Alias", but I'm not sure whether that's a good idea or not.

Here's a bit of a patch that I was messing with that is probably very naive about different type alias possibilities:

@@ -534,7 +535,22 @@ func (b *Builder) findTypesIn(pkgPath importPathString, u *types.Universe) error
                obj := s.Lookup(n)
                tn, ok := obj.(*tc.TypeName)
                if ok {
-                       t := b.walkType(*u, nil, tn.Type())
+                       var typeName *types.Name
+
+                       if tn.IsAlias() {
+                               log.Printf("found TypeName alias name=%q type.Name=%q pkg.Name=%q id=%q",
+                                       tn.Name(), tn.Type().String(), tn.Pkg().Path(), tn.Id())
+                               // typeName = tcNameToName(tn.Name())
+                               typeName = &types.Name{
+                                       Name: tn.Name(),
+                               }
+
+                               if tn.Pkg() != nil {
+                                       typeName.Package = tn.Pkg().Name()
+                               }
+                       }
+
+                       t := b.walkType(*u, typeName, tn.Type())
                        c1 := b.priorCommentLines(obj.Pos(), 1)
                        // c1.Text() is safe if c1 is nil
                        t.CommentLines = splitLines(c1.Text())

Time to version!

Gengo is slow enough moving that I think it's time to call it 1.0.0 and start paying attention to our interface changes.

Need examples and documentation for generating deep-copy functions for structs that reference ptypes

I am trying to generate deep-copy functions for my struct that contains structpb.Struct.

// +genclient
// +genclient:noStatus
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// My CRD
type MyStruct struct {
metav1.TypeMeta
metav1.ObjectMeta
Spec MySpec
Status MyStatus
ListOfStructs structpb.Struct
}
DeepCopyInto function is not generated for ListOfStructs. How do I either generate the functions or specify my own.

Codegen attempts to deepcopy time.Time

I have a type that contains times (time.Time).

type KayTime struct {
	// Type is the type of host repair action.
	Type KayTime `json:"type"`

	StartTime time.Time `json:"startTime"`

	ExpireTime time.Time `json:"expireTime"`
}

When I put the follow flag:
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

the code generator tries to do the following which is undefined for time.Time since it's underlying type is an integer:

in.StartTime.DeepCopyInto(&out.StartTime)
in.EndTime.DeepCopyInto(&out.EndTime)

AddDirRecursive panics when GOROOT is not set correctly

It seems that when GOROOT is misconfigured, Builder.AddDirRecursive panics:

W0611 10:07:38.859903   39295 parse.go:224] Ignoring directory github.com/k8spatterns/hello-operator/pkg/apis: unable to import "github.com/k8spatterns/hello-operator/pkg/apis": go/build: importGo github.com/k8spatterns/hello-operator/pkg/apis: exit status 2
go: cannot find GOROOT directory: /usr/local/go

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x1760595]

goroutine 1 [running]:
github.com/operator-framework/operator-sdk/vendor/k8s.io/gengo/parser.(*Builder).AddDirRecursive(0xc000962230, 0xc0006b71d0, 0x2e, 0x2, 0x2)
	src/github.com/operator-framework/operator-sdk/vendor/k8s.io/gengo/parser/parse.go:229 +0xb5

See operator-framework/operator-sdk#1545 for more details.

parser errors from external packages should be ignored

There's lots of false positives like:

W0516 14:25:25.242] 	/go/src/k8s.io/kubernetes/_output/dockerized/go/src/golang_org/x/net/lex/httplex (from $GOPATH))
W0516 14:25:25.243] I0516 14:25:25.243437    1949 parse.go:394] type checker error: /usr/local/go/src/net/http/h2_bundle.go:850:19: undeclared name: hpack
W0516 14:25:25.244] I0516 14:25:25.243796    1949 parse.go:394] type checker error: /usr/local/go/src/net/http/h2_bundle.go:1834:11: undeclared name: hpack
W0516 14:25:25.244] I0516 14:25:25.243833    1949 parse.go:394] type checker error: /usr/local/go/src/net/http/h2_bundle.go:1858:52: undeclared name: hpack
W0516 14:25:25.244] I0516 14:25:25.243854    1949 parse.go:394] type checker error: /usr/local/go/src/net/http/h2_bundle.go:1869:51: undeclared name: hpack
W0516 14:25:25.244] I0516 14:25:25.243880    1949 parse.go:394] type checker error: /usr/local/go/src/net/http/h2_bundle.go:5530:11: undeclared name: hpack
W0516 14:25:25.245] I0516 14:25:25.244088    1949 parse.go:394] type checker error: /usr/local/go/src/net/http/h2_bundle.go:7400:20: undeclared name: hpack
W0516 14:25:25.245] I0516 14:25:25.244903    1949 parse.go:394] type checker error: /usr/local/go/src/net/http/h2_bundle.go:3252:18: undeclared name: hpack
W0516 14:25:25.245] I0516 14:25:25.244985    1949 parse.go:394] type checker error: /usr/local/go/src/net/http/h2_bundle.go:3312:46: undeclared name: hpack
W0516 14:25:25.248] I0516 14:25:25.247794    1949 parse.go:394] type checker error: /usr/local/go/src/net/http/h2_bundle.go:7551:22: undeclared name: hpack
W0516 14:25:25.248] I0516 14:25:25.247900    1949 parse.go:394] type checker error: /usr/local/go/src/net/http/h2_bundle.go:7687:30: undeclared name: hpack
W0516 14:25:25.251] I0516 14:25:25.251452    1949 parse.go:346] type checking encountered some errors in "net/http", but ignoring.
W0516 14:25:26.515] I0516 14:25:26.514660    1949 execute.go:214] Processing package "v1", disk location "/go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/apis/example/v1"
W0516 14:25:26.524] I0516 14:25:26.524049    1949 execute.go:67] Assembling file "/go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/apis/example/v1/zz_generated.conversion.go"

That make it harder to find errors in kubernetes-verify jobs. Can we suppress type checker errors for stdlib packages?

Tracking Issue for improvements for built-in declarative defaults generator

Originally PR linked here: #192

Future Improvements:

We should target these for the beginning of 1.21

proposal: deepequal code generation

Hi,
While working on a project I had a need for a "DeepEqual" method that handled some usecases specific to our application that reflect.DeepEqual does not handle. I was wondering if there is any interest in me contributing this as a code generator along side the deepcopy-gen example that is provided in this repo or if there is any objection to splitting this off into a separate non-Kubernetes repo?

The two special cases that we needed handled are as follows. Both are off by default unless a special struct comment tag is supplied by the user:

  1. We needed slices to be compared such that order is unimportant. That is, two slices containing the same elements but in different order would report as equal. This is contrary to how reflect.DeepEqual works. I can see this being useful to other people as it is not always convenient to keep a slice in sorted order when adding/removing from it, or to want to sort it before comparing.

The type would be tagged like this to enable this special this handling:

// +k8s:deepequal-gen:unordered-array=true
type MyList []string
  1. We needed to handle a special usecase for struct comparisons whereby nil fields on the left hand side (the receiver) of the comparison would be ignored and assumed to be equal regardless of the value on the right hand side (the input). The reason for this is that we have a need to express certain fields as optional features and if the struct on the right has it set then we just treat that an acceptable value. For example, consider this struct.
// +k8s:deepequal-gen:ignore-nil-fields=true
type MyStruct struct {
    Name string `json:"name"`
    Address string `json:"address"`
    Age *int `json:"age,omitempty"`
}

a := MyStruct{Name: "John", Address: "Somewhere"}
ageB := 30
b := MyStruct{Name: "John", Address: "Somewhere", Age: &ageB}
ageC := 31
c := MyStruct{Name: "John", Address: "Somewhere", Age: &ageC}

a.DeepEqual(&b) == true
b.DeepEqual(&c) == false

I admit that this particular behavior may not be applicable to many users, but having this available as part of the code generator was a time saver as we have many structures and many of those have these optional fields that we needed to handle in this way.

If there is interest I can augment the unit tests and prepare a PR.

Numerous pathname bugs on Windows

This code appears to have quite a number of pathname bugs on Windows, as a result of assumptions about the path separator character (e.g. it looks for "/vendor/" in path strings in several places).

Clarify ownership and merge policy

After a couple of times with PRs not being merged here for weeks, can we clarify who can approve, lgtm and merge PRs in here? Looking at older PRs neither of these groups match the OWNERS file.

Clean up examples

Examples should contain only 100% general things.

Deep copy, defaulter, proto need to move to the kube-generator repo.

Import boss can probably be deleted, since we enforce that w/ bazel now.

Adding Proto3 support

We are exploring the possibility of adding proto3 support while keeping support for proto2. This is proving to be quite difficult, quite likely for a lack of knowledge on my side.

The implications of switching the syntax affect several parts of the codebase that have no parameter (or at least, not an obvious one) in common.

Can you provide some help/guidance on this?

If this is not the appropriate channel for asking this kinds of questions, please, let us know.

Thank you!

pkg/parser: Parses too much stuff, eventually goes into stdlib reflect, rune etc.

I'm author of https://github.com/ahmetb/gen-crd-api-reference-docs/ which is a tool to generate API reference docs for most kubernetes CRD projects (e.g. usually built with kubebuilder). I use gengo/parser package.

Recently it started to break because its parsing goes waaaay too deep.

It's parsing this k8s.io/apimachinery/pkg/runtime.Scheme type: https://sourcegraph.com/github.com/knative/serving@07437021afd54ecd391f84e66616751108bc6644/-/blob/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go#L47:6

This Scheme has unexported fields like gvkToType map[schema.GroupVersionKind]reflect.Type which refer to reflect.Type.

So gengo/parser goes and parses reflect.Type, which ends up going muuuuch deeper and ends up parsing types like rune builtin as Unsupported kind.

Eventually my program bursts out with Type{Name: "invalid type", Kind: Unsupported, Package: ""} which isn't great.

Would it be possible to change gengo/parser so that

  • it doesn't parse lowercase (unexported) fields
  • it doesn't parse stdlib runtime.* package

I think these two improvements would help massively.

Consider decoupling package->directory lookups from $PWD

Branching discussion from kubernetes/repo-infra#19

Gengo currently assumes that a package "k8s.io/foo/bar" can always be found in ${PWD}/k8s.io/foo/bar/, and becomes very unhappy if the generator program is called from a different directory. This makes its use from Bazel rules complicated, and requires Kubernetes BUILD files to use custom logic such as go_genrule() instead of Bazel's built-in genrule().

segfault when running make, seems to come from gengo

I get a segfault when I run make. I am rebased on latest upstream/master for k8s. This is not good.

Substituted private paths w/ PATHYMCPATHFACE:

$ make
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x58 pc=0x45dcf2]

goroutine 1 [running]:
panic(0x692840, 0xc4200102e0)
	/PATHYMCPATHFACE/go/src/runtime/panic.go:500 +0x1a1
k8s.io/kubernetes/vendor/k8s.io/gengo/examples/defaulter-gen/generators.getManualDefaultingFunctions(0xc430007a40, 0x0, 0xc4302989c0)
	/PATHYMCPATHFACE/go-tools/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/vendor/k8s.io/gengo/examples/defaulter-gen/generators/defaulter.go:113 +0x102
k8s.io/kubernetes/vendor/k8s.io/gengo/examples/defaulter-gen/generators.Packages(0xc430007a40, 0xc42001c680, 0x6db1d5, 0x6, 0xc430007a40)
	/PATHYMCPATHFACE/go-tools/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/vendor/k8s.io/gengo/examples/defaulter-gen/generators/defaulter.go:236 +0x6d2
k8s.io/kubernetes/vendor/k8s.io/gengo/args.(*GeneratorArgs).Execute(0xc42001c680, 0xc420016fc0, 0x6db1d5, 0x6, 0x700988, 0x0, 0x0)
	/PATHYMCPATHFACE/go-tools/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/vendor/k8s.io/gengo/args/args.go:165 +0x170
main.main()
	/PATHYMCPATHFACE/go-tools/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/cmd/libs/go2idl/defaulter-gen/main.go:74 +0x1fb
make[1]: *** [gen_defaulter] Error 1
make: *** [generated_files] Error 2

CI is silently failing

Running the current first step of the build shows the issue:

$ find . -name vendor -prune -o -name Makefile -execdir make test \;
unknown flag: --logtostderr
Usage of /tmp/defaulter-gen:
...
make: *** [test] Error 2
...

This started happening 5 months when the repo switched over from glog to klog (#129). The build log for it is https://travis-ci.org/kubernetes/gengo/jobs/450604661.

Since find wraps the error and returns zero, the CI has been silently failing since.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.