You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(pip): add pyproject.toml support via pip --dry-run --report (guacsec#465)
* feat(pip): add pyproject.toml support via pip --dry-run --report
Add Python_pip_pyproject provider that resolves PEP 621 pyproject.toml
dependencies using `pip install --dry-run --ignore-installed --report`.
This is the fallback provider when no lock file (uv.lock/poetry.lock)
is found, enabling analysis of standard pyproject.toml projects
without requiring uv or poetry.
The pip report JSON provides resolved versions, requires_dist for
building the dependency tree, and requested flags for direct vs
transitive classification. Extras-only deps are filtered out.
Supports TRUSTIFY_DA_PIP_REPORT env var for testing without pip.
Implements TC-4065
Assisted-by: Claude Code
* fix(python): align pip pyproject _getDependencyData signature with base class
Python_pip_pyproject._getDependencyData() had only 3 parameters
(manifestDir, parsed, opts) instead of the 4 defined by the base class
(manifestDir, workspaceDir, parsed, opts). When called from _createSbom()
with 4 arguments, workspaceDir was silently received as parsed, and
parsed was received as opts, causing argument misalignment.
Add the missing _workspaceDir parameter to match the base class contract
and sibling providers (python_uv, python_poetry).
Implements TC-4098
Assisted-by: Claude Code
* fix(python): only exclude root entry from pip report graph, not all dir_info entries
_parsePipReport() filtered nonRootPackages by checking
p.download_info?.dir_info === undefined, which excluded ALL packages
with dir_info (including local/path dependencies). Changed to filter
by identity (p !== rootEntry) so only the specific root project entry
is excluded, matching the Java implementation's behavior.
Implements TC-4099
Assisted-by: Claude Code
* refactor(test): parameterize pyproject SBOM tests and add doc comments
Extract shared SBOM_CASES constant and use forEach loops to eliminate
repetitive stack/component test pairs across uv, poetry, and pip suites.
Parameterize validateLockFile and workspace tests similarly. Add JSDoc
comments to all 39 test functions.
Implements TC-4065
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test(pip): add extras package to pip fixture for realistic extras filtering
Add requests[socks] to the test pyproject.toml and include PySocks in the
pip_report.json install list. This makes the extras-filtering test exercise
the actual code path: PySocks is now present in the report but correctly
excluded from the SBOM via _hasExtraMarker.
Previously the test trivially passed because PySocks was never in the
install list.
Implements TC-4065
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test(pip): call pip directly instead of using env var overrides
Remove TRUSTIFY_DA_PIP_REPORT setup/teardown from pip tests and let them
invoke pip directly. Pin fixture pyproject.toml versions to get
deterministic output, add --quiet flag to suppress non-JSON stdout, and
update expected SBOMs with real resolved versions. Add testing convention
to CONVENTIONS.md and ignore *.egg-info build artifacts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(test): lower requires-python to >=3.9 to match CI Python version
CI uses Python 3.9 (setup-python in test.yml), so pip rejects
pyproject.toml fixtures that require >=3.12.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(pip): clean up .egg-info directories created by pip --dry-run
pip creates .egg-info as a side effect of --dry-run --report. Snapshot
existing .egg-info dirs before invoking pip and remove only newly
created ones afterward to avoid polluting the user's project.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test(pip): replace manual ignore assertions with golden SBOM tests
The pip_pep621_ignore fixture was missing expected_stack_sbom.json and
expected_component_sbom.json, relying on partial manual assertions instead
of the standard SBOM_CASES golden-file pattern. Add the golden files and
switch to deep.equal comparison. Document the golden SBOM convention in
CONVENTIONS.md to prevent this gap in future implementations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(python): build true dependency graph instead of tree
The pyproject base class built an intermediate tree with a visited set
that prevented a dependency from appearing under multiple parents. This
caused PySocks to be missing from requests' dependsOn when both requests
and urllib3 declared it (via extras). All other providers (npm, cargo,
go, maven) already produce true CycloneDX graphs.
Replace _buildDependencyTree/_collectTransitive/_addAllDependencies with
graph-based BFS reachability + flat edge iteration. No recursion
prevention needed — Python resolvers reject circular dependencies.
Regenerate all pyproject golden SBOM files (pip, uv, poetry, workspace).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use GraphEntry typedef instead of inline type in JSDoc
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
-**Higher-order setup**: Functions like `interceptAndRun()` for test setup/teardown
84
+
-**Prefer real tool invocations over env var overrides**: Tests should call the actual ecosystem tools (pip, uv, poetry, mvn, npm, etc.) rather than injecting pre-recorded output via `TRUSTIFY_DA_*` environment variables. The CI environment has these tools available. Env var overrides (`TRUSTIFY_DA_PIP_REPORT`, `TRUSTIFY_DA_UV_EXPORT`, etc.) exist for users who lack the tool locally, but tests should exercise the real tool path to catch integration issues.
85
+
-**Golden SBOM files for every test fixture**: Every provider test fixture directory must include `expected_stack_sbom.json` and `expected_component_sbom.json` golden files. Tests must use the `SBOM_CASES` pattern to do a full `deep.equal` comparison of the provider output against these golden files. Manual partial assertions (e.g. checking a single component name) are not a substitute — they may be added as supplementary tests but never as the only verification for a fixture.
86
+
87
+
## Commit Messages
88
+
89
+
- Likely Conventional Commits format
90
+
- DCO (Developer Certificate of Origin) required
91
+
- Semantic versioning (`0.3.0` in package.json)
92
+
93
+
## Dependencies
94
+
95
+
-**Package manager**: npm with `package-lock.json`
96
+
-**Module system**: ES modules with explicit `.js` extensions in relative imports
97
+
-**Import convention**: `import fs from 'node:fs'` (node: protocol for built-ins)
98
+
-**Environment variables**: Prefixed with `TRUSTIFY_DA_` (e.g., `TRUSTIFY_DA_MVN_PATH`, `TRUSTIFY_DA_TOKEN`, `TRUSTIFY_DA_DEBUG`)
0 commit comments