From 891499685aa458f64cec6677e4836e5f1a5f8b38 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Fri, 7 Nov 2025 15:42:46 -0500 Subject: [PATCH] fix pdm Signed-off-by: Alex Goodman --- internal/capabilities/generate/README.md | 4 +- internal/capabilities/packages.yaml | 41 ++++++++++++++-- syft/pkg/cataloger/python/cataloger_test.go | 53 +++++++++++++++++++-- 3 files changed, 89 insertions(+), 9 deletions(-) diff --git a/internal/capabilities/generate/README.md b/internal/capabilities/generate/README.md index 80212502c..1213435c6 100644 --- a/internal/capabilities/generate/README.md +++ b/internal/capabilities/generate/README.md @@ -135,10 +135,8 @@ graph LR style E2 fill:#fff9c4 ``` -### Key Data Flows - 1. **Cataloger Discovery**: AST parser walks `syft/pkg/cataloger/` to find `generic.NewCataloger()` calls and extract parser information -2. **Config Discovery**: AST parser finds config structs and extracts fields with `// app-config:` annotations +2. **Cataloger Config Discovery**: AST parser finds config structs and extracts fields with `// app-config:` annotations 3. **App Config Discovery**: AST parser extracts ecosystem configurations from options package, including descriptions and defaults 4. **Metadata Discovery**: JSON reader loads test observations that record what metadata/package types each parser produces 5. **Linking**: AST analyzer connects catalogers to their config structs by examining constructor parameters diff --git a/internal/capabilities/packages.yaml b/internal/capabilities/packages.yaml index f74b3639c..9b7e5c6b5 100644 --- a/internal/capabilities/packages.yaml +++ b/internal/capabilities/packages.yaml @@ -3365,6 +3365,37 @@ catalogers: - package - python parsers: # AUTO-GENERATED structure + - function: parsePdmLock # AUTO-GENERATED + detector: # AUTO-GENERATED + method: glob # AUTO-GENERATED + criteria: # AUTO-GENERATED + - '**/pdm.lock' + metadata_types: # AUTO-GENERATED + - pkg.PythonPdmLockEntry + package_types: # AUTO-GENERATED + - python + json_schema_types: # AUTO-GENERATED + - PythonPdmLockEntry + capabilities: # MANUAL - config-driven capability definitions + - name: license + default: false + - name: dependency.depth + default: + - direct + - indirect + - name: dependency.edges + default: complete + - name: dependency.kinds + default: + - runtime + - dev + - optional + - name: package_manager.files.listing + default: false + - name: package_manager.files.digests + default: false + - name: package_manager.package_integrity_hash + default: false - function: parseUvLock # AUTO-GENERATED detector: # AUTO-GENERATED method: glob # AUTO-GENERATED @@ -3387,6 +3418,7 @@ catalogers: default: complete - name: dependency.kinds default: + - runtime - dev - optional - name: package_manager.files.listing @@ -3471,6 +3503,7 @@ catalogers: default: complete - name: dependency.kinds default: + - runtime - dev - optional - name: package_manager.files.listing @@ -3478,8 +3511,10 @@ catalogers: - name: package_manager.files.digests default: false - name: package_manager.package_integrity_hash - default: false - - function: parseRequirementsTxt # AUTO-GENERATED + default: true + evidence: + - PythonPoetryLockEntry.PackageHashes + - function: parseRequirementsTxt detector: # AUTO-GENERATED method: glob # AUTO-GENERATED criteria: # AUTO-GENERATED @@ -3490,7 +3525,7 @@ catalogers: - python json_schema_types: # AUTO-GENERATED - PythonPipRequirementsEntry - capabilities: # MANUAL - config-driven capability definitions + capabilities: # MANUAL - preserved across regeneration - name: license default: false - name: dependency.depth diff --git a/syft/pkg/cataloger/python/cataloger_test.go b/syft/pkg/cataloger/python/cataloger_test.go index 25fa4cc7e..3f93fdbbe 100644 --- a/syft/pkg/cataloger/python/cataloger_test.go +++ b/syft/pkg/cataloger/python/cataloger_test.go @@ -14,7 +14,7 @@ import ( "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" ) -func Test_PackageCataloger(t *testing.T) { +func Test_InstalledPackageCataloger(t *testing.T) { ctx := context.TODO() tests := []struct { name string @@ -402,10 +402,57 @@ func Test_PackageCataloger(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - (pkgtest.NewCatalogTester(). + pkgtest.NewCatalogTester(). FromDirectory(t, test.fixture). Expects(test.expectedPackages, nil). - TestCataloger(t, NewInstalledPackageCataloger())) + TestCataloger(t, NewInstalledPackageCataloger()) + }) + } +} + +func Test_PackageCataloger(t *testing.T) { + + tests := []struct { + name string + fixture string + expectedPackages []string + expectedRelationships []string + }{ + { + name: "pdm", + fixture: "test-fixtures/pdm-lock", + expectedPackages: []string{ + "certifi @ 2025.1.31 (pdm.lock)", + "chardet @ 3.0.4 (pdm.lock)", + "charset-normalizer @ 2.0.12 (pdm.lock)", + "colorama @ 0.3.9 (pdm.lock)", + "idna @ 2.7 (pdm.lock)", + "py @ 1.4.34 (pdm.lock)", + "pytest @ 3.2.5 (pdm.lock)", + "requests @ 2.27.1 (pdm.lock)", + "setuptools @ 39.2.0 (pdm.lock)", + "urllib3 @ 1.26.20 (pdm.lock)", + }, + expectedRelationships: []string{ + "certifi @ 2025.1.31 (pdm.lock) [dependency-of] requests @ 2.27.1 (pdm.lock)", + "chardet @ 3.0.4 (pdm.lock) [dependency-of] requests @ 2.27.1 (pdm.lock)", + "charset-normalizer @ 2.0.12 (pdm.lock) [dependency-of] requests @ 2.27.1 (pdm.lock)", + "colorama @ 0.3.9 (pdm.lock) [dependency-of] pytest @ 3.2.5 (pdm.lock)", + "idna @ 2.7 (pdm.lock) [dependency-of] requests @ 2.27.1 (pdm.lock)", + "py @ 1.4.34 (pdm.lock) [dependency-of] pytest @ 3.2.5 (pdm.lock)", + "setuptools @ 39.2.0 (pdm.lock) [dependency-of] pytest @ 3.2.5 (pdm.lock)", + "urllib3 @ 1.26.20 (pdm.lock) [dependency-of] requests @ 2.27.1 (pdm.lock)", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pkgtest.NewCatalogTester(). + FromDirectory(t, tt.fixture). + ExpectsPackageStrings(tt.expectedPackages). + ExpectsRelationshipStrings(tt.expectedRelationships). + TestCataloger(t, NewPackageCataloger(DefaultCatalogerConfig())) }) } }