chore: add modernize tool integration for code modernization (#9251)

Co-authored-by: knqyf263 <knqyf263@users.noreply.github.com>
This commit is contained in:
Teppei Fukuda
2025-07-29 11:13:54 +04:00
committed by GitHub
parent 54832a77b5
commit d2d0ec2b6d
68 changed files with 145 additions and 216 deletions

6
go.mod
View File

@@ -453,9 +453,10 @@ require (
golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sys v0.34.0 // indirect
golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7 // indirect
golang.org/x/telemetry v0.0.0-20250417124945-06ef541f3fa3 // indirect
golang.org/x/time v0.12.0 // indirect
golang.org/x/tools v0.34.0 // indirect
golang.org/x/tools v0.34.1-0.20250610205101-c26dd3ba555e // indirect
golang.org/x/tools/gopls v0.19.1 // indirect
google.golang.org/api v0.228.0 // indirect
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
@@ -497,5 +498,6 @@ tool (
github.com/magefile/mage
github.com/twitchtv/twirp/protoc-gen-twirp
golang.org/x/tools/cmd/goyacc
golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize
sigs.k8s.io/kind
)

10
go.sum
View File

@@ -2469,8 +2469,8 @@ golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7 h1:FemxDzfMUcK2f3YY4H+05K9CDzbSVr2+q/JKN45pey0=
golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
golang.org/x/telemetry v0.0.0-20250417124945-06ef541f3fa3 h1:RXY2+rSHXvxO2Y+gKrPjYVaEoGOqh3VEXFhnWAt1Irg=
golang.org/x/telemetry v0.0.0-20250417124945-06ef541f3fa3/go.mod h1:RoaXAWDwS90j6FxVKwJdBV+0HCU+llrKUGgJaxiKl6M=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -2585,8 +2585,10 @@ golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
golang.org/x/tools v0.34.1-0.20250610205101-c26dd3ba555e h1:XnjOegqwH6kBJoae6InSGbIFPHcLtUT/Eq8HjrZKbmQ=
golang.org/x/tools v0.34.1-0.20250610205101-c26dd3ba555e/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
golang.org/x/tools/gopls v0.19.1 h1:Yodhp3rnpnag60lVZrYPYbGMxTlTCIAj/B2Rv7AKuhA=
golang.org/x/tools/gopls v0.19.1/go.mod h1:wckRFPbJWrG05Cw01SpRSl1vVzIhtK9Yfq60NE3U9Wo=
golang.org/x/vuln v1.1.4 h1:Ju8QsuyhX3Hk8ma3CesTbO8vfJD9EvUBgHvkxHBzj0I=
golang.org/x/vuln v1.1.4/go.mod h1:F+45wmU18ym/ca5PLTPLsSzr2KppzswxPP603ldA67s=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@@ -339,15 +339,21 @@ func (t Test) E2e() error {
type Lint mg.Namespace
// Run runs linters
func (Lint) Run() error {
mg.Deps(Tool{}.GolangciLint)
return sh.RunV("golangci-lint", "run", "--build-tags=integration")
func (l Lint) Run() error {
mg.Deps(Tool{}.GolangciLint, Tool{}.Install)
if err := sh.RunV("golangci-lint", "run", "--build-tags=integration"); err != nil {
return err
}
return sh.RunV("modernize", "./...")
}
// Fix auto fixes linters
func (Lint) Fix() error {
mg.Deps(Tool{}.GolangciLint)
return sh.RunV("golangci-lint", "run", "--fix", "--build-tags=integration")
func (l Lint) Fix() error {
mg.Deps(Tool{}.GolangciLint, Tool{}.Install)
if err := sh.RunV("golangci-lint", "run", "--fix", "--build-tags=integration"); err != nil {
return err
}
return sh.RunV("modernize", "-fix", "./...")
}
// Fmt formats Go code

View File

@@ -80,7 +80,6 @@ func fixtureTerraformPlanSnapshots(ctx context.Context) error {
g.SetLimit(terraformParallelLimit)
for _, workingDir := range workingDirs {
workingDir := workingDir
g.Go(func() error {
if err := os.Remove(tfplanFile); err != nil && !errors.Is(err, os.ErrNotExist) {
return err

16
pkg/cache/fs_test.go vendored
View File

@@ -227,9 +227,7 @@ func TestFSCache_PutBlob(t *testing.T) {
"Packages": [
{
"Name": "musl",
"Version": "1.1.22-r3",
"Identifier": {},
"Layer": {}
"Version": "1.1.22-r3"
}
]
}
@@ -241,15 +239,11 @@ func TestFSCache_PutBlob(t *testing.T) {
"Packages": [
{
"Name":"guzzlehttp/guzzle",
"Version":"6.2.0",
"Identifier": {},
"Layer": {}
"Version":"6.2.0"
},
{
"Name":"guzzlehttp/promises",
"Version":"v1.3.1",
"Identifier": {},
"Layer": {}
"Version":"v1.3.1"
}
]
}
@@ -347,9 +341,7 @@ func TestFSCache_PutArtifact(t *testing.T) {
"HistoryPackages": [
{
"Name": "musl",
"Version": "1.2.3",
"Identifier": {},
"Layer": {}
"Version": "1.2.3"
}
]
}

View File

@@ -472,7 +472,7 @@ func TestRedisCache_Clear(t *testing.T) {
require.NoError(t, err)
defer s.Close()
for i := 0; i < 200; i++ {
for i := range 200 {
s.Set(fmt.Sprintf("fanal::key%d", i), "value")
}
s.Set("foo", "bar")
@@ -482,7 +482,7 @@ func TestRedisCache_Clear(t *testing.T) {
require.NoError(t, err)
require.NoError(t, c.Clear())
for i := 0; i < 200; i++ {
for i := range 200 {
assert.False(t, s.Exists(fmt.Sprintf("fanal::key%d", i)))
}
assert.True(t, s.Exists("foo"))

View File

@@ -125,7 +125,6 @@ func loadPluginCommands() []*cobra.Command {
return nil
}
for _, p := range plugins {
p := p
cmd := &cobra.Command{
Use: fmt.Sprintf("%s [flags]", p.Name),
Short: p.Summary,

View File

@@ -18,14 +18,7 @@
"Misconfigurations": [
{
"AVDID": "AVD-KSV012",
"Status": "FAIL",
"Layer": {},
"CauseMetadata": {
"Code": {
"Lines": null
},
"RenderedCause": {}
}
"Status": "FAIL"
}
]
}
@@ -42,14 +35,7 @@
"Misconfigurations": [
{
"AVDID": "AVD-KSV013",
"Status": "FAIL",
"Layer": {},
"CauseMetadata": {
"Code": {
"Lines": null
},
"RenderedCause": {}
}
"Status": "FAIL"
}
]
}

View File

@@ -88,8 +88,8 @@ func GetComplianceSpec(specNameOrPath, cacheDir string) (ComplianceSpec, error)
var b []byte
var err error
if strings.HasPrefix(specNameOrPath, "@") { // load user specified spec from disk
b, err = os.ReadFile(strings.TrimPrefix(specNameOrPath, "@"))
if after, ok := strings.CutPrefix(specNameOrPath, "@"); ok { // load user specified spec from disk
b, err = os.ReadFile(after)
if err != nil {
return ComplianceSpec{}, fmt.Errorf("error retrieving compliance spec from path: %w", err)
}

View File

@@ -2,7 +2,7 @@ package spec_test
import (
"path/filepath"
"sort"
"slices"
"testing"
"github.com/stretchr/testify/assert"
@@ -129,9 +129,7 @@ func TestComplianceSpec_Scanners(t *testing.T) {
if !tt.wantErr(t, err, "Scanners()") {
return
}
sort.Slice(got, func(i, j int) bool {
return got[i] < got[j]
}) // for consistency
slices.Sort(got) // for consistency
assert.Equalf(t, tt.want, got, "Scanners()")
})
}

View File

@@ -29,8 +29,8 @@ func evaluateVariable(s string, props map[string]string, seenProps []string) str
// env.X: https://maven.apache.org/pom.html#Properties
// e.g. env.PATH
if strings.HasPrefix(m[1], "env.") {
newValue = os.Getenv(strings.TrimPrefix(m[1], "env."))
if after, ok := strings.CutPrefix(m[1], "env."); ok {
newValue = os.Getenv(after)
} else {
// <properties> might include another property.
// e.g. <animal.sniffer.skip>${skipTests}</animal.sniffer.skip>

View File

@@ -2,7 +2,6 @@ package poetry
import (
"slices"
"sort"
"github.com/BurntSushi/toml"
"golang.org/x/xerrors"
@@ -101,9 +100,7 @@ func (p *Parser) parseDependencies(deps map[string]any, pkgVersions map[string][
dependsOn = append(dependsOn, dep)
}
}
sort.Slice(dependsOn, func(i, j int) bool {
return dependsOn[i] < dependsOn[j]
})
slices.Sort(dependsOn)
return dependsOn
}

View File

@@ -48,8 +48,6 @@ func MergeMaps(parent, child map[string]string) map[string]string {
}
// Clone parent map to avoid shadow overwrite
newParent := maps.Clone(parent)
for k, v := range child {
newParent[k] = v
}
maps.Copy(newParent, child)
return newParent
}

View File

@@ -1,6 +1,7 @@
package compare
import (
"slices"
"strings"
"golang.org/x/xerrors"
@@ -20,10 +21,8 @@ type matchVersion func(currentVersion, constraint string) (bool, error)
// IsVulnerable checks if the package version is vulnerable to the advisory.
func IsVulnerable(pkgVer string, advisory dbTypes.Advisory, match matchVersion) bool {
// If one of vulnerable/patched versions is empty, we should detect it anyway.
for _, v := range append(advisory.VulnerableVersions, advisory.PatchedVersions...) {
if v == "" {
return true
}
if slices.Contains(append(advisory.VulnerableVersions, advisory.PatchedVersions...), "") {
return true
}
var matched bool
var err error

View File

@@ -55,10 +55,7 @@ func (d Digest) String() string {
}
func (d Digest) sepIndex() int {
i := strings.Index(string(d), ":")
if i < 0 {
i = 0
}
i := max(strings.Index(string(d), ":"), 0)
return i
}

View File

@@ -2,6 +2,7 @@ package artifact
import (
"context"
"slices"
"sort"
"github.com/google/go-containerregistry/pkg/v1"
@@ -73,9 +74,7 @@ func (o *Option) ConfigAnalyzerOptions() analyzer.ConfigAnalyzerOptions {
}
func (o *Option) Sort() {
sort.Slice(o.DisabledAnalyzers, func(i, j int) bool {
return o.DisabledAnalyzers[i] < o.DisabledAnalyzers[j]
})
slices.Sort(o.DisabledAnalyzers)
sort.Strings(o.WalkerOption.SkipFiles)
sort.Strings(o.WalkerOption.SkipDirs)
sort.Strings(o.FilePatterns)

View File

@@ -223,7 +223,7 @@ func TestArtifact_inspectOCIReferrerSBOM(t *testing.T) {
},
wantBlobs: []cachetest.WantBlob{
{
ID: "sha256:a06ed679a3289fba254040e1ce8f3467fadcc454ee3d0d4720f6978065f56684",
ID: "sha256:2171d8ccf798e94d09aca9c6abf15d28abd3236def1caa4a394b6f0a69c4266d",
BlobInfo: types.BlobInfo{
SchemaVersion: types.BlobJSONSchemaVersion,
Applications: []types.Application{
@@ -267,9 +267,9 @@ func TestArtifact_inspectOCIReferrerSBOM(t *testing.T) {
want: artifact.Reference{
Name: registry + "/test/image:10",
Type: types.TypeCycloneDX,
ID: "sha256:a06ed679a3289fba254040e1ce8f3467fadcc454ee3d0d4720f6978065f56684",
ID: "sha256:2171d8ccf798e94d09aca9c6abf15d28abd3236def1caa4a394b6f0a69c4266d",
BlobIDs: []string{
"sha256:a06ed679a3289fba254040e1ce8f3467fadcc454ee3d0d4720f6978065f56684",
"sha256:2171d8ccf798e94d09aca9c6abf15d28abd3236def1caa4a394b6f0a69c4266d",
},
},
},

View File

@@ -118,16 +118,16 @@ func TestArtifact_Inspect(t *testing.T) {
rootDir: "testdata/alpine",
wantBlobs: []cachetest.WantBlob{
{
ID: "sha256:9ca6dbba47cea74d3f9b0bf0472314735d06f42d3ccf8cfe7c021f61a3420973",
ID: "sha256:c2baf06cb25f7b62686b169df5729402f0c50420bfcbdce8347f84c4bf623ab9",
BlobInfo: expectedBlobInfo,
},
},
want: artifact.Reference{
Name: "rawdata.img",
Type: types.TypeVM,
ID: "sha256:9ca6dbba47cea74d3f9b0bf0472314735d06f42d3ccf8cfe7c021f61a3420973",
ID: "sha256:c2baf06cb25f7b62686b169df5729402f0c50420bfcbdce8347f84c4bf623ab9",
BlobIDs: []string{
"sha256:9ca6dbba47cea74d3f9b0bf0472314735d06f42d3ccf8cfe7c021f61a3420973",
"sha256:c2baf06cb25f7b62686b169df5729402f0c50420bfcbdce8347f84c4bf623ab9",
},
},
},

View File

@@ -42,7 +42,7 @@ func (c RegistryConfig) GetRegistryAuth() (string, error) {
}
func (c RegistryConfig) GetBasicAuthorization() string {
return fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", c.Username, c.Password))))
return fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString(fmt.Appendf(nil, "%s:%s", c.Username, c.Password)))
}
type Docker struct {

View File

@@ -177,7 +177,7 @@ type BlobInfo struct {
WhiteoutFiles []string `json:",omitempty"`
// Analysis result
OS OS `json:",omitempty"`
OS OS `json:",omitzero"`
Repository *Repository `json:",omitempty"`
PackageInfos []PackageInfo `json:",omitempty"`
Applications []Application `json:",omitempty"`
@@ -206,7 +206,7 @@ func (b BlobInfo) Layer() Layer {
// ArtifactDetail represents the analysis result.
type ArtifactDetail struct {
OS OS `json:",omitempty"`
OS OS `json:",omitzero"`
Repository *Repository `json:",omitempty"`
Packages Packages `json:",omitempty"`
Applications Applications `json:",omitempty"`

View File

@@ -27,7 +27,7 @@ type LicenseFile struct {
FilePath string
PkgName string
Findings LicenseFindings
Layer Layer `json:",omitempty"`
Layer Layer `json:",omitzero"`
}
type LicenseFindings []LicenseFinding

View File

@@ -13,15 +13,15 @@ type Misconfiguration struct {
Successes MisconfResults `json:",omitempty"`
Warnings MisconfResults `json:",omitempty"`
Failures MisconfResults `json:",omitempty"`
Layer Layer `json:",omitempty"`
Layer Layer `json:",omitzero"`
}
type MisconfResult struct {
Namespace string `json:",omitempty"`
Query string `json:",omitempty"`
Message string `json:",omitempty"`
PolicyMetadata `json:",omitempty"`
CauseMetadata `json:",omitempty"`
PolicyMetadata `json:",omitzero"`
CauseMetadata `json:",omitzero"`
// For debugging
Traces []string `json:",omitempty"`
@@ -35,9 +35,9 @@ type CauseMetadata struct {
Service string `json:",omitempty"`
StartLine int `json:",omitempty"`
EndLine int `json:",omitempty"`
Code Code `json:",omitempty"`
Code Code `json:",omitzero"`
Occurrences []Occurrence `json:",omitempty"`
RenderedCause RenderedCause `json:",omitempty"`
RenderedCause RenderedCause `json:",omitzero"`
}
type Occurrence struct {

View File

@@ -179,7 +179,7 @@ type BuildInfo struct {
type Package struct {
ID string `json:",omitempty"`
Name string `json:",omitempty"`
Identifier PkgIdentifier `json:",omitempty"`
Identifier PkgIdentifier `json:",omitzero"`
Version string `json:",omitempty"`
Release string `json:",omitempty"`
Epoch int `json:",omitempty"`
@@ -203,7 +203,7 @@ type Package struct {
// Note: it may have interdependencies, which may lead to infinite loops.
DependsOn []string `json:",omitempty"`
Layer Layer `json:",omitempty"`
Layer Layer `json:",omitzero"`
// Each package metadata have the file path, while the package from lock files does not have.
FilePath string `json:",omitempty"`

View File

@@ -16,5 +16,5 @@ type SecretFinding struct {
EndLine int
Code Code
Match string
Layer Layer `json:",omitempty"`
Layer Layer `json:",omitzero"`
}

View File

@@ -54,8 +54,8 @@ func (w LayerTar) Walk(layer io.Reader, analyzeFn WalkFunc) ([]string, []string,
continue
}
// etc/.wh.hostname
if strings.HasPrefix(fileName, wh) {
name := strings.TrimPrefix(fileName, wh)
if after, ok := strings.CutPrefix(fileName, wh); ok {
name := after
fpath := path.Join(fileDir, name)
whFiles = append(whFiles, fpath)
continue

View File

@@ -515,8 +515,8 @@ func BenchmarkIsType_SmallFile(b *testing.B) {
require.NoError(b, err)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
for b.Loop() {
_ = IsType(fmt.Sprintf("./testdata/%s", "small.file"), bytes.NewReader(data), FileTypeAzureARM)
}
}
@@ -526,8 +526,8 @@ func BenchmarkIsType_BigFile(b *testing.B) {
require.NoError(b, err)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
for b.Loop() {
_ = IsType(fmt.Sprintf("./testdata/%s", "big.file"), bytes.NewReader(data), FileTypeAzureARM)
}
}

View File

@@ -237,7 +237,7 @@ func Test_FallbackErrorWithoutLocation(t *testing.T) {
},
}
for i := 0; i < ast.CompileErrorLimitDefault+1; i++ {
for i := range ast.CompileErrorLimitDefault + 1 {
src := `# METADATA
# schemas:
# - input: schema["fooschema"]
@@ -247,7 +247,7 @@ deny {
input.evil == "foo bar"
}`
fsys[fmt.Sprintf("policies/my-check%d.rego", i)] = &fstest.MapFile{
Data: []byte(fmt.Sprintf(src, i)),
Data: fmt.Appendf(nil, src, i),
}
}
@@ -330,7 +330,7 @@ func TestIsMinimumTrivyVersion(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
fsys := fstest.MapFS{
"check.rego": &fstest.MapFile{Data: []byte(fmt.Sprintf(`# METADATA
"check.rego": &fstest.MapFile{Data: fmt.Appendf(nil, `# METADATA
# title: "dummy title"
# description: "some description"
# scope: package
@@ -341,7 +341,7 @@ func TestIsMinimumTrivyVersion(t *testing.T) {
package builtin.foo.ABC123
deny {
input.evil
}`, tc.MinimumTrivyVersion))},
}`, tc.MinimumTrivyVersion)},
}
scanner := rego.NewScanner(
rego.WithPolicyDirs("."),

View File

@@ -3,6 +3,7 @@ package scan
import (
"fmt"
"regexp"
"slices"
"strings"
"golang.org/x/text/cases"
@@ -66,12 +67,7 @@ func (r Rule) HasID(id string) bool {
if r.AVDID == id || r.LongID() == id {
return true
}
for _, alias := range r.Aliases {
if alias == id {
return true
}
}
return false
return slices.Contains(r.Aliases, id)
}
func (r Rule) LongID() string {

View File

@@ -34,7 +34,7 @@ func BenchmarkUnmarshal_JFather(b *testing.B) {
}
}`)
for n := 0; n < b.N; n++ {
for b.Loop() {
metadata := types.NewTestMetadata()
require.NoError(b, Unmarshal(input, &target, &metadata))
}
@@ -65,7 +65,7 @@ func BenchmarkUnmarshal_Traditional(b *testing.B) {
}
}`)
for n := 0; n < b.N; n++ {
for b.Loop() {
require.NoError(b, json.Unmarshal(input, &target))
}
}

View File

@@ -16,7 +16,7 @@ func Test_Peeker(t *testing.T) {
var b rune
var err error
for i := 0; i < 30; i++ {
for range 30 {
b, err = peeker.Peek()
require.NoError(t, err)
assert.Equal(t, ('a'), b)
@@ -34,7 +34,7 @@ func Test_Peeker(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, ('c'), b)
for i := 0; i < 5; i++ {
for i := range 5 {
b, err = peeker.Next()
require.NoError(t, err)
assert.Equal(t, []rune(input)[2+i], b)
@@ -47,7 +47,7 @@ func Test_Peeker(t *testing.T) {
b, err = peeker.Next()
require.NoError(t, err)
assert.Equal(t, ('h'), b)
for i := 0; i < 18; i++ {
for i := range 18 {
b, err = peeker.Next()
require.NoError(t, err)
assert.Equal(t, []rune(input)[8+i], b)

View File

@@ -2,6 +2,7 @@ package functions
import (
"fmt"
"slices"
"strings"
)
@@ -23,11 +24,7 @@ func Contains(args ...any) any {
return strings.Contains(strings.ToLower(cType), fmt.Sprintf("%d", iType))
}
case []any:
for _, item := range cType {
if item == itemToFind {
return true
}
}
return slices.Contains(cType, itemToFind)
case map[string]any:
for key := range cType {
if key == itemToFind {

View File

@@ -12,7 +12,7 @@ func Equals(args ...any) any {
if len(slice1) != len(slice2) {
return false
}
for i := 0; i < len(slice1); i++ {
for i := range slice1 {
if slice1[i] != slice2[i] {
return false
}

View File

@@ -1,6 +1,9 @@
package functions
import "sort"
import (
"maps"
"sort"
)
func Intersection(args ...any) any {
@@ -54,9 +57,7 @@ func intersectionArray(args ...any) any {
func intersectionMap(args ...any) any {
hash := make(map[string]any)
for k, v := range args[0].(map[string]any) {
hash[k] = v
}
maps.Copy(hash, args[0].(map[string]any))
for i := 1; i < len(args); i++ {
workingHash := make(map[string]any)

View File

@@ -7,10 +7,7 @@ func PickZones(args ...any) any {
numOfZones := 1
if len(args) > 3 {
numOfZones = args[3].(int)
if numOfZones > 3 {
numOfZones = 3
}
numOfZones = min(args[3].(int), 3)
}
var zones []int

View File

@@ -1,6 +1,9 @@
package functions
import "sort"
import (
"maps"
"sort"
)
func Union(args ...any) any {
if len(args) == 0 {
@@ -26,9 +29,7 @@ func unionMap(args ...any) any {
for _, arg := range args {
if iType, ok := arg.(map[string]any); ok {
for k, v := range iType {
result[k] = v
}
maps.Copy(result, iType)
}
}

View File

@@ -1,6 +1,7 @@
package azure
import (
"maps"
"slices"
"strings"
"time"
@@ -70,9 +71,7 @@ func NewValue(value any, metadata types.Metadata) Value {
case map[string]Value:
v.Kind = KindObject
v.rMap = make(map[string]Value)
for key, val := range ty {
v.rMap[key] = val
}
maps.Copy(v.rMap, ty)
case string:
v.Kind = KindString
v.rLit = ty

View File

@@ -16,7 +16,7 @@ func ResolveAnd(property *Property) (resolved *Property, success bool) {
}
results := make([]bool, len(refValue))
for i := 0; i < len(refValue); i++ {
for i := range refValue {
r := false
if refValue[i].IsBool() {

View File

@@ -52,7 +52,7 @@ func calculateCidrs(ipaddress string, count, bit int, original *Property) ([]*Pr
return nil, err
}
for i := 0; i < count; i++ {
for i := range count {
next, err := cidr.Subnet(network, bit, i)
if err != nil {
return nil, errors.New("failed to create cidr blocks")

View File

@@ -16,7 +16,7 @@ func ResolveOr(property *Property) (resolved *Property, success bool) {
}
results := make([]bool, len(refValue))
for i := 0; i < len(refValue); i++ {
for i := range refValue {
r := false
if refValue[i].IsBool() {

View File

@@ -3,6 +3,7 @@ package parser
import (
"fmt"
"io"
"maps"
"net/url"
"os"
"strings"
@@ -73,9 +74,7 @@ func (opts *ValueOptions) MergeValues() (map[string]any, error) {
func mergeMaps(a, b map[string]any) map[string]any {
out := make(map[string]any, len(a))
for k, v := range a {
out[k] = v
}
maps.Copy(out, a)
for k, v := range b {
if v, ok := v.(map[string]any); ok {
if bv, ok := out[k]; ok {

View File

@@ -122,7 +122,6 @@ func (s *Scanner) getScanResults(ctx context.Context, path string, target fs.FS)
}
for _, file := range chartFiles {
file := file
s.logger.Debug("Processing rendered chart file", log.FilePath(file.TemplateFilePath))
ignoreRules := ignore.Parse(file.ManifestContent, file.TemplateFilePath, "")

View File

@@ -32,7 +32,7 @@ locals {
`,
})
for i := 0; i < 100; i++ {
for range 100 {
results, err := scanFS(fsys, ".",
rego.WithPolicyReader(strings.NewReader(emptyBucketCheck)),
rego.WithPolicyNamespaces("user"),

View File

@@ -93,7 +93,6 @@ func Test_insertTupleElement(t *testing.T) {
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

View File

@@ -171,7 +171,7 @@ func (e *evaluator) evaluateSubmodules(ctx context.Context, parent *terraform.Mo
e.logger.Debug("Starting submodules evaluation...")
for i := 0; i < maxContextIterations; i++ {
for i := range maxContextIterations {
changed := false
for _, sm := range submodules {
changed = changed || e.evaluateSubmodule(ctx, sm)
@@ -196,9 +196,7 @@ func (e *evaluator) evaluateSubmodules(ctx context.Context, parent *terraform.Mo
}
modules = append(modules, sm.modules...)
for k, v := range sm.fsMap {
fsMap[k] = v
}
maps.Copy(fsMap, sm.fsMap)
}
e.logger.Debug("Finished processing submodule(s).", log.Int("count", len(modules)))
@@ -268,7 +266,7 @@ func (e *evaluator) evaluateSubmodule(ctx context.Context, sm *submodule) bool {
func (e *evaluator) evaluateSteps() {
var lastContext hcl.EvalContext
for i := 0; i < maxContextIterations; i++ {
for i := range maxContextIterations {
e.logger.Debug("Starting iteration", log.Int("iteration", i))
e.evaluateStep()
@@ -281,9 +279,7 @@ func (e *evaluator) evaluateSteps() {
if len(e.ctx.Inner().Variables) != len(lastContext.Variables) {
lastContext.Variables = make(map[string]cty.Value, len(e.ctx.Inner().Variables))
}
for k, v := range e.ctx.Inner().Variables {
lastContext.Variables[k] = v
}
maps.Copy(lastContext.Variables, e.ctx.Inner().Variables)
}
}

View File

@@ -68,7 +68,7 @@ var IPv4 = stdnet.IPv4
// Parse IPv4 address (d.d.d.d).
func parseIPv4(s string) IP {
var p [IPv4len]byte
for i := 0; i < IPv4len; i++ {
for i := range IPv4len {
if len(s) == 0 {
// Missing octets.
return nil

View File

@@ -3,6 +3,7 @@ package parser
import (
"fmt"
"io/fs"
"maps"
"os"
"path/filepath"
"strings"
@@ -35,9 +36,7 @@ func loadTFVars(srcFS fs.FS, filenames []string) (map[string]cty.Value, error) {
if err != nil {
return nil, fmt.Errorf("failed to load tfvars from %s: %w", filename, err)
}
for k, v := range vars {
combinedVars[k] = v
}
maps.Copy(combinedVars, vars)
}
return combinedVars, nil

View File

@@ -1979,7 +1979,6 @@ func TestModuleParents(t *testing.T) {
modSet := set.New[*terraform.Module]()
var root *terraform.Module
for _, mod := range modules {
mod := mod
modChildren[mod] = make([]*terraform.Module, 0)
modSet.Append(mod)

View File

@@ -20,8 +20,7 @@ func BenchmarkCalculate(b *testing.B) {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for b.Loop() {
p := parser.New(f, "", parser.OptionStopOnHCLError(true))
require.NoError(b, p.ParseFS(b.Context(), "project"))
modules, err := p.EvaluateAll(b.Context())

View File

@@ -1,6 +1,7 @@
package severity
import (
"slices"
"strings"
)
@@ -19,12 +20,7 @@ var ValidSeverity = []Severity{
}
func (s *Severity) IsValid() bool {
for _, severity := range ValidSeverity {
if severity == *s {
return true
}
}
return false
return slices.Contains(ValidSeverity, *s)
}
func (s *Severity) Valid() []Severity {

View File

@@ -183,7 +183,7 @@ func (b *Block) Clone(index cty.Value) *Block {
if len(clone.hclBlock.Labels) > 0 {
position := len(clone.hclBlock.Labels) - 1
labels := make([]string, len(clone.hclBlock.Labels))
for i := 0; i < len(labels); i++ {
for i := range labels {
labels[i] = clone.hclBlock.Labels[i]
}
if index.IsKnown() && !index.IsNull() {

View File

@@ -1,6 +1,7 @@
package context
import (
"maps"
"strings"
"github.com/hashicorp/hcl/v2"
@@ -126,9 +127,7 @@ func mergeVars(src cty.Value, parts []string, value cty.Value) cty.Value {
func mergeObjects(a, b cty.Value) cty.Value {
output := make(map[string]cty.Value)
for key, val := range a.AsValueMap() {
output[key] = val
}
maps.Copy(output, a.AsValueMap())
b.ForEachElement(func(key, val cty.Value) (stop bool) {
k := key.AsString()
old := output[k]

View File

@@ -3,6 +3,7 @@ package terraform
import (
"fmt"
"regexp"
"slices"
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/gocty"
@@ -45,17 +46,9 @@ func executeFunction(functionName string, criteriaValues, testValue any) bool {
func isAny(criteriaValues, testValue any) bool {
switch t := criteriaValues.(type) {
case []any:
for _, v := range t {
if v == testValue {
return true
}
}
return slices.Contains(t, testValue)
case []string:
for _, v := range t {
if v == testValue.(string) {
return true
}
}
return slices.Contains(t, testValue.(string))
}
return false
}

View File

@@ -10,5 +10,5 @@ func CreateFSKey(filesystem fs.FS) string {
if filesystem == nil {
return ""
}
return fmt.Sprintf("%x", sha256.Sum256([]byte(fmt.Sprintf("%s%#[1]v", filesystem))))
return fmt.Sprintf("%x", sha256.Sum256(fmt.Appendf(nil, "%s%#[1]v", filesystem)))
}

View File

@@ -2,6 +2,7 @@ package types
import (
"encoding/json"
"slices"
"strings"
)
@@ -87,12 +88,7 @@ func (s StringValue) IsOneOf(values ...string) bool {
if s.metadata.isUnresolvable {
return false
}
for _, value := range values {
if value == s.value {
return true
}
}
return false
return slices.Contains(values, s.value)
}
func (s StringValue) GetMetadata() Metadata {

View File

@@ -199,7 +199,7 @@ func configureHeader(s SummaryWriter, t *table.Table, columnHeading []string) {
table.AlignLeft,
table.AlignLeft,
}
for i := 0; i < count; i++ {
for range count {
headerRow = append(headerRow, s.SeverityHeadings...)
colSpan = append(colSpan, sevCount)
headerAlignment = append(headerAlignment, table.AlignCenter)

View File

@@ -620,10 +620,7 @@ func isLicenseText(str string) bool {
func TrimLicenseText(text string) string {
s := strings.Split(text, " ")
n := len(s)
if n > 3 {
n = 3
}
n := min(len(s), 3)
return strings.Join(s[:n], " ") + "..."
}

View File

@@ -451,7 +451,7 @@ func CreateDataFS(dataPaths []string, opts ...string) (fs.FS, []string, error) {
if err := fsys.MkdirAll("system", 0o700); err != nil {
return nil, nil, err
}
data := []byte(fmt.Sprintf(`{"k8s": {"version": %q}}`, k8sVersion))
data := fmt.Appendf(nil, `{"k8s": {"version": %q}}`, k8sVersion)
if err := fsys.WriteVirtualFile("system/k8s-version.json", data, 0o600); err != nil {
return nil, nil, err
}

View File

@@ -6,6 +6,7 @@ import (
"encoding/xml"
"html"
"io"
"maps"
"os"
"strings"
"text/template"
@@ -29,8 +30,8 @@ type TemplateWriter struct {
// NewTemplateWriter is the factory method to return TemplateWriter object
func NewTemplateWriter(output io.Writer, outputTemplate, appVersion string) (*TemplateWriter, error) {
if strings.HasPrefix(outputTemplate, "@") {
buf, err := os.ReadFile(strings.TrimPrefix(outputTemplate, "@"))
if after, ok := strings.CutPrefix(outputTemplate, "@"); ok {
buf, err := os.ReadFile(after)
if err != nil {
return nil, xerrors.Errorf("error retrieving template from path: %w", err)
}
@@ -60,9 +61,7 @@ func NewTemplateWriter(output io.Writer, outputTemplate, appVersion string) (*Te
}
// Overwrite functions
for k, v := range CustomTemplateFuncMap {
templateFuncMap[k] = v
}
maps.Copy(templateFuncMap, CustomTemplateFuncMap)
tmpl, err := template.New("output template").Funcs(templateFuncMap).Parse(outputTemplate)
if err != nil {

View File

@@ -180,8 +180,7 @@ func TestReportWriter_Template(t *testing.T) {
"PkgIdentifier": {
"PURL": "pkg:npm/foobar@1.2.3"
},
"Status": "affected",
"Layer": {}
"Status": "affected"
}`,
},
{

View File

@@ -272,8 +272,8 @@ func parseIgnore(ignoreFile string) (IgnoreFindings, error) {
func getExpirationDate(fields []string) (time.Time, error) {
for _, field := range fields {
if strings.HasPrefix(field, "exp:") {
return time.Parse("2006-01-02", strings.TrimPrefix(field, "exp:"))
if after, ok := strings.CutPrefix(field, "exp:"); ok {
return time.Parse("2006-01-02", after)
}
}

View File

@@ -303,10 +303,10 @@ func (m *Marshaler) Licenses(licenses []string) *cdx.Licenses {
func (m *Marshaler) normalizeLicense(license string) cdx.LicenseChoice {
// Save text license as licenseChoice.license.name
if strings.HasPrefix(license, licensing.LicenseTextPrefix) {
if after, ok := strings.CutPrefix(license, licensing.LicenseTextPrefix); ok {
return cdx.LicenseChoice{
License: &cdx.License{
Name: strings.TrimPrefix(license, licensing.LicenseTextPrefix),
Name: after,
},
}
}

View File

@@ -419,8 +419,8 @@ func (m *Marshaler) normalizeLicenses(licenses []string) (string, []*spdx.OtherL
// We need to save text licenses before normalization,
// because it is impossible to handle all cases possible in the text.
// as an example, parse a license with 2 consecutive tokens (see https://github.com/aquasecurity/trivy/issues/8465)
if strings.HasPrefix(license, licensing.LicenseTextPrefix) {
license = strings.TrimPrefix(license, licensing.LicenseTextPrefix)
if after, ok := strings.CutPrefix(license, licensing.LicenseTextPrefix); ok {
license = after
otherLicense := m.newOtherLicense(license, true)
otherLicenses[otherLicense.LicenseIdentifier] = otherLicense
return otherLicense.LicenseIdentifier

View File

@@ -431,8 +431,8 @@ func toDetectedMisconfiguration(res ftypes.MisconfResult, defaultSeverity dbType
func toDetectedLicense(scanner licensing.Scanner, license, pkgName, filePath string) types.DetectedLicense {
var category ftypes.LicenseCategory
var severity, licenseText string
if strings.HasPrefix(license, licensing.LicenseTextPrefix) { // License text
licenseText = strings.TrimPrefix(license, licensing.LicenseTextPrefix)
if after, ok := strings.CutPrefix(license, licensing.LicenseTextPrefix); ok { // License text
licenseText = after
category, severity = scanner.ScanTextLicense(licenseText)
license = licensing.CustomLicensePrefix + ": " + licensing.TrimLicenseText(licenseText) // Use `CUSTOM LICENSE: *...` format for text licenses
} else { // License name

View File

@@ -17,8 +17,8 @@ type DetectedMisconfiguration struct {
PrimaryURL string `json:",omitempty"`
References []string `json:",omitempty"`
Status MisconfStatus `json:",omitempty"`
Layer ftypes.Layer `json:",omitempty"`
CauseMetadata ftypes.CauseMetadata `json:",omitempty"`
Layer ftypes.Layer `json:",omitzero"`
CauseMetadata ftypes.CauseMetadata `json:",omitzero"`
// For debugging
Traces []string `json:",omitempty"`

View File

@@ -12,10 +12,10 @@ import (
// Report represents a scan result
type Report struct {
SchemaVersion int `json:",omitempty"`
CreatedAt time.Time `json:",omitempty"`
CreatedAt time.Time `json:",omitzero"`
ArtifactName string `json:",omitempty"`
ArtifactType ftypes.ArtifactType `json:",omitempty"`
Metadata Metadata `json:",omitempty"`
Metadata Metadata `json:",omitzero"`
Results Results `json:",omitempty"`
// parsed SBOM
@@ -32,7 +32,7 @@ type Metadata struct {
DiffIDs []string `json:",omitempty"`
RepoTags []string `json:",omitempty"`
RepoDigests []string `json:",omitempty"`
ImageConfig v1.ConfigFile `json:",omitempty"`
ImageConfig v1.ConfigFile `json:",omitzero"`
Layers ftypes.Layers `json:",omitzero"`
}

View File

@@ -88,12 +88,7 @@ func (scanners *Scanners) Enabled(s Scanner) bool {
// AnyEnabled returns true if any of the passed scanners is included.
func (scanners *Scanners) AnyEnabled(ss ...Scanner) bool {
for _, s := range ss {
if scanners.Enabled(s) {
return true
}
}
return false
return slices.ContainsFunc(ss, scanners.Enabled)
}
// ScanTarget holds the attributes for scanning.

View File

@@ -12,11 +12,11 @@ type DetectedVulnerability struct {
PkgID string `json:",omitempty"` // It is used to construct dependency graph.
PkgName string `json:",omitempty"`
PkgPath string `json:",omitempty"` // This field is populated in the case of language-specific packages such as egg/wheel and gemspec
PkgIdentifier ftypes.PkgIdentifier `json:",omitempty"`
PkgIdentifier ftypes.PkgIdentifier `json:",omitzero"`
InstalledVersion string `json:",omitempty"`
FixedVersion string `json:",omitempty"`
Status types.Status `json:",omitempty"`
Layer ftypes.Layer `json:",omitempty"`
Layer ftypes.Layer `json:",omitzero"`
SeveritySource types.SourceID `json:",omitempty"`
PrimaryURL string `json:",omitempty"`

View File

@@ -284,7 +284,7 @@ func redactQueryParams(u *url.URL) *url.URL {
func (tt *traceTransport) redactBody(body []byte, contentType string) []byte {
// Check if body is too large
if len(body) > maxBodySize {
return []byte(fmt.Sprintf("<body too large: %d bytes>", len(body)))
return fmt.Appendf(nil, "<body too large: %d bytes>", len(body))
}
// Check if body is binary