-
Notifications
You must be signed in to change notification settings - Fork 54
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
Adds linting CI workflow #264
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT | ||
|
||
go 1.19 | ||
|
||
require github.com/golangci/golangci-lint v1.53.3 // cmd/golangci-lint |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
name: sanity | ||
|
||
on: | ||
workflow_dispatch: | ||
pull_request: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
verify: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- uses: actions/setup-go@v4 | ||
with: | ||
go-version-file: "go.mod" | ||
- name: Run verification checks | ||
run: make verify | ||
lint: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- uses: actions/setup-go@v4 | ||
with: | ||
go-version-file: "go.mod" | ||
|
||
- name: Run golangci linting checks | ||
run: make lint GOLANGCI_LINT_ARGS="--out-format github-actions" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
run: | ||
# Default timeout is 1m, up to give more room | ||
timeout: 4m | ||
|
||
linters: | ||
enable: | ||
- asciicheck | ||
- bodyclose | ||
- errorlint | ||
- ginkgolinter | ||
- gofmt | ||
- goimports | ||
- gosec | ||
- importas | ||
- misspell | ||
- nestif | ||
- nonamedreturns | ||
- prealloc | ||
- revive | ||
- stylecheck | ||
- tparallel | ||
- unconvert | ||
- unparam | ||
- unused | ||
- whitespace | ||
|
||
linters-settings: | ||
errorlint: | ||
errorf: false | ||
|
||
importas: | ||
alias: | ||
- pkg: k8s.io/apimachinery/pkg/apis/meta/v1 | ||
alias: metav1 | ||
- pkg: k8s.io/apimachinery/pkg/api/errors | ||
alias: apierrors | ||
- pkg: k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 | ||
alias: apiextensionsv1 | ||
- pkg: k8s.io/apimachinery/pkg/util/runtime | ||
alias: utilruntime | ||
- pkg: "^k8s\\.io/api/([^/]+)/(v[^/]+)$" | ||
alias: $1$2 | ||
- pkg: sigs.k8s.io/controller-runtime | ||
alias: ctrl | ||
- pkg: github.com/operator-framework/rukpak/api/v1alpha1 | ||
alias: rukpakv1alpha1 | ||
goimports: | ||
local-prefixes: github.com/operator-framework/operator-controller | ||
|
||
output: | ||
format: tab |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,7 +41,7 @@ import ( | |
|
||
operatorsv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1" | ||
"github.com/operator-framework/operator-controller/internal/controllers/validators" | ||
"github.com/operator-framework/operator-controller/internal/resolution/variable_sources/bundles_and_dependencies" | ||
"github.com/operator-framework/operator-controller/internal/resolution/variable_sources/bundlesanddependencies" | ||
"github.com/operator-framework/operator-controller/internal/resolution/variable_sources/entity" | ||
) | ||
|
||
|
@@ -107,6 +107,12 @@ func checkForUnexpectedFieldChange(a, b operatorsv1alpha1.Operator) bool { | |
} | ||
|
||
// Helper function to do the actual reconcile | ||
// | ||
// Today we always return ctrl.Result{} and an error. | ||
// But in the future we might update this function | ||
// to return different results (e.g. requeue). | ||
// | ||
//nolint:unparam | ||
func (r *OperatorReconciler) reconcile(ctx context.Context, op *operatorsv1alpha1.Operator) (ctrl.Result, error) { | ||
// validate spec | ||
if err := validators.ValidateOperatorSpec(op); err != nil { | ||
|
@@ -241,7 +247,7 @@ func mapBDStatusToInstalledCondition(existingTypedBundleDeployment *rukpakv1alph | |
func (r *OperatorReconciler) getBundleEntityFromSolution(solution *solver.Solution, packageName string) (*entity.BundleEntity, error) { | ||
for _, variable := range solution.SelectedVariables() { | ||
switch v := variable.(type) { | ||
case *bundles_and_dependencies.BundleVariable: | ||
case *bundlesanddependencies.BundleVariable: | ||
entityPkgName, err := v.BundleEntity().PackageName() | ||
if err != nil { | ||
return nil, err | ||
|
@@ -348,31 +354,6 @@ func (r *OperatorReconciler) existingBundleDeploymentUnstructured(ctx context.Co | |
return &unstructured.Unstructured{Object: unstrExistingBundleDeploymentObj}, nil | ||
} | ||
|
||
// verifyBDStatus reads the various possibilities of status in bundle deployment and translates | ||
// into corresponding operator condition status and message. | ||
func verifyBDStatus(dep *rukpakv1alpha1.BundleDeployment) (metav1.ConditionStatus, string) { | ||
isValidBundleCond := apimeta.FindStatusCondition(dep.Status.Conditions, rukpakv1alpha1.TypeHasValidBundle) | ||
isInstalledCond := apimeta.FindStatusCondition(dep.Status.Conditions, rukpakv1alpha1.TypeInstalled) | ||
|
||
if isValidBundleCond != nil && isValidBundleCond.Status == metav1.ConditionFalse { | ||
return metav1.ConditionFalse, isValidBundleCond.Message | ||
} | ||
|
||
if isInstalledCond != nil && isInstalledCond.Status == metav1.ConditionFalse { | ||
return metav1.ConditionFalse, isInstalledCond.Message | ||
} | ||
|
||
if isInstalledCond != nil && isInstalledCond.Status == metav1.ConditionTrue { | ||
return metav1.ConditionTrue, "install was successful" | ||
} | ||
return metav1.ConditionUnknown, fmt.Sprintf("could not determine the state of BundleDeployment %s", dep.Name) | ||
} | ||
|
||
// isBundleDepStale returns true if conditions are out of date. | ||
func isBundleDepStale(bd *rukpakv1alpha1.BundleDeployment) bool { | ||
return bd != nil && bd.Status.ObservedGeneration != bd.GetGeneration() | ||
} | ||
|
||
Comment on lines
-351
to
-375
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was all this unused code? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep |
||
// mapBundleMediaTypeToBundleProvisioner maps an olm.bundle.mediatype property to a | ||
// rukpak bundle provisioner class name that is capable of unpacking the bundle type | ||
func mapBundleMediaTypeToBundleProvisioner(mediaType string) (string, error) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1061,8 +1061,7 @@ var _ = Describe("Operator Controller Test", func() { | |
|
||
func verifyInvariants(ctx context.Context, c client.Client, op *operatorsv1alpha1.Operator) { | ||
key := client.ObjectKeyFromObject(op) | ||
err := c.Get(ctx, key, op) | ||
Expect(err).To(BeNil()) | ||
Expect(c.Get(ctx, key, op)).To(Succeed()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see a few other places where we're using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As far as I understand In general, I'm not a big fan of Ginkgo & Gomega because there are usually 10 ways to do the same. |
||
|
||
verifyConditionsInvariants(op) | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,10 +94,10 @@ var _ = AfterSuite(func() { | |
}) | ||
|
||
func namesFromList(list client.ObjectList) []string { | ||
var names []string | ||
|
||
items, err := meta.ExtractList(list) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
names := make([]string, 0, len(items)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Preallocation of the slice. There are few other places like this |
||
for _, item := range items { | ||
names = append(names, item.(client.Object).GetName()) | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,67 +5,66 @@ import ( | |
"encoding/json" | ||
"fmt" | ||
|
||
catalogd "github.com/operator-framework/catalogd/api/core/v1alpha1" | ||
"github.com/operator-framework/deppy/pkg/deppy" | ||
"github.com/operator-framework/deppy/pkg/deppy/input" | ||
"github.com/operator-framework/operator-controller/internal/resolution/variable_sources/entity" | ||
"github.com/operator-framework/operator-registry/alpha/property" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
|
||
catalogd "github.com/operator-framework/catalogd/api/core/v1alpha1" | ||
"github.com/operator-framework/operator-controller/internal/resolution/variable_sources/entity" | ||
) | ||
|
||
// catalogdEntitySource is a source for(/collection of) deppy defined input.Entity, built from content | ||
// CatalogdEntitySource is a source for(/collection of) deppy defined input.Entity, built from content | ||
// made accessible on-cluster by https://github.com/operator-framework/catalogd. | ||
// It is an implementation of deppy defined input.EntitySource | ||
type catalogdEntitySource struct { | ||
type CatalogdEntitySource struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
client client.Client | ||
} | ||
|
||
func NewCatalogdEntitySource(client client.Client) *catalogdEntitySource { | ||
|
||
return &catalogdEntitySource{client: client} | ||
func NewCatalogdEntitySource(client client.Client) *CatalogdEntitySource { | ||
return &CatalogdEntitySource{client: client} | ||
} | ||
|
||
func (es *catalogdEntitySource) Get(ctx context.Context, id deppy.Identifier) (*input.Entity, error) { | ||
func (es *CatalogdEntitySource) Get(_ context.Context, _ deppy.Identifier) (*input.Entity, error) { | ||
panic("not implemented") | ||
} | ||
|
||
func (es *catalogdEntitySource) Filter(ctx context.Context, filter input.Predicate) (input.EntityList, error) { | ||
func (es *CatalogdEntitySource) Filter(ctx context.Context, filter input.Predicate) (input.EntityList, error) { | ||
resultSet := input.EntityList{} | ||
entities, err := getEntities(ctx, es.client) | ||
if err != nil { | ||
return nil, err | ||
} | ||
for _, entity := range entities { | ||
if filter(&entity) { | ||
resultSet = append(resultSet, entity) | ||
for i := range entities { | ||
if filter(&entities[i]) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. gosec: G601: Implicit memory aliasing in for loop. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 on this fix. However it makes me wonder... is it necessary or important that |
||
resultSet = append(resultSet, entities[i]) | ||
} | ||
} | ||
return resultSet, nil | ||
} | ||
|
||
func (es *catalogdEntitySource) GroupBy(ctx context.Context, fn input.GroupByFunction) (input.EntityListMap, error) { | ||
func (es *CatalogdEntitySource) GroupBy(ctx context.Context, fn input.GroupByFunction) (input.EntityListMap, error) { | ||
entities, err := getEntities(ctx, es.client) | ||
if err != nil { | ||
return nil, err | ||
} | ||
resultSet := input.EntityListMap{} | ||
for _, entity := range entities { | ||
keys := fn(&entity) | ||
for i := range entities { | ||
keys := fn(&entities[i]) | ||
for _, key := range keys { | ||
resultSet[key] = append(resultSet[key], entity) | ||
resultSet[key] = append(resultSet[key], entities[i]) | ||
} | ||
} | ||
return resultSet, nil | ||
} | ||
|
||
func (es *catalogdEntitySource) Iterate(ctx context.Context, fn input.IteratorFunction) error { | ||
func (es *CatalogdEntitySource) Iterate(ctx context.Context, fn input.IteratorFunction) error { | ||
entities, err := getEntities(ctx, es.client) | ||
if err != nil { | ||
return err | ||
} | ||
for _, entity := range entities { | ||
if err := fn(&entity); err != nil { | ||
for i := range entities { | ||
if err := fn(&entities[i]); err != nil { | ||
return err | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as in rukpak (see this thread).