-
Notifications
You must be signed in to change notification settings - Fork 9
Adds nophase linter #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
JoelSpeed
merged 4 commits into
kubernetes-sigs:main
from
theobarberbany:tb/statussubresource
Dec 11, 2024
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package nophase | ||
|
||
import ( | ||
"errors" | ||
"go/ast" | ||
"strings" | ||
|
||
"github.com/JoelSpeed/kal/pkg/analysis/helpers/extractjsontags" | ||
"golang.org/x/tools/go/analysis" | ||
"golang.org/x/tools/go/analysis/passes/inspect" | ||
"golang.org/x/tools/go/ast/inspector" | ||
) | ||
|
||
const name = "nophase" | ||
|
||
var ( | ||
errCouldNotGetInspector = errors.New("could not get inspector") | ||
errCouldNotGetJSONTags = errors.New("could not get json tags") | ||
) | ||
|
||
// Analyzer is the analyzer for the nophase package. | ||
// It checks that no struct fields named 'phase', or that contain phase as a | ||
// substring are present. | ||
var Analyzer = &analysis.Analyzer{ | ||
Name: name, | ||
Doc: "phase fields are deprecated and conditions should be preferred, avoid phase like enum fields", | ||
Run: run, | ||
Requires: []*analysis.Analyzer{inspect.Analyzer, extractjsontags.Analyzer}, | ||
} | ||
|
||
func run(pass *analysis.Pass) (interface{}, error) { | ||
inspect, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) | ||
if !ok { | ||
return nil, errCouldNotGetInspector | ||
} | ||
|
||
jsonTags, ok := pass.ResultOf[extractjsontags.Analyzer].(extractjsontags.StructFieldTags) | ||
if !ok { | ||
return nil, errCouldNotGetJSONTags | ||
} | ||
|
||
// Filter to structs so that we can iterate over fields in a struct. | ||
nodeFilter := []ast.Node{ | ||
(*ast.StructType)(nil), | ||
} | ||
|
||
// Preorder visits all the nodes of the AST in depth-first order. It calls | ||
// f(n) for each node n before it visits n's children. | ||
// | ||
// We use the filter defined above, ensuring we only look at struct fields. | ||
inspect.Preorder(nodeFilter, func(n ast.Node) { | ||
sTyp, ok := n.(*ast.StructType) | ||
if !ok { | ||
return | ||
} | ||
|
||
if sTyp.Fields == nil { | ||
return | ||
} | ||
|
||
for _, field := range sTyp.Fields.List { | ||
if field == nil || len(field.Names) == 0 { | ||
continue | ||
} | ||
|
||
fieldName := field.Names[0].Name | ||
|
||
// First check if the struct field name contains 'phase' | ||
if strings.Contains(strings.ToLower(fieldName), "phase") { | ||
pass.Reportf(field.Pos(), | ||
"field %s: phase fields are deprecated and conditions should be preferred, avoid phase like enum fields", | ||
fieldName, | ||
) | ||
|
||
continue | ||
} | ||
|
||
// Then check if the json serialization of the field contains 'phase' | ||
tagInfo := jsonTags.FieldTags(sTyp, fieldName) | ||
|
||
if strings.Contains(strings.ToLower(tagInfo.Name), "phase") { | ||
pass.Reportf(field.Pos(), | ||
"field %s: phase fields are deprecated and conditions should be preferred, avoid phase like enum fields", | ||
fieldName, | ||
) | ||
} | ||
} | ||
}) | ||
|
||
return nil, nil //nolint:nilnil | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package nophase_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/JoelSpeed/kal/pkg/analysis/nophase" | ||
"golang.org/x/tools/go/analysis/analysistest" | ||
) | ||
|
||
func Test(t *testing.T) { | ||
testdata := analysistest.TestData() | ||
analysistest.RunWithSuggestedFixes(t, testdata, nophase.Analyzer, "a") | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/* | ||
nophase provides a linter to ensure that structs do not contain a Phase field. | ||
|
||
Phase fields are deprecated and conditions should be preferred. Avoid phase like enum | ||
fields. | ||
|
||
The linter will flag any struct field containing the substring 'phase'. This means both | ||
Phase and FooPhase will be flagged. | ||
*/ | ||
|
||
package nophase |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package nophase | ||
|
||
import ( | ||
"github.com/JoelSpeed/kal/pkg/config" | ||
"golang.org/x/tools/go/analysis" | ||
) | ||
|
||
// Initializer returns the AnalyzerInitializer for this | ||
// Analyzer so that it can be added to the registry. | ||
func Initializer() initializer { | ||
return initializer{} | ||
} | ||
|
||
// intializer implements the AnalyzerInitializer interface. | ||
type initializer struct{} | ||
|
||
// Name returns the name of the Analyzer. | ||
func (initializer) Name() string { | ||
return name | ||
} | ||
|
||
// Init returns the intialized Analyzer. | ||
func (initializer) Init(cfg config.LintersConfig) (*analysis.Analyzer, error) { | ||
return Analyzer, nil | ||
} | ||
|
||
// Default determines whether this Analyzer is on by default, or not. | ||
func (initializer) Default() bool { | ||
return true | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package a | ||
|
||
type NoPhaseTestStruct struct { | ||
// +optional | ||
Phase *string `json:"phase,omitempty"` // want "field Phase: phase fields are deprecated and conditions should be preferred, avoid phase like enum fields" | ||
theobarberbany marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
} | ||
|
||
type NoSubPhaseTestStruct struct { | ||
// +optional | ||
FooPhase *string `json:"fooPhase,omitempty"` // want "field FooPhase: phase fields are deprecated and conditions should be preferred, avoid phase like enum fields" | ||
|
||
} | ||
|
||
type SerializedPhaseTeststruct struct { | ||
// +optional | ||
FooField *string `json:"fooPhase,omitempty"` // want "field FooField: phase fields are deprecated and conditions should be preferred, avoid phase like enum fields" | ||
|
||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.