mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 14:37:00 +00:00
prevent deprecated & removed from being generated for GA types
This commit is contained in:
parent
8d45bbea2b
commit
0095f607ab
@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"path"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -364,6 +365,10 @@ func (g *genPreleaseLifecycle) Imports(c *generator.Context) (imports []string)
|
||||
return importLines
|
||||
}
|
||||
|
||||
var (
|
||||
isGAVersionRegex = regexp.MustCompile(`^v\d+$`)
|
||||
)
|
||||
|
||||
func (g *genPreleaseLifecycle) argsFromType(c *generator.Context, t *types.Type) (generator.Args, error) {
|
||||
a := generator.Args{
|
||||
"type": t,
|
||||
@ -372,37 +377,53 @@ func (g *genPreleaseLifecycle) argsFromType(c *generator.Context, t *types.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Take version from package last segment.
|
||||
// Use heuristic to determine whether the package is GA or prerelease.
|
||||
// If the package is GA, the version matches the format vN where N is a number.
|
||||
version := path.Base(t.Name.Package)
|
||||
isGAVersion := isGAVersionRegex.MatchString(version)
|
||||
|
||||
a = a.
|
||||
With("introducedMajor", introducedMajor).
|
||||
With("introducedMinor", introducedMinor)
|
||||
|
||||
// compute based on our policy
|
||||
hasDeprecated := tagExists(deprecatedTagName, t)
|
||||
hasRemoved := tagExists(removedTagName, t)
|
||||
|
||||
deprecatedMajor := introducedMajor
|
||||
deprecatedMinor := introducedMinor + 3
|
||||
// if someone intentionally override the deprecation release
|
||||
if tagExists(deprecatedTagName, t) {
|
||||
if hasDeprecated {
|
||||
_, deprecatedMajor, deprecatedMinor, err = extractDeprecatedTag(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
a = a.
|
||||
With("deprecatedMajor", deprecatedMajor).
|
||||
With("deprecatedMinor", deprecatedMinor)
|
||||
|
||||
if !isGAVersion || hasDeprecated {
|
||||
a = a.
|
||||
With("deprecatedMajor", deprecatedMajor).
|
||||
With("deprecatedMinor", deprecatedMinor)
|
||||
}
|
||||
|
||||
// compute based on our policy
|
||||
removedMajor := deprecatedMajor
|
||||
removedMinor := deprecatedMinor + 3
|
||||
// if someone intentionally override the removed release
|
||||
if tagExists(removedTagName, t) {
|
||||
if hasRemoved {
|
||||
_, removedMajor, removedMinor, err = extractRemovedTag(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
a = a.
|
||||
With("removedMajor", removedMajor).
|
||||
With("removedMinor", removedMinor)
|
||||
|
||||
if !isGAVersion || hasRemoved {
|
||||
a = a.
|
||||
With("removedMajor", removedMajor).
|
||||
With("removedMinor", removedMinor)
|
||||
}
|
||||
|
||||
replacementGroup, replacementVersion, replacementKind, hasReplacement, err := extractReplacementTag(t)
|
||||
if err != nil {
|
||||
@ -441,13 +462,17 @@ func (g *genPreleaseLifecycle) GenerateType(c *generator.Context, t *types.Type,
|
||||
sw.Do(" return $.introducedMajor$, $.introducedMinor$\n", args)
|
||||
sw.Do("}\n\n", nil)
|
||||
}
|
||||
if versionedMethodOrDie("APILifecycleDeprecated", t) == nil {
|
||||
sw.Do("// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison.\n", args)
|
||||
sw.Do("// It is controlled by \""+deprecatedTagName+"\" tags in types.go or \""+introducedTagName+"\" plus three minor.\n", args)
|
||||
sw.Do("func (in *$.type|intrapackage$) APILifecycleDeprecated() (major, minor int) {\n", args)
|
||||
sw.Do(" return $.deprecatedMajor$, $.deprecatedMinor$\n", args)
|
||||
sw.Do("}\n\n", nil)
|
||||
|
||||
if _, hasDeprecated := args["deprecatedMajor"]; hasDeprecated {
|
||||
if versionedMethodOrDie("APILifecycleDeprecated", t) == nil {
|
||||
sw.Do("// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison.\n", args)
|
||||
sw.Do("// It is controlled by \""+deprecatedTagName+"\" tags in types.go or \""+introducedTagName+"\" plus three minor.\n", args)
|
||||
sw.Do("func (in *$.type|intrapackage$) APILifecycleDeprecated() (major, minor int) {\n", args)
|
||||
sw.Do(" return $.deprecatedMajor$, $.deprecatedMinor$\n", args)
|
||||
sw.Do("}\n\n", nil)
|
||||
}
|
||||
}
|
||||
|
||||
if _, hasReplacement := args["replacementKind"]; hasReplacement {
|
||||
if versionedMethodOrDie("APILifecycleReplacement", t) == nil {
|
||||
sw.Do("// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type.\n", args)
|
||||
@ -457,12 +482,15 @@ func (g *genPreleaseLifecycle) GenerateType(c *generator.Context, t *types.Type,
|
||||
sw.Do("}\n\n", nil)
|
||||
}
|
||||
}
|
||||
if versionedMethodOrDie("APILifecycleRemoved", t) == nil {
|
||||
sw.Do("// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison.\n", args)
|
||||
sw.Do("// It is controlled by \""+removedTagName+"\" tags in types.go or \""+deprecatedTagName+"\" plus three minor.\n", args)
|
||||
sw.Do("func (in *$.type|intrapackage$) APILifecycleRemoved() (major, minor int) {\n", args)
|
||||
sw.Do(" return $.removedMajor$, $.removedMinor$\n", args)
|
||||
sw.Do("}\n\n", nil)
|
||||
|
||||
if _, hasRemoved := args["removedMajor"]; hasRemoved {
|
||||
if versionedMethodOrDie("APILifecycleRemoved", t) == nil {
|
||||
sw.Do("// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison.\n", args)
|
||||
sw.Do("// It is controlled by \""+removedTagName+"\" tags in types.go or \""+deprecatedTagName+"\" plus three minor.\n", args)
|
||||
sw.Do("func (in *$.type|intrapackage$) APILifecycleRemoved() (major, minor int) {\n", args)
|
||||
sw.Do(" return $.removedMajor$, $.removedMinor$\n", args)
|
||||
sw.Do("}\n\n", nil)
|
||||
}
|
||||
}
|
||||
|
||||
return sw.Error()
|
||||
|
@ -20,8 +20,11 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"k8s.io/gengo/v2/generator"
|
||||
"k8s.io/gengo/v2/types"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
@ -34,6 +37,248 @@ var mockType = &types.Type{
|
||||
SecondClosestCommentLines: []string{},
|
||||
}
|
||||
|
||||
func TestArgsFromType(t *testing.T) {
|
||||
type testcase struct {
|
||||
name string
|
||||
t *types.Type
|
||||
expected generator.Args
|
||||
expectedError string
|
||||
}
|
||||
|
||||
tests := []testcase{
|
||||
{
|
||||
name: "no comments",
|
||||
t: &types.Type{
|
||||
Name: types.Name{
|
||||
Name: "Simple",
|
||||
Package: "k8s.io/apis/core/v1",
|
||||
},
|
||||
},
|
||||
expectedError: `missing`,
|
||||
},
|
||||
{
|
||||
name: "GA type",
|
||||
t: &types.Type{
|
||||
Name: types.Name{
|
||||
Name: "Simple",
|
||||
Package: "k8s.io/apis/core/v1",
|
||||
},
|
||||
CommentLines: []string{
|
||||
"+k8s:prerelease-lifecycle-gen:introduced=1.5",
|
||||
},
|
||||
},
|
||||
expected: generator.Args{
|
||||
"introducedMajor": 1,
|
||||
"introducedMinor": 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "GA type v2",
|
||||
t: &types.Type{
|
||||
Name: types.Name{
|
||||
Name: "Simple",
|
||||
Package: "k8s.io/apis/core/v2",
|
||||
},
|
||||
CommentLines: []string{
|
||||
"+k8s:prerelease-lifecycle-gen:introduced=1.5",
|
||||
},
|
||||
},
|
||||
expected: generator.Args{
|
||||
"introducedMajor": 1,
|
||||
"introducedMinor": 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "GA type - explicit deprecated",
|
||||
t: &types.Type{
|
||||
Name: types.Name{
|
||||
Name: "Simple",
|
||||
Package: "k8s.io/apis/core/v1",
|
||||
},
|
||||
CommentLines: []string{
|
||||
"+k8s:prerelease-lifecycle-gen:introduced=1.5",
|
||||
"+k8s:prerelease-lifecycle-gen:deprecated=1.7",
|
||||
},
|
||||
},
|
||||
expected: generator.Args{
|
||||
"introducedMajor": 1,
|
||||
"introducedMinor": 5,
|
||||
"deprecatedMajor": 1,
|
||||
"deprecatedMinor": 7,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "GA type - explicit removed",
|
||||
t: &types.Type{
|
||||
Name: types.Name{
|
||||
Name: "Simple",
|
||||
Package: "k8s.io/apis/core/v1",
|
||||
},
|
||||
CommentLines: []string{
|
||||
"+k8s:prerelease-lifecycle-gen:introduced=1.5",
|
||||
"+k8s:prerelease-lifecycle-gen:removed=1.9",
|
||||
},
|
||||
},
|
||||
expected: generator.Args{
|
||||
"introducedMajor": 1,
|
||||
"introducedMinor": 5,
|
||||
"removedMajor": 1,
|
||||
"removedMinor": 9,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "GA type - explicit",
|
||||
t: &types.Type{
|
||||
Name: types.Name{
|
||||
Name: "Simple",
|
||||
Package: "k8s.io/apis/core/v1",
|
||||
},
|
||||
CommentLines: []string{
|
||||
"+k8s:prerelease-lifecycle-gen:introduced=1.5",
|
||||
"+k8s:prerelease-lifecycle-gen:deprecated=1.7",
|
||||
"+k8s:prerelease-lifecycle-gen:removed=1.9",
|
||||
},
|
||||
},
|
||||
expected: generator.Args{
|
||||
"introducedMajor": 1,
|
||||
"introducedMinor": 5,
|
||||
"deprecatedMajor": 1,
|
||||
"deprecatedMinor": 7,
|
||||
"removedMajor": 1,
|
||||
"removedMinor": 9,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "beta type - defaulted",
|
||||
t: &types.Type{
|
||||
Name: types.Name{
|
||||
Name: "Simple",
|
||||
Package: "k8s.io/apis/core/v1beta1",
|
||||
},
|
||||
CommentLines: []string{
|
||||
"+k8s:prerelease-lifecycle-gen:introduced=1.5",
|
||||
},
|
||||
},
|
||||
expected: generator.Args{
|
||||
"introducedMajor": 1,
|
||||
"introducedMinor": 5,
|
||||
"deprecatedMajor": 1,
|
||||
"deprecatedMinor": 8,
|
||||
"removedMajor": 1,
|
||||
"removedMinor": 11,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "beta type - explicit",
|
||||
t: &types.Type{
|
||||
Name: types.Name{
|
||||
Name: "Simple",
|
||||
Package: "k8s.io/apis/core/v1beta1",
|
||||
},
|
||||
CommentLines: []string{
|
||||
"+k8s:prerelease-lifecycle-gen:introduced=1.5",
|
||||
"+k8s:prerelease-lifecycle-gen:deprecated=1.7",
|
||||
"+k8s:prerelease-lifecycle-gen:removed=1.9",
|
||||
},
|
||||
},
|
||||
expected: generator.Args{
|
||||
"introducedMajor": 1,
|
||||
"introducedMinor": 5,
|
||||
"deprecatedMajor": 1,
|
||||
"deprecatedMinor": 7,
|
||||
"removedMajor": 1,
|
||||
"removedMinor": 9,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "beta type - explicit deprecated only",
|
||||
t: &types.Type{
|
||||
Name: types.Name{
|
||||
Name: "Simple",
|
||||
Package: "k8s.io/apis/core/v1beta1",
|
||||
},
|
||||
CommentLines: []string{
|
||||
"+k8s:prerelease-lifecycle-gen:introduced=1.5",
|
||||
"+k8s:prerelease-lifecycle-gen:deprecated=1.7",
|
||||
},
|
||||
},
|
||||
expected: generator.Args{
|
||||
"introducedMajor": 1,
|
||||
"introducedMinor": 5,
|
||||
"deprecatedMajor": 1,
|
||||
"deprecatedMinor": 7,
|
||||
"removedMajor": 1,
|
||||
"removedMinor": 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "beta type - explicit removed only",
|
||||
t: &types.Type{
|
||||
Name: types.Name{
|
||||
Name: "Simple",
|
||||
Package: "k8s.io/apis/core/v1beta1",
|
||||
},
|
||||
CommentLines: []string{
|
||||
"+k8s:prerelease-lifecycle-gen:introduced=1.5",
|
||||
"+k8s:prerelease-lifecycle-gen:removed=1.9",
|
||||
},
|
||||
},
|
||||
expected: generator.Args{
|
||||
"introducedMajor": 1,
|
||||
"introducedMinor": 5,
|
||||
"deprecatedMajor": 1,
|
||||
"deprecatedMinor": 8,
|
||||
"removedMajor": 1,
|
||||
"removedMinor": 9,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "alpha type - defaulted",
|
||||
t: &types.Type{
|
||||
Name: types.Name{
|
||||
Name: "Simple",
|
||||
Package: "k8s.io/apis/core/v1alpha1",
|
||||
},
|
||||
CommentLines: []string{
|
||||
"+k8s:prerelease-lifecycle-gen:introduced=1.5",
|
||||
},
|
||||
},
|
||||
expected: generator.Args{
|
||||
"introducedMajor": 1,
|
||||
"introducedMinor": 5,
|
||||
"deprecatedMajor": 1,
|
||||
"deprecatedMinor": 8,
|
||||
"removedMajor": 1,
|
||||
"removedMinor": 11,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if test.expected != nil {
|
||||
test.expected["type"] = test.t
|
||||
}
|
||||
gen := genPreleaseLifecycle{}
|
||||
args, err := gen.argsFromType(nil, test.t)
|
||||
if test.expectedError != "" {
|
||||
if err == nil {
|
||||
t.Errorf("expected error, got none")
|
||||
} else if !strings.Contains(err.Error(), test.expectedError) {
|
||||
t.Errorf("expected error %q, got %q", test.expectedError, err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if diff := cmp.Diff(test.expected, args); diff != "" {
|
||||
t.Error(diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_extractKubeVersionTag(t *testing.T) {
|
||||
oldKlogOsExit := klog.OsExit
|
||||
defer func() {
|
||||
|
Loading…
Reference in New Issue
Block a user