Skip to content

Commit 4ff3617

Browse files
committed
Support Spring SNAPSHOT/milestone repos by default
Closes gh-81
1 parent 26c3d0f commit 4ff3617

File tree

3 files changed

+53
-21
lines changed

3 files changed

+53
-21
lines changed

README.adoc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,19 @@ testImplementation 'org.springframework.experimental.boot:spring-boot-testjars-m
107107

108108
==== Custom Maven Repositories
109109

110-
By default, only Maven Central is searched.
110+
By default, the following repositories are added:
111+
- Maven Central
112+
- If it is a SNAPSHOT dependency with a group id that starts with `org.springframework`, then Spring's milestone and snapshot repositories are added
113+
- If it is a milestone or release candidate dependency with a group id that starts with `org.springframework`, then Spring's milestone repository is added
114+
111115
You can customize the repositories that are searched by injecting the repositories like the example below:
112116

113117
[source,java]
114118
----
115119
List<RemoteRepository> repositories = new ArrayList<>();
116120
repositories.add(new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/").build());
117-
repositories.add(new RemoteRepository.Builder("spring-milestone", "default", "https://repo.spring.io/milestone/").build());
118-
MavenClasspathEntry classpathEntry = new MavenClasspathEntry("org.springframework:spring-core:6.1.0-RC1", repositories);
121+
repositories.add(new RemoteRepository.Builder("sonatype-snapshot", "default", "https://oss.sonatype.org/content/repositories/snapshots/").build());
122+
MavenClasspathEntry classpathEntry = new MavenClasspathEntry("org.junit:junit5-api:5.0.0-SNAPSHOT", repositories);
119123
----
120124

121125
=== GenericSpringBootApplicationMain

spring-boot-testjars-maven/src/main/java/org/springframework/experimental/boot/server/exec/MavenClasspathEntry.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import java.io.File;
2020
import java.util.ArrayList;
21-
import java.util.Collections;
2221
import java.util.HashMap;
2322
import java.util.List;
2423

@@ -77,7 +76,7 @@ public class MavenClasspathEntry implements ClasspathEntry {
7776
* SpringBootVersion.getVersion()).
7877
*/
7978
public MavenClasspathEntry(String coords) {
80-
this(coords, newRepositories());
79+
this(coords, newRepositories(coords));
8180
}
8281

8382
/**
@@ -200,12 +199,32 @@ private static DefaultRepositorySystemSession newRepositorySystemSession(Reposit
200199
return session;
201200
}
202201

203-
private static List<RemoteRepository> newRepositories() {
204-
return new ArrayList<>(Collections.singletonList(newCentralRepository()));
202+
private static List<RemoteRepository> newRepositories(String coords) {
203+
List<RemoteRepository> result = new ArrayList<>();
204+
result.add(newCentralRepository());
205+
if (coords.startsWith("org.springframework")) {
206+
if (coords.endsWith("-SNAPSHOT")) {
207+
result.add(newSpringSnapshotRepository());
208+
// SNAPSHOT dependencies may contain milestones
209+
result.add(newSpringMilestoneRepository());
210+
}
211+
else if (coords.contains("-")) {
212+
result.add(newSpringMilestoneRepository());
213+
}
214+
}
215+
return result;
205216
}
206217

207218
private static RemoteRepository newCentralRepository() {
208219
return new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/").build();
209220
}
210221

222+
private static RemoteRepository newSpringSnapshotRepository() {
223+
return new RemoteRepository.Builder("spring-snapshot", "default", "https://repo.spring.io/snapshot/").build();
224+
}
225+
226+
private static RemoteRepository newSpringMilestoneRepository() {
227+
return new RemoteRepository.Builder("spring-milestone", "default", "https://repo.spring.io/milestone/").build();
228+
}
229+
211230
}

spring-boot-testjars-maven/src/test/java/org/springframework/experimental/boot/server/exec/MavenClasspathEntryTests.java

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.springframework.boot.SpringBootVersion;
2828

2929
import static org.assertj.core.api.Assertions.assertThat;
30+
import static org.assertj.core.api.Assertions.assertThatNoException;
3031

3132
class MavenClasspathEntryTests {
3233

@@ -88,21 +89,29 @@ void resolveDependencyWhenCustomRepository() {
8889
List<RemoteRepository> repositories = new ArrayList<>();
8990
repositories.add(
9091
new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/").build());
91-
repositories
92-
.add(new RemoteRepository.Builder("spring-milestone", "default", "https://repo.spring.io/milestone/")
93-
.build());
94-
MavenClasspathEntry classpathEntry = new MavenClasspathEntry("org.springframework:spring-core:6.1.0-RC1",
92+
repositories.add(new RemoteRepository.Builder("sonatype-snapshot", "default",
93+
"https://oss.sonatype.org/content/repositories/snapshots/").build());
94+
MavenClasspathEntry classpathEntry = new MavenClasspathEntry("org.junit:junit5-api:5.0.0-SNAPSHOT",
9595
repositories);
96-
List<String> entries = classpathEntry.resolve();
97-
assertThat(entries).hasSize(2);
98-
String mavenLocal = new File(System.getProperty("user.home"), ".m2/repository").getAbsolutePath();
99-
entries.forEach((entry) -> assertThat(entry).startsWith(mavenLocal));
100-
String springCorePathPartial = "/org/springframework/spring-core/6.1.0-RC1/spring-core-6.1.0-RC1.jar";
101-
Optional<String> springCoreEntry = entries.stream().filter((entry) -> entry.contains(springCorePathPartial))
102-
.findFirst();
103-
assertThat(springCoreEntry.isPresent())
104-
.withFailMessage("Unable to find spring-core with path that contains " + springCorePathPartial)
105-
.isTrue();
96+
assertThatNoException().isThrownBy(() -> classpathEntry.resolve());
97+
}
98+
99+
@Test
100+
void resolveDependencyWhenOrgSpringframeworkSnapshotThenDoesNotRequireCustomRepository() {
101+
MavenClasspathEntry classpathEntry = new MavenClasspathEntry("org.springframework:spring-core:6.2.0-SNAPSHOT");
102+
assertThatNoException().isThrownBy(() -> classpathEntry.resolve());
103+
}
104+
105+
@Test
106+
void resolveDependencyWhenOrgSpringframeworkRc1ThenDoesNotRequireCustomRepository() {
107+
MavenClasspathEntry classpathEntry = new MavenClasspathEntry("org.springframework:spring-core:6.2.0-RC1");
108+
assertThatNoException().isThrownBy(() -> classpathEntry.resolve());
109+
}
110+
111+
@Test
112+
void resolveDependencyWhenOrgSpringframeworkM1ThenDoesNotRequireCustomRepository() {
113+
MavenClasspathEntry classpathEntry = new MavenClasspathEntry("org.springframework:spring-core:6.2.0-M1");
114+
assertThatNoException().isThrownBy(() -> classpathEntry.resolve());
106115
}
107116

108117
}

0 commit comments

Comments
 (0)