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

View File

@ -59,7 +59,7 @@ func Attest(app clio.Application) *cobra.Command {
Use: "attest --output [FORMAT] <IMAGE>", Use: "attest --output [FORMAT] <IMAGE>",
Short: "Generate an SBOM as an attestation for the given [SOURCE] container 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", 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, "appName": id.Name,
"command": "attest", "command": "attest",
}), }),

View File

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

View File

@ -40,7 +40,7 @@ func Convert(app clio.Application) *cobra.Command {
Use: "convert [SOURCE-SBOM] -o [FORMAT]", Use: "convert [SOURCE-SBOM] -o [FORMAT]",
Short: "Convert between SBOM formats", 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", 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, "appName": id.Name,
"command": "convert", "command": "convert",
}), }),

View File

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

View File

@ -29,7 +29,7 @@ func Test_filterExpressionErrors_expressionErrorsHelp(t *testing.T) {
{ {
name: "single non-expression error is retained", name: "single non-expression error is retained",
err: errors.New("foo"), 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()) return assert.Equal(t, "foo", err.Error())
}, },
wantHelp: "", wantHelp: "",
@ -42,7 +42,7 @@ func Test_filterExpressionErrors_expressionErrorsHelp(t *testing.T) {
err = multierror.Append(err, errors.New("bar")) err = multierror.Append(err, errors.New("bar"))
return err 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 // note: this is the default formatting from the hashicorp multierror object
expected := `2 errors occurred: expected := `2 errors occurred:
* foo * foo
@ -64,7 +64,7 @@ func Test_filterExpressionErrors_expressionErrorsHelp(t *testing.T) {
err = multierror.Append(err, errors.New("last")) err = multierror.Append(err, errors.New("last"))
return err 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: expected := `5 errors occurred:
* foo * foo
* invalid expression: "foo": tags are not allowed with this operation (must use exact names) * 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)) 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: expected := `top: middle: 4 errors occurred:
* foo: bar: last * foo: bar: last
* invalid expression: "foo": tags are not allowed with this operation (must use exact names) * 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 // note we wrap the top error in a chain
return fmt.Errorf("top: %w", fmt.Errorf("middle: %w", err)) 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: expected := `top: middle: 4 errors occurred:
* foo: bar: last * foo: bar: last
* invalid expression: "foo": tags are not allowed with this operation (must use exact names) * 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 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 // note: the errors are removed and the help text shows the enriched error help
expected := `2 errors occurred: expected := `2 errors occurred:
* invalid expression: "foo": tags are not allowed with this operation (must use exact names) * 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]", Use: "scan [SOURCE]",
Short: "Generate an SBOM", Short: "Generate an SBOM",
Long: "Generate a packaged-based Software Bill Of Materials (SBOM) from container images and filesystems", 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, "appName": id.Name,
"command": "scan", "command": "scan",
}), }),

View File

@ -60,7 +60,7 @@ func Test_scanOptions_validateLegacyOptionsNotUsed(t *testing.T) {
} }
func assertErrorContains(contains string) assert.ErrorAssertionFunc { 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...) return assert.ErrorContains(t, err, contains, i...)
} }
} }

View File

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

View File

@ -32,7 +32,7 @@ func Test_MakeSBOMWriter(t *testing.T) {
{ {
name: "unknown format", name: "unknown format",
outputs: []string{"unknown"}, 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:`) return assert.ErrorContains(t, err, `unsupported output format "unknown", supported formats are:`)
}, },
}, },

View File

@ -2,6 +2,7 @@ package integration
import ( import (
"context" "context"
"slices"
"strings" "strings"
"testing" "testing"
@ -194,11 +195,8 @@ func assertPackages(t *testing.T, sbom sbom.SBOM, test testCase, observedLanguag
} }
var foundLang bool var foundLang bool
for _, lang := range strings.Split(test.pkgLanguage.String(), ",") { if slices.Contains(strings.Split(test.pkgLanguage.String(), ","), actualPkg.Language.String()) {
if actualPkg.Language.String() == lang { foundLang = true
foundLang = true
break
}
} }
if !foundLang { if !foundLang {
t.Errorf("bad language (pkg=%+v): %+v", actualPkg.Name, actualPkg.Language) 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{ exportsPerPackage[pkg].Add(exportToken{
Name: decl.Name.Name, Name: decl.Name.Name,
Type: reflect.TypeOf(decl.Type).String(), Type: reflect.TypeFor[*ast.FuncType]().String(),
SignatureSize: len(decl.Type.Params.List), SignatureSize: len(decl.Type.Params.List),
ReturnTypeNames: returnTypes, ReturnTypeNames: returnTypes,
}) })

View File

@ -36,33 +36,33 @@ func Test_logWriter(t *testing.T) {
type bufferLogger struct{ values []any } 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...) 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...) 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) {} func (l *bufferLogger) SetOutput(_ io.Writer) {}

2
go.mod
View File

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

View File

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

View File

