chore(deps): update Go version (#4773)

Signed-off-by: anchore-oss-update-bot <anchore-oss-update-bot@users.noreply.github.com>
Co-authored-by: anchore-oss-update-bot <anchore-oss-update-bot@users.noreply.github.com>
This commit is contained in:
anchore-oss-update-bot 2026-04-15 10:01:39 -04:00 committed by GitHub
parent 26e87c7cd3
commit 5b58ec96b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
113 changed files with 339 additions and 394 deletions

View File

@ -1,11 +1,10 @@
name: "Bootstrap"
description: "Bootstrap all tools and dependencies"
inputs:
go-version:
description: "Go version to install"
required: true
default: "1.26.x"
default: "1.26.2"
go-dependencies:
description: "Download go dependencies"
required: true
@ -24,7 +23,6 @@ inputs:
bootstrap-apt-packages:
description: "Space delimited list of tools to install via apt"
default: "libxml2-utils"
runs:
using: "composite"
steps:
@ -34,7 +32,6 @@ runs:
with:
go-version: ${{ inputs.go-version }}
check-latest: true
- name: Restore tool cache
if: inputs.tools == 'true'
id: tool-cache
@ -42,7 +39,6 @@ runs:
with:
path: ${{ github.workspace }}/.tool
key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-tool-${{ hashFiles('.binny.yaml') }}
- name: Install project tools
shell: bash
if: inputs.tools == 'true'
@ -50,12 +46,10 @@ runs:
make tools
.tool/binny list
.tool/binny check
- name: Install go dependencies
if: inputs.go-dependencies == 'true'
shell: bash
run: make ci-bootstrap-go
- name: Install apt packages
if: inputs.bootstrap-apt-packages != ''
shell: bash
@ -64,14 +58,12 @@ runs:
run: |
IFS=' ' read -ra packages <<< "$APT_PACKAGES"
DEBIAN_FRONTEND=noninteractive sudo apt update && sudo -E apt install -y "${packages[@]}"
- name: Restore ORAS cache from github actions
if: inputs.download-test-fixture-cache == 'true'
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: ${{ github.workspace }}/.tmp/oras-cache
key: ${{ inputs.cache-key-prefix }}-oras-cache
- name: Download test fixture cache
if: inputs.download-test-fixture-cache == 'true'
shell: bash

View File

@ -59,7 +59,7 @@ func Attest(app clio.Application) *cobra.Command {
Use: "attest --output [FORMAT] <IMAGE>",
Short: "Generate an SBOM as an attestation for the given [SOURCE] container image",
Long: "Generate a packaged-based Software Bill Of Materials (SBOM) from a container image as the predicate of an in-toto attestation that will be uploaded to the image registry",
Example: internal.Tprintf(attestHelp, map[string]interface{}{
Example: internal.Tprintf(attestHelp, map[string]any{
"appName": id.Name,
"command": "attest",
}),

View File

@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"os"
"slices"
"sort"
"strings"
@ -248,12 +249,7 @@ func renderCatalogerInfoJSON(doc *capabilities.Document, catalogers []capabiliti
// isDeprecatedCataloger checks if a cataloger is deprecated based on its selectors
func isDeprecatedCataloger(selectors []string) bool {
for _, selector := range selectors {
if selector == "deprecated" {
return true
}
}
return false
return slices.Contains(selectors, "deprecated")
}
// convertDetectorPackages converts detector package info to the JSON output format
@ -452,7 +448,7 @@ func extractArrayCapability(caps capabilities.CapabilitySet, name string) string
if len(v) > 0 {
return strings.Join(v, ", ")
}
case []interface{}:
case []any:
if len(v) > 0 {
strs := make([]string, 0, len(v))
for _, item := range v {
@ -475,7 +471,7 @@ func extractNodesCapability(caps capabilities.CapabilitySet) string {
switch v := cap.Default.(type) {
case []string:
return formatDepthStringArray(v)
case []interface{}:
case []any:
return formatDepthInterfaceArray(v)
}
return noStyle.Render("·")
@ -496,7 +492,7 @@ func formatDepthStringArray(v []string) string {
}
// formatDepthInterfaceArray formats a []interface{} dependency depth value
func formatDepthInterfaceArray(v []interface{}) string {
func formatDepthInterfaceArray(v []any) string {
if len(v) == 0 {
return noStyle.Render("·")
}

View File

@ -40,7 +40,7 @@ func Convert(app clio.Application) *cobra.Command {
Use: "convert [SOURCE-SBOM] -o [FORMAT]",
Short: "Convert between SBOM formats",
Long: "[Experimental] Convert SBOM files to, and from, SPDX, CycloneDX and Syft's format. For more info about data loss between formats see https://github.com/anchore/syft/wiki/format-conversion",
Example: internal.Tprintf(convertExample, map[string]interface{}{
Example: internal.Tprintf(convertExample, map[string]any{
"appName": id.Name,
"command": "convert",
}),

View File

@ -18,7 +18,7 @@ func Packages(app clio.Application, scanCmd *cobra.Command) *cobra.Command {
Short: scanCmd.Short,
Long: scanCmd.Long,
Args: scanCmd.Args,
Example: internal.Tprintf(scanHelp, map[string]interface{}{
Example: internal.Tprintf(scanHelp, map[string]any{
"appName": id.Name,
"command": "packages",
}),

View File

@ -29,7 +29,7 @@ func Test_filterExpressionErrors_expressionErrorsHelp(t *testing.T) {
{
name: "single non-expression error is retained",
err: errors.New("foo"),
wantErr: func(t assert.TestingT, err error, i ...interface{}) bool {
wantErr: func(t assert.TestingT, err error, i ...any) bool {
return assert.Equal(t, "foo", err.Error())
},
wantHelp: "",
@ -42,7 +42,7 @@ func Test_filterExpressionErrors_expressionErrorsHelp(t *testing.T) {
err = multierror.Append(err, errors.New("bar"))
return err
}(),
wantErr: func(t assert.TestingT, err error, i ...interface{}) bool {
wantErr: func(t assert.TestingT, err error, i ...any) bool {
// note: this is the default formatting from the hashicorp multierror object
expected := `2 errors occurred:
* foo
@ -64,7 +64,7 @@ func Test_filterExpressionErrors_expressionErrorsHelp(t *testing.T) {
err = multierror.Append(err, errors.New("last"))
return err
}(),
wantErr: func(t assert.TestingT, err error, i ...interface{}) bool {
wantErr: func(t assert.TestingT, err error, i ...any) bool {
expected := `5 errors occurred:
* foo
* invalid expression: "foo": tags are not allowed with this operation (must use exact names)
@ -103,7 +103,7 @@ func Test_filterExpressionErrors_expressionErrorsHelp(t *testing.T) {
return fmt.Errorf("top: %w", fmt.Errorf("middle: %w", err))
}(),
wantErr: func(t assert.TestingT, err error, i ...interface{}) bool {
wantErr: func(t assert.TestingT, err error, i ...any) bool {
expected := `top: middle: 4 errors occurred:
* foo: bar: last
* invalid expression: "foo": tags are not allowed with this operation (must use exact names)
@ -142,7 +142,7 @@ func Test_filterExpressionErrors_expressionErrorsHelp(t *testing.T) {
// note we wrap the top error in a chain
return fmt.Errorf("top: %w", fmt.Errorf("middle: %w", err))
}(),
wantErr: func(t assert.TestingT, err error, i ...interface{}) bool {
wantErr: func(t assert.TestingT, err error, i ...any) bool {
expected := `top: middle: 4 errors occurred:
* foo: bar: last
* invalid expression: "foo": tags are not allowed with this operation (must use exact names)
@ -178,7 +178,7 @@ func Test_filterExpressionErrors_expressionErrorsHelp(t *testing.T) {
return err
}(),
wantErr: func(t assert.TestingT, err error, i ...interface{}) bool {
wantErr: func(t assert.TestingT, err error, i ...any) bool {
// note: the errors are removed and the help text shows the enriched error help
expected := `2 errors occurred:
* invalid expression: "foo": tags are not allowed with this operation (must use exact names)

View File

@ -92,7 +92,7 @@ func Scan(app clio.Application) *cobra.Command {
Use: "scan [SOURCE]",
Short: "Generate an SBOM",
Long: "Generate a packaged-based Software Bill Of Materials (SBOM) from container images and filesystems",
Example: internal.Tprintf(scanHelp, map[string]interface{}{
Example: internal.Tprintf(scanHelp, map[string]any{
"appName": id.Name,
"command": "scan",
}),

View File

@ -60,7 +60,7 @@ func Test_scanOptions_validateLegacyOptionsNotUsed(t *testing.T) {
}
func assertErrorContains(contains string) assert.ErrorAssertionFunc {
return func(t assert.TestingT, err error, i ...interface{}) bool {
return func(t assert.TestingT, err error, i ...any) bool {
return assert.ErrorContains(t, err, contains, i...)
}
}

View File

@ -2,6 +2,7 @@ package options
import (
"fmt"
"slices"
"sort"
"strings"
@ -313,10 +314,8 @@ func enrichmentEnabled(enrichDirectives []string, features ...string) *bool {
directive = directive[1:]
enable = false
}
for _, feature := range features {
if directive == feature {
return &enable
}
if slices.Contains(features, directive) {
return &enable
}
}
return nil

View File

@ -32,7 +32,7 @@ func Test_MakeSBOMWriter(t *testing.T) {
{
name: "unknown format",
outputs: []string{"unknown"},
wantErr: func(t assert.TestingT, err error, bla ...interface{}) bool {
wantErr: func(t assert.TestingT, err error, bla ...any) bool {
return assert.ErrorContains(t, err, `unsupported output format "unknown", supported formats are:`)
},
},

View File

@ -2,6 +2,7 @@ package integration
import (
"context"
"slices"
"strings"
"testing"
@ -194,11 +195,8 @@ func assertPackages(t *testing.T, sbom sbom.SBOM, test testCase, observedLanguag
}
var foundLang bool
for _, lang := range strings.Split(test.pkgLanguage.String(), ",") {
if actualPkg.Language.String() == lang {
foundLang = true
break
}
if slices.Contains(strings.Split(test.pkgLanguage.String(), ","), actualPkg.Language.String()) {
foundLang = true
}
if !foundLang {
t.Errorf("bad language (pkg=%+v): %+v", actualPkg.Name, actualPkg.Language)

View File

@ -329,7 +329,7 @@ func packageCatalogerExports(t *testing.T) map[string]exportTokenSet {
}
exportsPerPackage[pkg].Add(exportToken{
Name: decl.Name.Name,
Type: reflect.TypeOf(decl.Type).String(),
Type: reflect.TypeFor[*ast.FuncType]().String(),
SignatureSize: len(decl.Type.Params.List),
ReturnTypeNames: returnTypes,
})

View File

@ -36,33 +36,33 @@ func Test_logWriter(t *testing.T) {
type bufferLogger struct{ values []any }
func (l *bufferLogger) Tracef(_ string, _ ...interface{}) {}
func (l *bufferLogger) Tracef(_ string, _ ...any) {}
func (l *bufferLogger) Debugf(_ string, _ ...interface{}) {}
func (l *bufferLogger) Debugf(_ string, _ ...any) {}
func (l *bufferLogger) Infof(_ string, _ ...interface{}) {}
func (l *bufferLogger) Infof(_ string, _ ...any) {}
func (l *bufferLogger) Warnf(_ string, _ ...interface{}) {}
func (l *bufferLogger) Warnf(_ string, _ ...any) {}
func (l *bufferLogger) Errorf(_ string, _ ...interface{}) {}
func (l *bufferLogger) Errorf(_ string, _ ...any) {}
func (l *bufferLogger) Trace(vals ...interface{}) {
func (l *bufferLogger) Trace(vals ...any) {
l.values = append(l.values, vals...)
}
func (l *bufferLogger) Debug(_ ...interface{}) {}
func (l *bufferLogger) Debug(_ ...any) {}
func (l *bufferLogger) Info(_ ...interface{}) {}
func (l *bufferLogger) Info(_ ...any) {}
func (l *bufferLogger) Warn(vals ...interface{}) {
func (l *bufferLogger) Warn(vals ...any) {
l.values = append(l.values, vals...)
}
func (l *bufferLogger) Error(_ ...interface{}) {}
func (l *bufferLogger) Error(_ ...any) {}
func (l *bufferLogger) WithFields(_ ...interface{}) logger.MessageLogger { return l }
func (l *bufferLogger) WithFields(_ ...any) logger.MessageLogger { return l }
func (l *bufferLogger) Nested(_ ...interface{}) logger.Logger { return l }
func (l *bufferLogger) Nested(_ ...any) logger.Logger { return l }
func (l *bufferLogger) SetOutput(_ io.Writer) {}

2
go.mod
View File

@ -1,6 +1,6 @@
module github.com/anchore/syft
go 1.25.8
go 1.26.2
require (
github.com/BurntSushi/toml v1.6.0

View File

@ -5,8 +5,8 @@ import "reflect"
// EvaluateCapabilities evaluates a capability set against a given configuration
// and returns the effective capability values as a flat map.
// Example: {"license": false, "dependency.depth": ["direct", "indirect"]}
func EvaluateCapabilities(caps CapabilitySet, config map[string]interface{}) map[string]interface{} {
result := make(map[string]interface{})
func EvaluateCapabilities(caps CapabilitySet, config map[string]any) map[string]any {
result := make(map[string]any)
for _, capField := range caps {
result[capField.Name] = EvaluateField(capField, config)
}
@ -16,7 +16,7 @@ func EvaluateCapabilities(caps CapabilitySet, config map[string]interface{}) map
// EvaluateField evaluates a single capability field against a configuration.
// Conditions are evaluated in order, and the first matching condition's value is returned.
// If no conditions match, the default value is returned.
func EvaluateField(capField CapabilityField, config map[string]interface{}) interface{} {
func EvaluateField(capField CapabilityField, config map[string]any) any {
// check conditions in order (first match wins)
for _, cond := range capField.Conditions {
if ConditionMatches(cond.When, config) {
@ -30,7 +30,7 @@ func EvaluateField(capField CapabilityField, config map[string]interface{}) inte
// ConditionMatches checks if a condition's when clause matches the given configuration.
// All fields in the when clause must match the config (AND logic).
// Returns true if all key-value pairs in when match the config.
func ConditionMatches(when map[string]interface{}, config map[string]interface{}) bool {
func ConditionMatches(when map[string]any, config map[string]any) bool {
// all fields in when must match config (AND logic)
for key, expectedValue := range when {
actualValue, exists := config[key]
@ -46,7 +46,7 @@ func ConditionMatches(when map[string]interface{}, config map[string]interface{}
// valuesEqual compares two values for equality, handling different types appropriately.
// Uses reflect.DeepEqual for complex types like slices and maps.
func valuesEqual(a, b interface{}) bool {
func valuesEqual(a, b any) bool {
// handle nil cases
if a == nil && b == nil {
return true

View File

@ -10,8 +10,8 @@ import (
func Test_valuesEqual(t *testing.T) {
tests := []struct {
name string
a interface{}
b interface{}
a any
b any
want bool
}{
{
@ -123,47 +123,47 @@ func Test_valuesEqual(t *testing.T) {
func TestConditionMatches(t *testing.T) {
tests := []struct {
name string
when map[string]interface{}
config map[string]interface{}
when map[string]any
config map[string]any
want bool
}{
{
name: "empty when clause matches anything",
when: map[string]interface{}{},
config: map[string]interface{}{"key": "value"},
when: map[string]any{},
config: map[string]any{"key": "value"},
want: true,
},
{
name: "empty when clause with empty config",
when: map[string]interface{}{},
config: map[string]interface{}{},
when: map[string]any{},
config: map[string]any{},
want: true,
},
{
name: "single key match",
when: map[string]interface{}{"SearchLocalModCacheLicenses": true},
config: map[string]interface{}{"SearchLocalModCacheLicenses": true},
when: map[string]any{"SearchLocalModCacheLicenses": true},
config: map[string]any{"SearchLocalModCacheLicenses": true},
want: true,
},
{
name: "single key mismatch",
when: map[string]interface{}{"SearchLocalModCacheLicenses": true},
config: map[string]interface{}{"SearchLocalModCacheLicenses": false},
when: map[string]any{"SearchLocalModCacheLicenses": true},
config: map[string]any{"SearchLocalModCacheLicenses": false},
want: false,
},
{
name: "key missing from config",
when: map[string]interface{}{"SearchLocalModCacheLicenses": true},
config: map[string]interface{}{},
when: map[string]any{"SearchLocalModCacheLicenses": true},
config: map[string]any{},
want: false,
},
{
name: "multiple keys all match",
when: map[string]interface{}{
when: map[string]any{
"SearchLocalModCacheLicenses": true,
"UseNetwork": true,
},
config: map[string]interface{}{
config: map[string]any{
"SearchLocalModCacheLicenses": true,
"UseNetwork": true,
"ExtraKey": "ignored",
@ -172,11 +172,11 @@ func TestConditionMatches(t *testing.T) {
},
{
name: "multiple keys one mismatch",
when: map[string]interface{}{
when: map[string]any{
"SearchLocalModCacheLicenses": true,
"UseNetwork": true,
},
config: map[string]interface{}{
config: map[string]any{
"SearchLocalModCacheLicenses": true,
"UseNetwork": false,
},
@ -184,31 +184,31 @@ func TestConditionMatches(t *testing.T) {
},
{
name: "multiple keys one missing",
when: map[string]interface{}{
when: map[string]any{
"SearchLocalModCacheLicenses": true,
"UseNetwork": true,
},
config: map[string]interface{}{
config: map[string]any{
"SearchLocalModCacheLicenses": true,
},
want: false,
},
{
name: "string value match",
when: map[string]interface{}{"mode": "fast"},
config: map[string]interface{}{"mode": "fast"},
when: map[string]any{"mode": "fast"},
config: map[string]any{"mode": "fast"},
want: true,
},
{
name: "slice value match",
when: map[string]interface{}{"formats": []string{"json", "yaml"}},
config: map[string]interface{}{"formats": []string{"json", "yaml"}},
when: map[string]any{"formats": []string{"json", "yaml"}},
config: map[string]any{"formats": []string{"json", "yaml"}},
want: true,
},
{
name: "slice value mismatch",
when: map[string]interface{}{"formats": []string{"json", "yaml"}},
config: map[string]interface{}{"formats": []string{"json", "xml"}},
when: map[string]any{"formats": []string{"json", "yaml"}},
config: map[string]any{"formats": []string{"json", "xml"}},
want: false,
},
}
@ -225,8 +225,8 @@ func TestEvaluateField(t *testing.T) {
tests := []struct {
name string
capField CapabilityField
config map[string]interface{}
want interface{}
config map[string]any
want any
}{
{
name: "no conditions returns default",
@ -235,7 +235,7 @@ func TestEvaluateField(t *testing.T) {
Default: false,
Conditions: nil,
},
config: map[string]interface{}{},
config: map[string]any{},
want: false,
},
{
@ -245,7 +245,7 @@ func TestEvaluateField(t *testing.T) {
Default: false,
Conditions: []CapabilityCondition{},
},
config: map[string]interface{}{},
config: map[string]any{},
want: false,
},
{
@ -260,7 +260,7 @@ func TestEvaluateField(t *testing.T) {
},
},
},
config: map[string]interface{}{"SearchLocalModCacheLicenses": true},
config: map[string]any{"SearchLocalModCacheLicenses": true},
want: true,
},
{
@ -275,7 +275,7 @@ func TestEvaluateField(t *testing.T) {
},
},
},
config: map[string]interface{}{"SearchLocalModCacheLicenses": false},
config: map[string]any{"SearchLocalModCacheLicenses": false},
want: false,
},
{
@ -294,7 +294,7 @@ func TestEvaluateField(t *testing.T) {
},
},
},
config: map[string]interface{}{
config: map[string]any{
"SearchLocalModCacheLicenses": true,
"SearchRemoteLicenses": true,
},
@ -316,7 +316,7 @@ func TestEvaluateField(t *testing.T) {
},
},
},
config: map[string]interface{}{
config: map[string]any{
"SearchLocalModCacheLicenses": false,
"SearchRemoteLicenses": true,
},
@ -338,7 +338,7 @@ func TestEvaluateField(t *testing.T) {
},
},
},
config: map[string]interface{}{
config: map[string]any{
"SearchLocalModCacheLicenses": false,
"SearchRemoteLicenses": false,
},
@ -351,7 +351,7 @@ func TestEvaluateField(t *testing.T) {
Default: []string{"direct", "indirect"},
Conditions: nil,
},
config: map[string]interface{}{},
config: map[string]any{},
want: []string{"direct", "indirect"},
},
{
@ -369,7 +369,7 @@ func TestEvaluateField(t *testing.T) {
},
},
},
config: map[string]interface{}{
config: map[string]any{
"EnableFeatureA": true,
"EnableFeatureB": true,
},
@ -390,7 +390,7 @@ func TestEvaluateField(t *testing.T) {
},
},
},
config: map[string]interface{}{
config: map[string]any{
"EnableFeatureA": true,
"EnableFeatureB": false,
},
@ -412,14 +412,14 @@ func TestEvaluateCapabilities(t *testing.T) {
tests := []struct {
name string
caps CapabilitySet
config map[string]interface{}
want map[string]interface{}
config map[string]any
want map[string]any
}{
{
name: "empty capability set",
caps: CapabilitySet{},
config: map[string]interface{}{},
want: map[string]interface{}{},
config: map[string]any{},
want: map[string]any{},
},
{
name: "single capability no conditions",
@ -429,8 +429,8 @@ func TestEvaluateCapabilities(t *testing.T) {
Default: false,
},
},
config: map[string]interface{}{},
want: map[string]interface{}{
config: map[string]any{},
want: map[string]any{
"license": false,
},
},
@ -448,8 +448,8 @@ func TestEvaluateCapabilities(t *testing.T) {
},
},
},
config: map[string]interface{}{"SearchLocalModCacheLicenses": true},
want: map[string]interface{}{
config: map[string]any{"SearchLocalModCacheLicenses": true},
want: map[string]any{
"license": true,
},
},
@ -475,8 +475,8 @@ func TestEvaluateCapabilities(t *testing.T) {
Default: "flat",
},
},
config: map[string]interface{}{"SearchLocalModCacheLicenses": true},
want: map[string]interface{}{
config: map[string]any{"SearchLocalModCacheLicenses": true},
want: map[string]any{
"license": true,
"dependency.depth": []string{"direct", "indirect"},
"dependency.edges": "flat",
@ -512,11 +512,11 @@ func TestEvaluateCapabilities(t *testing.T) {
Default: false,
},
},
config: map[string]interface{}{
config: map[string]any{
"SearchLocalModCacheLicenses": false,
"SearchRemoteLicenses": true,
},
want: map[string]interface{}{
want: map[string]any{
"license": true,
"dependency.depth": []string{"direct", "indirect"},
"dependency.edges": "flat",
@ -526,10 +526,10 @@ func TestEvaluateCapabilities(t *testing.T) {
{
name: "nil capability set",
caps: nil,
config: map[string]interface{}{
config: map[string]any{
"anything": true,
},
want: map[string]interface{}{},
want: map[string]any{},
},
}

View File

@ -15,9 +15,9 @@ import (
// AppConfigField represents an application-level configuration field for catalogers
type AppConfigField struct {
Key string // e.g., "golang.search-local-mod-cache-licenses"
Description string // extracted from DescribeFields() method
DefaultValue interface{} // extracted from Default*() functions
Key string // e.g., "golang.search-local-mod-cache-licenses"
Description string // extracted from DescribeFields() method
DefaultValue any // extracted from Default*() functions
}
// extractEcosystemConfigFieldsFromCatalog parses catalog.go and extracts the ecosystem-specific
@ -390,7 +390,7 @@ func extractDescriptionsFromDescribeFields(f *ast.File) map[string]string {
}
// extractNestedAppConfigs handles nested config structs like golang.MainModuleVersion
func extractNestedAppConfigs(f *ast.File, parentKey, parentFieldName string, fieldType ast.Expr, descriptions map[string]string, defaults map[string]interface{}) []AppConfigField {
func extractNestedAppConfigs(f *ast.File, parentKey, parentFieldName string, fieldType ast.Expr, descriptions map[string]string, defaults map[string]any) []AppConfigField {
var configs []AppConfigField
// find the nested struct type
@ -449,8 +449,8 @@ func extractNestedAppConfigs(f *ast.File, parentKey, parentFieldName string, fie
description := descriptions[nestedPath]
// try to get default value from nested defaults
var defaultValue interface{}
if nestedDefaults, ok := defaults[parentFieldName].(map[string]interface{}); ok {
var defaultValue any
if nestedDefaults, ok := defaults[parentFieldName].(map[string]any); ok {
defaultValue = nestedDefaults[fieldName]
}
@ -465,8 +465,8 @@ func extractNestedAppConfigs(f *ast.File, parentKey, parentFieldName string, fie
}
// extractAppDefaultValues extracts default values from the default*Config function
func extractAppDefaultValues(f *ast.File) map[string]interface{} {
defaults := make(map[string]interface{})
func extractAppDefaultValues(f *ast.File) map[string]any {
defaults := make(map[string]any)
for _, decl := range f.Decls {
funcDecl, ok := decl.(*ast.FuncDecl)
@ -518,7 +518,7 @@ func extractAppDefaultValues(f *ast.File) map[string]interface{} {
}
// extractAppValue extracts a Go value from an AST expression
func extractAppValue(expr ast.Expr) interface{} {
func extractAppValue(expr ast.Expr) any {
switch v := expr.(type) {
case *ast.BasicLit:
// string, int, bool literals
@ -543,7 +543,7 @@ func extractAppValue(expr ast.Expr) interface{} {
}
case *ast.CompositeLit:
// nested struct literal
nested := make(map[string]interface{})
nested := make(map[string]any)
for _, elt := range v.Elts {
kvExpr, ok := elt.(*ast.KeyValueExpr)
if !ok {

View File

@ -340,7 +340,7 @@ func TestExtractAppValue(t *testing.T) {
tests := []struct {
name string
src string
want interface{}
want any
}{
{
name: "string literal",
@ -406,7 +406,7 @@ func TestExtractAppValue_NestedStruct(t *testing.T) {
got := extractAppValue(compositeLit)
// verify it's a map with the expected values
gotMap, ok := got.(map[string]interface{})
gotMap, ok := got.(map[string]any)
require.True(t, ok)
require.Equal(t, "value", gotMap["Field1"])
require.Equal(t, true, gotMap["Field2"])

View File

@ -567,8 +567,8 @@ func resolveImportedConstant(pkgName, constName string, ctx *parseContext) strin
// resolveImportPath converts an import path to a file system path
func resolveImportPath(importPath, repoRoot string) string {
// for github.com/anchore/syft/... imports, convert to repo-relative path
if strings.HasPrefix(importPath, "github.com/anchore/syft/") {
relPath := strings.TrimPrefix(importPath, "github.com/anchore/syft/")
if after, ok := strings.CutPrefix(importPath, "github.com/anchore/syft/"); ok {
relPath := after
return filepath.Join(repoRoot, relPath)
}

View File

@ -214,7 +214,7 @@ func mapCatalogerToEcosystem(cat capabilities.CatalogerEntry) string {
}
// updateNodeTreeEcosystem updates an existing ecosystem YAML node tree
func updateNodeTreeEcosystem(rootNode *yaml.Node, doc interface{}) error {
func updateNodeTreeEcosystem(rootNode *yaml.Node, doc any) error {
var newNode yaml.Node
if err := newNode.Encode(doc); err != nil {
return err
@ -242,7 +242,7 @@ func updateNodeTreeEcosystem(rootNode *yaml.Node, doc interface{}) error {
}
// updateNodeTreeAppConfig updates appconfig YAML node tree
func updateNodeTreeAppConfig(rootNode *yaml.Node, doc interface{}) error {
func updateNodeTreeAppConfig(rootNode *yaml.Node, doc any) error {
return updateNodeTreeEcosystem(rootNode, doc)
}

View File

@ -30,7 +30,7 @@ const requireParserObservations = false
// metadataTypeCoverageExceptions lists metadata types that are allowed to not be represented in any cataloger
var metadataTypeCoverageExceptions = strset.New(
reflect.TypeOf(pkg.MicrosoftKbPatch{}).Name(),
reflect.TypeFor[pkg.MicrosoftKbPatch]().Name(),
)
// packageTypeCoverageExceptions lists package types that are allowed to not be represented in any cataloger
@ -408,7 +408,7 @@ func TestCapabilityValueTypes(t *testing.T) {
}
// validateCapabilityValueType checks if a value matches the expected type for a capability field
func validateCapabilityValueType(fieldPath string, value interface{}) error {
func validateCapabilityValueType(fieldPath string, value any) error {
if value == nil {
return nil // nil is acceptable
}
@ -428,7 +428,7 @@ func validateCapabilityValueType(fieldPath string, value interface{}) error {
switch v := value.(type) {
case []string:
// ok
case []interface{}:
case []any:
// check each element is a string
for i, elem := range v {
if _, ok := elem.(string); !ok {
@ -829,7 +829,6 @@ func TestCapabilityEvidenceFieldReferences(t *testing.T) {
// validate each evidence reference
for _, ref := range allReferences {
ref := ref // capture for subtest
// create test name
testName := ref.catalogerName
@ -989,7 +988,6 @@ func validateCapabilitiesFilled(t *testing.T, catalogers []capabilities.Cataloge
checkCompletenessTestsEnabled(t)
for _, c := range catalogers {
c := c // capture loop variable for subtest
t.Run(c.Name, func(t *testing.T) {
if c.Type == "generic" {
@ -997,7 +995,6 @@ func validateCapabilitiesFilled(t *testing.T, catalogers []capabilities.Cataloge
require.NotEmpty(t, c.Parsers, "generic cataloger must have at least one parser")
for _, p := range c.Parsers {
p := p // capture loop variable for subtest
t.Run(p.ParserFunction, func(t *testing.T) {
require.NotEmpty(t, p.Capabilities, "parser must have at least one capability field defined")
@ -1120,7 +1117,6 @@ func TestCatalogerStructure(t *testing.T) {
require.NoError(t, err)
for _, c := range catalogerEntries {
c := c // capture loop variable for subtest
t.Run(c.Name, func(t *testing.T) {
// ecosystem must always be set (it's MANUAL)

View File

@ -151,11 +151,11 @@ func TestGetter_GetToDir_CertConcerns(t *testing.T) {
}
}
func assertUnknownAuthorityError(t assert.TestingT, err error, _ ...interface{}) bool {
func assertUnknownAuthorityError(t assert.TestingT, err error, _ ...any) bool {
return assert.ErrorAs(t, err, &x509.UnknownAuthorityError{})
}
func assertErrNonArchiveSource(t assert.TestingT, err error, _ ...interface{}) bool {
func assertErrNonArchiveSource(t assert.TestingT, err error, _ ...any) bool {
return assert.ErrorIs(t, err, ErrNonArchiveSource)
}

View File

@ -1,5 +1,4 @@
//go:build !windows
// +build !windows
package file

View File

@ -1,5 +1,4 @@
//go:build !windows
// +build !windows
package file
@ -242,8 +241,8 @@ func assertZipSourceFixtureContents(t testing.TB, actual map[string]string, expe
}
// looks like there isn't a helper for this yet? https://github.com/stretchr/testify/issues/497
func assertErrorAs(expectedErr interface{}) assert.ErrorAssertionFunc {
return func(t assert.TestingT, actualErr error, i ...interface{}) bool {
func assertErrorAs(expectedErr any) assert.ErrorAssertionFunc {
return func(t assert.TestingT, actualErr error, i ...any) bool {
return errors.As(actualErr, &expectedErr)
}
}

View File

@ -143,7 +143,7 @@ func build() *jsonschema.Schema {
// srcMetadataContainer := assembleTypeContainer(sourcemetadata.AllTypes())
// srcMetadataContainerType := reflect.TypeOf(srcMetadataContainer)
documentSchema := reflector.ReflectFromType(reflect.TypeOf(&syftJsonModel.Document{}))
documentSchema := reflector.ReflectFromType(reflect.TypeFor[*syftJsonModel.Document]())
pkgMetadataSchema := reflector.ReflectFromType(reflect.TypeOf(pkgMetadataContainer))
// srcMetadataSchema := reflector.ReflectFromType(reflect.TypeOf(srcMetadataContainer))

View File

@ -30,61 +30,61 @@ func Get() logger.Logger {
}
// Errorf takes a formatted template string and template arguments for the error logging level.
func Errorf(format string, args ...interface{}) {
func Errorf(format string, args ...any) {
log.Errorf(format, args...)
}
// Error logs the given arguments at the error logging level.
func Error(args ...interface{}) {
func Error(args ...any) {
log.Error(args...)
}
// Warnf takes a formatted template string and template arguments for the warning logging level.
func Warnf(format string, args ...interface{}) {
func Warnf(format string, args ...any) {
log.Warnf(format, args...)
}
// Warn logs the given arguments at the warning logging level.
func Warn(args ...interface{}) {
func Warn(args ...any) {
log.Warn(args...)
}
// Infof takes a formatted template string and template arguments for the info logging level.
func Infof(format string, args ...interface{}) {
func Infof(format string, args ...any) {
log.Infof(format, args...)
}
// Info logs the given arguments at the info logging level.
func Info(args ...interface{}) {
func Info(args ...any) {
log.Info(args...)
}
// Debugf takes a formatted template string and template arguments for the debug logging level.
func Debugf(format string, args ...interface{}) {
func Debugf(format string, args ...any) {
log.Debugf(format, args...)
}
// Debug logs the given arguments at the debug logging level.
func Debug(args ...interface{}) {
func Debug(args ...any) {
log.Debug(args...)
}
// Tracef takes a formatted template string and template arguments for the trace logging level.
func Tracef(format string, args ...interface{}) {
func Tracef(format string, args ...any) {
log.Tracef(format, args...)
}
// Trace logs the given arguments at the trace logging level.
func Trace(args ...interface{}) {
func Trace(args ...any) {
log.Trace(args...)
}
// WithFields returns a message logger with multiple key-value fields.
func WithFields(fields ...interface{}) logger.MessageLogger {
func WithFields(fields ...any) logger.MessageLogger {
return log.WithFields(fields...)
}
// Nested returns a new logger with hard coded key-value pairs
func Nested(fields ...interface{}) logger.Logger {
func Nested(fields ...any) logger.Logger {
return log.Nested(fields...)
}

View File

@ -40,28 +40,28 @@ func TestReflectTypeFromJSONName(t *testing.T) {
{
name: "exact match on ID",
lookup: "rust-cargo-lock-entry",
wantRecord: reflect.TypeOf(pkg.RustCargoLockEntry{}),
wantRecord: reflect.TypeFor[pkg.RustCargoLockEntry](),
},
{
name: "exact match on former name",
lookup: "RustCargoPackageMetadata",
wantRecord: reflect.TypeOf(pkg.RustCargoLockEntry{}),
wantRecord: reflect.TypeFor[pkg.RustCargoLockEntry](),
},
{
name: "case insensitive on ID",
lookup: "RUST-CARGO-lock-entrY",
wantRecord: reflect.TypeOf(pkg.RustCargoLockEntry{}),
wantRecord: reflect.TypeFor[pkg.RustCargoLockEntry](),
},
{
name: "case insensitive on alias",
lookup: "rusTcArgopacKagEmEtadATa",
wantRecord: reflect.TypeOf(pkg.RustCargoLockEntry{}),
wantRecord: reflect.TypeFor[pkg.RustCargoLockEntry](),
},
{
name: "consistent override",
// there are two correct answers for this -- we should always get the same answer.
lookup: "HackageMetadataType",
wantRecord: reflect.TypeOf(pkg.HackageStackYamlLockEntry{}),
wantRecord: reflect.TypeFor[pkg.HackageStackYamlLockEntry](),
},
}
for _, tt := range tests {
@ -83,142 +83,142 @@ func TestReflectTypeFromJSONName_LegacyValues(t *testing.T) {
{
name: "map pkg.AlpmDBEntry struct type",
input: "AlpmMetadata",
expected: reflect.TypeOf(pkg.AlpmDBEntry{}),
expected: reflect.TypeFor[pkg.AlpmDBEntry](),
},
{
name: "map pkg.ApkDBEntry struct type",
input: "ApkMetadata",
expected: reflect.TypeOf(pkg.ApkDBEntry{}),
expected: reflect.TypeFor[pkg.ApkDBEntry](),
},
{
name: "map pkg.BinarySignature struct type",
input: "BinaryMetadata",
expected: reflect.TypeOf(pkg.BinarySignature{}),
expected: reflect.TypeFor[pkg.BinarySignature](),
},
{
name: "map pkg.CocoaPodfileLockEntry struct type",
input: "CocoapodsMetadataType",
expected: reflect.TypeOf(pkg.CocoaPodfileLockEntry{}),
expected: reflect.TypeFor[pkg.CocoaPodfileLockEntry](),
},
{
name: "map pkg.ConanLockEntry struct type",
input: "ConanLockMetadataType",
expected: reflect.TypeOf(pkg.ConanV1LockEntry{}),
expected: reflect.TypeFor[pkg.ConanV1LockEntry](),
},
{
name: "map pkg.ConanfileEntry struct type",
input: "ConanMetadataType",
expected: reflect.TypeOf(pkg.ConanfileEntry{}),
expected: reflect.TypeFor[pkg.ConanfileEntry](),
},
{
name: "map pkg.DartPubspecLockEntry struct type",
input: "DartPubMetadata",
expected: reflect.TypeOf(pkg.DartPubspecLockEntry{}),
expected: reflect.TypeFor[pkg.DartPubspecLockEntry](),
},
{
name: "map pkg.DotnetDepsEntry struct type",
input: "DotnetDepsMetadata",
expected: reflect.TypeOf(pkg.DotnetDepsEntry{}),
expected: reflect.TypeFor[pkg.DotnetDepsEntry](),
},
{
name: "map pkg.DpkgDBEntry struct type",
input: "DpkgMetadata",
expected: reflect.TypeOf(pkg.DpkgDBEntry{}),
expected: reflect.TypeFor[pkg.DpkgDBEntry](),
},
{
name: "map pkg.RubyGemspec struct type",
input: "GemMetadata",
expected: reflect.TypeOf(pkg.RubyGemspec{}),
expected: reflect.TypeFor[pkg.RubyGemspec](),
},
{
name: "map pkg.GolangBinaryBuildinfoEntry struct type",
input: "GolangBinMetadata",
expected: reflect.TypeOf(pkg.GolangBinaryBuildinfoEntry{}),
expected: reflect.TypeFor[pkg.GolangBinaryBuildinfoEntry](),
},
{
name: "map pkg.GolangModuleEntry struct type",
input: "GolangModMetadata",
expected: reflect.TypeOf(pkg.GolangModuleEntry{}),
expected: reflect.TypeFor[pkg.GolangModuleEntry](),
},
{
name: "map pkg.JavaArchive struct type",
input: "JavaMetadata",
expected: reflect.TypeOf(pkg.JavaArchive{}),
expected: reflect.TypeFor[pkg.JavaArchive](),
},
{
name: "map pkg.MicrosoftKbPatch struct type",
input: "KbPatchMetadata",
expected: reflect.TypeOf(pkg.MicrosoftKbPatch{}),
expected: reflect.TypeFor[pkg.MicrosoftKbPatch](),
},
{
name: "map pkg.LinuxKernel struct type",
input: "LinuxKernel",
expected: reflect.TypeOf(pkg.LinuxKernel{}),
expected: reflect.TypeFor[pkg.LinuxKernel](),
},
{
name: "map pkg.LinuxKernelModule struct type",
input: "LinuxKernelModule",
expected: reflect.TypeOf(pkg.LinuxKernelModule{}),
expected: reflect.TypeFor[pkg.LinuxKernelModule](),
},
{
name: "map pkg.ElixirMixLockEntry struct type",
input: "MixLockMetadataType",
expected: reflect.TypeOf(pkg.ElixirMixLockEntry{}),
expected: reflect.TypeFor[pkg.ElixirMixLockEntry](),
},
{
name: "map pkg.NixStoreEntry struct type",
input: "NixStoreMetadata",
expected: reflect.TypeOf(pkg.NixStoreEntry{}),
expected: reflect.TypeFor[pkg.NixStoreEntry](),
},
{
name: "map pkg.NpmPackage struct type",
input: "NpmPackageJsonMetadata",
expected: reflect.TypeOf(pkg.NpmPackage{}),
expected: reflect.TypeFor[pkg.NpmPackage](),
},
{
name: "map pkg.NpmPackageLockEntry struct type",
input: "NpmPackageLockJsonMetadata",
expected: reflect.TypeOf(pkg.NpmPackageLockEntry{}),
expected: reflect.TypeFor[pkg.NpmPackageLockEntry](),
},
{
name: "map pkg.PortageEntry struct type",
input: "PortageMetadata",
expected: reflect.TypeOf(pkg.PortageEntry{}),
expected: reflect.TypeFor[pkg.PortageEntry](),
},
{
name: "map pkg.PythonPackage struct type",
input: "PythonPackageMetadata",
expected: reflect.TypeOf(pkg.PythonPackage{}),
expected: reflect.TypeFor[pkg.PythonPackage](),
},
{
name: "map pkg.PythonPipfileLockEntry struct type",
input: "PythonPipfileLockMetadata",
expected: reflect.TypeOf(pkg.PythonPipfileLockEntry{}),
expected: reflect.TypeFor[pkg.PythonPipfileLockEntry](),
},
{
name: "map pkg.PythonRequirementsEntry struct type",
input: "PythonRequirementsMetadata",
expected: reflect.TypeOf(pkg.PythonRequirementsEntry{}),
expected: reflect.TypeFor[pkg.PythonRequirementsEntry](),
},
{
name: "map pkg.PhpPeclEntry struct type",
input: "PhpPeclMetadata",
expected: reflect.TypeOf(pkg.PhpPeclEntry{}),
expected: reflect.TypeFor[pkg.PhpPeclEntry](),
},
{
name: "map pkg.ErlangRebarLockEntry struct type",
input: "RebarLockMetadataType",
expected: reflect.TypeOf(pkg.ErlangRebarLockEntry{}),
expected: reflect.TypeFor[pkg.ErlangRebarLockEntry](),
},
{
name: "map pkg.RDescription struct type",
input: "RDescriptionFileMetadataType",
expected: reflect.TypeOf(pkg.RDescription{}),
expected: reflect.TypeFor[pkg.RDescription](),
},
{
name: "map pkg.RpmDBEntry struct type",
input: "RpmdbMetadata",
expected: reflect.TypeOf(pkg.RpmDBEntry{}),
expected: reflect.TypeFor[pkg.RpmDBEntry](),
},
// these cases are 1:many
{
@ -228,28 +228,28 @@ func TestReflectTypeFromJSONName_LegacyValues(t *testing.T) {
// from a data-shape perspective either would be equally correct
// however, the RPMDBMetadata has been around longer and may have been more widely used
// so we'll map to that type for backwards compatibility.
expected: reflect.TypeOf(pkg.RpmDBEntry{}),
expected: reflect.TypeFor[pkg.RpmDBEntry](),
},
{
name: "map pkg.HackageStackYamlLockEntry struct type - overlap with HackageStack*Metadata",
input: "HackageMetadataType",
// this used to be shared as a use case for both HackageStackYamlLockEntry and HackageStackYamlEntry
// but the HackageStackYamlLockEntry maps most closely to the original data shape.
expected: reflect.TypeOf(pkg.HackageStackYamlLockEntry{}),
expected: reflect.TypeFor[pkg.HackageStackYamlLockEntry](),
},
{
name: "map pkg.PhpComposerLockEntry struct type",
input: "PhpComposerJsonMetadata",
// this used to be shared as a use case for both PhpComposerLockEntry and PhpComposerInstalledEntry
// neither of these is more correct over the other. These parsers were also introduced at the same time.
expected: reflect.TypeOf(pkg.PhpComposerLockEntry{}),
expected: reflect.TypeFor[pkg.PhpComposerLockEntry](),
},
{
name: "map pkg.RustCargoLockEntry struct type",
input: "RustCargoPackageMetadata",
// this used to be shared as a use case for both RustCargoLockEntry and RustBinaryAuditEntry
// neither of these is more correct over the other.
expected: reflect.TypeOf(pkg.RustCargoLockEntry{}),
expected: reflect.TypeFor[pkg.RustCargoLockEntry](),
},
}

View File

@ -92,10 +92,7 @@ func processReaderInChunks(rdr io.Reader, chunkSize int, handler func(data []byt
lastRead := 0
for {
offset := half
if lastRead < half {
offset = lastRead
}
offset := min(lastRead, half)
start := half - offset
if lastRead > 0 {
copy(buf[start:], buf[half+offset:half+lastRead])

View File

@ -26,9 +26,9 @@ var (
pkg.BitnamiPkg,
}
binaryMetadataTypes = []string{
reflect.TypeOf(pkg.ELFBinaryPackageNoteJSONPayload{}).Name(),
reflect.TypeOf(pkg.BinarySignature{}).Name(),
reflect.TypeOf(pkg.JavaVMInstallation{}).Name(),
reflect.TypeFor[pkg.ELFBinaryPackageNoteJSONPayload]().Name(),
reflect.TypeFor[pkg.BinarySignature]().Name(),
reflect.TypeFor[pkg.JavaVMInstallation]().Name(),
}
)

View File

@ -15,7 +15,6 @@ func TestExcludeByFileOwnershipOverlap(t *testing.T) {
packageC := pkg.Package{Name: "package-c", Type: pkg.BinaryPkg, Metadata: pkg.ELFBinaryPackageNoteJSONPayload{Type: "rpm"}}
packageD := pkg.Package{Name: "package-d", Type: pkg.BitnamiPkg}
for _, p := range []*pkg.Package{&packageA, &packageB, &packageC, &packageD} {
p := p
p.SetID()
}

View File

@ -8,11 +8,11 @@ import (
)
var jsonNameFromType = map[reflect.Type][]string{
reflect.TypeOf(source.DirectoryMetadata{}): {"directory", "dir"},
reflect.TypeOf(source.FileMetadata{}): {"file"},
reflect.TypeOf(source.ImageMetadata{}): {"image"},
reflect.TypeOf(source.SnapMetadata{}): {"snap"},
reflect.TypeOf(source.OCIModelMetadata{}): {"oci-model"},
reflect.TypeFor[source.DirectoryMetadata](): {"directory", "dir"},
reflect.TypeFor[source.FileMetadata](): {"file"},
reflect.TypeFor[source.ImageMetadata](): {"image"},
reflect.TypeFor[source.SnapMetadata](): {"snap"},
reflect.TypeFor[source.OCIModelMetadata](): {"oci-model"},
}
func AllTypeNames() []string {

View File

@ -1,6 +1,9 @@
package internal
import "strings"
import (
"slices"
"strings"
)
// HasAnyOfPrefixes returns an indication if the given string has any of the given prefixes.
func HasAnyOfPrefixes(input string, prefixes ...string) bool {
@ -32,12 +35,7 @@ func TruncateMiddleEllipsis(input string, maxLen int) string {
}
func StringInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
return slices.Contains(list, a)
}
func SplitAny(s string, seps string) []string {

View File

@ -198,7 +198,7 @@ func TestConcurrentNewChildAndNewFile(t *testing.T) {
errs := make(chan error, goroutines)
paths := make(chan string, goroutines)
for i := 0; i < goroutines; i++ {
for i := range goroutines {
go func(i int) {
if i%2 == 0 {
child, cleanup, err := td.NewChild("concurrent")
@ -223,7 +223,7 @@ func TestConcurrentNewChildAndNewFile(t *testing.T) {
}
seen := make(map[string]bool)
for i := 0; i < goroutines; i++ {
for range goroutines {
err := <-errs
require.NoError(t, err)
}
@ -250,7 +250,7 @@ func TestConcurrentNewChildDuringCleanup(t *testing.T) {
close(done)
}()
// try creating children concurrently with cleanup — should get errors, not panics
for i := 0; i < 10; i++ {
for range 10 {
_, c, _ := td.NewChild("race")
if c != nil {
c()

View File

@ -6,7 +6,7 @@ import (
)
// Tprintf renders a string from a given template string and field values
func Tprintf(tmpl string, data map[string]interface{}) string {
func Tprintf(tmpl string, data map[string]any) string {
t := template.Must(template.New("").Parse(tmpl))
buf := &bytes.Buffer{}
if err := t.Execute(buf, data); err != nil {

View File

@ -3,6 +3,7 @@ package unknown
import (
"errors"
"fmt"
"slices"
"strings"
"github.com/anchore/syft/internal/log"
@ -155,12 +156,7 @@ func containsErr(out []error, err error) bool {
log.Tracef("error comparing errors: %v", err)
}
}()
for _, e := range out {
if e == err {
return true
}
}
return false
return slices.Contains(out, err)
}
// visitErrors visits every wrapped error. the returned error replaces the provided error, null errors are omitted from

View File

@ -13,7 +13,7 @@ type Identifiable interface {
ID() ID
}
func IDByHash(obj interface{}) (ID, error) {
func IDByHash(obj any) (ID, error) {
f, err := hashstructure.Hash(obj, &hashstructure.HashOptions{
ZeroNil: true,
SlicesAsSets: true,

View File

@ -38,5 +38,5 @@ type Relationship struct {
From Identifiable
To Identifiable
Type RelationshipType
Data interface{}
Data any
}

View File

@ -41,7 +41,7 @@ func (cfg configurationAuditTrail) MarshalJSON() ([]byte, error) {
return nil, err
}
var dataMap map[string]interface{}
var dataMap map[string]any
if err := json.Unmarshal(initialJSON, &dataMap); err != nil {
return nil, err
}
@ -55,13 +55,13 @@ func (cfg configurationAuditTrail) MarshalJSON() ([]byte, error) {
}
// marshalSorted recursively marshals a map with sorted keys
func marshalSorted(m interface{}) ([]byte, error) {
func marshalSorted(m any) ([]byte, error) {
if reflect.TypeOf(m).Kind() != reflect.Map {
return json.Marshal(m)
}
val := reflect.ValueOf(m)
sortedMap := make(map[string]interface{})
sortedMap := make(map[string]any)
for _, key := range val.MapKeys() {
value := val.MapIndex(key).Interface()

View File

@ -33,7 +33,7 @@ func Test_configurationAuditTrail_StructTags(t *testing.T) {
}
func getJSONTags(t *testing.T, v interface{}) []string {
func getJSONTags(t *testing.T, v any) []string {
var tags []string
err := collectJSONTags(t, reflect.ValueOf(v), &tags, "", "")
require.NoError(t, err)
@ -142,7 +142,7 @@ func Test_collectJSONTags(t *testing.T) {
tests := []struct {
name string
v interface{}
v any
want []string
wantErr require.ErrorAssertionFunc
}{

View File

@ -34,7 +34,7 @@ type CreateSBOMConfig struct {
// audit what tool is being used to generate the SBOM
ToolName string
ToolVersion string
ToolConfiguration interface{}
ToolConfiguration any
packageTaskFactories task.Factories
packageCatalogerReferences []pkgcataloging.CatalogerReference

View File

@ -17,14 +17,14 @@ import (
type ErrBadPayload struct {
Type partybus.EventType
Field string
Value interface{}
Value any
}
func (e *ErrBadPayload) Error() string {
return fmt.Sprintf("event='%s' has bad event payload field=%q: %q", string(e.Type), e.Field, e.Value)
}
func newPayloadErr(t partybus.EventType, field string, value interface{}) error {
func newPayloadErr(t partybus.EventType, field string, value any) error {
return &ErrBadPayload{
Type: t,
Field: field,

View File

@ -310,9 +310,9 @@ func toRootPackage(s source.Description) *spdx.Package {
func toSPDXID(identifiable artifact.Identifiable) spdx.ElementID {
id := string(identifiable.ID())
if strings.HasPrefix(id, "SPDXRef-") {
if after, ok := strings.CutPrefix(id, "SPDXRef-"); ok {
// this is already an SPDX ID, no need to change it (except for the prefix)
return spdx.ElementID(helpers.SanitizeElementID(strings.TrimPrefix(id, "SPDXRef-")))
return spdx.ElementID(helpers.SanitizeElementID(after))
}
maxLen := 40
switch it := identifiable.(type) {

View File

@ -479,7 +479,7 @@ func toSyftLocation(f *spdx.File) file.Location {
return l
}
func requireAndTrimPrefix(val interface{}, prefix string) string {
func requireAndTrimPrefix(val any, prefix string) string {
if v, ok := val.(string); ok {
if i := strings.Index(v, prefix); i == 0 {
return strings.Replace(v, prefix, "", 1)

View File

@ -119,7 +119,7 @@ func Test_extractMetadata(t *testing.T) {
oneTwoThreeFour := 1234
tests := []struct {
pkg spdx.Package
meta interface{}
meta any
}{
{
pkg: spdx.Package{

View File

@ -73,6 +73,6 @@ type DependencyGraph map[string]DependencyNode
type ISO8601Date = string
type Scalar interface{} // should be: null | boolean | string | number
type Scalar any // should be: null | boolean | string | number
type Metadata map[string]Scalar

View File

@ -31,7 +31,7 @@ func encodeAuthor(p pkg.Package) string {
return ""
}
func decodeAuthor(author string, metadata interface{}) {
func decodeAuthor(author string, metadata any) {
switch meta := metadata.(type) {
case *pkg.NpmPackage:
meta.Author = author

View File

@ -202,7 +202,7 @@ func setPackageName(p *pkg.Package, c *cyclonedx.Component) {
}
func decodeLocations(vals map[string]string) file.LocationSet {
v := Decode(reflect.TypeOf([]file.Location{}), vals, "syft:location", CycloneDXFields)
v := Decode(reflect.TypeFor[[]file.Location](), vals, "syft:location", CycloneDXFields)
out, ok := v.([]file.Location)
if !ok {
out = nil
@ -210,7 +210,7 @@ func decodeLocations(vals map[string]string) file.LocationSet {
return file.NewLocationSet(out...)
}
func decodePackageMetadata(vals map[string]string, c *cyclonedx.Component, typeName string) interface{} {
func decodePackageMetadata(vals map[string]string, c *cyclonedx.Component, typeName string) any {
if typeName != "" && c.Properties != nil {
metadataType := packagemetadata.ReflectTypeFromJSONName(typeName)
if metadataType == nil {

View File

@ -26,7 +26,7 @@ func ToSyftModel(bom *cyclonedx.BOM) (*sbom.SBOM, error) {
Descriptor: extractDescriptor(bom.Metadata),
}
idMap := make(map[string]interface{})
idMap := make(map[string]any)
if err := collectBomPackages(bom, s, idMap); err != nil {
return nil, err
@ -37,7 +37,7 @@ func ToSyftModel(bom *cyclonedx.BOM) (*sbom.SBOM, error) {
return s, nil
}
func collectBomPackages(bom *cyclonedx.BOM, s *sbom.SBOM, idMap map[string]interface{}) error {
func collectBomPackages(bom *cyclonedx.BOM, s *sbom.SBOM, idMap map[string]any) error {
componentsPresent := false
if bom.Components != nil {
for i := range *bom.Components {
@ -58,7 +58,7 @@ func collectBomPackages(bom *cyclonedx.BOM, s *sbom.SBOM, idMap map[string]inter
return nil
}
func collectPackages(component *cyclonedx.Component, s *sbom.SBOM, idMap map[string]interface{}) {
func collectPackages(component *cyclonedx.Component, s *sbom.SBOM, idMap map[string]any) {
switch component.Type {
case cyclonedx.ComponentTypeOS:
case cyclonedx.ComponentTypeContainer:
@ -168,7 +168,7 @@ func getPropertyValue(component *cyclonedx.Component, name string) string {
return ""
}
func collectRelationships(bom *cyclonedx.BOM, s *sbom.SBOM, idMap map[string]interface{}) {
func collectRelationships(bom *cyclonedx.BOM, s *sbom.SBOM, idMap map[string]any) {
if bom.Dependencies == nil {
return
}

View File

@ -14,7 +14,7 @@ func encodeDescription(p pkg.Package) string {
return ""
}
func decodeDescription(description string, metadata interface{}) {
func decodeDescription(description string, metadata any) {
switch meta := metadata.(type) {
case *pkg.ApkDBEntry:
meta.Description = description

View File

@ -100,7 +100,7 @@ func toCycloneDXAlgorithm(algorithm string) cyclonedx.HashAlgorithm {
return validMap[strings.ToLower(algorithm)]
}
func decodeExternalReferences(c *cyclonedx.Component, metadata interface{}) {
func decodeExternalReferences(c *cyclonedx.Component, metadata any) {
if c.ExternalReferences == nil {
return
}

View File

@ -11,7 +11,7 @@ func encodeGroup(p pkg.Package) string {
return ""
}
func decodeGroup(group string, metadata interface{}) {
func decodeGroup(group string, metadata any) {
if meta, ok := metadata.(*pkg.JavaArchive); ok {
if meta.PomProperties == nil {
meta.PomProperties = &pkg.JavaPomProperties{}

View File

@ -10,7 +10,7 @@ var (
CycloneDXFields = RequiredTag("cyclonedx")
)
func EncodeProperties(obj interface{}, prefix string) (out []cyclonedx.Property) {
func EncodeProperties(obj any, prefix string) (out []cyclonedx.Property) {
for _, p := range Sorted(Encode(obj, prefix, CycloneDXFields)) {
out = append(out, cyclonedx.Property{
Name: p.Name,
@ -23,8 +23,8 @@ func EncodeProperties(obj interface{}, prefix string) (out []cyclonedx.Property)
func decodeProperties(properties []cyclonedx.Property, prefix string) map[string]string {
labels := make(map[string]string)
for _, property := range properties {
if strings.HasPrefix(property.Name, prefix) {
labelName := strings.TrimPrefix(property.Name, prefix)
if after, ok := strings.CutPrefix(property.Name, prefix); ok {
labelName := after
labels[labelName] = property.Value
}
}

View File

@ -300,8 +300,8 @@ func decode(vals map[string]string, value reflect.Value, prefix string, fn Field
// NOTE: this will not work for nested maps
for key := range vals {
// test for map prefix
if strings.HasPrefix(key, str) {
keyVals[key] = strings.TrimPrefix(key, str)
if after, ok := strings.CutPrefix(key, str); ok {
keyVals[key] = after
// create new placeholder and decode key
newKeyType := keyType
if keyType.Kind() == reflect.Ptr {

View File

@ -46,7 +46,7 @@ func Test_EncodeDecodeCycle(t *testing.T) {
tests := []struct {
name string
value interface{}
value any
}{
{
name: "all values",

View File

@ -18,7 +18,7 @@ func encodePublisher(p pkg.Package) string {
return ""
}
func decodePublisher(publisher string, metadata interface{}) {
func decodePublisher(publisher string, metadata any) {
switch meta := metadata.(type) {
case *pkg.ApkDBEntry:
meta.Maintainer = publisher

View File

@ -44,7 +44,7 @@ type Descriptor struct {
Version string `json:"version"`
// Configuration contains the tool configuration used during SBOM generation.
Configuration interface{} `json:"configuration,omitempty"`
Configuration any `json:"configuration,omitempty"`
}
// Schema specifies the JSON schema version and URL reference that defines the structure and validation rules for this document format.

View File

@ -11,7 +11,7 @@ import (
func TestIDLikes_UnmarshalJSON(t *testing.T) {
tests := []struct {
name string
data interface{}
data any
expected IDLikes
}{
{

View File

@ -205,7 +205,7 @@ func unpackPkgMetadata(p *Package, unpacker packageMetadataUnpacker) error {
if typ == nil {
// capture unknown metadata as a generic struct
if len(unpacker.Metadata) > 0 {
var val interface{}
var val any
if err := json.Unmarshal(unpacker.Metadata, &val); err != nil {
return err
}

View File

@ -207,7 +207,7 @@ func Test_UnmarshalJSON(t *testing.T) {
`),
assert: func(p *Package) {
assert.Equal(t, pkg.RpmPkg, p.Type)
assert.Equal(t, reflect.TypeOf(pkg.RpmDBEntry{}).Name(), reflect.TypeOf(p.Metadata).Name())
assert.Equal(t, reflect.TypeFor[pkg.RpmDBEntry]().Name(), reflect.TypeOf(p.Metadata).Name())
},
},
{
@ -248,7 +248,7 @@ func Test_UnmarshalJSON(t *testing.T) {
`),
assert: func(p *Package) {
assert.Equal(t, pkg.RpmPkg, p.Type)
assert.Equal(t, reflect.TypeOf(pkg.RpmArchive{}).Name(), reflect.TypeOf(p.Metadata).Name())
assert.Equal(t, reflect.TypeFor[pkg.RpmArchive]().Name(), reflect.TypeOf(p.Metadata).Name())
},
},
{
@ -287,7 +287,7 @@ func Test_UnmarshalJSON(t *testing.T) {
}`),
assert: func(p *Package) {
assert.Equal(t, pkg.HackagePkg, p.Type)
assert.Equal(t, reflect.TypeOf(pkg.HackageStackYamlEntry{}).Name(), reflect.TypeOf(p.Metadata).Name())
assert.Equal(t, reflect.TypeFor[pkg.HackageStackYamlEntry]().Name(), reflect.TypeOf(p.Metadata).Name())
},
},
{
@ -327,7 +327,7 @@ func Test_UnmarshalJSON(t *testing.T) {
}`),
assert: func(p *Package) {
assert.Equal(t, pkg.HackagePkg, p.Type)
assert.Equal(t, reflect.TypeOf(pkg.HackageStackYamlLockEntry{}).Name(), reflect.TypeOf(p.Metadata).Name())
assert.Equal(t, reflect.TypeFor[pkg.HackageStackYamlLockEntry]().Name(), reflect.TypeOf(p.Metadata).Name())
},
},
{
@ -355,7 +355,7 @@ func Test_UnmarshalJSON(t *testing.T) {
}`),
assert: func(p *Package) {
assert.Equal(t, pkg.HackagePkg, p.Type)
assert.Equal(t, reflect.TypeOf(pkg.RustCargoLockEntry{}).Name(), reflect.TypeOf(p.Metadata).Name())
assert.Equal(t, reflect.TypeFor[pkg.RustCargoLockEntry]().Name(), reflect.TypeOf(p.Metadata).Name())
},
},
{
@ -383,7 +383,7 @@ func Test_UnmarshalJSON(t *testing.T) {
}`),
assert: func(p *Package) {
assert.Equal(t, pkg.HackagePkg, p.Type)
assert.Equal(t, reflect.TypeOf(pkg.RustBinaryAuditEntry{}).Name(), reflect.TypeOf(p.Metadata).Name())
assert.Equal(t, reflect.TypeFor[pkg.RustBinaryAuditEntry]().Name(), reflect.TypeOf(p.Metadata).Name())
},
},
{
@ -654,7 +654,7 @@ func Test_unpackMetadata(t *testing.T) {
}
}`),
wantErr: require.Error,
wantMetadata: map[string]interface{}{
wantMetadata: map[string]any{
"thing": "thing-1",
},
},

View File

@ -12,5 +12,5 @@ type Relationship struct {
Type string `json:"type"`
// Metadata contains additional relationship-specific metadata.
Metadata interface{} `json:"metadata,omitempty"`
Metadata any `json:"metadata,omitempty"`
}

View File

@ -30,7 +30,7 @@ type Source struct {
Type string `json:"type"`
// Metadata contains additional source-specific metadata.
Metadata interface{} `json:"metadata"`
Metadata any `json:"metadata"`
}
// sourceUnpacker is used to unmarshal Source objects
@ -97,7 +97,7 @@ func cleanPreSchemaV9MetadataType(t string) string {
return t
}
func extractPreSchemaV9Metadata(t string, target []byte) (interface{}, error) {
func extractPreSchemaV9Metadata(t string, target []byte) (any, error) {
switch t {
case "directory", "dir":
cleanTarget, err := strconv.Unquote(string(target))

View File

@ -4,6 +4,7 @@ import (
"encoding/json"
"os"
"path/filepath"
"slices"
"testing"
"github.com/iancoleman/strcase"
@ -79,10 +80,8 @@ func isFollowingConvention(path, fieldName string) (bool, string) {
result := exp == fieldName
exception := func(exceptions ...string) (bool, string) {
for _, e := range exceptions {
if e == fieldName {
return true, fieldName
}
if slices.Contains(exceptions, fieldName) {
return true, fieldName
}
return result, exp
}

View File

@ -21,11 +21,11 @@ import (
)
// MetadataType infers the metadata type value based on the pkg.Metadata payload.
func MetadataType(metadata interface{}) string {
func MetadataType(metadata any) string {
return metadataType(metadata, false)
}
func metadataType(metadata interface{}, legacy bool) string {
func metadataType(metadata any, legacy bool) string {
if legacy {
return packagemetadata.JSONLegacyName(metadata)
}

View File

@ -223,7 +223,7 @@ func toInternalLinuxRelease(d model.LinuxRelease) *linux.Release {
}
func toSyftRelationships(doc *model.Document, catalog *pkg.Collection, relationships []model.Relationship, idAliases map[string]string) ([]artifact.Relationship, []error) {
idMap := make(map[string]interface{})
idMap := make(map[string]any)
for _, p := range catalog.Sorted() {
idMap[string(p.ID())] = p
@ -263,7 +263,7 @@ func toSyftSource(s model.Source) source.Source {
return source.FromDescription(*description)
}
func toSyftRelationship(idMap map[string]interface{}, relationship model.Relationship, idAliases map[string]string) (*artifact.Relationship, error) {
func toSyftRelationship(idMap map[string]any, relationship model.Relationship, idAliases map[string]string) (*artifact.Relationship, error) {
id := func(id string) string {
aliased, ok := idAliases[id]
if ok {

View File

@ -448,7 +448,7 @@ func Test_toSyftRelationship(t *testing.T) {
parentPackage := packageWithId("some-parent-id")
tests := []struct {
name string
idMap map[string]interface{}
idMap map[string]any
idAliases map[string]string
relationships model.Relationship
want *artifact.Relationship
@ -456,7 +456,7 @@ func Test_toSyftRelationship(t *testing.T) {
}{
{
name: "one relationship no warnings",
idMap: map[string]interface{}{
idMap: map[string]any{
"some-child-id": childPackage,
"some-parent-id": parentPackage,
},
@ -474,7 +474,7 @@ func Test_toSyftRelationship(t *testing.T) {
},
{
name: "relationship unknown type one warning",
idMap: map[string]interface{}{
idMap: map[string]any{
"some-child-id": childPackage,
"some-parent-id": parentPackage,
},
@ -490,7 +490,7 @@ func Test_toSyftRelationship(t *testing.T) {
},
{
name: "relationship missing child ID one warning",
idMap: map[string]interface{}{
idMap: map[string]any{
"some-parent-id": parentPackage,
},
idAliases: map[string]string{},
@ -505,7 +505,7 @@ func Test_toSyftRelationship(t *testing.T) {
},
{
name: "relationship missing parent ID one warning",
idMap: map[string]interface{}{
idMap: map[string]any{
"some-child-id": childPackage,
},
idAliases: map[string]string{},

View File

@ -34,7 +34,7 @@ func NewFormatEncoder(cfg EncoderConfig) (sbom.FormatEncoder, error) {
// TODO: revisit this... should no template file be an error or simply render an empty result? or render the json output?
// Note: do not check for the existence of the template file here, as the default encoder cannot provide one.
f := sprig.HermeticTxtFuncMap()
f["getLastIndex"] = func(collection interface{}) int {
f["getLastIndex"] = func(collection any) int {
if v := reflect.ValueOf(collection); v.Kind() == reflect.Slice {
return v.Len() - 1
}
@ -42,7 +42,7 @@ func NewFormatEncoder(cfg EncoderConfig) (sbom.FormatEncoder, error) {
return 0
}
// Checks if a field is defined
f["hasField"] = func(obj interface{}, field string) bool {
f["hasField"] = func(obj any, field string) bool {
t := reflect.TypeOf(obj)
_, ok := t.FieldByName(field)
return ok

View File

@ -148,7 +148,7 @@ func TestValidateSourcePlatform_UnsupportedMetadataTypes(t *testing.T) {
tests := []struct {
name string
metadata interface{}
metadata any
}{
{
name: "string metadata",

View File

@ -385,8 +385,8 @@ func (r directoryIndexer) addSymlinkToIndex(p string, info os.FileInfo) (string,
// we cannot directly concatenate ".." to "/root/symlink",however,
// the parent directory of linkTarget should be "/root"
for strings.HasPrefix(dir, "..") {
if strings.HasPrefix(dir, "../") {
dir = strings.TrimPrefix(dir, "../")
if after, ok := strings.CutPrefix(dir, "../"); ok {
dir = after
} else {
dir = strings.TrimPrefix(dir, "..")
}

View File

@ -1,5 +1,4 @@
//go:build !windows
// +build !windows
package fileresolver

View File

@ -1,5 +1,4 @@
//go:build !windows
// +build !windows
package fileresolver
@ -1355,7 +1354,7 @@ func (t testFileInfo) IsDir() bool {
panic("implement me")
}
func (t testFileInfo) Sys() interface{} {
func (t testFileInfo) Sys() any {
panic("implement me")
}

View File

@ -426,7 +426,7 @@ func assertSkipErr() assert.ErrorAssertionFunc {
}
func assertErrorIs(want error) assert.ErrorAssertionFunc {
return func(t assert.TestingT, got error, msgAndArgs ...interface{}) bool {
return func(t assert.TestingT, got error, msgAndArgs ...any) bool {
return assert.ErrorIs(t, got, want, msgAndArgs...)
}
}

View File

@ -300,7 +300,7 @@ func (u UnindexedDirectory) resolveLinks(filePath string) []string {
resolvedPath := ""
parts := strings.Split(filePath, "/")
for i := 0; i < len(parts); i++ {
for i := range parts {
part := parts[i]
if resolvedPath == "" {
resolvedPath = part

View File

@ -1,5 +1,4 @@
//go:build !windows
// +build !windows
package fileresolver

View File

@ -168,7 +168,7 @@ func TestReaderAtAdapter_ReadAt(t *testing.T) {
adapter := newReaderAtAdapter(reader)
// read the same data multiple times
for i := 0; i < 3; i++ {
for i := range 3 {
buf := make([]byte, 5)
n, err := adapter.ReadAt(buf, 7)
@ -194,12 +194,12 @@ func TestReaderAtAdapter_ReadAt(t *testing.T) {
var wg sync.WaitGroup
results := make(chan bool, numGoroutines*numReads)
for i := 0; i < numGoroutines; i++ {
for i := range numGoroutines {
wg.Add(1)
go func(goroutineID int) {
defer wg.Done()
for j := 0; j < numReads; j++ {
for range numReads {
offset := int64(goroutineID % len(td))
buf := make([]byte, 1)

View File

@ -71,11 +71,11 @@ type spaceDelimitedStringSlice []string
func (m *ApkDBEntry) UnmarshalJSON(data []byte) error {
var fields []reflect.StructField
t := reflect.TypeOf(ApkDBEntry{})
t := reflect.TypeFor[ApkDBEntry]()
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if f.Name == "Dependencies" {
f.Type = reflect.TypeOf(spaceDelimitedStringSlice{})
f.Type = reflect.TypeFor[spaceDelimitedStringSlice]()
}
fields = append(fields, f)
}
@ -89,7 +89,7 @@ func (m *ApkDBEntry) UnmarshalJSON(data []byte) error {
}
func (a *spaceDelimitedStringSlice) UnmarshalJSON(data []byte) error {
var jsonObj interface{}
var jsonObj any
if err := json.Unmarshal(data, &jsonObj); err != nil {
return err
@ -103,7 +103,7 @@ func (a *spaceDelimitedStringSlice) UnmarshalJSON(data []byte) error {
*a = strings.Split(obj, " ")
}
return nil
case []interface{}:
case []any:
s := make([]string, 0, len(obj))
for _, v := range obj {
value, ok := v.(string)

View File

@ -76,7 +76,7 @@ func TestGGUFCataloger(t *testing.T) {
GGUFVersion: 3,
TensorCount: 0,
MetadataKeyValuesHash: "6e3d368066455ce4",
RemainingKeyValues: map[string]interface{}{
RemainingKeyValues: map[string]any{
"general.some_random_kv": "foobar",
},
},
@ -113,7 +113,7 @@ func TestGGUFCataloger(t *testing.T) {
GGUFVersion: 3,
TensorCount: 0,
MetadataKeyValuesHash: "9dc6f23591062a27",
RemainingKeyValues: map[string]interface{}{
RemainingKeyValues: map[string]any{
"gpt2.context_length": "1024",
"gpt2.embedding_length": uint32(768),
},

View File

@ -46,8 +46,8 @@ func copyHeader(w io.Writer, r io.Reader) error {
}
// Helper to convert gguf_parser metadata to simpler types
func convertGGUFMetadataKVs(kvs gguf_parser.GGUFMetadataKVs) map[string]interface{} {
result := make(map[string]interface{})
func convertGGUFMetadataKVs(kvs gguf_parser.GGUFMetadataKVs) map[string]any {
result := make(map[string]any)
for _, kv := range kvs {
// Skip standard fields that are extracted separately

View File

@ -35,7 +35,7 @@ type testGGUFBuilder struct {
type testKVPair struct {
key string
valueType uint32
value interface{}
value any
}
func newTestGGUFBuilder() *testGGUFBuilder {

View File

@ -153,7 +153,7 @@ func newScanner(reader io.Reader) *bufio.Scanner {
scanner := bufio.NewScanner(reader)
scanner.Buffer(bufScan, maxScannerCapacity)
onDoubleLF := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
for i := 0; i < len(data); i++ {
for i := range data {
if i > 0 && data[i-1] == '\n' && data[i] == '\n' {
return i + 1, data[:i-1], nil
}
@ -188,7 +188,7 @@ func getLocation(path string, resolver file.Resolver) (file.Location, error) {
func parseDatabase(b *bufio.Scanner) (*parsedData, error) {
var err error
pkgFields := make(map[string]interface{})
pkgFields := make(map[string]any)
for b.Scan() {
fields := strings.SplitN(b.Text(), "\n", 2)
@ -213,12 +213,12 @@ func parseDatabase(b *bufio.Scanner) (*parsedData, error) {
}
pkgFields[key] = files
case "backup":
var backup []map[string]interface{}
var backup []map[string]any
for _, f := range strings.Split(value, "\n") {
fields := strings.SplitN(f, "\t", 2)
p := fmt.Sprintf("/%s", fields[0])
if ok := ignoredFiles[p]; !ok {
backup = append(backup, map[string]interface{}{
backup = append(backup, map[string]any{
"path": p,
"digests": []file.Digest{{
Algorithm: "md5",
@ -257,7 +257,7 @@ func processLibrarySpecs(value string) []string {
return librarySpecs
}
func parsePkgFiles(pkgFields map[string]interface{}) (*parsedData, error) {
func parsePkgFiles(pkgFields map[string]any) (*parsedData, error) {
var entry parsedData
if err := mapstructure.Decode(pkgFields, &entry); err != nil {
return nil, fmt.Errorf("unable to parse ALPM metadata: %w", err)
@ -292,7 +292,7 @@ func parseMtree(r io.Reader) ([]pkg.AlpmFileRecord, error) {
for _, f := range specDh.Entries {
var entry pkg.AlpmFileRecord
entry.Digests = make([]file.Digest, 0)
fileFields := make(map[string]interface{})
fileFields := make(map[string]any)
if ok := ignoredFiles[f.Name]; ok {
continue
}

View File

@ -195,7 +195,7 @@ func Test_CondaCataloger(t *testing.T) {
name: "badly formatted conda meta json file",
fixture: "testdata/conda-meta-bad-json",
expectedPackages: nil,
wantErr: func(t require.TestingT, err error, msgAndArgs ...interface{}) {
wantErr: func(t require.TestingT, err error, msgAndArgs ...any) {
require.Error(t, err)
require.Contains(t, err.Error(), "failed to parse conda-meta package file at conda-meta/package-1.2.3-pyhd8ed1ab_0.json")
require.Contains(t, err.Error(), "invalid character")

View File

@ -194,8 +194,8 @@ func splitPkgList(pkgList string) (ret []string) {
return ret
}
func extractAllFields(reader *bufio.Reader) (map[string]interface{}, error) {
dpkgFields := make(map[string]interface{})
func extractAllFields(reader *bufio.Reader) (map[string]any, error) {
dpkgFields := make(map[string]any)
var key string
for {
@ -234,7 +234,7 @@ func extractAllFields(reader *bufio.Reader) (map[string]interface{}, error) {
dpkgFields[key] = val
default:
// parse a new key
var val interface{}
var val any
key, val, err = handleNewKeyValue(line)
if err != nil {
log.Tracef("parsing dpkg status: extracting key-value from line: %s err: %v", line, err)
@ -259,7 +259,7 @@ func extractSourceVersion(source string) (string, string) {
}
// handleNewKeyValue parse a new key-value pair from the given unprocessed line
func handleNewKeyValue(line string) (key string, val interface{}, err error) {
func handleNewKeyValue(line string) (key string, val any, err error) {
if i := strings.Index(line, ":"); i > 0 {
key = strings.TrimSpace(line[0:i])
// mapstruct cant handle "-"

View File

@ -339,7 +339,7 @@ func TestSourceVersionExtract(t *testing.T) {
}
func requireAs(expected error) require.ErrorAssertionFunc {
return func(t require.TestingT, err error, i ...interface{}) {
return func(t require.TestingT, err error, i ...any) {
require.ErrorAs(t, err, &expected)
}
}
@ -413,7 +413,7 @@ func Test_handleNewKeyValue(t *testing.T) {
name string
line string
wantKey string
wantVal interface{}
wantVal any
wantErr require.ErrorAssertionFunc
}{
{

View File

@ -10,7 +10,7 @@ import (
)
type erlangNode struct {
value interface{}
value any
}
var errSkipComments = errors.New("")
@ -39,7 +39,7 @@ func (e erlangNode) Get(index int) erlangNode {
return erlangNode{}
}
func node(value interface{}) erlangNode {
func node(value any) erlangNode {
return erlangNode{
value: value,
}

View File

@ -143,9 +143,9 @@ func replaceLicenseGroups(licenses []string, groups map[string][]string) []strin
result := make([]string, 0, len(licenses))
for _, license := range licenses {
if strings.HasPrefix(license, "@") {
if after, ok := strings.CutPrefix(license, "@"); ok {
// this is a license group...
name := strings.TrimPrefix(license, "@")
name := after
if expandedLicenses, ok := groups[name]; ok {
result = append(result, expandedLicenses...)
} else {

View File

@ -346,7 +346,7 @@ func parseELFPTLoadOffsets(elfHeader []byte) []uint64 {
phnum := binary.LittleEndian.Uint16(elfHeader[0x38:0x3a])
var offsets []uint64
for i := uint16(0); i < phnum; i++ {
for i := range phnum {
phStart := phoff + uint64(i)*uint64(phentsize)
if phStart+uint64(phentsize) > uint64(len(elfHeader)) {
break
@ -499,10 +499,7 @@ func decompressLZMA(compressedData []byte, uncompressedSize uint32) ([]byte, err
// it may be that the dictionary size was not considered properly in this code.
const minDictSize = 64 * 1024 // 64KB minimum
const maxDictSize = 128 * 1024 * 1024 // 128MB maximum
dictSize := nextPowerOf2(uncompressedSize)
if dictSize < minDictSize {
dictSize = minDictSize
}
dictSize := max(nextPowerOf2(uncompressedSize), minDictSize)
if dictSize > maxDictSize {
dictSize = maxDictSize
}

View File

@ -42,8 +42,8 @@ func upstreamCandidates(m pkg.ApkDBEntry) (candidates []upstreamCandidate) {
}
for prefix, typ := range prefixesToPackageType {
if strings.HasPrefix(name, prefix) {
t := strings.TrimPrefix(name, prefix)
if after, ok0 := strings.CutPrefix(name, prefix); ok0 {
t := after
if t != "" {
candidates = append(candidates, upstreamCandidate{Name: t, Type: typ})
return candidates

View File

@ -260,8 +260,8 @@ func addEntryForNPMPackage(indexed *dictionary.Indexed, ref string, cpeItemName
}
func phpExtensionPackageFromURLFragment(ref string) string {
if strings.HasPrefix(ref, "package/") { // package/HTML_QuickForm/download
ref = strings.TrimPrefix(ref, "package/")
if after, ok := strings.CutPrefix(ref, "package/"); ok { // package/HTML_QuickForm/download
ref = after
components := strings.Split(ref, "/")
if len(components) < 1 {

View File

@ -206,7 +206,7 @@ func (c *NVDAPIClient) fetchDateRange(ctx context.Context, start, end time.Time)
func (c *NVDAPIClient) fetchPage(ctx context.Context, startIndex int, start, end time.Time) (NVDProductsResponse, error) {
var lastErr error
for attempt := 0; attempt < maxRetries; attempt++ {
for attempt := range maxRetries {
// wait for rate limiter
if err := c.rateLimiter.Wait(ctx); err != nil {
return NVDProductsResponse{}, fmt.Errorf("rate limiter error: %w", err)

View File

@ -33,7 +33,6 @@ func Test_IsLicenseFile(t *testing.T) {
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got := IsLicenseFile(tt.input)

View File

@ -206,7 +206,7 @@ func readDepsJSONAtOffset(r io.ReadSeeker, offset, size int64) (string, error) {
// findDepsJSONInManifest parses manifest entries to find deps.json (for V1 bundles or fallback)
func findDepsJSONInManifest(r io.ReadSeeker, numFiles int32, majorVersion uint32) (string, error) {
for i := int32(0); i < numFiles; i++ {
for range numFiles {
var offset, size int64
if err := binary.Read(r, binary.LittleEndian, &offset); err != nil {

View File

@ -422,7 +422,7 @@ func parseResourceDirectory(sec *extractedSection, dirs *u32set.Set, fields map[
return fmt.Errorf("invalid number of entries in resource directory: %d", numEntries)
}
for i := 0; i < numEntries; i++ {
for i := range numEntries {
var entry peImageResourceDirectoryEntry
entryOffset := offset + int64(binary.Size(directoryHeader)) + int64(i*binary.Size(entry))

View File

@ -7,6 +7,7 @@ import (
"os"
"path/filepath"
"reflect"
"slices"
"sort"
"sync"
"time"
@ -322,7 +323,7 @@ func (t *MetadataTracker) RecordCatalogerObservations(
// getMetadataTypeName returns the fully qualified type name of metadata (e.g., "pkg.ApkDBEntry").
// extracts just the last package path segment to keep names concise.
func getMetadataTypeName(metadata interface{}) string {
func getMetadataTypeName(metadata any) string {
if metadata == nil {
return ""
}
@ -361,7 +362,7 @@ func lastPathSegment(path string) string {
// hasIntegrityHash checks if metadata contains an integrity hash field.
// note: this uses a best-effort approach checking common field names.
// DO NOT depend on these values in auto-generated capabilities definitions - use for test validation only.
func hasIntegrityHash(metadata interface{}) bool {
func hasIntegrityHash(metadata any) bool {
v := dereferenceToStruct(metadata)
if !v.IsValid() || v.Kind() != reflect.Struct {
return false
@ -378,7 +379,7 @@ func hasIntegrityHash(metadata interface{}) bool {
// hasFileDigests checks if metadata contains file records with digests.
// note: uses a best-effort approach for detection.
// DO NOT depend on these values in auto-generated capabilities definitions - use for test validation only.
func hasFileDigests(metadata interface{}) bool {
func hasFileDigests(metadata any) bool {
v := dereferenceToStruct(metadata)
if !v.IsValid() || v.Kind() != reflect.Struct {
return false
@ -400,7 +401,7 @@ func hasFileDigests(metadata interface{}) bool {
// dereferenceToStruct handles pointer dereferencing and returns the underlying value.
// returns an invalid value if the input is nil or not convertible to a struct.
func dereferenceToStruct(v interface{}) reflect.Value {
func dereferenceToStruct(v any) reflect.Value {
if v == nil {
return reflect.Value{}
}
@ -460,12 +461,7 @@ func countDependencyRelationships(relationships []artifact.Relationship) int {
// contains checks if a string slice contains a specific string.
func contains(slice []string, item string) bool {
for _, s := range slice {
if s == item {
return true
}
}
return false
return slices.Contains(slice, item)
}
// ===== Result Writing =====
@ -494,7 +490,7 @@ func (t *MetadataTracker) WriteResults() error {
}
// writeJSONFile writes data as pretty-printed JSON to the specified path.
func writeJSONFile(path string, data interface{}) error {
func writeJSONFile(path string, data any) error {
file, err := os.Create(path)
if err != nil {
return err

View File

@ -6,6 +6,7 @@ import (
"context"
"fmt"
"io"
"slices"
"sort"
"github.com/scylladb/go-set/strset"
@ -43,10 +44,8 @@ func NewObservingResolver(resolver file.Resolver) *ObservingResolver {
// ObservedPathQuery checks if a specific path pattern was queried.
func (r *ObservingResolver) ObservedPathQuery(input string) bool {
for _, queries := range r.pathQueries {
for _, query := range queries {
if query == input {
return true
}
if slices.Contains(queries, input) {
return true
}
}
return false

View File

@ -498,7 +498,7 @@ func stringPackage(p pkg.Package) string {
}
// getFunctionName extracts the function name from a function pointer using reflection
func getFunctionName(fn interface{}) string {
func getFunctionName(fn any) string {
// get the function pointer
ptr := reflect.ValueOf(fn).Pointer()
@ -532,7 +532,7 @@ func getCatalogerName(_ *testing.T, cataloger pkg.Cataloger) string {
// getPackagePath extracts the package path from a function name
// e.g., "github.com/anchore/syft/syft/pkg/cataloger/python.parseRequirementsTxt" -> "python"
func getPackagePath(fn interface{}) string {
func getPackagePath(fn any) string {
ptr := reflect.ValueOf(fn).Pointer()
funcForPC := runtime.FuncForPC(ptr)
if funcForPC == nil {
@ -566,7 +566,7 @@ func getPackagePath(fn interface{}) string {
func getPackagePathFromCataloger(_ pkg.Cataloger) string {
// walk up the call stack to find the test file
// we're looking for a file in the cataloger directory structure
for i := 0; i < 10; i++ {
for i := range 10 {
_, file, _, ok := runtime.Caller(i)
if !ok {
break

View File

@ -395,7 +395,6 @@ func TestParseJar(t *testing.T) {
var parent *pkg.Package
for _, a := range actual {
a := a
if strings.Contains(a.Name, "example-") {
parent = &a
}
@ -682,7 +681,6 @@ func TestParseNestedJar(t *testing.T) {
actualNameVersionPairSet := strset.New()
for _, a := range actual {
a := a
key := makeKey(&a)
actualNameVersionPairSet.Add(key)
if !expectedNameVersionPairSet.Has(key) {
@ -701,7 +699,6 @@ func TestParseNestedJar(t *testing.T) {
}
for _, a := range actual {
a := a
actualKey := makeKey(&a)
metadata := a.Metadata.(pkg.JavaArchive)
@ -1493,7 +1490,7 @@ func Test_deterministicMatchingPomProperties(t *testing.T) {
t.Run(test.fixture, func(t *testing.T) {
fixturePath := generateJavaMetadataJarFixture(t, test.fixture, "jar")
for i := 0; i < 5; i++ {
for range 5 {
func() {
fixture, err := os.Open(fixturePath)
require.NoError(t, err)

View File

@ -58,14 +58,14 @@ func parseJavaManifest(path string, reader io.Reader) (*pkg.JavaManifest, error)
}
// this is a new key-value pair
idx := strings.Index(line, ":")
if idx == -1 {
before, after, ok := strings.Cut(line, ":")
if !ok {
log.Debugf("java manifest %q: unable to split java manifest key-value pairs: %q", path, line)
continue
}
key := strings.TrimSpace(line[0:idx])
value := strings.TrimSpace(line[idx+1:])
key := strings.TrimSpace(before)
value := strings.TrimSpace(after)
if key == "" {
// don't attempt to add new keys or sections unless there is a non-empty key

View File

@ -446,7 +446,7 @@ func Test_resolveLicenses(t *testing.T) {
require.Equal(t, "child-one", child1.Name)
got := child1.Licenses.ToSlice()
for i := 0; i < len(got); i++ {
for i := range got {
// ignore locations, just check license text
(&got[i]).Locations = file.LocationSet{}
}
@ -810,7 +810,7 @@ func expectedTransientPackageData() expected {
}
pkgs := make([]pkg.Package, len(allPackages))
for i := 0; i < len(allPackages); i++ {
for i := range allPackages {
pkgs[i] = *allPackages[i]
}

View File

@ -7,6 +7,7 @@ import (
"fmt"
"io"
"regexp"
"slices"
"strings"
"github.com/go-viper/mapstructure/v2"
@ -95,7 +96,7 @@ func (p *person) UnmarshalJSON(b []byte) error {
}
} else {
// it's a map that may contain fields of various data types (not just strings)
var fields map[string]interface{}
var fields map[string]any
if err := json.Unmarshal(b, &fields); err != nil {
return fmt.Errorf("unable to parse package.json author: %w", err)
}
@ -210,12 +211,7 @@ func licensesFromJSON(b []byte) ([]npmPackageLicense, error) {
var filepathSeparator = regexp.MustCompile(`[\\/]`)
func pathContainsNodeModulesDirectory(p string) bool {
for _, subPath := range filepathSeparator.Split(p, -1) {
if subPath == "node_modules" {
return true
}
}
return false
return slices.Contains(filepathSeparator.Split(p, -1), "node_modules")
}
func (p *people) UnmarshalJSON(b []byte) error {
@ -242,7 +238,7 @@ func (p *people) UnmarshalJSON(b []byte) error {
}
// Try to unmarshal as an array of objects
var authorObjs []map[string]interface{}
var authorObjs []map[string]any
if err := json.Unmarshal(b, &authorObjs); err == nil {
// Successfully parsed as an array of objects
auths := make([]person, len(authorObjs))

View File

@ -41,7 +41,7 @@ type pnpmV6PackageEntry struct {
// pnpmV6LockYaml represents the structure of pnpm lockfiles for versions < 9.0.
type pnpmV6LockYaml struct {
Dependencies map[string]interface{} `yaml:"dependencies"`
Dependencies map[string]any `yaml:"dependencies"`
Packages map[string]pnpmV6PackageEntry `yaml:"packages"`
}
@ -61,7 +61,7 @@ type pnpmV9PackageEntry struct {
// pnpmV9LockYaml represents the structure of pnpm lockfiles for versions >= 9.0.
type pnpmV9LockYaml struct {
LockfileVersion string `yaml:"lockfileVersion"`
Importers map[string]interface{} `yaml:"importers"` // Using interface{} for forward compatibility
Importers map[string]any `yaml:"importers"` // Using interface{} for forward compatibility
Packages map[string]pnpmV9PackageEntry `yaml:"packages"`
Snapshots map[string]pnpmV9SnapshotEntry `yaml:"snapshots"`
}
@ -214,11 +214,11 @@ func (a genericPnpmLockAdapter) parsePnpmLock(ctx context.Context, resolver file
}
// parseVersionField extracts the version string from a dependency entry.
func parseVersionField(name string, info interface{}) (string, error) {
func parseVersionField(name string, info any) (string, error) {
switch v := info.(type) {
case string:
return v, nil
case map[string]interface{}:
case map[string]any:
if ver, ok := v["version"].(string); ok {
// e.g., "1.2.3(react@17.0.0)" -> "1.2.3"
return strings.SplitN(ver, "(", 2)[0], nil

View File

@ -14,7 +14,7 @@ type rockspec struct {
type rockspecNode struct {
key string
value interface{}
value any
}
func (r rockspecNode) Slice() []rockspecNode {

Some files were not shown because too many files have changed in this diff Show More