Port the build to Gradle

Closes gh-19609
Closes gh-19608
This commit is contained in:
Andy Wilkinson
2020-01-10 13:48:43 +00:00
parent abe95fa8a7
commit ce99db1902
974 changed files with 17108 additions and 26596 deletions

View File

@@ -43,39 +43,40 @@ class CommandLineIT {
this.cli = new CommandLineInvoker(tempDir);
}
@Test void hintProducesListOfValidCommands()
throws IOException, InterruptedException {
@Test
void hintProducesListOfValidCommands() throws IOException, InterruptedException {
Invocation cli = this.cli.invoke("hint");
assertThat(cli.await()).isEqualTo(0);
assertThat(cli.getErrorOutput()).isEmpty();
assertThat(cli.getStandardOutputLines()).hasSize(11);
}
@Test void invokingWithNoArgumentsDisplaysHelp()
throws IOException, InterruptedException {
@Test
void invokingWithNoArgumentsDisplaysHelp() throws IOException, InterruptedException {
Invocation cli = this.cli.invoke();
assertThat(cli.await()).isEqualTo(1);
assertThat(cli.getErrorOutput()).isEmpty();
assertThat(cli.getStandardOutput()).startsWith("usage:");
}
@Test void unrecognizedCommandsAreHandledGracefully()
throws IOException, InterruptedException {
@Test
void unrecognizedCommandsAreHandledGracefully() throws IOException, InterruptedException {
Invocation cli = this.cli.invoke("not-a-real-command");
assertThat(cli.await()).isEqualTo(1);
assertThat(cli.getErrorOutput())
.contains("'not-a-real-command' is not a valid command");
assertThat(cli.getErrorOutput()).contains("'not-a-real-command' is not a valid command");
assertThat(cli.getStandardOutput()).isEmpty();
}
@Test void version() throws IOException, InterruptedException {
@Test
void version() throws IOException, InterruptedException {
Invocation cli = this.cli.invoke("version");
assertThat(cli.await()).isEqualTo(0);
assertThat(cli.getErrorOutput()).isEmpty();
assertThat(cli.getStandardOutput()).startsWith("Spring CLI v");
}
@Test void help() throws IOException, InterruptedException {
@Test
void help() throws IOException, InterruptedException {
Invocation cli = this.cli.invoke("help");
assertThat(cli.await()).isEqualTo(1);
assertThat(cli.getErrorOutput()).isEmpty();

View File

@@ -37,8 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class JarCommandIT {
private static final boolean JAVA_9_OR_LATER = isClassPresent(
"java.security.cert.URICertStoreParameters");
private static final boolean JAVA_9_OR_LATER = isClassPresent("java.security.cert.URICertStoreParameters");
private CommandLineInvoker cli;
@@ -46,31 +45,32 @@ class JarCommandIT {
@BeforeEach
void setup(@TempDir File tempDir) {
this.cli = new CommandLineInvoker(new File("src/it/resources/jar-command"),
tempDir);
this.cli = new CommandLineInvoker(new File("src/intTest/resources/jar-command"), tempDir);
this.tempDir = tempDir;
}
@Test void noArguments() throws Exception {
@Test
void noArguments() throws Exception {
Invocation invocation = this.cli.invoke("jar");
invocation.await();
assertThat(invocation.getStandardOutput()).isEqualTo("");
assertThat(invocation.getErrorOutput()).contains("The name of the "
+ "resulting jar and at least one source file must be specified");
assertThat(invocation.getErrorOutput())
.contains("The name of the " + "resulting jar and at least one source file must be specified");
}
@Test void noSources() throws Exception {
@Test
void noSources() throws Exception {
Invocation invocation = this.cli.invoke("jar", "test-app.jar");
invocation.await();
assertThat(invocation.getStandardOutput()).isEqualTo("");
assertThat(invocation.getErrorOutput()).contains("The name of the "
+ "resulting jar and at least one source file must be specified");
assertThat(invocation.getErrorOutput())
.contains("The name of the " + "resulting jar and at least one source file must be specified");
}
@Test void jarCreationWithGrabResolver() throws Exception {
@Test
void jarCreationWithGrabResolver() throws Exception {
File jar = new File(this.tempDir, "test-app.jar");
Invocation invocation = this.cli.invoke("run", jar.getAbsolutePath(),
"bad.groovy");
Invocation invocation = this.cli.invoke("run", jar.getAbsolutePath(), "bad.groovy");
invocation.await();
if (!JAVA_9_OR_LATER) {
assertThat(invocation.getErrorOutput()).isEqualTo("");
@@ -82,8 +82,7 @@ class JarCommandIT {
}
assertThat(jar).exists();
Process process = new JavaExecutable()
.processBuilder("-jar", jar.getAbsolutePath()).start();
Process process = new JavaExecutable().processBuilder("-jar", jar.getAbsolutePath()).start();
invocation = new Invocation(process);
invocation.await();
@@ -92,9 +91,33 @@ class JarCommandIT {
}
}
@Test void jarCreation() throws Exception {
@Test
void jarCreation() throws Exception {
File jar = new File(this.tempDir, "test-app.jar");
Invocation invocation = this.cli.invoke("jar", jar.getAbsolutePath(),
Invocation invocation = this.cli.invoke("jar", jar.getAbsolutePath(), "jar.groovy");
invocation.await();
if (!JAVA_9_OR_LATER) {
assertThat(invocation.getErrorOutput()).isEmpty();
}
assertThat(jar).exists();
Process process = new JavaExecutable().processBuilder("-jar", jar.getAbsolutePath()).start();
invocation = new Invocation(process);
invocation.await();
if (!JAVA_9_OR_LATER) {
assertThat(invocation.getErrorOutput()).isEqualTo("");
}
assertThat(invocation.getStandardOutput()).contains("Hello World!")
.contains("/BOOT-INF/classes!/public/public.txt").contains("/BOOT-INF/classes!/resources/resource.txt")
.contains("/BOOT-INF/classes!/static/static.txt").contains("/BOOT-INF/classes!/templates/template.txt")
.contains("/BOOT-INF/classes!/root.properties").contains("Goodbye Mama");
}
@Test
void jarCreationWithIncludes() throws Exception {
File jar = new File(this.tempDir, "test-app.jar");
Invocation invocation = this.cli.invoke("jar", jar.getAbsolutePath(), "--include", "-public/**,-resources/**",
"jar.groovy");
invocation.await();
if (!JAVA_9_OR_LATER) {
@@ -102,42 +125,14 @@ class JarCommandIT {
}
assertThat(jar).exists();
Process process = new JavaExecutable()
.processBuilder("-jar", jar.getAbsolutePath()).start();
Process process = new JavaExecutable().processBuilder("-jar", jar.getAbsolutePath()).start();
invocation = new Invocation(process);
invocation.await();
if (!JAVA_9_OR_LATER) {
assertThat(invocation.getErrorOutput()).isEqualTo("");
}
assertThat(invocation.getStandardOutput()).contains("Hello World!")
.contains("/BOOT-INF/classes!/public/public.txt")
.contains("/BOOT-INF/classes!/resources/resource.txt")
.contains("/BOOT-INF/classes!/static/static.txt")
.contains("/BOOT-INF/classes!/templates/template.txt")
.contains("/BOOT-INF/classes!/root.properties").contains("Goodbye Mama");
}
@Test void jarCreationWithIncludes() throws Exception {
File jar = new File(this.tempDir, "test-app.jar");
Invocation invocation = this.cli.invoke("jar", jar.getAbsolutePath(), "--include",
"-public/**,-resources/**", "jar.groovy");
invocation.await();
if (!JAVA_9_OR_LATER) {
assertThat(invocation.getErrorOutput()).isEmpty();
}
assertThat(jar).exists();
Process process = new JavaExecutable()
.processBuilder("-jar", jar.getAbsolutePath()).start();
invocation = new Invocation(process);
invocation.await();
if (!JAVA_9_OR_LATER) {
assertThat(invocation.getErrorOutput()).isEqualTo("");
}
assertThat(invocation.getStandardOutput()).contains("Hello World!")
.doesNotContain("/public/public.txt")
assertThat(invocation.getStandardOutput()).contains("Hello World!").doesNotContain("/public/public.txt")
.doesNotContain("/resources/resource.txt").contains("/static/static.txt")
.contains("/templates/template.txt").contains("Goodbye Mama");
}

View File

@@ -43,25 +43,22 @@ class WarCommandIT {
@BeforeEach
void setup(@TempDir File tempDir) {
this.cli = new CommandLineInvoker(new File("src/it/resources/war-command"),
tempDir);
this.cli = new CommandLineInvoker(new File("src/intTest/resources/war-command"), tempDir);
this.tempDir = tempDir;
}
@Test void warCreation() throws Exception {
@Test
void warCreation() throws Exception {
File war = new File(this.tempDir, "test-app.war");
Invocation invocation = this.cli.invoke("war", war.getAbsolutePath(),
"war.groovy");
Invocation invocation = this.cli.invoke("war", war.getAbsolutePath(), "war.groovy");
invocation.await();
assertThat(war.exists()).isTrue();
Process process = new JavaExecutable()
.processBuilder("-jar", war.getAbsolutePath(), "--server.port=0").start();
Process process = new JavaExecutable().processBuilder("-jar", war.getAbsolutePath(), "--server.port=0").start();
invocation = new Invocation(process);
invocation.await();
assertThat(invocation.getOutput()).contains("onStart error");
assertThat(invocation.getOutput()).contains("Tomcat started");
assertThat(invocation.getOutput())
.contains("/WEB-INF/lib-provided/tomcat-embed-core");
assertThat(invocation.getOutput()).contains("/WEB-INF/lib-provided/tomcat-embed-core");
assertThat(invocation.getOutput()).contains("WEB-INF/classes!/root.properties");
process.destroy();
}

View File

@@ -25,6 +25,10 @@ import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -63,19 +67,22 @@ public final class CommandLineInvoker {
}
private Process runCliProcess(String... args) throws IOException {
Path m2 = this.temp.toPath().resolve(".m2");
Files.createDirectories(m2);
Files.copy(Paths.get("src", "intTest", "resources", "settings.xml"), m2.resolve("settings.xml"),
StandardCopyOption.REPLACE_EXISTING);
List<String> command = new ArrayList<>();
command.add(findLaunchScript().getAbsolutePath());
command.addAll(Arrays.asList(args));
ProcessBuilder processBuilder = new ProcessBuilder(command)
.directory(this.workingDirectory);
processBuilder.environment().remove("JAVA_OPTS");
ProcessBuilder processBuilder = new ProcessBuilder(command).directory(this.workingDirectory);
processBuilder.environment().put("JAVA_OPTS", "-Duser.home=" + this.temp);
return processBuilder.start();
}
private File findLaunchScript() throws IOException {
File unpacked = new File(this.temp, "unpacked-cli");
if (!unpacked.isDirectory()) {
File zip = new BuildOutput(getClass()).getRootLocation()
File zip = new File(new BuildOutput(getClass()).getRootLocation(), "distributions")
.listFiles((pathname) -> pathname.getName().endsWith("-bin.zip"))[0];
try (ZipInputStream input = new ZipInputStream(new FileInputStream(zip))) {
ZipEntry entry;
@@ -99,8 +106,7 @@ public final class CommandLineInvoker {
File bin = new File(unpacked.listFiles()[0], "bin");
File launchScript = new File(bin, isWindows() ? "spring.bat" : "spring");
Assert.state(launchScript.exists() && launchScript.isFile(),
() -> "Could not find CLI launch script "
+ launchScript.getAbsolutePath());
() -> "Could not find CLI launch script " + launchScript.getAbsolutePath());
return launchScript;
}
@@ -125,10 +131,10 @@ public final class CommandLineInvoker {
public Invocation(Process process) {
this.process = process;
this.streamReaders.add(new Thread(new StreamReadingRunnable(
this.process.getErrorStream(), this.err, this.combined)));
this.streamReaders.add(new Thread(new StreamReadingRunnable(
this.process.getInputStream(), this.out, this.combined)));
this.streamReaders
.add(new Thread(new StreamReadingRunnable(this.process.getErrorStream(), this.err, this.combined)));
this.streamReaders
.add(new Thread(new StreamReadingRunnable(this.process.getInputStream(), this.out, this.combined)));
for (Thread streamReader : this.streamReaders) {
streamReader.start();
}
@@ -162,10 +168,8 @@ public final class CommandLineInvoker {
}
private List<String> getLines(StringBuffer buffer) {
BufferedReader reader = new BufferedReader(
new StringReader(buffer.toString()));
return reader.lines().filter((line) -> !line.startsWith("Picked up "))
.collect(Collectors.toList());
BufferedReader reader = new BufferedReader(new StringReader(buffer.toString()));
return reader.lines().filter((line) -> !line.startsWith("Picked up ")).collect(Collectors.toList());
}
public int await() throws InterruptedException {

View File

@@ -0,0 +1,23 @@
<settings>
<localRepository>../../../../build/local-m2-repository</localRepository>
<profiles>
<profile>
<id>cli-test-repo</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>local.central</id>
<url>file:../../../../build/test-repository</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
</settings>

View File

@@ -4,7 +4,7 @@ class Springboot < Formula
homepage 'https://spring.io/projects/spring-boot'
url 'https://repo.spring.io/${repo}/org/springframework/boot/spring-boot-cli/${project.version}/spring-boot-cli-${project.version}-bin.tar.gz'
version '${project.version}'
sha256 '${checksum}'
sha256 '${hash}'
head 'https://github.com/spring-projects/spring-boot.git'
if build.head?

View File

@@ -42,8 +42,8 @@ public class SpringBootDependenciesDependencyManagement extends MavenModelDepend
modelProcessor.setModelReader(new DefaultModelReader());
try {
return modelProcessor.read(
SpringBootDependenciesDependencyManagement.class.getResourceAsStream("effective-pom.xml"), null);
return modelProcessor.read(SpringBootDependenciesDependencyManagement.class
.getResourceAsStream("spring-boot-dependencies-effective-bom.xml"), null);
}
catch (IOException ex) {
throw new IllegalStateException("Failed to build model from effective pom", ex);

View File

@@ -17,7 +17,6 @@
package org.springframework.boot.cli.compiler.maven;
import java.io.File;
import java.lang.reflect.Field;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.building.DefaultSettingsBuilderFactory;
@@ -83,21 +82,7 @@ public class MavenSettingsReader {
}
private SettingsDecrypter createSettingsDecrypter() {
SettingsDecrypter settingsDecrypter = new DefaultSettingsDecrypter();
setField(DefaultSettingsDecrypter.class, "securityDispatcher", settingsDecrypter,
new SpringBootSecDispatcher());
return settingsDecrypter;
}
private void setField(Class<?> sourceClass, String fieldName, Object target, Object value) {
try {
Field field = sourceClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(target, value);
}
catch (Exception ex) {
throw new IllegalStateException("Failed to set field '" + fieldName + "' on '" + target + "'", ex);
}
return new DefaultSettingsDecrypter(new SpringBootSecDispatcher());
}
private class SpringBootSecDispatcher extends DefaultSecDispatcher {

View File

@@ -1,11 +1,11 @@
{
"homepage": "https://projects.spring.io/spring-boot/",
"version": "${scoop-version}",
"version": "${scoopVersion}",
"license": "Apache 2.0",
"hash": "${hash}",
"url": "https://repo.spring.io/${repo}/org/springframework/boot/spring-boot-cli/${project.version}/spring-boot-cli-${project.version}-bin.zip",
"extract_dir": "spring-${project.version}",
"bin": "bin\\spring.bat",
"bin": "bin\\\\spring.bat",
"suggest": {
"JDK": [
"java/oraclejdk",
@@ -14,13 +14,13 @@
},
"checkver": {
"github": "https://github.com/spring-projects/spring-boot",
"re": "/releases/tag/(?:v)?(2[\\d.]+)\\.RELEASE"
"re": "/releases/tag/(?:v)?(2[\\d.]+)\\\\.RELEASE"
},
"autoupdate": {
"url": "https://repo.spring.io/release/org/springframework/boot/spring-boot-cli/$version.RELEASE/spring-boot-cli-$version.RELEASE-bin.zip",
"extract_dir": "spring-$version.RELEASE",
"url": "https://repo.spring.io/release/org/springframework/boot/spring-boot-cli/\$version.RELEASE/spring-boot-cli-\$version.RELEASE-bin.zip",
"extract_dir": "spring-\$version.RELEASE",
"hash": {
"url": "$url.sha256"
"url": "\$url.sha256"
}
}
}

View File

@@ -96,12 +96,14 @@ public class CliTester implements BeforeEachCallback, AfterEachCallback {
for (String arg : args) {
if (arg.startsWith("--classpath=")) {
arg = arg + ":" + this.buildOutput.getTestClassesLocation().getAbsolutePath();
arg = arg + ":" + this.buildOutput.getTestResourcesLocation().getAbsolutePath();
classpathUpdated = true;
}
updatedArgs.add(arg);
}
if (!classpathUpdated) {
updatedArgs.add("--classpath=.:" + this.buildOutput.getTestClassesLocation().getAbsolutePath());
updatedArgs.add("--classpath=.:" + this.buildOutput.getTestClassesLocation().getAbsolutePath() + ":"
+ this.buildOutput.getTestResourcesLocation().getAbsolutePath());
}
Future<RunCommand> future = submitCommand(new RunCommand(), StringUtils.toStringArray(updatedArgs));
this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS));
@@ -134,6 +136,8 @@ public class CliTester implements BeforeEachCallback, AfterEachCallback {
"org.springframework.boot.cli.CliTesterSpringApplication");
this.serverPortFile = new File(this.temp, "server.port");
System.setProperty("portfile", this.serverPortFile.getAbsolutePath());
String userHome = System.getProperty("user.home");
System.setProperty("user.home", "src/test/resources/cli-tester");
try {
command.run(sources);
return command;
@@ -142,6 +146,7 @@ public class CliTester implements BeforeEachCallback, AfterEachCallback {
System.clearProperty("server.port");
System.clearProperty("spring.application.class.name");
System.clearProperty("portfile");
System.setProperty("user.home", userHome);
Thread.currentThread().setContextClassLoader(loader);
}
});

View File

@@ -57,15 +57,12 @@ class GrabCommandIntegrationTests {
@Test
void grab() throws Exception {
System.setProperty("grape.root", this.cli.getTemp().getAbsolutePath());
System.setProperty("groovy.grape.report.downloads", "true");
// Use --autoconfigure=false to limit the amount of downloaded dependencies
String output = this.cli.grab("grab.groovy", "--autoconfigure=false");
assertThat(new File(this.cli.getTemp(), "repository/joda-time/joda-time")).isDirectory();
// Should be resolved from local repository cache
assertThat(output.contains("Downloading: file:")).isTrue();
assertThat(output).contains("Downloading: ");
}
@Test

View File

@@ -42,7 +42,7 @@ class RunCommandIntegrationTests {
CliTester cli;
RunCommandIntegrationTests(CapturedOutput output) {
this.cli = new CliTester("src/it/resources/run-command/", output);
this.cli = new CliTester("src/test/resources/run-command/", output);
}
private Properties systemProperties = new Properties();

View File

@@ -19,7 +19,6 @@ package org.springframework.boot.cli.compiler.dependencies;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.empty;
/**
* Tests for {@link SpringBootDependenciesDependencyManagement}
@@ -45,7 +44,7 @@ class SpringBootDependenciesDependencyManagementTests {
@Test
void getDependencies() {
assertThat(this.dependencyManagement.getDependencies()).isNotEqualTo(empty());
assertThat(this.dependencyManagement.getDependencies()).isNotEmpty();
}
}

View File

@@ -47,9 +47,12 @@ class AetherGrapeEngineTests {
private final GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
private final RepositoryConfiguration springMilestones = new RepositoryConfiguration("spring-milestones",
private final RepositoryConfiguration springMilestone = new RepositoryConfiguration("spring-milestone",
URI.create("https://repo.spring.io/milestone"), false);
private final RepositoryConfiguration springSnaphot = new RepositoryConfiguration("spring-snapshot",
URI.create("https://repo.spring.io/snapshot"), true);
private AetherGrapeEngine createGrapeEngine(RepositoryConfiguration... additionalRepositories) {
List<RepositoryConfiguration> repositoryConfigurations = new ArrayList<>();
repositoryConfigurations
@@ -64,7 +67,7 @@ class AetherGrapeEngineTests {
@Test
void dependencyResolution() {
Map<String, Object> args = new HashMap<>();
createGrapeEngine(this.springMilestones).grab(args,
createGrapeEngine(this.springMilestone, this.springSnaphot).grab(args,
createDependency("org.springframework", "spring-jdbc", null));
assertThat(this.groovyClassLoader.getURLs()).hasSize(5);
}
@@ -104,7 +107,7 @@ class AetherGrapeEngineTests {
Map<String, Object> args = new HashMap<>();
args.put("excludes", Arrays.asList(createExclusion("org.springframework", "spring-core")));
createGrapeEngine(this.springMilestones).grab(args,
createGrapeEngine(this.springMilestone, this.springSnaphot).grab(args,
createDependency("org.springframework", "spring-jdbc", "3.2.4.RELEASE"),
createDependency("org.springframework", "spring-beans", "3.2.4.RELEASE"));
@@ -126,7 +129,7 @@ class AetherGrapeEngineTests {
GroovyClassLoader customClassLoader = new GroovyClassLoader();
args.put("classLoader", customClassLoader);
createGrapeEngine(this.springMilestones).grab(args,
createGrapeEngine(this.springMilestone, this.springSnaphot).grab(args,
createDependency("org.springframework", "spring-jdbc", null));
assertThat(this.groovyClassLoader.getURLs()).isEmpty();

View File

@@ -2,7 +2,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>build/local-m2-repository</localRepository>
<mirrors>
<mirror>
<id>central-mirror</id>
@@ -10,7 +10,6 @@
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
<servers>
<server>
<id>central-mirror</id>
@@ -18,7 +17,6 @@
<password>password</password>
</server>
</servers>
<proxies>
<proxy>
<active>true</active>
@@ -29,5 +27,4 @@
<password>password</password>
</proxy>
</proxies>
</settings>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<localRepository>build/local-m2-repository</localRepository>
<profiles>
<profile>
<id>cli-test-repo</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>local.central</id>
<url>file:build/test-repository</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshot</id>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestone</id>
<url>https://repo.spring.io/milestone</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
</settings>

View File

@@ -0,0 +1,10 @@
package org.test
@Component
class Example implements CommandLineRunner {
void run(String... args) {
print "Ssshh"
}
}