Merge remote-tracking branch 'upstream/main' into add-nested-archive-cataloging

This commit is contained in:
Keith Zantow
2026-10-05 15:42:07 -04:00
91 changed files with 2176 additions and 359 deletions
+4
View File
@@ -6,6 +6,7 @@ import (
"net/url"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"time"
@@ -95,6 +96,9 @@ func Test_makeDiskKey(t *testing.T) {
}
func Test_errors(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("windows ignores unix permission bits on directories")
}
tmp := t.TempDir()
cache := filepath.Join(tmp, "cache")
// make a non-writable directory
@@ -212,7 +212,7 @@ func parseGenericCatalogerFunction(funcDecl *ast.FuncDecl, filePath, repoRoot st
// extractPackageNameFromPath extracts the package name from a cataloger source file path
// e.g., "syft/pkg/cataloger/swift/cataloger.go" -> "swift"
func extractPackageNameFromPath(filePath string) string {
parts := strings.Split(filePath, string(filepath.Separator))
parts := strings.Split(filepath.ToSlash(filePath), "/")
// find the LAST occurrence of "cataloger" in the path
// (to handle test fixtures with multiple "cataloger" segments)
@@ -4,6 +4,7 @@ import (
"go/ast"
"go/parser"
"go/token"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
@@ -337,7 +338,7 @@ func TestResolveImportPath(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := resolveImportPath(tt.importPath, testRepoRoot)
require.Equal(t, tt.want, got)
require.Equal(t, filepath.FromSlash(tt.want), got)
})
}
}
+14 -1
View File
@@ -502,6 +502,19 @@ func convertToJSONSchemaTypesFromMetadata(metadataTypes []string) []string {
return result
}
// packageTypeConstName renders a package type using its go constant name, which is what the detector
// "type" field reports (e.g. "BinaryPkg").
// a switch rather than a derivation, since pkg.Type values don't reliably map back to their constant
// names (e.g. "java-archive" is JavaPkg); add an arm when a classifier declares a new type.
func packageTypeConstName(t pkg.Type) string {
switch t {
case pkg.CpanPkg:
return "CpanPkg"
default:
return "BinaryPkg"
}
}
// EnrichWithBinaryClassifier enriches an entry with binary classifier detectors if it's the binary-classifier-cataloger
func (e *EnrichmentData) EnrichWithBinaryClassifier(catalogerName string, entry *capabilities.CatalogerEntry) {
// special handling for binary-classifier-cataloger: auto-generate one detector per classifier
@@ -523,7 +536,7 @@ func (e *EnrichmentData) EnrichWithBinaryClassifier(catalogerName string, entry
Name: classifier.Package,
PURL: purlStr,
CPEs: cpeStrings,
Type: "BinaryPkg",
Type: packageTypeConstName(classifier.PackageType()),
},
}
+4 -3
View File
@@ -4,7 +4,7 @@ import (
"errors"
"io/fs"
"os"
"path/filepath"
"path"
"strings"
"github.com/diskfs/go-diskfs/filesystem"
@@ -25,7 +25,8 @@ func WalkDiskDir(fsys filesystem.FileSystem, root string, fn WalkDiskDirFunc) er
}
for _, info := range infos {
p := filepath.Join(root, info.Name())
// squashfs paths are posix regardless of host os
p := path.Join(root, info.Name())
err = walkDiskDir(fsys, p, info, fn)
if err != nil {
if errors.Is(err, fs.SkipDir) {
@@ -74,7 +75,7 @@ func walkDiskDir(fsys filesystem.FileSystem, name string, d os.FileInfo, walkDir
}
for _, d1 := range dirs {
name1 := filepath.Join(name, d1.Name())
name1 := path.Join(name, d1.Name())
if err := walkDiskDir(fsys, name1, d1, walkDirFn); err != nil {
if errors.Is(err, fs.SkipDir) {
break
+2
View File
@@ -19,6 +19,8 @@ func createTestFS(t *testing.T) filesystem.FileSystem {
filename := "test.squashfs"
f, err := os.Create(filepath.Join(dir, filename))
require.NoError(t, err)
// windows can't remove the temp dir while the backing file is open
t.Cleanup(func() { _ = f.Close() })
b := file.New(f, false)
fsys, err := squashfs.Create(b, 0, 0, 4096)
+2 -1
View File
@@ -84,7 +84,8 @@ func ExtractGlobsFromTarToUniqueTempFile(ctx context.Context, archivePath, dir s
func matchesAnyGlob(name string, globs ...string) bool {
for _, glob := range globs {
if matches, err := doublestar.PathMatch(glob, name); err == nil && matches {
// tar entry names are always posix, so don't match with the host separator (PathMatch)
if matches, err := doublestar.Match(glob, name); err == nil && matches {
return true
}
}
+2
View File
@@ -16,6 +16,7 @@ import (
"github.com/anchore/syft/internal/os"
"github.com/anchore/syft/internal/sbomsync"
"github.com/anchore/syft/internal/task"
"github.com/anchore/syft/internal/testutils"
"github.com/anchore/syft/syft"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/linux"
@@ -84,6 +85,7 @@ func Test_EnvironmentTask(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
testutils.SkipWithoutLinuxContainers(t)
tarPath := imagetest.GetFixtureImageTarPath(t, test.name)
// get the source
+30
View File
@@ -0,0 +1,30 @@
package testutils
import (
"os/exec"
"runtime"
"strings"
"sync"
"testing"
)
var dockerServerOS = sync.OnceValue(func() string {
out, err := exec.Command("docker", "version", "--format", "{{.Server.Os}}").Output()
if err != nil {
return ""
}
return strings.TrimSpace(string(out))
})
// SkipWithoutLinuxContainers skips tests whose fixtures are linux container images (built or run via docker).
// This only kicks in on windows, where the docker daemon is often running windows containers (or is absent),
// so the linux fixture images can't be built. Everywhere else the fixture tooling is left to fail loudly.
func SkipWithoutLinuxContainers(t testing.TB) {
t.Helper()
if runtime.GOOS != "windows" {
return
}
if os := dockerServerOS(); os != "linux" {
t.Skipf("linux container fixtures unavailable (docker server os=%q)", os)
}
}
+2 -1
View File
@@ -265,8 +265,9 @@ func TestLazyCreation(t *testing.T) {
// root dir is not created until needed
assert.Equal(t, "", td.root)
_, _, err := td.NewFile("trigger-*")
f, _, err := td.NewFile("trigger-*")
require.NoError(t, err)
require.NoError(t, f.Close())
assert.NotEmpty(t, td.root)