Skip to content

Conversation

sig-abyreddy
Copy link
Contributor

@sig-abyreddy sig-abyreddy commented Sep 19, 2025

Description

Support for buildless inspection of Go Mod package manager through parsing of go.mod file.

Changes/Additions/Notes

  • Created a new detector named "Go Mod File"
  • Support for computing dependency graph for transitives by polling the go registry (https://proxy.golang.org)
  • Support for overriding the go registry URL through --detect.go.forge property
  • Support for considering toolchain, exclude, and replace go directives
  • Cascading Mechanism: Go Mod (1) > Go Mod File (2)
  • Accuracy: HIGH
  • Documentation for Go Mod File detector

Copy link
Contributor

@Copilot 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 a new Go mod file detector that provides buildless inspection of Go module dependencies by parsing go.mod files directly. The detector fetches transitive dependencies from the Go proxy (proxy.golang.org) and handles Go directives like toolchain, exclude, and replace.

  • Creates a Go Mod File detector with high accuracy
  • Implements recursive dependency resolution via Go proxy API calls
  • Supports configuration override for Go forge URL through --detect.go.forge property

Reviewed Changes

Copilot reviewed 29 out of 30 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
DetectDetectableFactory.java Adds factory method for creating GoModFileDetectable instances
DetectorRuleFactory.java Configures Go Mod File detector as fallback after Go Mod CLI detector
DetectableOptionFactory.java Creates options factory with Go proxy URL configuration
DetectProperties.java Adds new property for configuring Go forge URL
DetectableFactory.java Integrates GoModFileDetectable creation into main factory
GoModFile*.java Core implementation files for parsing, dependency resolution, and proxy communication
Test files Comprehensive test coverage for all components

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Contributor

@Copilot 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

Copilot reviewed 28 out of 30 changed files in this pull request and generated no new comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@sig-abyreddy sig-abyreddy changed the title Draft: Feat. Go mod file detector Feat. Go mod file detector Sep 19, 2025
## Go Mod CLI (GO_MOD) detector

* Discovers dependencies of go language (GoLang) projects.
* Discovers dependencies of Go projects that uses Go Mod package manager.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps a small change to reflect the go mod command versus the Go Module package manager?

  • Discovers dependencies of Go projects that use Go Module package manager.


## Overview

[detect_product_short] has four detectors for GoLang:
Copy link
Contributor

@cpottsbd cpottsbd Sep 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we up to six detectors now I think?

[detect_product_short] has four detectors for GoLang:

* Go Mod CLI (GO_MOD) detector (recommended)
* Go Mod File (GO_MOD) detector
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be using something other than (GO_MOD) to differentiate from Go Mod CLI?


## Go Mod File (GO_MOD) detector

* Discovers dependencies of Go projects that uses Go Mod package manager.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:

  • Discovers dependencies of Go projects that use Go Module package manager.

@andrian-sevastyanov
Copy link
Contributor

There are a couple of tests that seem to perform real HTTP requests.
Those should either be mocked, or we should mark the tests as integration tests using @Tag("integration").

Copy link
Contributor

@andrian-sevastyanov andrian-sevastyanov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall the changes look good. Please consider the comments I put down.

import com.blackduck.integration.detectable.detectables.go.gomodfile.parse.model.GoModuleInfo;
import com.blackduck.integration.detectable.detectables.go.gomodfile.parse.model.GoReplaceDirective;

import java.util.*;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: We generally try to make imports explicit and avoid wildcards. Same applies to other classes in this PR.

Set<GoModuleInfo> retractedVersions) {

// Check for block starts
if (line.startsWith("require (")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to be a bit more flexible regarding the number of spaces between the word and parentheses?
Same question applies to other similar checks.

return fileParser.parseGoModFile(goModContents);
}

private void printDependencyGraphOfIndirectDependency(Dependency dependency, List<GoDependencyNode> path) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this doesn't print anything to the logs in debug mode, there's still quite a bit of processing going on when not in debug mode. You can avoid the unnecessary processing by introducing a check like if (logger.isDebugEnabled()) { ... }.

return graph;
}

public List<GoDependencyNode> GetDependencyPathFromGraph(GoDependencyNode targetNode, GoDependencyNode graph, List<GoDependencyNode> visited) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: method names should start with a lowercase letter

this.externalIdFactory = externalIdFactory;
}

public Dependency CreateDependency(GoModuleInfo moduleInfo) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:c at the start of the method name should be lower cased

if (childPath.isEmpty()) {
visited.remove(visited.size() - 1);
}
if (!childPath.isEmpty()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: duplicate check to the one a few lines above. This could be an if/else instead.

HttpClient client = HttpClient.newBuilder().followRedirects(Redirect.ALWAYS).build();
try {
// configure http client to follow redirects
HttpRequest request = HttpRequest.newBuilder()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should set some timeout settings. Otherwise the request may hang too long or even indefinitely.
Same applies to the requests that fetch dependency information.

* Discovers dependencies of Go projects that uses Go Mod package manager.
* Attempts to run on your project if a go.mod file is found in your source directory.
* Parses go.mod file to gather dependency information.
* It computes dependency graph of transitives by fetching go.mod files of direct dependencies from proxy.golang.org or custom Go proxy supplied via [detect.go.forge](../properties/detectors/go.md#go-forge) property. If the proxy is not reachable, then the transitive dependencies are listed as additional components under the root module.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor wording change suggestion:

  • Computes transitive dependency graph by fetching go.mod files of direct dependencies from proxy.golang.org or custom Go proxy supplied via detect.go.forge property. If the proxy is not reachable, the transitive dependencies are listed as additional components under the root module.

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