mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 23:15:14 +00:00
Merge pull request #45057 from caesarxuchao/fix-conversion-for-pr
Automatic merge from submit-queue (batch tested with PRs 45057, 47259) Allow conversion-gen to take types that are not in the output path Part of fixing https://github.com/kubernetes/kubernetes/issues/44065. Partially address https://github.com/kubernetes/features/issues/282. The first commit is the changes to the conversion-gen (and vendor). The second commit moves the api/v1 types to staging, and the third commit shows the resulted changes in the generated conversions.
This commit is contained in:
commit
e1efc5465d
@ -46,13 +46,26 @@ type CustomArgs struct {
|
||||
SkipUnsafe bool
|
||||
}
|
||||
|
||||
// This is the comment tag that carries parameters for conversion generation.
|
||||
const tagName = "k8s:conversion-gen"
|
||||
// These are the comment tags that carry parameters for conversion generation.
|
||||
const (
|
||||
// e.g., "+k8s:conversion-gen=<peer-pkg>" in doc.go, where <peer-pkg> is the
|
||||
// import path of the package the peer types are defined in.
|
||||
// e.g., "+k8s:conversion-gen=false" in a type's comment will let
|
||||
// conversion-gen skip that type.
|
||||
tagName = "k8s:conversion-gen"
|
||||
// e.g., "+k8s:conversion-gen-external-types=<type-pkg>" in doc.go, where
|
||||
// <type-pkg> is the relative path to the package the types are defined in.
|
||||
externalTypesTagName = "k8s:conversion-gen-external-types"
|
||||
)
|
||||
|
||||
func extractTag(comments []string) []string {
|
||||
return types.ExtractCommentTags("+", comments)[tagName]
|
||||
}
|
||||
|
||||
func extractExternalTypesTag(comments []string) []string {
|
||||
return types.ExtractCommentTags("+", comments)[externalTypesTagName]
|
||||
}
|
||||
|
||||
func isCopyOnly(comments []string) bool {
|
||||
values := types.ExtractCommentTags("+", comments)["k8s:conversion-fn"]
|
||||
return len(values) == 1 && values[0] == "copy-only"
|
||||
@ -198,6 +211,10 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
|
||||
for i := range inputs {
|
||||
glog.V(5).Infof("considering pkg %q", i)
|
||||
pkg := context.Universe[i]
|
||||
// typesPkg is where the versioned types are defined. Sometimes it is
|
||||
// different from pkg. For example, kubernetes core/v1 types are defined
|
||||
// in vendor/k8s.io/api/core/v1, while pkg is at pkg/api/v1.
|
||||
typesPkg := pkg
|
||||
if pkg == nil {
|
||||
// If the input had no Go files, for example.
|
||||
continue
|
||||
@ -224,6 +241,24 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
|
||||
skipUnsafe = customArgs.SkipUnsafe
|
||||
}
|
||||
|
||||
// if the external types are not in the same package where the conversion functions to be generated
|
||||
externalTypesValues := extractExternalTypesTag(pkg.Comments)
|
||||
if externalTypesValues != nil {
|
||||
if len(externalTypesValues) != 1 {
|
||||
glog.Fatalf(" expect only one value for %q tag, got: %q", externalTypesTagName, externalTypesValues)
|
||||
}
|
||||
externalTypes := externalTypesValues[0]
|
||||
glog.V(5).Infof(" external types tags: %q", externalTypes)
|
||||
var err error
|
||||
typesPkg, err = context.AddDirectory(filepath.Join(pkg.Path, externalTypes))
|
||||
if err != nil {
|
||||
glog.Fatalf("cannot import package %s", externalTypes)
|
||||
}
|
||||
// update context.Order to the latest context.Universe
|
||||
orderer := namer.Orderer{Namer: namer.NewPublicNamer(1)}
|
||||
context.Order = orderer.OrderUniverse(context.Universe)
|
||||
}
|
||||
|
||||
// if the source path is within a /vendor/ directory (for example,
|
||||
// k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1), allow
|
||||
// generation to output to the proper relative path (under vendor).
|
||||
@ -263,11 +298,11 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
|
||||
HeaderText: header,
|
||||
GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
|
||||
return []generator.Generator{
|
||||
NewGenConversion(arguments.OutputFileBaseName, pkg.Path, manualConversions, peerPkgs, unsafeEquality),
|
||||
NewGenConversion(arguments.OutputFileBaseName, typesPkg.Path, pkg.Path, manualConversions, peerPkgs, unsafeEquality),
|
||||
}
|
||||
},
|
||||
FilterFunc: func(c *generator.Context, t *types.Type) bool {
|
||||
return t.Name.Package == pkg.Path
|
||||
return t.Name.Package == typesPkg.Path
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -380,7 +415,12 @@ type TypesEqual interface {
|
||||
// genConversion produces a file with a autogenerated conversions.
|
||||
type genConversion struct {
|
||||
generator.DefaultGen
|
||||
targetPackage string
|
||||
// the package that contains the types that conversion func are going to be
|
||||
// generated for
|
||||
typesPackage string
|
||||
// the package that the conversion funcs are going to be output to
|
||||
outputPackage string
|
||||
// packages that contain the peer of types in typesPacakge
|
||||
peerPackages []string
|
||||
manualConversions conversionFuncMap
|
||||
imports namer.ImportTracker
|
||||
@ -389,12 +429,13 @@ type genConversion struct {
|
||||
useUnsafe TypesEqual
|
||||
}
|
||||
|
||||
func NewGenConversion(sanitizedName, targetPackage string, manualConversions conversionFuncMap, peerPkgs []string, useUnsafe TypesEqual) generator.Generator {
|
||||
func NewGenConversion(sanitizedName, typesPackage, outputPackage string, manualConversions conversionFuncMap, peerPkgs []string, useUnsafe TypesEqual) generator.Generator {
|
||||
return &genConversion{
|
||||
DefaultGen: generator.DefaultGen{
|
||||
OptionalName: sanitizedName,
|
||||
},
|
||||
targetPackage: targetPackage,
|
||||
typesPackage: typesPackage,
|
||||
outputPackage: outputPackage,
|
||||
peerPackages: peerPkgs,
|
||||
manualConversions: manualConversions,
|
||||
imports: generator.NewImportTracker(),
|
||||
@ -407,7 +448,7 @@ func NewGenConversion(sanitizedName, targetPackage string, manualConversions con
|
||||
func (g *genConversion) Namers(c *generator.Context) namer.NameSystems {
|
||||
// Have the raw namer for this file track what it imports.
|
||||
return namer.NameSystems{
|
||||
"raw": namer.NewRawNamer(g.targetPackage, g.imports),
|
||||
"raw": namer.NewRawNamer(g.outputPackage, g.imports),
|
||||
"publicIT": &namerPlusImportTracking{
|
||||
delegate: conversionNamer(),
|
||||
tracker: g.imports,
|
||||
@ -428,13 +469,13 @@ func (n *namerPlusImportTracking) Name(t *types.Type) string {
|
||||
func (g *genConversion) convertibleOnlyWithinPackage(inType, outType *types.Type) bool {
|
||||
var t *types.Type
|
||||
var other *types.Type
|
||||
if inType.Name.Package == g.targetPackage {
|
||||
if inType.Name.Package == g.typesPackage {
|
||||
t, other = inType, outType
|
||||
} else {
|
||||
t, other = outType, inType
|
||||
}
|
||||
|
||||
if t.Name.Package != g.targetPackage {
|
||||
if t.Name.Package != g.typesPackage {
|
||||
return false
|
||||
}
|
||||
// If the type has opted out, skip it.
|
||||
@ -471,10 +512,10 @@ func (g *genConversion) Filter(c *generator.Context, t *types.Type) bool {
|
||||
}
|
||||
|
||||
func (g *genConversion) isOtherPackage(pkg string) bool {
|
||||
if pkg == g.targetPackage {
|
||||
if pkg == g.outputPackage {
|
||||
return false
|
||||
}
|
||||
if strings.HasSuffix(pkg, `"`+g.targetPackage+`"`) {
|
||||
if strings.HasSuffix(pkg, `"`+g.outputPackage+`"`) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
Loading…
Reference in New Issue
Block a user