Skip to content

Commit 9b2bb1a

Browse files
Strum355claude
andcommitted
fix(workspace): fix Gradle init script output parsing for root project
The parser used split("::") which failed on root project lines where project.path is ":" — the single colon merged with the :: delimiters, creating an ambiguous sequence that split consumed incorrectly. Replaced with lastIndexOf-based parsing: strip the ::DA_PROJECT:: prefix, find the last :: separator (directory paths never contain ::), and extract path and dir from there. Also fixed test data to use the correct number of colons matching actual Gradle init script output (::DA_PROJECT:: + ":" + :: = 5 colons for the root project line). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent eaae875 commit 9b2bb1a

2 files changed

Lines changed: 18 additions & 17 deletions

File tree

src/main/java/io/github/guacsec/trustifyda/impl/ExhortApi.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,20 +1040,21 @@ static List<GradleProject> parseGradleInitScriptOutput(String raw) {
10401040
if (raw == null || raw.isBlank()) {
10411041
return List.of();
10421042
}
1043+
String prefix = "::DA_PROJECT::";
10431044
List<GradleProject> projects = new ArrayList<>();
10441045
for (String line : raw.split("\n")) {
1045-
if (!line.startsWith("::DA_PROJECT::")) {
1046+
if (!line.startsWith(prefix)) {
10461047
continue;
10471048
}
1048-
String[] parts = line.split("::");
1049-
List<String> nonEmpty = new ArrayList<>();
1050-
for (String part : parts) {
1051-
if (!part.isEmpty()) {
1052-
nonEmpty.add(part);
1053-
}
1049+
String remainder = line.substring(prefix.length());
1050+
int lastSep = remainder.lastIndexOf("::");
1051+
if (lastSep < 0) {
1052+
continue;
10541053
}
1055-
if (nonEmpty.size() >= 3) {
1056-
projects.add(new GradleProject(nonEmpty.get(1), nonEmpty.get(2)));
1054+
String path = remainder.substring(0, lastSep);
1055+
String dir = remainder.substring(lastSep + 2);
1056+
if (!path.isEmpty() && !dir.isEmpty()) {
1057+
projects.add(new GradleProject(path, dir));
10571058
}
10581059
}
10591060
return projects;

src/test/java/io/github/guacsec/trustifyda/impl/GradleWorkspaceDiscoveryTest.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class GradleWorkspaceDiscoveryTest {
4141
@Test
4242
void parseGradleInitScriptOutput_standardOutput() {
4343
String raw =
44-
"::DA_PROJECT::::/home/project\n"
44+
"::DA_PROJECT:::::/home/project\n"
4545
+ "::DA_PROJECT:::app::/home/project/app\n"
4646
+ "::DA_PROJECT:::lib::/home/project/lib\n";
4747

@@ -57,7 +57,7 @@ void parseGradleInitScriptOutput_standardOutput() {
5757
@Test
5858
void parseGradleInitScriptOutput_nestedProjects() {
5959
String raw =
60-
"::DA_PROJECT::::/home/project\n"
60+
"::DA_PROJECT:::::/home/project\n"
6161
+ "::DA_PROJECT:::libs:core::/home/project/libs/core\n"
6262
+ "::DA_PROJECT:::libs:util::/home/project/libs/util\n";
6363

@@ -96,7 +96,7 @@ void discoverWorkspaceManifests_gradleMultiProject() throws IOException {
9696
GRADLE_FIXTURES.resolve("gradle_multi_project").toAbsolutePath().normalize();
9797

9898
String initScriptOutput =
99-
"::DA_PROJECT::::"
99+
"::DA_PROJECT:::::"
100100
+ workspaceDir
101101
+ "\n"
102102
+ "::DA_PROJECT:::app::"
@@ -136,7 +136,7 @@ void discoverWorkspaceManifests_nestedSubprojects() throws IOException {
136136
GRADLE_FIXTURES.resolve("gradle_nested_subprojects").toAbsolutePath().normalize();
137137

138138
String initScriptOutput =
139-
"::DA_PROJECT::::"
139+
"::DA_PROJECT:::::"
140140
+ workspaceDir
141141
+ "\n"
142142
+ "::DA_PROJECT:::libs:core::"
@@ -184,7 +184,7 @@ void discoverWorkspaceManifests_mixedGroovyAndKotlin() throws IOException {
184184
GRADLE_FIXTURES.resolve("gradle_mixed_variants").toAbsolutePath().normalize();
185185

186186
String initScriptOutput =
187-
"::DA_PROJECT::::"
187+
"::DA_PROJECT:::::"
188188
+ workspaceDir
189189
+ "\n"
190190
+ "::DA_PROJECT:::app::"
@@ -223,7 +223,7 @@ void discoverWorkspaceManifests_noSubprojects() throws IOException {
223223
Path workspaceDir =
224224
GRADLE_FIXTURES.resolve("gradle_no_subprojects").toAbsolutePath().normalize();
225225

226-
String initScriptOutput = "::DA_PROJECT::::" + workspaceDir + "\n";
226+
String initScriptOutput = "::DA_PROJECT:::::" + workspaceDir + "\n";
227227

228228
try (MockedStatic<Operations> mockOps = Mockito.mockStatic(Operations.class)) {
229229
mockOps.when(() -> Operations.getWrapperPreference("gradle")).thenReturn(false);
@@ -276,7 +276,7 @@ void discoverWorkspaceManifests_missingSubprojectDirectory() throws IOException
276276
GRADLE_FIXTURES.resolve("gradle_missing_subproject").toAbsolutePath().normalize();
277277

278278
String initScriptOutput =
279-
"::DA_PROJECT::::"
279+
"::DA_PROJECT:::::"
280280
+ workspaceDir
281281
+ "\n"
282282
+ "::DA_PROJECT:::app::"
@@ -314,7 +314,7 @@ void discoverWorkspaceManifests_ignorePatternFiltering() throws IOException {
314314
GRADLE_FIXTURES.resolve("gradle_multi_project").toAbsolutePath().normalize();
315315

316316
String initScriptOutput =
317-
"::DA_PROJECT::::"
317+
"::DA_PROJECT:::::"
318318
+ workspaceDir
319319
+ "\n"
320320
+ "::DA_PROJECT:::app::"

0 commit comments

Comments
 (0)