findUncommittedChanges(Repository repository) {
+
+ return withTry(() -> new Git(repository), git -> {
+
+ var status = git.status().call();
return Streams.concat(status.getUncommittedChanges().stream(), status.getUntracked().stream())
- .map(ModifiedFilePath::new);
- } catch (GitAPIException e) {
- throw new IOException("Unable to find uncommitted changes", e);
- }
+ .map(ModifiedFile::new);
+ });
}
-
}
diff --git a/spring-modulith-junit/src/main/java/org/springframework/modulith/junit/diff/UnpushedCommitsDetector.java b/spring-modulith-junit/src/main/java/org/springframework/modulith/junit/diff/UnpushedCommitsDetector.java
index 0995e9e5..3683786c 100644
--- a/spring-modulith-junit/src/main/java/org/springframework/modulith/junit/diff/UnpushedCommitsDetector.java
+++ b/spring-modulith-junit/src/main/java/org/springframework/modulith/junit/diff/UnpushedCommitsDetector.java
@@ -1,15 +1,25 @@
+/*
+ * Copyright 2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.springframework.modulith.junit.diff;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.stream.Collectors;
+import static org.springframework.modulith.junit.diff.JGitUtil.*;
+
import java.util.stream.Stream;
-import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.lib.BranchConfig;
-import org.springframework.core.env.PropertyResolver;
-import org.springframework.lang.NonNull;
/**
*
@@ -17,25 +27,30 @@
*
* To be precise, this finds the diff between the local HEAD and its tracking branch and the uncommitted and untracked
* changes. Note: This will not fetch from the remote first!
+ *
+ * @author Lukas Dohmen
+ * @author David Bilge
+ * @author Oliver Drotbohm
*/
-public class UnpushedCommitsDetector implements FileModificationDetector {
+enum UnpushedCommitsDetector implements FileModificationDetector {
+ INSTANCE;
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.modulith.junit.FileModificationDetector#getModifiedFiles()
+ */
@Override
- public @NonNull Set getModifiedFiles(@NonNull PropertyResolver propertyResolver)
- throws IOException {
- try (var repo = JGitUtil.buildRepository()) {
- String localBranch = repo.getFullBranch();
- String trackingBranch = new BranchConfig(repo.getConfig(), repo.getBranch()).getTrackingBranch();
-
- Stream diff = localBranch != null && trackingBranch != null
- ? JGitUtil.diffRefs(repo, localBranch, trackingBranch)
- : Stream.empty();
+ public Stream getModifiedFiles() {
- HashSet result = new HashSet<>();
- result.addAll(new UncommittedChangesDetector().getModifiedFiles(propertyResolver));
- result.addAll(JGitUtil.convertDiffEntriesToFileChanges(diff).collect(Collectors.toSet()));
- return result;
- }
- }
+ return withRepository(repo -> {
+
+ var localBranch = repo.getFullBranch();
+ var trackingBranch = new BranchConfig(repo.getConfig(), repo.getBranch()).getTrackingBranch();
+ return localBranch != null && trackingBranch != null
+ ? toModifiedFiles(repo, localBranch, trackingBranch)
+ : Stream.empty();
+ });
+ }
}
diff --git a/spring-modulith-junit/src/main/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/spring-modulith-junit/src/main/resources/META-INF/services/org.junit.jupiter.api.extension.Extension
index 924a6a1b..917af696 100644
--- a/spring-modulith-junit/src/main/resources/META-INF/services/org.junit.jupiter.api.extension.Extension
+++ b/spring-modulith-junit/src/main/resources/META-INF/services/org.junit.jupiter.api.extension.Extension
@@ -1 +1 @@
-org.springframework.modulith.junit.ModulithExecutionExtension
+org.springframework.modulith.junit.ModulithExecutionCondition
diff --git a/spring-modulith-junit/src/main/resources/META-INF/services/org.springframework.modulith.FileModificationDetector b/spring-modulith-junit/src/main/resources/META-INF/services/org.springframework.modulith.FileModificationDetector
deleted file mode 100644
index b96b4406..00000000
--- a/spring-modulith-junit/src/main/resources/META-INF/services/org.springframework.modulith.FileModificationDetector
+++ /dev/null
@@ -1,3 +0,0 @@
-org.springframework.modulith.git.UncommittedChangesDetector
-org.springframework.modulith.git.UnpushedGitChangesDetector
-org.springframework.modulith.git.DiffDetector
diff --git a/spring-modulith-junit/src/test/java/example/a/package-info.java b/spring-modulith-junit/src/test/java/example/a/package-info.java
new file mode 100644
index 00000000..be87a764
--- /dev/null
+++ b/spring-modulith-junit/src/test/java/example/a/package-info.java
@@ -0,0 +1 @@
+package example.a;
diff --git a/spring-modulith-junit/src/test/java/example/b/package-info.java b/spring-modulith-junit/src/test/java/example/b/package-info.java
new file mode 100644
index 00000000..58d83ab5
--- /dev/null
+++ b/spring-modulith-junit/src/test/java/example/b/package-info.java
@@ -0,0 +1 @@
+package example.b;
diff --git a/spring-modulith-junit/src/test/java/example/package-info.java b/spring-modulith-junit/src/test/java/example/package-info.java
new file mode 100644
index 00000000..e83ec38c
--- /dev/null
+++ b/spring-modulith-junit/src/test/java/example/package-info.java
@@ -0,0 +1 @@
+package example;
diff --git a/spring-modulith-junit/src/test/java/org/springframework/modulith/junit/ChangeTest.java b/spring-modulith-junit/src/test/java/org/springframework/modulith/junit/ChangeTest.java
deleted file mode 100644
index 0531b634..00000000
--- a/spring-modulith-junit/src/test/java/org/springframework/modulith/junit/ChangeTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.springframework.modulith.junit;
-
-import static org.assertj.core.api.Assertions.*;
-
-import java.util.Set;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.modulith.junit.Change.JavaClassChange;
-import org.springframework.modulith.junit.Change.JavaTestClassChange;
-import org.springframework.modulith.junit.Change.OtherFileChange;
-import org.springframework.modulith.junit.diff.ModifiedFilePath;
-
-class ChangesTest {
- @Test
- void shouldInterpredModifiedFilePathsCorrectly() {
- // given
- Set modifiedFilePaths = Set.of(
- new ModifiedFilePath("spring-modulith-junit/src/main/java/org/springframework/modulith/Changes.java"),
- new ModifiedFilePath("spring-modulith-junit/src/test/java/org/springframework/modulith/ChangesTest.java"),
- new ModifiedFilePath(
- "spring-modulith-junit/src/main/resources/META-INF/additional-spring-configuration-metadata.json"));
-
- // when
- Set result = Changes.toChanges(modifiedFilePaths);
-
- // then
- assertThat(result).containsExactlyInAnyOrder(
- new JavaClassChange("org.springframework.modulith.Changes"),
- new JavaTestClassChange("org.springframework.modulith.ChangesTest"),
- new OtherFileChange(
- "spring-modulith-junit/src/main/resources/META-INF/additional-spring-configuration-metadata.json"));
- }
-}
diff --git a/spring-modulith-junit/src/test/java/org/springframework/modulith/junit/ChangesUnitTests.java b/spring-modulith-junit/src/test/java/org/springframework/modulith/junit/ChangesUnitTests.java
new file mode 100644
index 00000000..644f3833
--- /dev/null
+++ b/spring-modulith-junit/src/test/java/org/springframework/modulith/junit/ChangesUnitTests.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.modulith.junit;
+
+import static org.assertj.core.api.Assertions.*;
+
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestFactory;
+import org.springframework.modulith.junit.Changes.Change.JavaSourceChange;
+import org.springframework.modulith.junit.Changes.Change.JavaTestSourceChange;
+import org.springframework.modulith.junit.Changes.Change.OtherFileChange;
+import org.springframework.modulith.junit.diff.ModifiedFile;
+
+/**
+ * Unit tests for {@link Changes}.
+ *
+ * @author Lukas Dohmen
+ * @author David Bilge
+ * @author Oliver Drotbohm
+ */
+class ChangesUnitTests {
+
+ @TestFactory // GH-31
+ Stream detectsClasspathFileChange() {
+
+ var files = Stream.of("src/main/resources/some.txt", "src/test/resources/some.txt");
+
+ return DynamicTest.stream(files, it -> it + " is considered classpath resource", it -> {
+ assertThat(new OtherFileChange(it).isClasspathResource()).isTrue();
+ });
+ }
+
+ @TestFactory // GH-31
+ Stream detectsNonClasspathFileChange() {
+
+ var files = Stream.of("pom.xml", "build.gradle", "build.kt");
+
+ return DynamicTest.stream(files, it -> it + " is considered build resource", it -> {
+
+ var change = new OtherFileChange(it);
+
+ assertThat(change.isClasspathResource()).isFalse();
+ assertThat(change.affectsBuildResource()).isTrue();
+ });
+ }
+
+ @Test // GH-31
+ void shouldInterpredModifiedFilePathsCorrectly() {
+
+ // given
+ var modifiedFilePaths = Stream.of(
+ "src/main/java/org/springframework/modulith/junit/Changes.java",
+ "src/test/java/org/springframework/modulith/ChangesTest.java",
+ "src/main/resources/META-INF/additional-spring-configuration-metadata.json")
+ .map(ModifiedFile::new);
+
+ // when
+ var result = Changes.of(modifiedFilePaths);
+
+ // then
+ assertThat(result.hasClasspathResourceChange()).isTrue();
+ assertThat(result).containsExactlyInAnyOrder(
+ new JavaSourceChange("org.springframework.modulith.junit.Changes"),
+ new JavaTestSourceChange("org.springframework.modulith.ChangesTest"),
+ new OtherFileChange("src/main/resources/META-INF/additional-spring-configuration-metadata.json"));
+ }
+}
diff --git a/spring-modulith-junit/src/test/java/org/springframework/modulith/junit/diff/ReferenceCommitDetectorUnitTests.java b/spring-modulith-junit/src/test/java/org/springframework/modulith/junit/diff/ReferenceCommitDetectorUnitTests.java
new file mode 100644
index 00000000..70f5e65e
--- /dev/null
+++ b/spring-modulith-junit/src/test/java/org/springframework/modulith/junit/diff/ReferenceCommitDetectorUnitTests.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.modulith.junit.diff;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit tests for {@link ReferenceCommitDetector}.
+ *
+ * @author Oliver Drotbohm
+ */
+public class ReferenceCommitDetectorUnitTests {
+
+ @Test
+ void detectsChangesOfHead() {
+
+ var detector = new ReferenceCommitDetector(null);
+
+ assertThat(detector.getModifiedFiles()).isEmpty();
+ }
+
+ @Test
+ void detectsChangesFromEarlierCommit() {
+
+ var first = new ReferenceCommitDetector(null).getModifiedFiles().toList();
+ var second = new ReferenceCommitDetector("HEAD^^^^^").getModifiedFiles().toList();
+
+ assertThat(second).isNotEqualTo(first);
+ }
+}