This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-analyser.git
The following commit(s) were added to refs/heads/master by this push:
new a97109a SLING-13291 - Fix false repo-init conflict detection caused
by first primaryType in create path (#61)
a97109a is described below
commit a97109a634b4f6e7176cce9c33f86e1bff2445c0
Author: michalwedzik <[email protected]>
AuthorDate: Thu Aug 6 15:31:13 2026 +0200
SLING-13291 - Fix false repo-init conflict detection caused by first
primaryType in create path (#61)
---------
Co-authored-by: sii12877 <[email protected]>
---
pom.xml | 5 +
.../RepoInitConflictsValidator.java | 17 +--
.../task/impl/CheckRepoInitConflictsTest.java | 120 +++++++++++++++------
3 files changed, 103 insertions(+), 39 deletions(-)
diff --git a/pom.xml b/pom.xml
index 9c239eb..b8c389d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -164,6 +164,11 @@
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-params</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
diff --git
a/src/main/java/org/apache/sling/feature/analyser/task/impl/repoinitconflicts/RepoInitConflictsValidator.java
b/src/main/java/org/apache/sling/feature/analyser/task/impl/repoinitconflicts/RepoInitConflictsValidator.java
index ae4ffbc..f912a39 100644
---
a/src/main/java/org/apache/sling/feature/analyser/task/impl/repoinitconflicts/RepoInitConflictsValidator.java
+++
b/src/main/java/org/apache/sling/feature/analyser/task/impl/repoinitconflicts/RepoInitConflictsValidator.java
@@ -95,20 +95,17 @@ public class RepoInitConflictsValidator {
List<PathSegmentDefinition> aDefs = a.getDefinitions();
List<PathSegmentDefinition> bDefs = b.getDefinitions();
- // different depth → no conflict
- if (aDefs.size() != bDefs.size()) {
+ String aWithoutTypes = pathWithoutTypes(a);
+ String bWithoutTypes = pathWithoutTypes(b);
+ if (!aWithoutTypes.equals(bWithoutTypes)) {
return Collections.emptyList();
}
+
List<CreatePath[]> conflicts = new ArrayList<>();
for (int i = 0; i < aDefs.size(); i++) {
PathSegmentDefinition aSeg = aDefs.get(i);
PathSegmentDefinition bSeg = bDefs.get(i);
- // segments diverge → stop comparing this pair
- if (!Objects.equals(aSeg.getSegment(), bSeg.getSegment())) {
- return Collections.emptyList();
- }
-
// same segment but different type → conflict
if (!Objects.equals(aSeg.getPrimaryType(), bSeg.getPrimaryType()))
{
CreatePath[] conflict = new CreatePath[2];
@@ -121,4 +118,10 @@ public class RepoInitConflictsValidator {
}
return conflicts;
}
+
+ private static String pathWithoutTypes(final CreatePath createPath) {
+ return createPath.getDefinitions().stream()
+ .map(PathSegmentDefinition::getSegment)
+ .collect(Collectors.joining("/"));
+ }
}
diff --git
a/src/test/java/org/apache/sling/feature/analyser/task/impl/CheckRepoInitConflictsTest.java
b/src/test/java/org/apache/sling/feature/analyser/task/impl/CheckRepoInitConflictsTest.java
index 35c17c7..cd46394 100644
---
a/src/test/java/org/apache/sling/feature/analyser/task/impl/CheckRepoInitConflictsTest.java
+++
b/src/test/java/org/apache/sling/feature/analyser/task/impl/CheckRepoInitConflictsTest.java
@@ -18,15 +18,24 @@
*/
package org.apache.sling.feature.analyser.task.impl;
+import java.util.stream.Stream;
+
import org.apache.sling.feature.Extension;
import org.apache.sling.feature.ExtensionType;
import org.apache.sling.feature.Feature;
import org.apache.sling.feature.analyser.task.AnalyserTask;
import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.contains;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
class CheckRepoInitConflictsTest {
@@ -40,84 +49,131 @@ class CheckRepoInitConflictsTest {
@Test
void shouldNotReportWarningWhenNoRepoinit() {
- final AnalyserTaskContext ctx =
Mockito.mock(AnalyserTaskContext.class);
+ final AnalyserTaskContext ctx = mock(AnalyserTaskContext.class);
+
+ Feature feature = mock(Feature.class);
+ org.apache.sling.feature.Extensions extensions =
mock(org.apache.sling.feature.Extensions.class);
+
+ when(ctx.getFeature()).thenReturn(feature);
+ when(feature.getExtensions()).thenReturn(extensions);
+ when(extensions.getByName("repoinit")).thenReturn(null);
+
+ CheckRepoInitConflicts task = new CheckRepoInitConflicts();
+ task.execute(ctx);
+
+ verify(ctx).getFeature();
+ verifyNoMoreInteractions(ctx);
+ }
- Feature feature = Mockito.mock(Feature.class);
- org.apache.sling.feature.Extensions extensions =
Mockito.mock(org.apache.sling.feature.Extensions.class);
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("nonConflictingRepoinitStatements")
+ void shouldNotReportWarningWhenNoConflicts(String scenario, String
repoinitText) {
+ final AnalyserTaskContext ctx = mock(AnalyserTaskContext.class);
- Mockito.when(ctx.getFeature()).thenReturn(feature);
- Mockito.when(feature.getExtensions()).thenReturn(extensions);
- Mockito.when(extensions.getByName("repoinit")).thenReturn(null);
+ Feature feature = featureWithExtension(textExtension(repoinitText));
+
+ when(ctx.getFeature()).thenReturn(feature);
CheckRepoInitConflicts task = new CheckRepoInitConflicts();
task.execute(ctx);
- Mockito.verify(ctx).getFeature();
- Mockito.verifyNoMoreInteractions(ctx);
+ verify(ctx).getFeature();
+ verifyNoMoreInteractions(ctx);
+ }
+
+ private static Stream<Arguments> nonConflictingRepoinitStatements() {
+ return Stream.of(
+ Arguments.of(
+ "shouldNotReportWarningWhenNoConflicts",
+ "create path (sling:Folder) /apps/a/b\n" + "create
path (sling:Folder) /apps/a/c"),
+ Arguments.of(
+
"shouldNotReportWarningWhenDifferentTypesOnTheBeginning",
+ "create path (sling:Folder) /content/dam/a\n"
+ + "create path (sling:OrderedFolder)
/content/dam/b"),
+ Arguments.of(
+ "shouldNotReportWarningWhenSimilarPaths",
+ "create path (sling:Folder) /con/tent/my/nestedpath\n"
+ + "create path (sling:Folder)
/content/my/nested/path(cq:ClientLibraryFolder)"));
}
@Test
- void shouldNotReportWarningWhenNoConflicts() {
- final AnalyserTaskContext ctx =
Mockito.mock(AnalyserTaskContext.class);
+ void shouldNotReportWarningWhenOddNumberOfPaths() {
+ final AnalyserTaskContext ctx = mock(AnalyserTaskContext.class);
- Feature feature = featureWithExtension(
- textExtension("create path (sling:Folder) /apps/a/b\n" +
"create path (sling:Folder) /apps/a/c"));
+ Feature feature = featureWithExtension(textExtension("create path
(sling:Folder) /content/dam/a\n"));
- Mockito.when(ctx.getFeature()).thenReturn(feature);
+ when(ctx.getFeature()).thenReturn(feature);
CheckRepoInitConflicts task = new CheckRepoInitConflicts();
task.execute(ctx);
- Mockito.verify(ctx).getFeature();
- Mockito.verifyNoMoreInteractions(ctx);
+ verify(ctx).getFeature();
+ verifyNoMoreInteractions(ctx);
}
@Test
void shouldReportWarningWhenConflictExists() {
- final AnalyserTaskContext ctx =
Mockito.mock(AnalyserTaskContext.class);
+ final AnalyserTaskContext ctx = mock(AnalyserTaskContext.class);
Feature feature =
featureWithExtension(textExtension("create path (sling:Folder)
/apps/a/b(cq:ClientLibraryFolder)\n"
+ "create path (sling:Folder) /apps/a/b"));
- Mockito.when(ctx.getFeature()).thenReturn(feature);
+ when(ctx.getFeature()).thenReturn(feature);
+
+ CheckRepoInitConflicts task = new CheckRepoInitConflicts();
+ task.execute(ctx);
+
+ verify(ctx).getFeature();
+ verify(ctx).reportWarning(contains("conflicting repoinit"));
+ verify(ctx).reportWarning(contains("Conflicting statement"));
+ }
+
+ @Test
+ void shouldReportWarningWhenConflictExistsInTheFirstPrimaryType() {
+ final AnalyserTaskContext ctx = mock(AnalyserTaskContext.class);
+
+ Feature feature = featureWithExtension(textExtension(
+ "create path (sling:Folder) /content/dam/a\n" + "create path
(sling:OrderedFolder) /content/dam/a"));
+
+ when(ctx.getFeature()).thenReturn(feature);
CheckRepoInitConflicts task = new CheckRepoInitConflicts();
task.execute(ctx);
- Mockito.verify(ctx).getFeature();
- Mockito.verify(ctx).reportWarning(Mockito.contains("conflicting
repoinit"));
- Mockito.verify(ctx).reportWarning(Mockito.contains("Conflicting
statement"));
+ verify(ctx).getFeature();
+ verify(ctx).reportWarning(contains("conflicting repoinit"));
+ verify(ctx).reportWarning(contains("Conflicting statement"));
}
@Test
void shouldIgnoreInvalidRepoinitSyntax() {
- final AnalyserTaskContext ctx =
Mockito.mock(AnalyserTaskContext.class);
+ final AnalyserTaskContext ctx = mock(AnalyserTaskContext.class);
Feature feature = featureWithExtension(textExtension("invalid $$$"));
- Mockito.when(ctx.getFeature()).thenReturn(feature);
+ when(ctx.getFeature()).thenReturn(feature);
CheckRepoInitConflicts task = new CheckRepoInitConflicts();
task.execute(ctx);
- Mockito.verify(ctx).getFeature();
- Mockito.verifyNoMoreInteractions(ctx);
+ verify(ctx).getFeature();
+ verifyNoMoreInteractions(ctx);
}
private Extension textExtension(String text) {
- Extension extension = Mockito.mock(Extension.class);
- Mockito.when(extension.getType()).thenReturn(ExtensionType.TEXT);
- Mockito.when(extension.getText()).thenReturn(text);
+ Extension extension = mock(Extension.class);
+ when(extension.getType()).thenReturn(ExtensionType.TEXT);
+ when(extension.getText()).thenReturn(text);
return extension;
}
private Feature featureWithExtension(Extension extension) {
- Feature feature = Mockito.mock(Feature.class);
- org.apache.sling.feature.Extensions extensions =
Mockito.mock(org.apache.sling.feature.Extensions.class);
+ Feature feature = mock(Feature.class);
+ org.apache.sling.feature.Extensions extensions =
mock(org.apache.sling.feature.Extensions.class);
- Mockito.when(feature.getExtensions()).thenReturn(extensions);
- Mockito.when(extensions.getByName("repoinit")).thenReturn(extension);
+ when(feature.getExtensions()).thenReturn(extensions);
+ when(extensions.getByName("repoinit")).thenReturn(extension);
return feature;
}