chore: correctly parse and differentiate between indirect & direct dependencies in go.mod files#416
chore: correctly parse and differentiate between indirect & direct dependencies in go.mod files#416Strum355 wants to merge 1 commit intoguacsec:mainfrom
Conversation
…pendencies in go.mod files
Review Summary by QodoReplace regex parsing with tree-sitter for robust go.mod dependency handling and fix indirect dependency classification
WalkthroughsDescription• Replaced regex-based go.mod parsing with tree-sitter LR-parser for more robust and maintainable dependency extraction • Fixed indirect dependency handling by properly differentiating between direct and indirect dependencies in SBOM output • Corrected exhortignore marker format from // indirect exhortignore to `// indirect; exhortignore` for proper Go tooling compatibility • Made provideStack() and provideComponent() async functions to support parser initialization • Added new gomod_parser.js module providing tree-sitter parser initialization with WebAssembly-based Go language grammar • Updated all Go module SBOM test fixtures to reflect correct indirect dependency classification • Added tree-sitter-gomod dependency and updated build scripts to include WebAssembly parser files • Updated test cases to use async/await syntax for async provider functions • Fixed JSDoc type annotations in Python pip provider Diagramflowchart LR
A["go.mod file"] -->|"tree-sitter parser"| B["Parsed AST"]
B -->|"extract requires"| C["All dependencies"]
C -->|"go mod edit -json"| D["Direct vs Indirect"]
D -->|"filter indirect"| E["SBOM with correct classification"]
F["exhortignore marker"] -->|"semicolon format"| G["Proper Go tooling parsing"]
File Changes1. src/providers/golang_gomodules.js
|
Code Review by Qodo
1. Duplicate gomod parser init
|
ruromero
left a comment
There was a problem hiding this comment.
Thanks for the fix. Only a couple of optional comments.
| let comments = specNode.children.filter(c => c.type === 'comment') | ||
| for (let comment of comments) { | ||
| let text = comment.text | ||
| if (/^\/\/\s*indirect;\s*exhortignore/.test(text)) { |
There was a problem hiding this comment.
Be aware that this pattern also matches //indirect;exhortignore (without space)
In the docs you say that it must be //indirect; exhortignore. If you want to enforce the space use \s+ instead.
If not, that's fine. I don't think that's a problem
| let allIgnoredDeps = ignoredDeps.map((dep) => dep.toString()) | ||
| let sbom = new Sbom(); | ||
| let rows = goGraphOutput.split(getLineSeparatorGolang()).filter(line => !line.includes(' go@')); | ||
| let root = getParentVertexFromEdge(goModEditOutput['Module']['Path']) |
There was a problem hiding this comment.
I noticed that the getParentVertexFromEdge is not used as expected because here it won't receive an edge but a single path with no space.
The result will just be the same goModEditOutput['Module']['Path'], do you mind replacing it?
Description
This PR addresses a number of issues in the handling of go.mod manifests:
exhortignoremarker format caused indirect (aka transitive) dependencies in go.mod files to be considered direct dependencies by the Go tooling. Specifically,// indirect exhortignoreshould be// indirect; exhortignoreinstead. The README, test fixtures and code have been updated for the correct formatting.All SBOM fixtures have been updated, the diffs are large mostly due to the array of
componentsbeing re-arranged. The only material difference is a shorterdependsOnsection for the root module due to the fixed indirect dependency handlingChecklist