-
Notifications
You must be signed in to change notification settings - Fork 84
feat. Bazel V2 Detector With Bzlmod Support #1634
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: master
Are you sure you want to change the base?
Conversation
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.
Pull request overview
This PR introduces the Bazel V2 detector, a comprehensive rewrite that delivers robust, mode-agnostic dependency extraction for both BZLMOD (MODULE.bazel) and WORKSPACE-based Bazel projects. The V2 detector replaces the legacy detector's hardcoded WORKSPACE-only approach with an intelligent pipeline selection system that automatically detects the Bazel environment mode and probes the dependency graph to determine which extraction pipelines to run.
Changes:
- Introduced automatic Bazel mode detection (BZLMOD vs WORKSPACE) with graceful fallback and manual override capability
- Implemented intelligent dependency graph probing to automatically select appropriate extraction pipelines
- Enhanced HTTP-family detection with mode-aware strategies and configurable probe limits
- Renamed
detect.bazel.workspace.rulestodetect.bazel.dependency.sourcesfor consistent naming across modes
Reviewed changes
Copilot reviewed 43 out of 47 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/main/java/com/blackduck/integration/detect/lifecycle/run/operation/OperationRunner.java |
Switches from legacy Bazel detector to new V2 detector |
src/main/java/com/blackduck/integration/detect/configuration/DetectProperties.java |
Renames property from DETECT_BAZEL_WORKSPACE_RULES to DETECT_BAZEL_DEPENDENCY_SOURCES and adds new properties for mode override and HTTP probe limit |
detectable/src/main/java/com/blackduck/integration/detectable/detectables/bazel/DependencySource.java |
Renames enum from WorkspaceRule to DependencySource for consistent terminology |
detectable/src/main/java/com/blackduck/integration/detectable/detectables/bazel/v2/BazelV2Detectable.java |
New V2 detectable implementation with mode detection and graph probing |
detectable/src/main/java/com/blackduck/integration/detectable/detectables/bazel/v2/BazelEnvironmentAnalyzer.java |
Detects Bazel mode (BZLMOD vs WORKSPACE) via bazel mod show_repo probe |
detectable/src/main/java/com/blackduck/integration/detectable/detectables/bazel/v2/BazelGraphProber.java |
Probes dependency graph to determine which pipelines to enable |
detectable/src/main/java/com/blackduck/integration/detectable/detectables/bazel/v2/HttpFamilyProber.java |
Mode-aware HTTP archive detection with configurable probe limits |
detectable/src/main/java/com/blackduck/integration/detectable/detectables/bazel/pipeline/Pipelines.java |
Adds mode-aware HTTP pipeline selection (bzlmod vs workspace variants) |
documentation/src/main/markdown/packagemgrs/bazel.md |
Comprehensive documentation update explaining V2 features, properties, and troubleshooting |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...m/blackduck/integration/detectable/detectables/bazel/pipeline/step/BazelCommandExecutor.java
Outdated
Show resolved
Hide resolved
...rc/main/java/com/blackduck/integration/detectable/detectables/bazel/v2/BazelGraphProber.java
Outdated
Show resolved
Hide resolved
...n/detectable/detectables/bazel/pipeline/step/IntermediateStepExecuteShowRepoWithMapping.java
Outdated
Show resolved
Hide resolved
...detectable/detectables/bazel/pipeline/step/IntermediateStepParseShowRepoToUrlCandidates.java
Outdated
Show resolved
Hide resolved
src/main/java/com/blackduck/integration/detect/configuration/DetectProperties.java
Outdated
Show resolved
Hide resolved
...st/java/com/blackduck/integration/detectable/detectables/bazel/unit/BazelDetectableTest.java
Outdated
Show resolved
Hide resolved
| try { | ||
| return executableRunner.execute(ExecutableUtils.createFromTarget(workspaceDir, bazelExe, args)); | ||
| } catch (Exception e) { | ||
| String command = (bazelExe != null ? bazelExe.toCommand() : "bazel") + " " + String.join(" ", args == null ? java.util.Collections.emptyList() : args); |
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 could avoid fully qualified import here, unless there's not any name conflict for the emptyList() method. We tend to avoid fully qualified imports throughout detect.
And, we can move the string literal to a static final constant and use it here (e.g. "bazel").
| String repo = githubUrlParser.parseRepo(potentialGithubUrl); | ||
| String version = githubUrlParser.parseVersion(potentialGithubUrl); | ||
| // Normalize GitHub archive ref tags like `refs/tags/<tag>` to `<tag>` | ||
| if (version != null && version.startsWith("refs/tags/")) { |
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 can move these two string literals to a static final constant.
| if (token.isEmpty()) continue; | ||
|
|
||
| // Determine if the repo name is canonical (starts with @@) or synthetic (contains +/~) | ||
| boolean sawCanonical = token.startsWith("@@"); |
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.
"@" and "@@" both seems to be candidate for being used with static final string constants.
| * @throws DetectableException if Bazel command execution fails | ||
| */ | ||
| @Override | ||
| public List<String> process(List<String> input) throws DetectableException { |
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.
My sonarcube is complaining regarding this method, and suggesting to reduce cognitive complexity. Maybe due to so much conditional checks. Could you kindly check with sonarcube (for ide) and see whether this can be refactored to reduce the cognitive complexity warning? This could lead to detect sonarcube pipeline failure.
| private static final Pattern IMPORTPATH_PATTERN = Pattern.compile("(?i)\\bimportpath\\s*=\\s*\"([^\"]+)\""); | ||
|
|
||
| @Override | ||
| public List<String> process(List<String> input) throws DetectableException { |
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.
This method also has higher cognitive complexity.
| * @param haskellParser Parses Haskell cabal library JSON proto output | ||
| * @param projectNameGenerator Generates project names from Bazel targets | ||
| */ | ||
| public BazelV2Extractor(ExternalIdFactory externalIdFactory, |
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.
Quite good usage of doc comments. Really appreciated!
| public boolean detect(String target) throws Exception { | ||
| // Query for all library dependencies of the target | ||
| Optional<String> depsOut = bazel.executeToString(Arrays.asList( | ||
| "query", "kind(.*library, deps(" + target + "))" |
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.
Candidates for static final constants.
| Map<String, LinkedHashSet<String>> repoLabels = new HashMap<>(); | ||
| for (String line : lines) { | ||
| // Look for external repository labels (start with @ or @@) | ||
| if (line.startsWith("@") && line.contains("//")) { |
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.
Candidate for static final constant.
| private boolean probeRepoWithLabelKind(String repo, String queryTarget, String strategyName) { | ||
| try { | ||
| Optional<String> result = bazel.executeToString(Arrays.asList( | ||
| "query", "kind('rule', " + queryTarget + ")", "--output", "label_kind" |
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.
Candidate for static final constant.
| * @throws Exception if Bazel command execution fails | ||
| */ | ||
| private boolean classifyRepoByModShowRepo(String repo, boolean canonical) throws Exception { | ||
| String at = canonical ? "@@" : "@"; |
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.
As these symbols are used in quite a places, are possible candidates for global (within the scope of bazel detector) static final constants.
This PR introduces the Bazel V2 detector, delivering mode-agnostic dependency extraction for both BZLMOD (MODULE.bazel) and WORKSPACE projects.
Key features
Properties introduced/changed