@ -10,8 +10,8 @@ import (
func Test_valuesEqual(t *testing.T) { func Test_valuesEqual(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
a interface{} a any
b interface{} b any
want bool want bool
}{ }{
{ {
@ -123,47 +123,47 @@ func Test_valuesEqual(t *testing.T) {
func TestConditionMatches(t *testing.T) { func TestConditionMatches(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
when map[string]interface{} when map[string]any
config map[string]interface{} config map[string]any
want bool want bool
}{ }{
{ {
name: "empty when clause matches anything", name: "empty when clause matches anything",
when: map[string]interface{}{}, when: map[string]any{},
config: map[string]interface{}{"key": "value"}, config: map[string]any{"key": "value"},
want: true, want: true,
}, },
{ {
name: "empty when clause with empty config", name: "empty when clause with empty config",
when: map[string]interface{}{}, when: map[string]any{},
config: map[string]interface{}{}, config: map[string]any{},
want: true, want: true,
}, },
{ {
name: "single key match", name: "single key match",
when: map[string]interface{}{"SearchLocalModCacheLicenses": true}, when: map[string]any{"SearchLocalModCacheLicenses": true},
config: map[string]interface{}{"SearchLocalModCacheLicenses": true}, config: map[string]any{"SearchLocalModCacheLicenses": true},
want: true, want: true,
}, },
{ {
name: "single key mismatch", name: "single key mismatch",
when: map[string]interface{}{"SearchLocalModCacheLicenses": true}, when: map[string]any{"SearchLocalModCacheLicenses": true},
config: map[string]interface{}{"SearchLocalModCacheLicenses": false}, config: map[string]any{"SearchLocalModCacheLicenses": false},
want: false, want: false,
}, },
{ {
name: "key missing from config", name: "key missing from config",
when: map[string]interface{}{"SearchLocalModCacheLicenses": true}, when: map[string]any{"SearchLocalModCacheLicenses": true},
config: map[string]interface{}{}, config: map[string]any{},
want: false, want: false,
}, },
{ {
name: "multiple keys all match", name: "multiple keys all match",
when: map[string]interface{}{ when: map[string]any{
"SearchLocalModCacheLicenses": true, "SearchLocalModCacheLicenses": true,
"UseNetwork": true, "UseNetwork": true,
}, },
config: map[string]interface{}{ config: map[string]any{
"SearchLocalModCacheLicenses": true, "SearchLocalModCacheLicenses": true,
"UseNetwork": true, "UseNetwork": true,
"ExtraKey": "ignored", "ExtraKey": "ignored",
@ -172,11 +172,11 @@ func TestConditionMatches(t *testing.T) {
}, },
{ {
name: "multiple keys one mismatch", name: "multiple keys one mismatch",
when: map[string]interface{}{ when: map[string]any{
"SearchLocalModCacheLicenses": true, "SearchLocalModCacheLicenses": true,
"UseNetwork": true, "UseNetwork": true,
}, },
config: map[string]interface{}{ config: map[string]any{
"SearchLocalModCacheLicenses": true, "SearchLocalModCacheLicenses": true,
"UseNetwork": false, "UseNetwork": false,
}, },
@ -184,31 +184,31 @@ func TestConditionMatches(t *testing.T) {
}, },
{ {
name: "multiple keys one missing", name: "multiple keys one missing",
when: map[string]interface{}{ when: map[string]any{
"SearchLocalModCacheLicenses": true, "SearchLocalModCacheLicenses": true,
"UseNetwork": true, "UseNetwork": true,
}, },
config: map[string]interface{}{ config: map[string]any{
"SearchLocalModCacheLicenses": true, "SearchLocalModCacheLicenses": true,
}, },
want: false, want: false,
}, },
{ {
name: "string value match", name: "string value match",
when: map[string]interface{}{"mode": "fast"}, when: map[string]any{"mode": "fast"},
config: map[string]interface{}{"mode": "fast"}, config: map[string]any{"mode": "fast"},
want: true, want: true,
}, },
{ {
name: "slice value match", name: "slice value match",
when: map[string]interface{}{"formats": []string{"json", "yaml"}}, when: map[string]any{"formats": []string{"json", "yaml"}},
config: map[string]interface{}{"formats": []string{"json", "yaml"}}, config: map[string]any{"formats": []string{"json", "yaml"}},
want: true, want: true,
}, },
{ {
name: "slice value mismatch", name: "slice value mismatch",
when: map[string]interface{}{"formats": []string{"json", "yaml"}}, when: map[string]any{"formats": []string{"json", "yaml"}},
config: map[string]interface{}{"formats": []string{"json", "xml"}}, config: map[string]any{"formats": []string{"json", "xml"}},
want: false, want: false,
}, },
} }
@ -225,8 +225,8 @@ func TestEvaluateField(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
capField CapabilityField capField CapabilityField
config map[string]interface{} config map[string]any
want interface{} want any
}{ }{
{ {
name: "no conditions returns default", name: "no conditions returns default",
@ -235,7 +235,7 @@ func TestEvaluateField(t *testing.T) {
Default: false, Default: false,
Conditions: nil, Conditions: nil,
}, },
config: map[string]interface{}{}, config: map[string]any{},
want: false, want: false,
}, },
{ {
@ -245,7 +245,7 @@ func TestEvaluateField(t *testing.T) {
Default: false, Default: false,
Conditions: []CapabilityCondition{}, Conditions: []CapabilityCondition{},
}, },
config: map[string]interface{}{}, config: map[string]any{},
want: false, 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, 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, want: false,
}, },
{ {
@ -294,7 +294,7 @@ func TestEvaluateField(t *testing.T) {
}, },
}, },
}, },
config: map[string]interface{}{ config: map[string]any{
"SearchLocalModCacheLicenses": true, "SearchLocalModCacheLicenses": true,
"SearchRemoteLicenses": true, "SearchRemoteLicenses": true,
}, },
@ -316,7 +316,7 @@ func TestEvaluateField(t *testing.T) {
}, },
}, },
}, },
config: map[string]interface{}{ config: map[string]any{
"SearchLocalModCacheLicenses": false, "SearchLocalModCacheLicenses": false,
"SearchRemoteLicenses": true, "SearchRemoteLicenses": true,
}, },
@ -338,7 +338,7 @@ func TestEvaluateField(t *testing.T) {
}, },
}, },
}, },
config: map[string]interface{}{ config: map[string]any{
"SearchLocalModCacheLicenses": false, "SearchLocalModCacheLicenses": false,
"SearchRemoteLicenses": false, "SearchRemoteLicenses": false,
}, },
@ -351,7 +351,7 @@ func TestEvaluateField(t *testing.T) {
Default: []string{"direct", "indirect"}, Default: []string{"direct", "indirect"},
Conditions: nil, Conditions: nil,
}, },
config: map[string]interface{}{}, config: map[string]any{},
want: []string{"direct", "indirect"}, want: []string{"direct", "indirect"},
}, },
{ {
@ -369,7 +369,7 @@ func TestEvaluateField(t *testing.T) {
}, },
}, },
}, },
config: map[string]interface{}{ config: map[string]any{
"EnableFeatureA": true, "EnableFeatureA": true,
"EnableFeatureB": true, "EnableFeatureB": true,
}, },
@ -390,7 +390,7 @@ func TestEvaluateField(t *testing.T) {
}, },
}, },
}, },
config: map[string]interface{}{ config: map[string]any{
"EnableFeatureA": true, "EnableFeatureA": true,
"EnableFeatureB": false, "EnableFeatureB": false,
}, },
@ -412,14 +412,14 @@ func TestEvaluateCapabilities(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
caps CapabilitySet caps CapabilitySet
config map[string]interface{} config map[string]any
want map[string]interface{} want map[string]any
}{ }{
{ {
name: "empty capability set", name: "empty capability set",
caps: CapabilitySet{}, caps: CapabilitySet{},
config: map[string]interface{}{}, config: map[string]any{},
want: map[string]interface{}{}, want: map[string]any{},
}, },
{ {
name: "single capability no conditions", name: "single capability no conditions",
@ -429,8 +429,8 @@ func TestEvaluateCapabilities(t *testing.T) {
Default: false, Default: false,
}, },
}, },
config: map[string]interface{}{}, config: map[string]any{},
want: map[string]interface{}{ want: map[string]any{
"license": false, "license": false,
}, },
}, },
@ -448,8 +448,8 @@ func TestEvaluateCapabilities(t *testing.T) {
}, },
}, },
}, },
config: map[string]interface{}{"SearchLocalModCacheLicenses": true}, config: map[string]any{"SearchLocalModCacheLicenses": true},
want: map[string]interface{}{ want: map[string]any{
"license": true, "license": true,
}, },
}, },
@ -475,8 +475,8 @@ func TestEvaluateCapabilities(t *testing.T) {
Default: "flat", Default: "flat",
}, },
}, },
config: map[string]interface{}{"SearchLocalModCacheLicenses": true}, config: map[string]any{"SearchLocalModCacheLicenses": true},
want: map[string]interface{}{ want: map[string]any{
"license": true, "license": true,
"dependency.depth": []string{"direct", "indirect"}, "dependency.depth": []string{"direct", "indirect"},
"dependency.edges": "flat", "dependency.edges": "flat",
@ -512,11 +512,11 @@ func TestEvaluateCapabilities(t *testing.T) {
Default: false, Default: false,
}, },
}, },
config: map[string]interface{}{ config: map[string]any{
"SearchLocalModCacheLicenses": false, "SearchLocalModCacheLicenses": false,
"SearchRemoteLicenses": true, "SearchRemoteLicenses": true,
}, },
want: map[string]interface{}{ want: map[string]any{
"license": true, "license": true,
"dependency.depth": []string{"direct", "indirect"}, "dependency.depth": []string{"direct", "indirect"},
"dependency.edges": "flat", "dependency.edges": "flat",
@ -526,10 +526,10 @@ func TestEvaluateCapabilities(t *testing.T) {
{ {
name: "nil capability set", name: "nil capability set",
caps: nil, caps: nil,
config: map[string]interface{}{ config: map[string]any{
"anything": true, "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 // AppConfigField represents an application-level configuration field for catalogers
type AppConfigField struct { type AppConfigField struct {
Key string // e.g., "golang.search-local-mod-cache-licenses" Key string // e.g., "golang.search-local-mod-cache-licenses"
Description string // extracted from DescribeFields() method Description string // extracted from DescribeFields() method
DefaultValue interface{} // extracted from Default*() functions DefaultValue any // extracted from Default*() functions
} }
// extractEcosystemConfigFieldsFromCatalog parses catalog.go and extracts the ecosystem-specific // 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 // 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 var configs []AppConfigField
// find the nested struct type // find the nested struct type
@ -449,8 +449,8 @@ func extractNestedAppConfigs(f *ast.File, parentKey, parentFieldName string, fie
description := descriptions[nestedPath] description := descriptions[nestedPath]
// try to get default value from nested defaults // try to get default value from nested defaults
var defaultValue interface{} var defaultValue any
if nestedDefaults, ok := defaults[parentFieldName].(map[string]interface{}); ok { if nestedDefaults, ok := defaults[parentFieldName].(map[string]any); ok {
defaultValue = nestedDefaults[fieldName] 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 // extractAppDefaultValues extracts default values from the default*Config function
func extractAppDefaultValues(f *ast.File) map[string]interface{} { func extractAppDefaultValues(f *ast.File) map[string]any {
defaults := make(map[string]interface{}) defaults := make(map[string]any)
for _, decl := range f.Decls { for _, decl := range f.Decls {
funcDecl, ok := decl.(*ast.FuncDecl) 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 // 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) { switch v := expr.(type) {
case *ast.BasicLit: case *ast.BasicLit:
// string, int, bool literals // string, int, bool literals
@ -543,7 +543,7 @@ func extractAppValue(expr ast.Expr) interface{} {
} }
case *ast.CompositeLit: case *ast.CompositeLit:
// nested struct literal // nested struct literal
nested := make(map[string]interface{}) nested := make(map[string]any)
for _, elt := range v.Elts { for _, elt := range v.Elts {
kvExpr, ok := elt.(*ast.KeyValueExpr) kvExpr, ok := elt.(*ast.KeyValueExpr)
if !ok { if !ok {

View File

@ -340,7 +340,7 @@ func TestExtractAppValue(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
src string src string
want interface{} want any
}{ }{
{ {
name: "string literal", name: "string literal",
@ -406,7 +406,7 @@ func TestExtractAppValue_NestedStruct(t *testing.T) {
got := extractAppValue(compositeLit) got := extractAppValue(compositeLit)
// verify it's a map with the expected values // 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.True(t, ok)
require.Equal(t, "value", gotMap["Field1"]) require.Equal(t, "value", gotMap["Field1"])
require.Equal(t, true, gotMap["Field2"]) 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 // resolveImportPath converts an import path to a file system path
func resolveImportPath(importPath, repoRoot string) string { func resolveImportPath(importPath, repoRoot string) string {
// for github.com/anchore/syft/... imports, convert to repo-relative path // for github.com/anchore/syft/... imports, convert to repo-relative path
if strings.HasPrefix(importPath, "github.com/anchore/syft/") { if after, ok := strings.CutPrefix(importPath, "github.com/anchore/syft/"); ok {
relPath := strings.TrimPrefix(importPath, "github.com/anchore/syft/") relPath := after
return filepath.Join(repoRoot, relPath) 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 // 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 var newNode yaml.Node
if err := newNode.Encode(doc); err != nil { if err := newNode.Encode(doc); err != nil {
return err return err
@ -242,7 +242,7 @@ func updateNodeTreeEcosystem(rootNode *yaml.Node, doc interface{}) error {
} }
// updateNodeTreeAppConfig updates appconfig YAML node tree // 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) 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 // metadataTypeCoverageExceptions lists metadata types that are allowed to not be represented in any cataloger
var metadataTypeCoverageExceptions = strset.New( 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 // 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 // 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 { if value == nil {
return nil // nil is acceptable return nil // nil is acceptable
} }
@ -428,7 +428,7 @@ func validateCapabilityValueType(fieldPath string, value interface{}) error {
switch v := value.(type) { switch v := value.(type) {
case []string: case []string:
// ok // ok
case []interface{}: case []any:
// check each element is a string // check each element is a string
for i, elem := range v { for i, elem := range v {
if _, ok := elem.(string); !ok { if _, ok := elem.(string); !ok {
@ -829,7 +829,6 @@ func TestCapabilityEvidenceFieldReferences(t *testing.T) {
// validate each evidence reference // validate each evidence reference
for _, ref := range allReferences { for _, ref := range allReferences {
ref := ref // capture for subtest
// create test name // create test name
testName := ref.catalogerName testName := ref.catalogerName
@ -989,7 +988,6 @@ func validateCapabilitiesFilled(t *testing.T, catalogers []capabilities.Cataloge
checkCompletenessTestsEnabled(t) checkCompletenessTestsEnabled(t)
for _, c := range catalogers { for _, c := range catalogers {
c := c // capture loop variable for subtest
t.Run(c.Name, func(t *testing.T) { t.Run(c.Name, func(t *testing.T) {
if c.Type == "generic" { 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") require.NotEmpty(t, c.Parsers, "generic cataloger must have at least one parser")
for _, p := range c.Parsers { for _, p := range c.Parsers {
p := p // capture loop variable for subtest
t.Run(p.ParserFunction, func(t *testing.T) { t.Run(p.ParserFunction, func(t *testing.T) {
require.NotEmpty(t, p.Capabilities, "parser must have at least one capability field defined") 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) require.NoError(t, err)
for _, c := range catalogerEntries { for _, c := range catalogerEntries {
c := c // capture loop variable for subtest
t.Run(c.Name, func(t *testing.T) { t.Run(c.Name, func(t *testing.T) {
// ecosystem must always be set (it's MANUAL) // 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{}) 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) return assert.ErrorIs(t, err, ErrNonArchiveSource)
} }

View File

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

View File

@ -1,5 +1,4 @@
//go:build !windows //go:build !windows
// +build !windows
package file 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 // looks like there isn't a helper for this yet? https://github.com/stretchr/testify/issues/497
func assertErrorAs(expectedErr interface{}) assert.ErrorAssertionFunc { func assertErrorAs(expectedErr any) assert.ErrorAssertionFunc {
return func(t assert.TestingT, actualErr error, i ...interface{}) bool { return func(t assert.TestingT, actualErr error, i ...any) bool {
return errors.As(actualErr, &expectedErr) return errors.As(actualErr, &expectedErr)
} }
} }

View File

@ -143,7 +143,7 @@ func build() *jsonschema.Schema {
// srcMetadataContainer := assembleTypeContainer(sourcemetadata.AllTypes()) // srcMetadataContainer := assembleTypeContainer(sourcemetadata.AllTypes())
// srcMetadataContainerType := reflect.TypeOf(srcMetadataContainer) // srcMetadataContainerType := reflect.TypeOf(srcMetadataContainer)
documentSchema := reflector.ReflectFromType(reflect.TypeOf(&syftJsonModel.Document{})) documentSchema := reflector.ReflectFromType(reflect.TypeFor[*syftJsonModel.Document]())
pkgMetadataSchema := reflector.ReflectFromType(reflect.TypeOf(pkgMetadataContainer)) pkgMetadataSchema := reflector.ReflectFromType(reflect.TypeOf(pkgMetadataContainer))
// srcMetadataSchema := reflector.ReflectFromType(reflect.TypeOf(srcMetadataContainer)) // 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. // 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...) log.Errorf(format, args...)
} }
// Error logs the given arguments at the error logging level. // Error logs the given arguments at the error logging level.
func Error(args ...interface{}) { func Error(args ...any) {
log.Error(args...) log.Error(args...)
} }
// Warnf takes a formatted template string and template arguments for the warning logging level. // 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...) log.Warnf(format, args...)
} }
// Warn logs the given arguments at the warning logging level. // Warn logs the given arguments at the warning logging level.
func Warn(args ...interface{}) { func Warn(args ...any) {
log.Warn(args...) log.Warn(args...)
} }
// Infof takes a formatted template string and template arguments for the info logging level. // 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...) log.Infof(format, args...)
} }
// Info logs the given arguments at the info logging level. // Info logs the given arguments at the info logging level.
func Info(args ...interface{}) { func Info(args ...any) {
log.Info(args...) log.Info(args...)
} }
// Debugf takes a formatted template string and template arguments for the debug logging level. // 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...) log.Debugf(format, args...)
} }
// Debug logs the given arguments at the debug logging level. // Debug logs the given arguments at the debug logging level.
func Debug(args ...interface{}) { func Debug(args ...any) {
log.Debug(args...) log.Debug(args...)
} }
// Tracef takes a formatted template string and template arguments for the trace logging level. // 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...) log.Tracef(format, args...)
} }
// Trace logs the given arguments at the trace logging level. // Trace logs the given arguments at the trace logging level.
func Trace(args ...interface{}) { func Trace(args ...any) {
log.Trace(args...) log.Trace(args...)
} }
// WithFields returns a message logger with multiple key-value fields. // 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...) return log.WithFields(fields...)
} }
// Nested returns a new logger with hard coded key-value pairs // 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...) return log.Nested(fields...)
} }

View File

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

View File

@ -26,9 +26,9 @@ var (
pkg.BitnamiPkg, pkg.BitnamiPkg,
} }
binaryMetadataTypes = []string{ binaryMetadataTypes = []string{
reflect.TypeOf(pkg.ELFBinaryPackageNoteJSONPayload{}).Name(), reflect.TypeFor[pkg.ELFBinaryPackageNoteJSONPayload]().Name(),
reflect.TypeOf(pkg.BinarySignature{}).Name(), reflect.TypeFor[pkg.BinarySignature]().Name(),
reflect.TypeOf(pkg.JavaVMInstallation{}).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"}} packageC := pkg.Package{Name: "package-c", Type: pkg.BinaryPkg, Metadata: pkg.ELFBinaryPackageNoteJSONPayload{Type: "rpm"}}
packageD := pkg.Package{Name: "package-d", Type: pkg.BitnamiPkg} packageD := pkg.Package{Name: "package-d", Type: pkg.BitnamiPkg}
for _, p := range []*pkg.Package{&packageA, &packageB, &packageC, &packageD} { for _, p := range []*pkg.Package{&packageA, &packageB, &packageC, &packageD} {
p := p
p.SetID() p.SetID()
} }

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@ import (
) )
// Tprintf renders a string from a given template string and field values // 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)) t := template.Must(template.New("").Parse(tmpl))
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
if err := t.Execute(buf, data); err != nil { if err := t.Execute(buf, data); err != nil {

View File

@ -3,6 +3,7 @@ package unknown
import ( import (
"errors" "errors"
"fmt" "fmt"
"slices"
"strings" "strings"
"github.com/anchore/syft/internal/log" "github.com/anchore/syft/internal/log"
@ -155,12 +156,7 @@ func containsErr(out []error, err error) bool {
log.Tracef("error comparing errors: %v", err) log.Tracef("error comparing errors: %v", err)
} }
}() }()
for _, e := range out { return slices.Contains(out, err)
if e == err {
return true
}
}
return false
} }
// visitErrors visits every wrapped error. the returned error replaces the provided error, null errors are omitted from // 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 ID() ID
} }
func IDByHash(obj interface{}) (ID, error) { func IDByHash(obj any) (ID, error) {
f, err := hashstructure.Hash(obj, &hashstructure.HashOptions{ f, err := hashstructure.Hash(obj, &hashstructure.HashOptions{
ZeroNil: true, ZeroNil: true,
SlicesAsSets: true, SlicesAsSets: true,

View File

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

View File

@ -41,7 +41,7 @@ func (cfg configurationAuditTrail) MarshalJSON() ([]byte, error) {
return nil, err return nil, err
} }
var dataMap map[string]interface{} var dataMap map[string]any
if err := json.Unmarshal(initialJSON, &dataMap); err != nil { if err := json.Unmarshal(initialJSON, &dataMap); err != nil {
return nil, err return nil, err
} }
@ -55,13 +55,13 @@ func (cfg configurationAuditTrail) MarshalJSON() ([]byte, error) {
} }
// marshalSorted recursively marshals a map with sorted keys // 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 { if reflect.TypeOf(m).Kind() != reflect.Map {
return json.Marshal(m) return json.Marshal(m)
} }
val := reflect.ValueOf(m) val := reflect.ValueOf(m)
sortedMap := make(map[string]interface{}) sortedMap := make(map[string]any)
for _, key := range val.MapKeys() { for _, key := range val.MapKeys() {
value := val.MapIndex(key).Interface() 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 var tags []string
err := collectJSONTags(t, reflect.ValueOf(v), &tags, "", "") err := collectJSONTags(t, reflect.ValueOf(v), &tags, "", "")
require.NoError(t, err) require.NoError(t, err)
@ -142,7 +142,7 @@ func Test_collectJSONTags(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
v interface{} v any
want []string want []string
wantErr require.ErrorAssertionFunc wantErr require.ErrorAssertionFunc
}{ }{

View File

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

View File

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

View File

@ -310,9 +310,9 @@ func toRootPackage(s source.Description) *spdx.Package {
func toSPDXID(identifiable artifact.Identifiable) spdx.ElementID { func toSPDXID(identifiable artifact.Identifiable) spdx.ElementID {
id := string(identifiable.ID()) 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) // 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 maxLen := 40
switch it := identifiable.(type) { switch it := identifiable.(type) {

View File

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

View File

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

View File

@ -73,6 +73,6 @@ type DependencyGraph map[string]DependencyNode
type ISO8601Date = string 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 type Metadata map[string]Scalar

View File

@ -31,7 +31,7 @@ func encodeAuthor(p pkg.Package) string {
return "" return ""
} }
func decodeAuthor(author string, metadata interface{}) { func decodeAuthor(author string, metadata any) {
switch meta := metadata.(type) { switch meta := metadata.(type) {
case *pkg.NpmPackage: case *pkg.NpmPackage:
meta.Author = author 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 { 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) out, ok := v.([]file.Location)
if !ok { if !ok {
out = nil out = nil
@ -210,7 +210,7 @@ func decodeLocations(vals map[string]string) file.LocationSet {
return file.NewLocationSet(out...) 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 { if typeName != "" && c.Properties != nil {
metadataType := packagemetadata.ReflectTypeFromJSONName(typeName) metadataType := packagemetadata.ReflectTypeFromJSONName(typeName)
if metadataType == nil { if metadataType == nil {

View File

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

View File

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

View File

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

View File

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

View File

@ -10,7 +10,7 @@ var (
CycloneDXFields = RequiredTag("cyclonedx") 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)) { for _, p := range Sorted(Encode(obj, prefix, CycloneDXFields)) {
out = append(out, cyclonedx.Property{ out = append(out, cyclonedx.Property{
Name: p.Name, 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 { func decodeProperties(properties []cyclonedx.Property, prefix string) map[string]string {
labels := make(map[string]string) labels := make(map[string]string)
for _, property := range properties { for _, property := range properties {
if strings.HasPrefix(property.Name, prefix) { if after, ok := strings.CutPrefix(property.Name, prefix); ok {
labelName := strings.TrimPrefix(property.Name, prefix) labelName := after
labels[labelName] = property.Value 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 // NOTE: this will not work for nested maps
for key := range vals { for key := range vals {
// test for map prefix // test for map prefix
if strings.HasPrefix(key, str) { if after, ok := strings.CutPrefix(key, str); ok {
keyVals[key] = strings.TrimPrefix(key, str) keyVals[key] = after
// create new placeholder and decode key // create new placeholder and decode key
newKeyType := keyType newKeyType := keyType
if keyType.Kind() == reflect.Ptr { if keyType.Kind() == reflect.Ptr {

View File

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

View File

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

View File

@ -44,7 +44,7 @@ type Descriptor struct {
Version string `json:"version"` Version string `json:"version"`
// Configuration contains the tool configuration used during SBOM generation. // 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. // 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) { func TestIDLikes_UnmarshalJSON(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
data interface{} data any
expected IDLikes expected IDLikes
}{ }{
{ {

View File

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

View File

@ -207,7 +207,7 @@ func Test_UnmarshalJSON(t *testing.T) {
`), `),
assert: func(p *Package) { assert: func(p *Package) {
assert.Equal(t, pkg.RpmPkg, p.Type) 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: func(p *Package) {
assert.Equal(t, pkg.RpmPkg, p.Type) 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: func(p *Package) {
assert.Equal(t, pkg.HackagePkg, p.Type) 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: func(p *Package) {
assert.Equal(t, pkg.HackagePkg, p.Type) 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: func(p *Package) {
assert.Equal(t, pkg.HackagePkg, p.Type) 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: func(p *Package) {
assert.Equal(t, pkg.HackagePkg, p.Type) 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, wantErr: require.Error,
wantMetadata: map[string]interface{}{ wantMetadata: map[string]any{
"thing": "thing-1", "thing": "thing-1",
}, },
}, },

View File

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

View File

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

View File

@ -21,11 +21,11 @@ import (
) )
// MetadataType infers the metadata type value based on the pkg.Metadata payload. // 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) return metadataType(metadata, false)
} }
func metadataType(metadata interface{}, legacy bool) string { func metadataType(metadata any, legacy bool) string {
if legacy { if legacy {
return packagemetadata.JSONLegacyName(metadata) 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) { 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() { for _, p := range catalog.Sorted() {
idMap[string(p.ID())] = p idMap[string(p.ID())] = p
@ -263,7 +263,7 @@ func toSyftSource(s model.Source) source.Source {
return source.FromDescription(*description) 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 { id := func(id string) string {
aliased, ok := idAliases[id] aliased, ok := idAliases[id]
if ok { if ok {

View File

@ -448,7 +448,7 @@ func Test_toSyftRelationship(t *testing.T) {
parentPackage := packageWithId("some-parent-id") parentPackage := packageWithId("some-parent-id")
tests := []struct { tests := []struct {
name string name string
idMap map[string]interface{} idMap map[string]any
idAliases map[string]string idAliases map[string]string
relationships model.Relationship relationships model.Relationship
want *artifact.Relationship want *artifact.Relationship
@ -456,7 +456,7 @@ func Test_toSyftRelationship(t *testing.T) {
}{ }{
{ {
name: "one relationship no warnings", name: "one relationship no warnings",
idMap: map[string]interface{}{ idMap: map[string]any{
"some-child-id": childPackage, "some-child-id": childPackage,
"some-parent-id": parentPackage, "some-parent-id": parentPackage,
}, },
@ -474,7 +474,7 @@ func Test_toSyftRelationship(t *testing.T) {
}, },
{ {
name: "relationship unknown type one warning", name: "relationship unknown type one warning",
idMap: map[string]interface{}{ idMap: map[string]any{
"some-child-id": childPackage, "some-child-id": childPackage,
"some-parent-id": parentPackage, "some-parent-id": parentPackage,
}, },
@ -490,7 +490,7 @@ func Test_toSyftRelationship(t *testing.T) {
}, },
{ {
name: "relationship missing child ID one warning", name: "relationship missing child ID one warning",
idMap: map[string]interface{}{ idMap: map[string]any{
"some-parent-id": parentPackage, "some-parent-id": parentPackage,
}, },
idAliases: map[string]string{}, idAliases: map[string]string{},
@ -505,7 +505,7 @@ func Test_toSyftRelationship(t *testing.T) {
}, },
{ {
name: "relationship missing parent ID one warning", name: "relationship missing parent ID one warning",
idMap: map[string]interface{}{ idMap: map[string]any{
"some-child-id": childPackage, "some-child-id": childPackage,
}, },
idAliases: map[string]string{}, 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? // 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. // Note: do not check for the existence of the template file here, as the default encoder cannot provide one.
f := sprig.HermeticTxtFuncMap() f := sprig.HermeticTxtFuncMap()
f["getLastIndex"] = func(collection interface{}) int { f["getLastIndex"] = func(collection any) int {
if v := reflect.ValueOf(collection); v.Kind() == reflect.Slice { if v := reflect.ValueOf(collection); v.Kind() == reflect.Slice {
return v.Len() - 1 return v.Len() - 1
} }
@ -42,7 +42,7 @@ func NewFormatEncoder(cfg EncoderConfig) (sbom.FormatEncoder, error) {
return 0 return 0
} }
// Checks if a field is defined // 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) t := reflect.TypeOf(obj)
_, ok := t.FieldByName(field) _, ok := t.FieldByName(field)
return ok return ok

View File

@ -148,7 +148,7 @@ func TestValidateSourcePlatform_UnsupportedMetadataTypes(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
metadata interface{} metadata any
}{ }{
{ {
name: "string metadata", 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, // we cannot directly concatenate ".." to "/root/symlink",however,
// the parent directory of linkTarget should be "/root" // the parent directory of linkTarget should be "/root"
for strings.HasPrefix(dir, "..") { for strings.HasPrefix(dir, "..") {
if strings.HasPrefix(dir, "../") { if after, ok := strings.CutPrefix(dir, "../"); ok {
dir = strings.TrimPrefix(dir, "../") dir = after
} else { } else {
dir = strings.TrimPrefix(dir, "..") dir = strings.TrimPrefix(dir, "..")
} }

View File

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

View File

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

View File

@ -426,7 +426,7 @@ func assertSkipErr() assert.ErrorAssertionFunc {
} }
func assertErrorIs(want error) 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...) return assert.ErrorIs(t, got, want, msgAndArgs...)
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -76,7 +76,7 @@ func TestGGUFCataloger(t *testing.T) {
GGUFVersion: 3, GGUFVersion: 3,
TensorCount: 0, TensorCount: 0,
MetadataKeyValuesHash: "6e3d368066455ce4", MetadataKeyValuesHash: "6e3d368066455ce4",
RemainingKeyValues: map[string]interface{}{ RemainingKeyValues: map[string]any{
"general.some_random_kv": "foobar", "general.some_random_kv": "foobar",
}, },
}, },
@ -113,7 +113,7 @@ func TestGGUFCataloger(t *testing.T) {
GGUFVersion: 3, GGUFVersion: 3,
TensorCount: 0, TensorCount: 0,
MetadataKeyValuesHash: "9dc6f23591062a27", MetadataKeyValuesHash: "9dc6f23591062a27",
RemainingKeyValues: map[string]interface{}{ RemainingKeyValues: map[string]any{
"gpt2.context_length": "1024", "gpt2.context_length": "1024",
"gpt2.embedding_length": uint32(768), "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 // Helper to convert gguf_parser metadata to simpler types
func convertGGUFMetadataKVs(kvs gguf_parser.GGUFMetadataKVs) map[string]interface{} { func convertGGUFMetadataKVs(kvs gguf_parser.GGUFMetadataKVs) map[string]any {
result := make(map[string]interface{}) result := make(map[string]any)
for _, kv := range kvs { for _, kv := range kvs {
// Skip standard fields that are extracted separately // Skip standard fields that are extracted separately

View File

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

View File

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

View File

@ -195,7 +195,7 @@ func Test_CondaCataloger(t *testing.T) {
name: "badly formatted conda meta json file", name: "badly formatted conda meta json file",
fixture: "testdata/conda-meta-bad-json", fixture: "testdata/conda-meta-bad-json",
expectedPackages: nil, 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.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(), "failed to parse conda-meta package file at conda-meta/package-1.2.3-pyhd8ed1ab_0.json")
require.Contains(t, err.Error(), "invalid character") require.Contains(t, err.Error(), "invalid character")

View File

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

View File

@ -339,7 +339,7 @@ func TestSourceVersionExtract(t *testing.T) {
} }
func requireAs(expected error) require.ErrorAssertionFunc { 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) require.ErrorAs(t, err, &expected)
} }
} }
@ -413,7 +413,7 @@ func Test_handleNewKeyValue(t *testing.T) {
name string name string
line string line string
wantKey string wantKey string
wantVal interface{} wantVal any
wantErr require.ErrorAssertionFunc wantErr require.ErrorAssertionFunc
}{ }{
{ {

View File

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

View File

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

View File

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

View File

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

View File

@ -260,8 +260,8 @@ func addEntryForNPMPackage(indexed *dictionary.Indexed, ref string, cpeItemName
} }
func phpExtensionPackageFromURLFragment(ref string) string { func phpExtensionPackageFromURLFragment(ref string) string {
if strings.HasPrefix(ref, "package/") { // package/HTML_QuickForm/download if after, ok := strings.CutPrefix(ref, "package/"); ok { // package/HTML_QuickForm/download
ref = strings.TrimPrefix(ref, "package/") ref = after
components := strings.Split(ref, "/") components := strings.Split(ref, "/")
if len(components) < 1 { 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) { func (c *NVDAPIClient) fetchPage(ctx context.Context, startIndex int, start, end time.Time) (NVDProductsResponse, error) {
var lastErr error var lastErr error
for attempt := 0; attempt < maxRetries; attempt++ { for attempt := range maxRetries {
// wait for rate limiter // wait for rate limiter
if err := c.rateLimiter.Wait(ctx); err != nil { if err := c.rateLimiter.Wait(ctx); err != nil {
return NVDProductsResponse{}, fmt.Errorf("rate limiter error: %w", err) 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 { for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
t.Parallel() t.Parallel()
got := IsLicenseFile(tt.input) 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) // findDepsJSONInManifest parses manifest entries to find deps.json (for V1 bundles or fallback)
func findDepsJSONInManifest(r io.ReadSeeker, numFiles int32, majorVersion uint32) (string, error) { 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 var offset, size int64
if err := binary.Read(r, binary.LittleEndian, &offset); err != nil { 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) 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 var entry peImageResourceDirectoryEntry
entryOffset := offset + int64(binary.Size(directoryHeader)) + int64(i*binary.Size(entry)) entryOffset := offset + int64(binary.Size(directoryHeader)) + int64(i*binary.Size(entry))

View File

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

View File

@ -6,6 +6,7 @@ import (
"context" "context"
"fmt" "fmt"
"io" "io"
"slices"
"sort" "sort"
"github.com/scylladb/go-set/strset" "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. // ObservedPathQuery checks if a specific path pattern was queried.
func (r *ObservingResolver) ObservedPathQuery(input string) bool { func (r *ObservingResolver) ObservedPathQuery(input string) bool {
for _, queries := range r.pathQueries { for _, queries := range r.pathQueries {
for _, query := range queries { if slices.Contains(queries, input) {
if query == input { return true
return true
}
} }
} }
return false 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 // 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 // get the function pointer
ptr := reflect.ValueOf(fn).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 // getPackagePath extracts the package path from a function name
// e.g., "github.com/anchore/syft/syft/pkg/cataloger/python.parseRequirementsTxt" -> "python" // 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() ptr := reflect.ValueOf(fn).Pointer()
funcForPC := runtime.FuncForPC(ptr) funcForPC := runtime.FuncForPC(ptr)
if funcForPC == nil { if funcForPC == nil {
@ -566,7 +566,7 @@ func getPackagePath(fn interface{}) string {
func getPackagePathFromCataloger(_ pkg.Cataloger) string { func getPackagePathFromCataloger(_ pkg.Cataloger) string {
// walk up the call stack to find the test file // walk up the call stack to find the test file
// we're looking for a file in the cataloger directory structure // 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) _, file, _, ok := runtime.Caller(i)
if !ok { if !ok {
break break

View File

@ -395,7 +395,6 @@ func TestParseJar(t *testing.T) {
var parent *pkg.Package var parent *pkg.Package
for _, a := range actual { for _, a := range actual {
a := a
if strings.Contains(a.Name, "example-") { if strings.Contains(a.Name, "example-") {
parent = &a parent = &a
} }
@ -682,7 +681,6 @@ func TestParseNestedJar(t *testing.T) {
actualNameVersionPairSet := strset.New() actualNameVersionPairSet := strset.New()
for _, a := range actual { for _, a := range actual {
a := a
key := makeKey(&a) key := makeKey(&a)
actualNameVersionPairSet.Add(key) actualNameVersionPairSet.Add(key)
if !expectedNameVersionPairSet.Has(key) { if !expectedNameVersionPairSet.Has(key) {
@ -701,7 +699,6 @@ func TestParseNestedJar(t *testing.T) {
} }
for _, a := range actual { for _, a := range actual {
a := a
actualKey := makeKey(&a) actualKey := makeKey(&a)
metadata := a.Metadata.(pkg.JavaArchive) metadata := a.Metadata.(pkg.JavaArchive)
@ -1493,7 +1490,7 @@ func Test_deterministicMatchingPomProperties(t *testing.T) {
t.Run(test.fixture, func(t *testing.T) { t.Run(test.fixture, func(t *testing.T) {
fixturePath := generateJavaMetadataJarFixture(t, test.fixture, "jar") fixturePath := generateJavaMetadataJarFixture(t, test.fixture, "jar")
for i := 0; i < 5; i++ { for range 5 {
func() { func() {
fixture, err := os.Open(fixturePath) fixture, err := os.Open(fixturePath)
require.NoError(t, err) 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 // this is a new key-value pair
idx := strings.Index(line, ":") before, after, ok := strings.Cut(line, ":")
if idx == -1 { if !ok {
log.Debugf("java manifest %q: unable to split java manifest key-value pairs: %q", path, line) log.Debugf("java manifest %q: unable to split java manifest key-value pairs: %q", path, line)
continue continue
} }
key := strings.TrimSpace(line[0:idx]) key := strings.TrimSpace(before)
value := strings.TrimSpace(line[idx+1:]) value := strings.TrimSpace(after)
if key == "" { if key == "" {
// don't attempt to add new keys or sections unless there is a non-empty 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) require.Equal(t, "child-one", child1.Name)
got := child1.Licenses.ToSlice() got := child1.Licenses.ToSlice()
for i := 0; i < len(got); i++ { for i := range got {
// ignore locations, just check license text // ignore locations, just check license text
(&got[i]).Locations = file.LocationSet{} (&got[i]).Locations = file.LocationSet{}
} }
@ -810,7 +810,7 @@ func expectedTransientPackageData() expected {
} }
pkgs := make([]pkg.Package, len(allPackages)) pkgs := make([]pkg.Package, len(allPackages))
for i := 0; i < len(allPackages); i++ { for i := range allPackages {
pkgs[i] = *allPackages[i] pkgs[i] = *allPackages[i]
} }

View File

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"io" "io"
"regexp" "regexp"
"slices"
"strings" "strings"
"github.com/go-viper/mapstructure/v2" "github.com/go-viper/mapstructure/v2"
@ -95,7 +96,7 @@ func (p *person) UnmarshalJSON(b []byte) error {
} }
} else { } else {
// it's a map that may contain fields of various data types (not just strings) // 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 { if err := json.Unmarshal(b, &fields); err != nil {
return fmt.Errorf("unable to parse package.json author: %w", err) 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(`[\\/]`) var filepathSeparator = regexp.MustCompile(`[\\/]`)
func pathContainsNodeModulesDirectory(p string) bool { func pathContainsNodeModulesDirectory(p string) bool {
for _, subPath := range filepathSeparator.Split(p, -1) { return slices.Contains(filepathSeparator.Split(p, -1), "node_modules")
if subPath == "node_modules" {
return true
}
}
return false
} }
func (p *people) UnmarshalJSON(b []byte) error { 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 // 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 { if err := json.Unmarshal(b, &authorObjs); err == nil {
// Successfully parsed as an array of objects // Successfully parsed as an array of objects
auths := make([]person, len(authorObjs)) 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. // pnpmV6LockYaml represents the structure of pnpm lockfiles for versions < 9.0.
type pnpmV6LockYaml struct { type pnpmV6LockYaml struct {
Dependencies map[string]interface{} `yaml:"dependencies"` Dependencies map[string]any `yaml:"dependencies"`
Packages map[string]pnpmV6PackageEntry `yaml:"packages"` Packages map[string]pnpmV6PackageEntry `yaml:"packages"`
} }
@ -61,7 +61,7 @@ type pnpmV9PackageEntry struct {
// pnpmV9LockYaml represents the structure of pnpm lockfiles for versions >= 9.0. // pnpmV9LockYaml represents the structure of pnpm lockfiles for versions >= 9.0.
type pnpmV9LockYaml struct { type pnpmV9LockYaml struct {
LockfileVersion string `yaml:"lockfileVersion"` 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"` Packages map[string]pnpmV9PackageEntry `yaml:"packages"`
Snapshots map[string]pnpmV9SnapshotEntry `yaml:"snapshots"` 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. // 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) { switch v := info.(type) {
case string: case string:
return v, nil return v, nil
case map[string]interface{}: case map[string]any:
if ver, ok := v["version"].(string); ok { if ver, ok := v["version"].(string); ok {
// e.g., "1.2.3(react@17.0.0)" -> "1.2.3" // e.g., "1.2.3(react@17.0.0)" -> "1.2.3"
return strings.SplitN(ver, "(", 2)[0], nil return strings.SplitN(ver, "(", 2)[0], nil

View File

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

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