Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
### Fixed
- `--exclude-paths` patterns are now matched relative to the scan root in every build root. They now also exclude modules a build reaches outside its own directory (Maven `../` modules, relocated Gradle projects) and modules matched by wildcards that span a build-root boundary, such as `*/core`.
- `--exclude-paths` patterns written with Windows `\` separators now exclude JVM build modules in single-root runs too.
- Maven SBOMs keep the dependencies a module reaches through a sibling module's test-jar.

## [1.12.2](https://github.com/SocketDev/socket-cli/releases/tag/v1.12.2) - 2026-10-30

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -416,14 +416,12 @@ private String visit(
String type = artifact.getProperty(ARTIFACT_PROPERTY_TYPE, artifact.getExtension());
String classifier = artifact.getClassifier();
String version = artifact.getBaseVersion();
String id = internal
? SocketSupport.bareId(artifact.getGroupId(), artifact.getArtifactId(), version)
: externalId(artifact);

// One walk per node per module traversal: a shared subtree reached via another edge is already
// fully recorded (node, children, resolved file), so hand back the id without re-descending.
// Keeps reconverging graphs linear.
if (!visited.add(id)) return id;
String key = externalId(artifact);
String id = internal ? SocketSupport.bareId(artifact.getGroupId(), artifact.getArtifactId(), version) : key;

// One walk per artifact: a shared subtree is already recorded. Keyed by coordinate, as a sibling's jar
// and test-jar share a node but Maven can keep the sibling's dependencies under either.
if (!visited.add(key)) return id;

Node node = internal
? upsert(nodes, id, artifact.getGroupId(), artifact.getArtifactId(), "", "", version, gav)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
</parent>
<artifactId>app</artifactId>
<dependencies>
<!-- internal reactor module -> inter-module edge, bare-id component -->
<!-- internal reactor modules -> inter-module edges, bare-id components. lib's jar comes in
through mid, deeper than lib's test-jar further down, so Maven keeps demo.ext:libdep (with
its compile scope) under the test-jar node and none under the jar node, which the walk
reaches first. -->
<dependency>
<groupId>demo</groupId>
<artifactId>lib</artifactId>
<artifactId>mid</artifactId>
<version>1.0</version>
</dependency>
<!-- external prod dep (stub artifact from the generated repo, no transitive deps) -->
Expand Down Expand Up @@ -43,5 +46,12 @@
<artifactId>conflict-prod</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>demo</groupId>
<artifactId>lib</artifactId>
<version>1.0</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,25 @@
<version>1.0</version>
</parent>
<artifactId>lib</artifactId>
<dependencies>
<dependency>
<groupId>demo.ext</groupId>
<artifactId>libdep</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>demo</groupId>
<artifactId>root</artifactId>
<version>1.0</version>
</parent>
<artifactId>mid</artifactId>
<dependencies>
<dependency>
<groupId>demo</groupId>
<artifactId>lib</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package demo;

public class Mid {
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<packaging>pom</packaging>
<modules>
<module>lib</module>
<module>mid</module>
<module>app</module>
</modules>
<properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ if tool != 'maven':
errors.append(f"meta tool {tool!r} != 'maven'")
if build_root != sys.argv[2]:
errors.append(f"buildRoot {build_root!r} != {sys.argv[2]!r}")
expected_build_files = {'pom.xml', 'lib/pom.xml', 'app/pom.xml'}
expected_build_files = {'pom.xml', 'lib/pom.xml', 'mid/pom.xml', 'app/pom.xml'}
if build_files != expected_build_files:
errors.append(f"projectBuild files {sorted(build_files)} != {sorted(expected_build_files)}")
expected = {'root', 'lib', 'app'}
expected = {'root', 'lib', 'mid', 'app'}
if set(projects) != expected:
errors.append(f"expected reactor modules {sorted(expected)}, got {sorted(projects)}")
for artifact in expected & set(projects):
Expand Down
13 changes: 12 additions & 1 deletion src/commands/manifest/scripts/test/maven-compat/smoke-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
# inter-module edge lines up with its `project` record);
# - resolves a scope conflict so the retained node stays reachable from its parent root;
# - every component is reachable from a direct dependency of its own root (no orphaned components);
# - keeps the dependencies Maven leaves only under a sibling module's test-jar (app reaches
# demo.ext:libdep under lib's test-jar node, after lib's jar node through mid);
# - materializes resolved external jars under -Dsocket.withFiles;
# - scopes that materialization to -Dsocket.populateFilesFor (a newline-delimited GAV file).
#
Expand Down Expand Up @@ -36,7 +38,8 @@ bash "$HERE/../make-stub-repo.sh" "$STUBS" \
'demo.ext:harness-core:1.0' \
'demo.ext:conflict-test:1.0+demo.ext:shared:1.0' \
'demo.ext:conflict-prod:1.0+demo.ext:shared:1.0' \
'demo.ext:shared:1.0'
'demo.ext:shared:1.0' \
'demo.ext:libdep:1.0'
# Maven's own plugin closure stays cached between runs; the stubs never do, so every run has to
# resolve them from the repo just generated.
rm -rf "$M2/demo" "$RECORDS" "$PROJECT"/*/target "$PROJECT"/target
Expand All @@ -52,6 +55,14 @@ echo "+ $("$MVN" -v 2>/dev/null | head -1)"
compile )

python3 "$HERE/assert-records.py" "$RECORDS"
python3 - "$RECORDS" <<'PY'
import sys
rows = [l.rstrip('\n').split('\t') for l in open(sys.argv[1]) if l.strip()]
app = {r[1] for r in rows if r[0] == 'root' and r[2] == 'demo:app:1.0'}
if not any(r[0] == 'node' and r[1] in app and r[2].startswith('demo.ext:libdep:') for r in rows):
print("FAIL: demo.ext:libdep missing from app"); sys.exit(1)
print("PASS: demo.ext:libdep in app through lib's test-jar")
PY
python3 "$HERE/../assert-reachability.py" "$RECORDS"

# Second run: scope --with-files to a single GAV and assert ONLY that artifact is materialized.
Expand Down
Loading