-
Notifications
You must be signed in to change notification settings - Fork 24
[SP-2874] feat: add licenses sub-command, add support for ingesting CDX, add CDX input validation #131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughAdds a component "licenses" sub-command with gRPC/REST support, integrates CycloneDX validation/ingestion across component commands, implements license retrieval APIs, enforces gRPC/protobuf runtime version checks in generated stubs, updates dependencies and docs, and bumps package version to 1.33.0. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant User
participant CLI as CLI (component licenses)
participant Comp as Components
participant CDX as CycloneDx
participant API as ScanossGrpc
participant S as Server
User->>CLI: component licenses [-p ... | -i file.cdx.json] [-o out.json] [--grpc]
CLI->>Comp: comp_licenses(args)
alt input file provided
Comp->>Comp: validate_json_file()
Comp->>CDX: is_cyclonedx_json?
alt CycloneDX
CDX-->>Comp: get_purls_request_from_cdx()
else JSON with purls
Comp-->>Comp: use parsed JSON
end
else purls via flags
Comp-->>Comp: build request from --purl
end
Comp->>API: get_licenses(request)
alt --grpc
API->>S: RPC GetComponentsLicenses
S-->>API: ComponentsLicenseResponse
else REST
API->>S: POST /licenses/components
S-->>API: JSON response
end
API-->>Comp: licenses dict
Comp-->>CLI: write output (JSON)
CLI-->>User: exit code
sequenceDiagram
autonumber
participant User
participant Crypt as CryptographyConfig
participant CDX as CycloneDx
User->>Crypt: init(input_file=...?)
Crypt->>Crypt: _process_input_file()
alt has input_file
Crypt->>Crypt: validate_json_file()
Crypt->>CDX: is_cyclonedx_json?
alt CycloneDX
CDX-->>Crypt: get_purls_request_from_cdx()
else
Crypt-->>Crypt: use JSON as-is
end
Crypt->>Crypt: validate 'purls' structure
else
Crypt-->>Crypt: use configured purls
end
Crypt-->>User: ready config
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
CHANGELOG.md
(2 hunks)requirements.txt
(1 hunks)setup.cfg
(1 hunks)src/scanoss/__init__.py
(1 hunks)src/scanoss/api/common/v2/scanoss_common_pb2.py
(1 hunks)src/scanoss/api/common/v2/scanoss_common_pb2_grpc.py
(1 hunks)src/scanoss/api/licenses/v2/scanoss_licenses_pb2.py
(1 hunks)src/scanoss/api/licenses/v2/scanoss_licenses_pb2_grpc.py
(1 hunks)src/scanoss/cli.py
(8 hunks)src/scanoss/components.py
(4 hunks)src/scanoss/cyclonedx.py
(2 hunks)src/scanoss/scanossgrpc.py
(4 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/scanoss/scanossgrpc.py (2)
src/scanoss/api/licenses/v2/scanoss_licenses_pb2_grpc.py (3)
LicenseStub
(29-59)GetLicenses
(74-79)GetLicenses
(159-183)src/scanoss/components.py (1)
get_licenses
(373-403)
src/scanoss/components.py (1)
src/scanoss/scanossgrpc.py (1)
get_licenses
(668-683)
🪛 GitHub Actions: Build/Test Local Python Package
src/scanoss/api/licenses/v2/scanoss_licenses_pb2.py
[error] 27-27: ModuleNotFoundError: No module named 'protoc_gen_openapiv2'. The scanoss-py command failed with exit code 1.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (27)
setup.cfg (1)
42-42
: LGTM: CycloneDX dependency addition is appropriate.The addition of
cyclonedx-python-lib[validation]
supports the new CycloneDX JSON validation and processing features. The[validation]
extra ensures JSON schema validation capabilities are available.src/scanoss/__init__.py (1)
25-25
: LGTM: Version bump aligns with new feature additions.The version increment from 1.27.1 to 1.28.0 is appropriate for a minor release introducing new license sub-command and CycloneDX support features.
requirements.txt (1)
16-16
: LGTM: Dependency addition is consistent with setup.cfg.The
cyclonedx-python-lib[validation]
dependency addition matches the setup.cfg configuration and supports the new CycloneDX functionality.CHANGELOG.md (2)
12-17
: LGTM: Changelog entry is well-formatted and comprehensive.The version 1.28.0 changelog entry clearly documents the three main additions: licenses sub-command, CycloneDX ingestion support, and CDX input validation. The format follows the existing changelog structure.
592-592
: LGTM: Version comparison link is consistent.The version comparison link for 1.28.0 follows the established pattern and maintains consistency with existing entries.
src/scanoss/scanossgrpc.py (5)
39-39
: LGTM: License stub import added correctly.The import follows the same pattern as other gRPC stub imports in the file.
45-45
: LGTM: ComponentBatchRequest import added correctly.This import is needed for the new license functionality and follows the existing import pattern.
175-175
: LGTM: License stub initialization for insecure channels.The initialization follows the same pattern as other stubs in the class.
188-188
: LGTM: License stub initialization for secure channels.The initialization follows the same pattern as other stubs in the class.
668-683
: LGTM: Well-implemented get_licenses method.The method follows the established patterns in the class:
- Uses the
_call_rpc
helper for consistent error handling- Proper type hints with
Optional[Dict]
return type- Appropriate debug message template
- Correct usage of
ComponentBatchRequest
typeThe implementation is consistent with other gRPC methods in the class.
src/scanoss/cyclonedx.py (3)
31-32
: LGTM: Required imports for CycloneDX validation.The imports are necessary for the new validation functionality and follow the existing import pattern.
311-329
: LGTM: Well-implemented CycloneDX validation method.The method provides proper validation functionality:
- Uses CycloneDX schema v1.6 for validation
- Includes comprehensive error handling with try-catch
- Consistent error messaging using
print_stderr
- Returns boolean indicating validation success
- Follows the existing class patterns
The implementation is robust and handles validation errors appropriately.
331-349
: LGTM: Effective PURL extraction from CycloneDX.The method correctly extracts PURL requests from CycloneDX components:
- Properly handles optional version requirements
- Creates appropriate request structure with 'purls' key
- Handles both cases (with and without version) correctly
- Returns the expected dictionary format
The implementation aligns with the expected input format for the license API.
src/scanoss/cli.py (3)
309-316
: LGTM: Licenses sub-command properly definedThe new
licenses
sub-command follows the established pattern for other component sub-commands. The aliaslics
and handler function assignment are correctly implemented.
419-427
: LGTM: Licenses sub-command properly included in common optionsThe
c_licenses
parser is correctly added to the list of parsers that receive common purl and input options, maintaining consistency with other component sub-commands.
1888-1920
: LGTM: Licenses handler function correctly implementedThe
comp_licenses
function follows the established pattern for other component handlers:
- Proper input validation (purl XOR input)
- Certificate file existence check
- PAC file processing
- Components instance creation with all necessary parameters
- Error handling with appropriate exit codes
The implementation is consistent with similar handlers like
comp_vulns
andcomp_semgrep
.src/scanoss/api/common/v2/scanoss_common_pb2.py (2)
12-19
: LGTM: Runtime version validation addedThe protobuf runtime version validation ensures compatibility with protobuf version 5.29.0, which is a good practice for generated code.
49-52
: LGTM: New message types properly definedThe serialization offsets for the new
ComponentBatchRequest
andComponentRequest
message types are correctly generated and will be used by the licenses API.src/scanoss/components.py (4)
32-33
: LGTM: Proper imports for CycloneDX supportThe imports for
CycloneDx
andvalidate_json_file
are correctly added to support CycloneDX input validation and processing.
89-89
: LGTM: CycloneDx instance properly initializedThe
CycloneDx
instance is correctly initialized with the debug flag from the parent class, enabling CycloneDX processing capabilities.
100-108
: LGTM: Enhanced load_purls method with CycloneDX supportThe updated
load_purls
method properly:
- Uses
validate_json_file
for robust JSON validation- Detects CycloneDX format using
self.cdx.is_cyclonedx_json
- Converts CycloneDX data to PURL request format via
self.cdx.get_purls_request_from_cdx
- Falls back to direct JSON data usage for non-CycloneDX inputs
This implementation maintains backward compatibility while adding CycloneDX support.
373-403
: LGTM: get_licenses method correctly implementedThe new
get_licenses
method follows the established pattern of otherget_*
methods in the class:
- Proper input validation and loading
- File/stdout handling with error checking
- Correct construction of
ComponentBatchRequest
dictionary- Appropriate gRPC API call to
self.grpc_api.get_licenses
- JSON output formatting and success handling
- Consistent error handling and file cleanup
The method integrates well with the existing codebase architecture.
src/scanoss/api/licenses/v2/scanoss_licenses_pb2_grpc.py (5)
1-27
: Well-implemented version compatibility checking.The version checking logic is robust and follows gRPC best practices. It gracefully handles import errors and provides clear upgrade/downgrade instructions for version mismatches.
29-60
: Correctly implemented client-side gRPC stub.The LicenseStub class properly implements all four RPC methods with correct endpoint paths, serialization, and deserialization. The implementation follows standard gRPC client patterns.
62-94
: Appropriate placeholder implementations for server-side servicer.The LicenseServicer class correctly implements placeholder methods that raise NotImplementedError with UNIMPLEMENTED status. This is the expected pattern for generated gRPC servicers, allowing developers to provide actual implementations by subclassing or overriding these methods.
96-123
: Correctly implemented server registration function.The add_LicenseServicer_to_server function properly registers all RPC method handlers with appropriate serialization/deserialization configuration. The implementation follows standard gRPC server setup patterns.
125-238
: Well-implemented experimental gRPC API.The License experimental class provides static methods for direct RPC calls with full parameter support. The implementation correctly uses grpc.experimental.unary_unary and follows the expected patterns for experimental gRPC APIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/scanoss/cryptography.py
(3 hunks)
🧰 Additional context used
🪛 GitHub Actions: Lint
src/scanoss/cryptography.py
[error] 30-30: Ruff: Too many branches (14 > 12) in function 'post_init' (PLR0912)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: build
🔇 Additional comments (2)
src/scanoss/cryptography.py (2)
5-5
: LGTM: Clean import addition.The import of
CycloneDx
is properly placed and follows the existing import structure.
193-193
: LGTM: Method signature formatting improvement.The single-line method signature is cleaner and more consistent with Python conventions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/scanoss/api/common/v2/scanoss_common_pb2_grpc.py (1)
7-24
: Version mismatch issue persists and has worsened.The generated code now requires grpcio>=1.73.1, but based on previous review comments, the project dependencies only specify grpcio>=1.70.0. This creates a version mismatch where users with grpcio versions 1.70.0-1.73.0 will encounter a RuntimeError.
This is a continuation of the issue flagged in previous reviews, but it has worsened as the required version has increased from 1.70.0 to 1.73.1.
Please ensure the project dependencies are updated to align with the generated code requirement:
# In setup.cfg and requirements.txt -grpcio>=1.70.0 +grpcio>=1.73.1Or alternatively, regenerate the gRPC stubs with a lower version threshold that matches the current project dependencies.
🧹 Nitpick comments (1)
src/scanoss/api/common/v2/scanoss_common_pb2_grpc.py (1)
4-4
: Remove unused import.The
warnings
import is not used in the code and should be removed.-import warnings
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/scanoss/api/common/v2/scanoss_common_pb2.py
(1 hunks)src/scanoss/api/common/v2/scanoss_common_pb2_grpc.py
(1 hunks)src/scanoss/api/licenses/v2/scanoss_licenses_pb2.py
(1 hunks)src/scanoss/api/licenses/v2/scanoss_licenses_pb2_grpc.py
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- src/scanoss/api/licenses/v2/scanoss_licenses_pb2.py
- src/scanoss/api/common/v2/scanoss_common_pb2.py
- src/scanoss/api/licenses/v2/scanoss_licenses_pb2_grpc.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (6)
src/scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2_grpc.py (3)
1-1
: Manual modifications to generated code may be lost.This file is marked as generated code with "DO NOT EDIT!" but contains changes. Ensure these modifications are made in the source proto files or generation scripts to prevent loss during regeneration.
4-4
: Remove unused import.The
warnings
module is imported but never used in the code.
9-27
: Version check may be overly restrictive.The runtime version check enforces exactly
grpcio>=1.73.1
, which could cause issues for users with newer compatible versions.src/scanoss/api/dependencies/v2/scanoss_dependencies_pb2_grpc.py (3)
1-1
: Manual modifications to generated code may be lost.This file is marked as generated code with "DO NOT EDIT!" but contains changes. Ensure these modifications are made in the source proto files or generation scripts to prevent loss during regeneration.
4-4
: Remove unused import.The
warnings
module is imported but never used in the code.
9-27
: Version check may be overly restrictive.The runtime version check enforces exactly
grpcio>=1.73.1
, which could cause issues for users with newer compatible versions.
🧹 Nitpick comments (6)
src/protoc_gen_swagger/options/openapiv2_pb2_grpc.py (1)
4-4
: Remove unused import.The
warnings
module is imported but never used in the code.-import warnings
src/protoc_gen_swagger/options/annotations_pb2_grpc.py (1)
4-4
: Remove unused import.The
warnings
module is imported but not used in this generated file.-import warnings
src/scanoss/api/cryptography/v2/scanoss_cryptography_pb2_grpc.py (1)
4-4
: Remove unused import.The
warnings
module is imported but not used in this generated file.-import warnings
src/scanoss/api/semgrep/v2/scanoss_semgrep_pb2_grpc.py (1)
4-4
: Remove unused import.The
warnings
module is imported but not used in this generated file.-import warnings
src/scanoss/api/scanning/v2/scanoss_scanning_pb2_grpc.py (1)
4-4
: Remove unused import.The
warnings
module is imported but not used in this generated file.-import warnings
src/scanoss/api/components/v2/scanoss_components_pb2_grpc.py (1)
4-4
: Remove unused import.The
warnings
module is imported but not used in this generated file.-import warnings
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (20)
src/protoc_gen_swagger/options/annotations_pb2.py
(2 hunks)src/protoc_gen_swagger/options/annotations_pb2.pyi
(1 hunks)src/protoc_gen_swagger/options/annotations_pb2_grpc.py
(1 hunks)src/protoc_gen_swagger/options/openapiv2_pb2.py
(2 hunks)src/protoc_gen_swagger/options/openapiv2_pb2.pyi
(1 hunks)src/protoc_gen_swagger/options/openapiv2_pb2_grpc.py
(1 hunks)src/scanoss/api/components/v2/scanoss_components_pb2.py
(1 hunks)src/scanoss/api/components/v2/scanoss_components_pb2_grpc.py
(7 hunks)src/scanoss/api/cryptography/v2/scanoss_cryptography_pb2.py
(1 hunks)src/scanoss/api/cryptography/v2/scanoss_cryptography_pb2_grpc.py
(9 hunks)src/scanoss/api/dependencies/v2/scanoss_dependencies_pb2.py
(1 hunks)src/scanoss/api/dependencies/v2/scanoss_dependencies_pb2_grpc.py
(6 hunks)src/scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2.py
(1 hunks)src/scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2_grpc.py
(6 hunks)src/scanoss/api/scanning/v2/scanoss_scanning_pb2.py
(2 hunks)src/scanoss/api/scanning/v2/scanoss_scanning_pb2_grpc.py
(5 hunks)src/scanoss/api/semgrep/v2/scanoss_semgrep_pb2.py
(1 hunks)src/scanoss/api/semgrep/v2/scanoss_semgrep_pb2_grpc.py
(5 hunks)src/scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py
(1 hunks)src/scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2_grpc.py
(6 hunks)
✅ Files skipped from review due to trivial changes (11)
- src/protoc_gen_swagger/options/annotations_pb2.py
- src/scanoss/api/components/v2/scanoss_components_pb2.py
- src/scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py
- src/scanoss/api/cryptography/v2/scanoss_cryptography_pb2.py
- src/protoc_gen_swagger/options/openapiv2_pb2.py
- src/scanoss/api/semgrep/v2/scanoss_semgrep_pb2.py
- src/scanoss/api/scanning/v2/scanoss_scanning_pb2.py
- src/protoc_gen_swagger/options/annotations_pb2.pyi
- src/scanoss/api/dependencies/v2/scanoss_dependencies_pb2.py
- src/scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2.py
- src/protoc_gen_swagger/options/openapiv2_pb2.pyi
🔇 Additional comments (11)
src/protoc_gen_swagger/options/openapiv2_pb2_grpc.py (2)
7-10
: LGTM: Version constants are properly defined.The version constants and initialization are correctly implemented for version compatibility checking.
11-24
: LGTM: Robust version compatibility checking.The version checking logic is well-implemented with proper error handling:
- Uses try-except to handle cases where
first_version_is_lower
utility might not be available- Provides a comprehensive error message with actionable guidance
- Gracefully falls back to marking version as unsupported if the utility is unavailable
This ensures that users are informed about version incompatibilities and know how to resolve them.
src/protoc_gen_swagger/options/annotations_pb2_grpc.py (1)
7-24
: LGTM: Version compatibility check is well implemented.The version compatibility check correctly handles both the case where
first_version_is_lower
is available and when it's not, providing clear error messages to guide users on how to resolve version conflicts.src/scanoss/api/cryptography/v2/scanoss_cryptography_pb2_grpc.py (2)
44-69
: LGTM: Explicit method registration is properly implemented.The addition of
_registered_method=True
flags to all unary-unary RPC method calls in the stub class correctly implements explicit method registration as per the updated gRPC Python API.
156-156
: LGTM: Server-side method registration is correctly added.The call to
server.add_registered_method_handlers
complements the existing generic handler registration, ensuring methods are properly registered on the server side.src/scanoss/api/semgrep/v2/scanoss_semgrep_pb2_grpc.py (1)
44-49
: LGTM: Method registration flags are properly added.The
_registered_method=True
flags are correctly added to all RPC method calls in the stub class.src/scanoss/api/scanning/v2/scanoss_scanning_pb2_grpc.py (1)
44-49
: LGTM: Method registration is correctly implemented.The explicit method registration flags are properly added to all RPC methods in the stub class.
src/scanoss/api/components/v2/scanoss_components_pb2_grpc.py (2)
44-59
: LGTM: Method registration flags are consistently applied.All RPC method calls in the stub class correctly include the
_registered_method=True
flag for explicit method registration.
122-122
: LGTM: Server method registration is properly implemented.The server-side method registration call is correctly added to ensure methods are properly registered.
src/scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2_grpc.py (2)
1-1
: Manual modifications to generated code may be lost.This file is marked as generated code with "DO NOT EDIT!" but contains changes. Ensure these modifications are made in the source proto files or generation scripts to prevent loss during regeneration.
9-27
: Keep the strict gRPC version check as-isThe gRPC Python team intentionally added a runtime enforcement (since v1.65.0) to ensure that generated stubs run against the same—or a newer—
grpcio
release. This prevents subtle incompatibilities (e.g. Protobuf runtime updates in v1.73.0+) and avoids runtime errors caused by mismatched code and library versions. Feel free to retain the currentgrpcio>=1.73.1
check and accompanying error message.Likely an incorrect or invalid review comment.
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! | ||
"""Client and server classes corresponding to protobuf-defined services.""" | ||
import grpc | ||
import warnings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove unused import.
The warnings
module is imported but never used in the code.
import grpc
-import warnings
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import warnings | |
import grpc |
🤖 Prompt for AI Agents
In src/scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2_grpc.py at line 4,
the warnings module is imported but not used anywhere in the file. Remove the
import statement for warnings to clean up unused imports.
b167952
to
4c37f13
Compare
4c37f13
to
f12fd1b
Compare
SCANOSS SCAN Completed 🚀
View more details on SCANOSS Action Summary |
SCANOSS SCAN Completed 🚀
View more details on SCANOSS Action Summary |
@eeisegn undeclared policy check is failing because of lot of false positives. could you please be so kind to take a look? mostly related to |
SCANOSS SCAN Completed 🚀
View more details on SCANOSS Action Summary |
SCANOSS SCAN Completed 🚀
View more details on SCANOSS Action Summary |
5db9740
to
be1fed9
Compare
SCANOSS SCAN Completed 🚀
View more details on SCANOSS Action Summary |
…DX, add CDX input validation
5a3d08b
to
5f920dc
Compare
SCANOSS SCAN Completed 🚀
View more details on SCANOSS Action Summary |
SCANOSS SCAN Completed 🚀
View more details on SCANOSS Action Summary |
SCANOSS SCAN Completed 🚀
View more details on SCANOSS Action Summary |
71c89f2
to
70f73c6
Compare
SCANOSS SCAN Completed 🚀
View more details on SCANOSS Action Summary |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to review with Agus on a few items
SCANOSS SCAN Completed 🚀
View more details on SCANOSS Action Summary |
SCANOSS SCAN Completed 🚀
View more details on SCANOSS Action Summary |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (9)
setup.cfg (2)
38-38
: Drop importlib_resources for Python ≥3.9.You already require Python >=3.9;
importlib.resources
is in the stdlib, so the backportimportlib_resources
is unnecessary. Remove to slim installs.- importlib_resources
44-44
: Consider pinning a floor for the new CycloneDX dependency.
cyclonedx-python-lib[validation]
is valid and maintained; add a conservative minimum (e.g.,>=11.0.0
) once you confirm compatibility to reduce future breakage from older transitive installs. Docs confirm thevalidation
extra. (pypi.org)Example:
- cyclonedx-python-lib[validation] + cyclonedx-python-lib[validation]>=11.0.0src/scanoss/scanossgrpc.py (1)
88-88
: Consider making this configurable or documenting the choice.The hardcoded
MAX_CONCURRENT_REQUESTS = 5
might benefit from being configurable based on system resources or API rate limits, especially for enterprise environments.src/protoc_gen_swagger/options/openapiv2_pb2.py (1)
3-3
: Header contradicts repo stateThe “NO CHECKED-IN PROTOBUF GENCODE” banner conflicts with checking this in. Clarify policy or remove the banner to avoid confusion.
src/protoc_gen_swagger/options/openapiv2_pb2.pyi (1)
6-21
: Keep stubs and generators in lockstepPlease pin the mypy-protobuf generator version in tooling/CI to avoid drift between .py and .pyi.
Add a brief note in CONTRIBUTING.md about the exact command/version used to regenerate these stubs.
src/protoc_gen_swagger/options/annotations_pb2.py (1)
3-3
: Banner vs. realityIf we intend to vendor generated code, drop or reword the “NO CHECKED-IN PROTOBUF GENCODE” line.
src/protoc_gen_swagger/options/annotations_pb2_grpc.py (3)
11-16
: Make version check resilient when grpc._utilities is unavailableRaising on ImportError can break even on compatible grpc versions. Add a safe fallback comparator.
Apply this diff:
import grpc -import warnings +import warnings -GRPC_GENERATED_VERSION = '1.73.1' +GRPC_GENERATED_VERSION = '1.73.1' GRPC_VERSION = grpc.__version__ _version_not_supported = False try: from grpc._utilities import first_version_is_lower _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) except ImportError: - _version_not_supported = True + # Fallback comparator without relying on private grpc internals + def _parse(v: str): + parts = ''.join(ch if ch.isdigit() or ch == '.' else ' ' for ch in v).split() + return tuple(int(p) for p in (parts[0].split('.') if parts else [])) + try: + _version_not_supported = _parse(GRPC_VERSION) < _parse(GRPC_GENERATED_VERSION) + except Exception: + warnings.warn( + f"Unable to verify grpc version compatibility ({GRPC_VERSION} vs {GRPC_GENERATED_VERSION}); " + "proceeding at your own risk.", + RuntimeWarning, + ) + _version_not_supported = FalseAlso applies to: 17-24
4-4
: Unused importwarnings is unused after the change above unless you keep the fallback. Either remove it or use it as in the suggested fallback.
1-24
: Reduce policy false-positives for generated filesIf your “undeclared policy check” flags this file, consider excluding vendor/generated patterns like: src//_pb2.py and src//_pb2_grpc.py.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (23)
.github/workflows/container-local-test.yml
(3 hunks).github/workflows/container-publish-ghcr.yml
(1 hunks).github/workflows/python-publish-pypi.yml
(2 hunks).github/workflows/python-publish-testpypi.yml
(2 hunks).github/workflows/version-tag.yml
(1 hunks)CHANGELOG.md
(7 hunks)CLIENT_HELP.md
(1 hunks)requirements.txt
(1 hunks)scanoss.json
(2 hunks)setup.cfg
(1 hunks)src/protoc_gen_swagger/options/annotations_pb2.py
(2 hunks)src/protoc_gen_swagger/options/annotations_pb2.pyi
(1 hunks)src/protoc_gen_swagger/options/annotations_pb2_grpc.py
(1 hunks)src/protoc_gen_swagger/options/openapiv2_pb2.py
(2 hunks)src/protoc_gen_swagger/options/openapiv2_pb2.pyi
(1 hunks)src/protoc_gen_swagger/options/openapiv2_pb2_grpc.py
(1 hunks)src/scanoss/__init__.py
(1 hunks)src/scanoss/api/common/v2/scanoss_common_pb2_grpc.py
(1 hunks)src/scanoss/cli.py
(27 hunks)src/scanoss/components.py
(5 hunks)src/scanoss/cryptography.py
(4 hunks)src/scanoss/cyclonedx.py
(2 hunks)src/scanoss/scanossgrpc.py
(9 hunks)
✅ Files skipped from review due to trivial changes (2)
- src/scanoss/init.py
- .github/workflows/python-publish-testpypi.yml
🚧 Files skipped from review as they are similar to previous changes (9)
- .github/workflows/version-tag.yml
- src/scanoss/api/common/v2/scanoss_common_pb2_grpc.py
- src/protoc_gen_swagger/options/openapiv2_pb2_grpc.py
- .github/workflows/container-local-test.yml
- .github/workflows/python-publish-pypi.yml
- src/scanoss/cyclonedx.py
- .github/workflows/container-publish-ghcr.yml
- CHANGELOG.md
- requirements.txt
🧰 Additional context used
🧬 Code graph analysis (5)
src/scanoss/components.py (4)
src/scanoss/cyclonedx.py (2)
is_cyclonedx_json
(394-412)get_purls_request_from_cdx
(414-433)src/scanoss/utils/file.py (1)
validate_json_file
(44-84)src/scanoss/scanossbase.py (2)
print_stderr
(45-49)print_msg
(51-56)src/scanoss/scanossgrpc.py (1)
get_licenses
(711-724)
src/protoc_gen_swagger/options/annotations_pb2.pyi (1)
src/protoc_gen_swagger/options/openapiv2_pb2.pyi (5)
Swagger
(25-212)Operation
(217-378)Schema
(748-803)Tag
(974-999)JSONSchema
(808-969)
src/scanoss/scanossgrpc.py (2)
src/scanoss/api/licenses/v2/scanoss_licenses_pb2_grpc.py (1)
LicenseStub
(29-64)src/scanoss/components.py (1)
get_licenses
(393-423)
src/scanoss/cli.py (4)
src/scanoss/spdxlite.py (1)
print_stderr
(55-59)src/scanoss/scanossbase.py (1)
print_stderr
(45-49)src/scanoss/components.py (2)
Components
(40-423)get_licenses
(393-423)src/scanoss/scanossgrpc.py (1)
get_licenses
(711-724)
src/scanoss/cryptography.py (2)
src/scanoss/cyclonedx.py (3)
CycloneDx
(39-433)is_cyclonedx_json
(394-412)get_purls_request_from_cdx
(414-433)src/scanoss/utils/file.py (1)
validate_json_file
(44-84)
🪛 GitHub Actions: Build/Test Local Python Package
scanoss.json
[warning] 1-1: Settings file 'tests/scanoss.json' was not found or is empty. Skipping...
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (30)
setup.cfg (1)
32-33
: Tighten protobuf and cap grpcio in setup.cfg (lines 32–33)pip --dry-run resolved grpcio-1.75.0, protobuf-6.32.1 and google-api-core-2.25.1 — the proposed bounds are compatible.
- grpcio>=1.70.0 - protobuf>3.19.1 + grpcio>=1.70.0,<2 + protobuf>=5.26.1,<7scanoss.json (2)
6-8
: Update skip patterns aligns with broader PR changes.The scanning skip pattern updates look correct. Changing from specific paths to broader directories (e.g.,
src/protoc_gen_swagger/
→src/protoc_gen_swagger
) and includingscanoss_common_pb2_grpc.py
aligns with the new gRPC/protobuf runtime checks mentioned in the AI summary.
20-20
: LGTM! Added empty remove list is valid JSON structure.The addition of
"remove": []
field provides a clear structure for potential future use while maintaining valid JSON format.src/scanoss/cryptography.py (4)
5-5
: LGTM! CycloneDx import enables CDX validation functionality.The import aligns with the broader PR goal of adding CycloneDX support across component commands.
30-60
: Excellent refactoring that addresses complexity concerns.This extraction of input file processing logic into a separate method effectively reduces the complexity of
__post_init__
that was flagged in past reviews. The method properly handles both regular JSON and CycloneDX input validation with clear error handling.
75-76
: LGTM! Clean delegation to extracted method.The refactored
__post_init__
now cleanly delegates to the extracted_process_input_file
method, making the code more maintainable and addressing the complexity concerns from previous reviews.
207-207
: LGTM! Clean method signature formatting.The single-line method signature formatting improves readability without changing functionality.
CLIENT_HELP.md (2)
340-354
: Excellent documentation for the new licenses command.The documentation clearly explains the new
comp licenses
command with practical examples showing both multiple PURL usage and CycloneDX SBOM input support. This aligns well with the broader PR objectives.
355-377
: Comprehensive CDX input support documentation.Great documentation that clearly lists all supported commands with CDX input (
comp vulns
,comp licenses
,comp crypto
,comp semgrep
) and provides practical examples. The note about automatic validation is particularly helpful for users.src/scanoss/components.py (5)
32-33
: LGTM! Imports support CycloneDX integration.The new imports enable CycloneDX support and improved JSON validation as described in the PR objectives.
96-96
: LGTM! CycloneDx integration initialization.The initialization of the CycloneDx helper enables CycloneDX processing throughout the Components class.
98-110
: Method signature improvement for clarity.The updated method signature with proper type hints improves code clarity and aligns with the broader refactoring theme in this PR.
120-145
: Excellent CycloneDX integration with robust error handling.The enhanced
load_purls
method now properly validates JSON input and automatically detects CycloneDX format, converting it appropriately using the CycloneDx helper. The error handling is comprehensive and user-friendly.
393-423
: Well-implemented licenses retrieval functionality.The new
get_licenses
method follows the established pattern from other detail methods in the class. It correctly:
- Uses
load_purls
for input processing (supporting both regular JSON and CycloneDX)- Converts to ComponentBatchRequest format for the license API
- Handles output appropriately with proper error handling
src/scanoss/cli.py (5)
37-39
: LGTM! Import formatting improvement.The parenthetical grouping of the long import improves readability while maintaining functionality.
315-323
: LGTM! New licenses sub-command follows established patterns.The new
c_licenses
parser is properly configured with aliases and integrates well with the existing component sub-command structure. The past review comment has been addressed by keeping it within the "comp" command as requested.
426-434
: Good integration of licenses command in shared options.The addition of
c_licenses
to the list ensures it receives all the common PURL component sub-command options (--purl, --input), maintaining consistency across component commands.
448-448
: Comprehensive integration across all CLI option groups.The systematic addition of
c_licenses
across all relevant option groups (timeout, output, GRPC options, global GRPC options, and debug options) ensures feature parity with other component sub-commands.Also applies to: 913-913, 988-988, 1027-1027, 1093-1093
2304-2337
: Well-implemented command handler following established patterns.The
comp_licenses
function properly:
- Validates input requirements (exactly one of --purl or --input)
- Checks certificate file existence
- Creates Components instance with all necessary configuration
- Delegates to the
get_licenses
method with proper error handlingThe implementation is consistent with other component sub-command handlers in the file.
src/scanoss/scanossgrpc.py (6)
47-48
: LGTM! New imports enable license functionality.The imports of ComponentsLicenseResponse and LicenseStub enable the new license retrieval functionality via both gRPC and REST.
217-217
: LGTM! License stub initialization for both connection types.The license stub is properly initialized for both insecure and secure gRPC connections, enabling license retrieval functionality.
Also applies to: 230-230
711-724
: Well-designed dual-path license retrieval dispatcher.The
get_licenses
method provides a clean interface that abstracts the choice between gRPC and REST implementations based on theuse_grpc
flag, following the established pattern used by other methods in the class.
726-740
: LGTM! Clean gRPC implementation using shared helper.The
_get_licenses_grpc
method effectively uses the_call_rpc
helper method to handle the license retrieval via gRPC, maintaining consistency with other gRPC methods in the class.
742-742
: Method signature improvement for URL parameter support.The addition of the optional
url
parameter toload_generic_headers
enables REST-based license retrieval logic while maintaining backward compatibility.
806-831
: Well-implemented REST license retrieval method.The
_get_licenses_rest
method properly:
- Validates input parameters
- Uses appropriate REST endpoint (
/licenses/components
)- Handles response parsing with ComponentsLicenseResponse
- Validates status response and removes status field from return value
- Follows the established pattern from other REST methods
However, I notice this addresses the past review comment asking "where is the REST function call?" - it's now properly implemented here.
src/protoc_gen_swagger/options/openapiv2_pb2.py (1)
31-34
: Descriptor build path changes look correctSwitch to _globals container and conditional C-descriptor handling matches current protoc Python output.
Also applies to: 34-128
src/protoc_gen_swagger/options/openapiv2_pb2.pyi (1)
24-216
: Type stubs align with runtime APIThe .pyi content mirrors the generated runtime well and provides strong IDE/mypy support.
Also applies to: 217-381, 382-420, 421-526, 527-617, 618-666, 667-705, 706-746, 747-806, 807-971, 973-1001, 1003-1050, 1051-1203, 1204-1276, 1277-1318
src/protoc_gen_swagger/options/annotations_pb2.py (1)
31-37
: Descriptor/extension build looks standardThe builder usage and serialized options block match current protoc output.
src/protoc_gen_swagger/options/annotations_pb2.pyi (2)
14-49
: Extension stubs LGTMDescriptors and field numbers are exposed with precise types. Good for static analysis.
14-49
: Confirm extensions are importable at runtimeNo explicit top-level assignments for openapiv2_{swagger,operation,schema,tag,field} appear in src/protoc_gen_swagger/options/annotations_pb2.py (DESCRIPTOR + builder calls at lines 29–33); verify they are created on import by running:
python -c "import importlib; m=importlib.import_module('protoc_gen_swagger.options.annotations_pb2'); print({n: hasattr(m,n) for n in ('openapiv2_swagger','openapiv2_operation','openapiv2_schema','openapiv2_tag','openapiv2_field')})"
Paste the output.
grpcio>1.42.0 | ||
grpcio>=1.70.0 | ||
protobuf>3.19.1 | ||
protoc-gen-openapiv2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
🧩 Analysis chain
Duplicate dependency and likely wrong package variant for OpenAPI v2 protos.
protoc-gen-openapiv2
is listed twice (Lines 34 and 43).- The
protoc-gen-openapiv2
package on PyPI appears unmaintained (last release 0.0.1 on Dec 2, 2022). A more up-to-date alternative isgrpc-gateway-protoc-openapiv2
(e.g., 2.25.1.0 released Jan 11, 2025). Please align the dependency with whatever import path your generated code uses and deduplicate. (pypi.org)
Suggested fix (choose the package that matches your generated imports; if you import grpc_gateway_protoc_openapiv2.*
, use the first option below):
- protoc-gen-openapiv2
+ grpc-gateway-protoc-openapiv2
...
- protoc-gen-openapiv2
If your generated imports are protoc_gen_openapiv2.*
, keep that variant but remove the duplicate and consider switching to a maintained fork when feasible. The upstream gRPC‑Gateway docs also indicate the plugin is a Go tool (protoc-gen-openapiv2
), hence the need for Python-packaged stubs. (github.com)
Run to confirm which package your code imports:
Also applies to: 43-43
🏁 Script executed:
#!/bin/bash
# Detect which OpenAPI v2 stub package the code expects
rg -nP -C2 'from\s+(grpc_gateway_protoc_openapiv2|protoc_gen_openapiv2)\b|import\s+(grpc_gateway_protoc_openapiv2|protoc_gen_openapiv2)\b' -g 'src/**'
Length of output: 5380
Remove duplicate dependency; keep protoc-gen-openapiv2 to match generated imports
Generated protos import protoc_gen_openapiv2.options — remove the duplicate protoc-gen-openapiv2 entry from setup.cfg.
🤖 Prompt for AI Agents
In setup.cfg around line 34 the dependency protoc-gen-openapiv2 is duplicated;
remove the duplicate entry so only a single protoc-gen-openapiv2 remains to
match generated protos that import protoc_gen_openapiv2.options. Edit setup.cfg
to delete the redundant line and ensure the remaining entry uses the correct
package name and version (if applicable) to keep imports consistent with
generated code.
SCANOSS SCAN Completed 🚀
View more details on SCANOSS Action Summary |
SCANOSS SCAN Completed 🚀
View more details on SCANOSS Action Summary |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
tests/data/requirements.txt (2)
5-6
: Add safe upper bounds to prevent future breaking changes.Loosening to >= is fine for the new runtime checks, but guard against major-version breaks.
-grpcio>=1.73.1 -protobuf>=6.3.1 +grpcio>=1.73.1,<2.0.0 +protobuf>=6.3.1,<7.0.0
6-6
: Consider pinning in tests for reproducibility.If tests/data/requirements.txt is used to build CI envs (not just sample data), prefer exact pins or a constraints file to avoid non‑deterministic failures.
Happy to generate a constraints.txt and update CI to use
-c constraints.txt
if this file feeds CI env creation.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
requirements.txt
(1 hunks)setup.cfg
(1 hunks)tests/data/requirements.txt
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- setup.cfg
- requirements.txt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (1)
tests/data/requirements.txt (1)
5-5
: Verify grpcio wheels are available for all CI Python versionsFile: tests/data/requirements.txt (line 5)
grpcio>=1.73.1
Sandbox fetch of PyPI metadata failed; verify locally that grpcio 1.73.1 publishes prebuilt wheel files for every Python version and OS/arch in your CI matrix (otherwise CI may build from source and fail). Run locally:
curl -s https://pypi.org/pypi/grpcio/1.73.1/json | jq -r '.releases["1.73.1"][] | "(.packagetype) | (.python_version) | (.filename)"'
Summary by CodeRabbit
New Features
Documentation
Chores