mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 08:17:26 +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"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path"
|
"path"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -364,6 +365,10 @@ func (g *genPreleaseLifecycle) Imports(c *generator.Context) (imports []string)
|
|||||||
return importLines
|
return importLines
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
isGAVersionRegex = regexp.MustCompile(`^v\d+$`)
|
||||||
|
)
|
||||||
|
|
||||||
func (g *genPreleaseLifecycle) argsFromType(c *generator.Context, t *types.Type) (generator.Args, error) {
|
func (g *genPreleaseLifecycle) argsFromType(c *generator.Context, t *types.Type) (generator.Args, error) {
|
||||||
a := generator.Args{
|
a := generator.Args{
|
||||||
"type": t,
|
"type": t,
|
||||||
@ -372,37 +377,53 @@ func (g *genPreleaseLifecycle) argsFromType(c *generator.Context, t *types.Type)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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.
|
a = a.
|
||||||
With("introducedMajor", introducedMajor).
|
With("introducedMajor", introducedMajor).
|
||||||
With("introducedMinor", introducedMinor)
|
With("introducedMinor", introducedMinor)
|
||||||
|
|
||||||
// compute based on our policy
|
// compute based on our policy
|
||||||
|
hasDeprecated := tagExists(deprecatedTagName, t)
|
||||||
|
hasRemoved := tagExists(removedTagName, t)
|
||||||
|
|
||||||
deprecatedMajor := introducedMajor
|
deprecatedMajor := introducedMajor
|
||||||
deprecatedMinor := introducedMinor + 3
|
deprecatedMinor := introducedMinor + 3
|
||||||
// if someone intentionally override the deprecation release
|
// if someone intentionally override the deprecation release
|
||||||
if tagExists(deprecatedTagName, t) {
|
if hasDeprecated {
|
||||||
_, deprecatedMajor, deprecatedMinor, err = extractDeprecatedTag(t)
|
_, deprecatedMajor, deprecatedMinor, err = extractDeprecatedTag(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a = a.
|
|
||||||
With("deprecatedMajor", deprecatedMajor).
|
if !isGAVersion || hasDeprecated {
|
||||||
With("deprecatedMinor", deprecatedMinor)
|
a = a.
|
||||||
|
With("deprecatedMajor", deprecatedMajor).
|
||||||
|
With("deprecatedMinor", deprecatedMinor)
|
||||||
|
}
|
||||||
|
|
||||||
// compute based on our policy
|
// compute based on our policy
|
||||||
removedMajor := deprecatedMajor
|
removedMajor := deprecatedMajor
|
||||||
removedMinor := deprecatedMinor + 3
|
removedMinor := deprecatedMinor + 3
|
||||||
// if someone intentionally override the removed release
|
// if someone intentionally override the removed release
|
||||||
if tagExists(removedTagName, t) {
|
if hasRemoved {
|
||||||
_, removedMajor, removedMinor, err = extractRemovedTag(t)
|
_, removedMajor, removedMinor, err = extractRemovedTag(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a = a.
|
|
||||||
With("removedMajor", removedMajor).
|
if !isGAVersion || hasRemoved {
|
||||||
With("removedMinor", removedMinor)
|
a = a.
|
||||||
|
With("removedMajor", removedMajor).
|
||||||
|
With("removedMinor", removedMinor)
|
||||||
|
}
|
||||||
|
|
||||||
replacementGroup, replacementVersion, replacementKind, hasReplacement, err := extractReplacementTag(t)
|
replacementGroup, replacementVersion, replacementKind, hasReplacement, err := extractReplacementTag(t)
|
||||||
if err != nil {
|
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(" return $.introducedMajor$, $.introducedMinor$\n", args)
|
||||||
sw.Do("}\n\n", nil)
|
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)
|
if _, hasDeprecated := args["deprecatedMajor"]; hasDeprecated {
|
||||||
sw.Do("// It is controlled by \""+deprecatedTagName+"\" tags in types.go or \""+introducedTagName+"\" plus three minor.\n", args)
|
if versionedMethodOrDie("APILifecycleDeprecated", t) == nil {
|
||||||
sw.Do("func (in *$.type|intrapackage$) APILifecycleDeprecated() (major, minor int) {\n", args)
|
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(" return $.deprecatedMajor$, $.deprecatedMinor$\n", args)
|
sw.Do("// It is controlled by \""+deprecatedTagName+"\" tags in types.go or \""+introducedTagName+"\" plus three minor.\n", args)
|
||||||
sw.Do("}\n\n", nil)
|
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 _, hasReplacement := args["replacementKind"]; hasReplacement {
|
||||||
if versionedMethodOrDie("APILifecycleReplacement", t) == nil {
|
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)
|
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)
|
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)
|
if _, hasRemoved := args["removedMajor"]; hasRemoved {
|
||||||
sw.Do("// It is controlled by \""+removedTagName+"\" tags in types.go or \""+deprecatedTagName+"\" plus three minor.\n", args)
|
if versionedMethodOrDie("APILifecycleRemoved", t) == nil {
|
||||||
sw.Do("func (in *$.type|intrapackage$) APILifecycleRemoved() (major, minor int) {\n", args)
|
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(" return $.removedMajor$, $.removedMinor$\n", args)
|
sw.Do("// It is controlled by \""+removedTagName+"\" tags in types.go or \""+deprecatedTagName+"\" plus three minor.\n", args)
|
||||||
sw.Do("}\n\n", nil)
|
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()
|
return sw.Error()
|
||||||
|
@ -20,8 +20,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"k8s.io/gengo/v2/generator"
|
||||||
"k8s.io/gengo/v2/types"
|
"k8s.io/gengo/v2/types"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
)
|
)
|
||||||
@ -34,6 +37,248 @@ var mockType = &types.Type{
|
|||||||
SecondClosestCommentLines: []string{},
|
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) {
|
func Test_extractKubeVersionTag(t *testing.T) {
|
||||||
oldKlogOsExit := klog.OsExit
|
oldKlogOsExit := klog.OsExit
|
||||||
defer func() {
|
defer func() {
|
||||||
|
Loading…
Reference in New Issue
Block a user