Skip to content

Conversation

@bd-samratmuk
Copy link
Contributor

@bd-samratmuk bd-samratmuk commented Jan 27, 2026

This PR introduces the Bazel V2 detector, delivering mode-agnostic dependency extraction for both BZLMOD (MODULE.bazel) and WORKSPACE projects.

Key features

  • Automatic mode detection (BZLMOD vs WORKSPACE) via bazel mod show_repo, with fallback and manual override.
  • Pipeline selection (MAVEN_INSTALL, MAVEN_JAR, HASKELL_CABAL_LIBRARY, HTTP_ARCHIVE) based on graph probing.
  • Enhanced HTTP-family detection (http_archive, git_repository, go_repository, http_file) with mode-aware strategies and configurable probe limits.
  • Deterministic pipeline execution order and single code location output with project name generation from the Bazel target. The code location generation pattern is same as v1.

Properties introduced/changed

  • detect.bazel.dependency.sources (renamed from detect.bazel.workspace.rules): consistent naming across modes; same behavior, supports manual pipeline selection to skip probing.
  • detect.bazel.mode: optional override for BZLMOD or WORKSPACE when auto-detection isn’t suitable.
  • detect.bazel.http.probe.limit: caps external repo probing for performance on large targets.

@bd-samratmuk bd-samratmuk requested a review from Copilot January 27, 2026 15:29
Copy link
Contributor

Copilot AI left a 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.rules to detect.bazel.dependency.sources for 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.

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);
Copy link
Collaborator

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/")) {
Copy link
Collaborator

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("@@");
Copy link
Collaborator

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 {
Copy link
Collaborator

@zahidblackduck zahidblackduck Jan 30, 2026

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 {
Copy link
Collaborator

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,
Copy link
Collaborator

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 + "))"
Copy link
Collaborator

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("//")) {
Copy link
Collaborator

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"
Copy link
Collaborator

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 ? "@@" : "@";
Copy link
Collaborator

@zahidblackduck zahidblackduck Jan 30, 2026

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants