diff --git a/README.adoc b/README.adoc index ffbfdb3d5da..d4ff285819e 100755 --- a/README.adoc +++ b/README.adoc @@ -125,12 +125,6 @@ For example, if you want to get started using Spring and JPA for database access -=== spring-boot-cli -The Spring command-line application compiles and runs Groovy source, allowing you to write the absolute minimum amount of code to get an application running. -Spring CLI can also watch files, automatically recompiling and restarting when they change. - - - === spring-boot-actuator Actuator endpoints let you monitor and interact with your application. Spring Boot Actuator provides the infrastructure required for actuator endpoints. @@ -170,12 +164,6 @@ Developer tools are automatically disabled when running a fully packaged applica -== Samples -Groovy samples for use with the command line application are available in link:spring-boot-project/spring-boot-cli/samples[spring-boot-cli/samples]. -To run the CLI samples, type `spring run .groovy` from the samples directory. - - - == Guides The https://spring.io/[spring.io] site contains several guides that show how to use Spring Boot step-by-step: diff --git a/spring-boot-project/spring-boot-cli/build.gradle b/spring-boot-project/spring-boot-cli/build.gradle index 1cc9bcf7193..421895f7739 100644 --- a/spring-boot-project/spring-boot-cli/build.gradle +++ b/spring-boot-project/spring-boot-cli/build.gradle @@ -18,9 +18,6 @@ configurations { dependencies { compileOnlyProject(project(":spring-boot-project:spring-boot")) - compileOnly("jakarta.servlet:jakarta.servlet-api") - compileOnly("org.apache.groovy:groovy-templates") - compileOnly("org.springframework:spring-web") dependenciesBom(project(path: ":spring-boot-project:spring-boot-dependencies", configuration: "effectiveBom")) @@ -31,30 +28,10 @@ dependencies { implementation("org.apache.httpcomponents:httpclient") { exclude group: "commons-logging", module: "commons-logging" } - implementation("org.apache.maven:maven-model") - implementation("org.apache.maven:maven-resolver-provider") { - exclude group: "com.google.guava", module: "guava" - exclude group: "javax.inject", module: "javax.inject" - } - implementation("org.apache.maven.resolver:maven-resolver-connector-basic") - implementation("org.apache.maven.resolver:maven-resolver-transport-file") - implementation("org.apache.maven.resolver:maven-resolver-transport-http") { - exclude group: "org.slf4j", module: "jcl-over-slf4j" - } - implementation("org.apache.maven:maven-settings-builder") { - exclude group: "javax.inject", module: "javax.inject" - } - implementation("org.apache.groovy:groovy") implementation("org.slf4j:slf4j-simple") - implementation("org.sonatype.plexus:plexus-sec-dispatcher") - implementation("org.sonatype.sisu:sisu-inject-plexus") { - exclude group: "javax.enterprise", module: "cdi-api" - exclude group: "org.sonatype.sisu", module: "sisu-inject-bean" - } implementation("org.springframework:spring-core") implementation("org.springframework.security:spring-security-crypto") - intTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-loader-tools")) intTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) intTestImplementation("org.assertj:assertj-core") intTestImplementation("org.junit.jupiter:junit-jupiter") @@ -62,47 +39,14 @@ dependencies { loader(project(":spring-boot-project:spring-boot-tools:spring-boot-loader")) - testCompileOnly("org.apache.tomcat.embed:tomcat-embed-core") testImplementation(project(":spring-boot-project:spring-boot")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) testImplementation(project(":spring-boot-project:spring-boot-test")) testImplementation("org.assertj:assertj-core") - testImplementation("org.apache.groovy:groovy-templates") testImplementation("org.junit.jupiter:junit-jupiter") testImplementation("org.mockito:mockito-core") testImplementation("org.mockito:mockito-junit-jupiter") testImplementation("org.springframework:spring-test") - - testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-actuator", configuration: "mavenRepository")) - testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-amqp", configuration: "mavenRepository")) - testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-aop", configuration: "mavenRepository")) - testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-artemis", configuration: "mavenRepository")) - testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-batch", configuration: "mavenRepository")) - testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-data-jpa", configuration: "mavenRepository")) - testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-jdbc", configuration: "mavenRepository")) - testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-integration", configuration: "mavenRepository")) - testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-security", configuration: "mavenRepository")) - testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-web", configuration: "mavenRepository")) -} - -task syncSpringBootDependenciesBom(type: Sync) { - destinationDir = file("${buildDir}/generated-resources/org/springframework/boot/cli/compiler/dependencies") - from configurations.dependenciesBom -} - -task syncTestRepository(type: Sync) { - destinationDir = file("${buildDir}/test-repository") - from configurations.testRepository -} - -sourceSets { - main { - output.dir("${buildDir}/generated-resources", builtBy: "syncSpringBootDependenciesBom") - } -} - -test { - dependsOn syncTestRepository } task fullJar(type: Jar) { @@ -124,7 +68,6 @@ task fullJar(type: Jar) { } manifest { attributes( - "Class-Loader": "groovy.lang.GroovyClassLoader", "Main-Class": "org.springframework.boot.loader.JarLauncher", "Start-Class": "org.springframework.boot.cli.SpringCli" ) @@ -155,7 +98,7 @@ task zip(type: Zip) { } intTest { - dependsOn syncTestRepository, zip + dependsOn zip } task tar(type: Tar) { diff --git a/spring-boot-project/spring-boot-cli/samples/actuator.groovy b/spring-boot-project/spring-boot-cli/samples/actuator.groovy deleted file mode 100644 index ffad280f9da..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/actuator.groovy +++ /dev/null @@ -1,12 +0,0 @@ -package org.test - -@Grab("spring-boot-starter-actuator") - -@RestController -class SampleController { - - @RequestMapping("/") - public def hello() { - [message: "Hello World!"] - } -} diff --git a/spring-boot-project/spring-boot-cli/samples/app.groovy b/spring-boot-project/spring-boot-cli/samples/app.groovy deleted file mode 100644 index f273c49434a..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/app.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package org.test - -@Component -class Example implements CommandLineRunner { - - @Autowired - private MyService myService - - void run(String... args) { - println "Hello ${this.myService.sayWorld()} From ${getClass().getClassLoader().getResource('samples/app.groovy')}" - } -} - - -@Service -class MyService { - - String sayWorld() { - return "World!" - } -} - - diff --git a/spring-boot-project/spring-boot-cli/samples/beans.groovy b/spring-boot-project/spring-boot-cli/samples/beans.groovy deleted file mode 100644 index 4fbf427876b..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/beans.groovy +++ /dev/null @@ -1,15 +0,0 @@ -@RestController -class Application { - - @Autowired - String foo - - @RequestMapping("/") - String home() { - "Hello ${foo}!" - } -} - -beans { - foo String, "World" -} diff --git a/spring-boot-project/spring-boot-cli/samples/caching.groovy b/spring-boot-project/spring-boot-cli/samples/caching.groovy deleted file mode 100644 index c826f56e722..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/caching.groovy +++ /dev/null @@ -1,47 +0,0 @@ -package org.test - -import java.util.concurrent.atomic.AtomicLong - -@Configuration(proxyBeanMethods = false) -@EnableCaching -class Sample { - - @Bean CacheManager cacheManager() { - new ConcurrentMapCacheManager() - } - - @Component - static class MyClient implements CommandLineRunner { - - private final MyService myService - - @Autowired - MyClient(MyService myService) { - this.myService = myService - } - - void run(String... args) { - long counter = myService.get('someKey') - long counter2 = myService.get('someKey') - if (counter == counter2) { - println 'Hello World' - } else { - println 'Something went wrong with the cache setup' - } - - } - } - - @Component - static class MyService { - - private final AtomicLong counter = new AtomicLong() - - @Cacheable('foo') - Long get(String id) { - return counter.getAndIncrement() - } - - } - -} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-cli/samples/http.groovy b/spring-boot-project/spring-boot-cli/samples/http.groovy deleted file mode 100644 index 0f87b29098a..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/http.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package org.test - -import org.springframework.web.client.RestTemplate; - -@Controller -class Example implements CommandLineRunner { - - @Autowired - ApplicationContext context - - @RequestMapping("/") - @ResponseBody - public String helloWorld() { - return "World!" - } - - void run(String... args) { - def port = context.webServer.port - def world = new RestTemplate().getForObject("http://localhost:" + port + "/", String.class); - print "Hello " + world - } - -} diff --git a/spring-boot-project/spring-boot-cli/samples/integration.groovy b/spring-boot-project/spring-boot-cli/samples/integration.groovy deleted file mode 100644 index 62a54dd73f2..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/integration.groovy +++ /dev/null @@ -1,39 +0,0 @@ -package org.test - -@Configuration -@EnableIntegration -class SpringIntegrationExample implements CommandLineRunner { - - @Autowired - private ApplicationContext context - - @Bean - DirectChannel input() { - new DirectChannel() - } - - @Override - void run(String... args) { - println() - println '>>>> ' + new MessagingTemplate(input()).convertSendAndReceive("World", String) + ' <<<<' - println() - /* - * Since this is a simple application that we want to exit right away, - * close the context. For an active integration application, with pollers - * etc, you can either suspend the main thread here (e.g. with System.in.read()), - * or exit the run() method without closing the context, and stop the - * application later using some other technique (kill, JMX etc). - */ - context.close() - } -} - -@MessageEndpoint -class HelloTransformer { - - @Transformer(inputChannel="input") - String transform(String payload) { - "Hello, ${payload}" - } - -} diff --git a/spring-boot-project/spring-boot-cli/samples/jms.groovy b/spring-boot-project/spring-boot-cli/samples/jms.groovy deleted file mode 100644 index 42ab364a659..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/jms.groovy +++ /dev/null @@ -1,33 +0,0 @@ -package org.test - -@Grab("spring-boot-starter-artemis") -@Grab("artemis-jakarta-server") -import java.util.concurrent.CountDownLatch - -@Log -@Configuration(proxyBeanMethods = false) -@EnableJms -class JmsExample implements CommandLineRunner { - - private CountDownLatch latch = new CountDownLatch(1) - - @Autowired - JmsTemplate jmsTemplate - - void run(String... args) { - def messageCreator = { session -> - session.createObjectMessage("Greetings from Spring Boot via Artemis") - } as MessageCreator - log.info "Sending JMS message..." - jmsTemplate.send("spring-boot", messageCreator) - log.info "Send JMS message, waiting..." - latch.await() - } - - @JmsListener(destination = 'spring-boot') - def receive(String message) { - log.info "Received ${message}" - latch.countDown() - } - -} diff --git a/spring-boot-project/spring-boot-cli/samples/job.groovy b/spring-boot-project/spring-boot-cli/samples/job.groovy deleted file mode 100644 index 04c0777ebc5..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/job.groovy +++ /dev/null @@ -1,38 +0,0 @@ -package org.test - -import org.springframework.transaction.TransactionManager - -@Grab("hsqldb") -@Configuration(proxyBeanMethods = false) -@EnableBatchProcessing -class JobConfig { - - @Autowired - private JobBuilderFactory jobs - - @Autowired - private StepBuilderFactory steps - - @Autowired - private TransactionManager transactionManager - - @Bean - protected Tasklet tasklet() { - return new Tasklet() { - @Override - RepeatStatus execute(StepContribution contribution, ChunkContext context) { - return RepeatStatus.FINISHED - } - } - } - - @Bean - Job job() throws Exception { - return jobs.get("job").start(step1()).build() - } - - @Bean - protected Step step1() throws Exception { - return steps.get("step1").tasklet(tasklet()).transactionManager(this.transactionManager).build() - } -} diff --git a/spring-boot-project/spring-boot-cli/samples/rabbit.groovy b/spring-boot-project/spring-boot-cli/samples/rabbit.groovy deleted file mode 100644 index 82757ddb3ab..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/rabbit.groovy +++ /dev/null @@ -1,32 +0,0 @@ -package org.test - -import java.util.concurrent.CountDownLatch - -@Log -@Configuration(proxyBeanMethods = false) -@EnableRabbit -class RabbitExample implements CommandLineRunner { - - private CountDownLatch latch = new CountDownLatch(1) - - @Autowired - RabbitTemplate rabbitTemplate - - void run(String... args) { - log.info "Sending RabbitMQ message..." - rabbitTemplate.convertAndSend("spring-boot", "Greetings from Spring Boot via RabbitMQ") - latch.await() - } - - @RabbitListener(queues = 'spring-boot') - def receive(String message) { - log.info "Received ${message}" - latch.countDown() - } - - @Bean - org.springframework.amqp.core.Queue queue() { - new org.springframework.amqp.core.Queue("spring-boot", false) - } - -} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-cli/samples/retry.groovy b/spring-boot-project/spring-boot-cli/samples/retry.groovy deleted file mode 100644 index 3aa5c5e5a02..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/retry.groovy +++ /dev/null @@ -1,28 +0,0 @@ -package org.test - -@EnableRetry -@Component -class Example implements CommandLineRunner { - - @Autowired - private MyService myService - - void run(String... args) { - println "Hello ${this.myService.sayWorld()} From ${getClass().getClassLoader().getResource('samples/retry.groovy')}" - } -} - - -@Service -class MyService { - - static int count = 0 - - @Retryable - String sayWorld() { - if (count++==0) { - throw new IllegalStateException("Planned") - } - return "World!" - } -} diff --git a/spring-boot-project/spring-boot-cli/samples/runner.groovy b/spring-boot-project/spring-boot-cli/samples/runner.groovy deleted file mode 100644 index 0fc79fa310a..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/runner.groovy +++ /dev/null @@ -1,8 +0,0 @@ -package org.test - -class Runner implements CommandLineRunner { - - void run(String... args) { - print "Hello World!" - } -} diff --git a/spring-boot-project/spring-boot-cli/samples/runner.xml b/spring-boot-project/spring-boot-cli/samples/runner.xml deleted file mode 100644 index ac4fb0599e1..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/runner.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/spring-boot-project/spring-boot-cli/samples/secure.groovy b/spring-boot-project/spring-boot-cli/samples/secure.groovy deleted file mode 100644 index 6615bc144ff..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/secure.groovy +++ /dev/null @@ -1,13 +0,0 @@ -package org.test - -@Grab("spring-boot-starter-security") -@Grab("spring-boot-starter-actuator") - -@RestController -class SampleController { - - @RequestMapping("/") - public def hello() { - [message: "Hello World!"] - } -} diff --git a/spring-boot-project/spring-boot-cli/samples/template.groovy b/spring-boot-project/spring-boot-cli/samples/template.groovy deleted file mode 100644 index 95f8b134bc1..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/template.groovy +++ /dev/null @@ -1,24 +0,0 @@ -package org.test - -import static org.springframework.boot.groovy.GroovyTemplate.* - -@Component -class Example implements CommandLineRunner { - - @Autowired - private MyService myService - - @Override - void run(String... args) { - print template("test.txt", ["message":myService.sayWorld()]) - } -} - - -@Service -class MyService { - - String sayWorld() { - return "World" - } -} diff --git a/spring-boot-project/spring-boot-cli/samples/tx.groovy b/spring-boot-project/spring-boot-cli/samples/tx.groovy deleted file mode 100644 index 08c5af019c6..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/tx.groovy +++ /dev/null @@ -1,17 +0,0 @@ -package org.test - -@Grab("hsqldb") - -@Configuration(proxyBeanMethods = false) -@EnableTransactionManagement -class Example implements CommandLineRunner { - - @Autowired - JdbcTemplate jdbcTemplate - - @Transactional - void run(String... args) { - println "Foo count=" + jdbcTemplate.queryForObject("SELECT COUNT(*) from FOO", Integer) - } -} - diff --git a/spring-boot-project/spring-boot-cli/samples/ui.groovy b/spring-boot-project/spring-boot-cli/samples/ui.groovy deleted file mode 100644 index e5a04e630f6..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/ui.groovy +++ /dev/null @@ -1,12 +0,0 @@ -package app - -@Grab("thymeleaf-spring6") -@Controller -class Example { - - @RequestMapping("/") - public String helloWorld(Map model) { - model.putAll([title: "My Page", date: new Date(), message: "Hello World"]) - return "home" - } -} diff --git a/spring-boot-project/spring-boot-cli/samples/web.groovy b/spring-boot-project/spring-boot-cli/samples/web.groovy deleted file mode 100644 index 4af8649eec6..00000000000 --- a/spring-boot-project/spring-boot-cli/samples/web.groovy +++ /dev/null @@ -1,21 +0,0 @@ -@Controller -class Example { - - @Autowired - private MyService myService - - @RequestMapping("/") - @ResponseBody - public String helloWorld() { - return myService.sayWorld() - } - -} - -@Service -class MyService { - - public String sayWorld() { - return "World!" - } -} diff --git a/spring-boot-project/spring-boot-cli/src/intTest/java/org/springframework/boot/cli/CommandLineIT.java b/spring-boot-project/spring-boot-cli/src/intTest/java/org/springframework/boot/cli/CommandLineIT.java index c35c03d1ed2..f58de97ba85 100644 --- a/spring-boot-project/spring-boot-cli/src/intTest/java/org/springframework/boot/cli/CommandLineIT.java +++ b/spring-boot-project/spring-boot-cli/src/intTest/java/org/springframework/boot/cli/CommandLineIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 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. @@ -48,7 +48,7 @@ class CommandLineIT { Invocation cli = this.cli.invoke("hint"); assertThat(cli.await()).isEqualTo(0); assertThat(cli.getErrorOutput()).isEmpty(); - assertThat(cli.getStandardOutputLines()).hasSize(11); + assertThat(cli.getStandardOutputLines()).hasSize(5); } @Test diff --git a/spring-boot-project/spring-boot-cli/src/intTest/java/org/springframework/boot/cli/JarCommandIT.java b/spring-boot-project/spring-boot-cli/src/intTest/java/org/springframework/boot/cli/JarCommandIT.java deleted file mode 100644 index 5bb7857eadd..00000000000 --- a/spring-boot-project/spring-boot-cli/src/intTest/java/org/springframework/boot/cli/JarCommandIT.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli; - -import java.io.File; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -import org.springframework.boot.cli.command.archive.JarCommand; -import org.springframework.boot.cli.infrastructure.CommandLineInvoker; -import org.springframework.boot.cli.infrastructure.CommandLineInvoker.Invocation; -import org.springframework.boot.loader.tools.JavaExecutable; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test for {@link JarCommand}. - * - * @author Andy Wilkinson - * @author Stephane Nicoll - */ -class JarCommandIT { - - private static final boolean JAVA_9_OR_LATER = isClassPresent("java.security.cert.URICertStoreParameters"); - - private CommandLineInvoker cli; - - private File tempDir; - - @BeforeEach - void setup(@TempDir File tempDir) { - this.cli = new CommandLineInvoker(new File("src/intTest/resources/jar-command"), tempDir); - this.tempDir = tempDir; - } - - @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"); - } - - @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"); - } - - @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.await(); - if (!JAVA_9_OR_LATER) { - assertThat(invocation.getErrorOutput()).isEqualTo(""); - } - invocation = this.cli.invoke("jar", jar.getAbsolutePath(), "bad.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(""); - } - } - - @Test - void jarCreation() throws Exception { - File jar = new File(this.tempDir, "test-app.jar"); - 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) { - 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") - .doesNotContain("/resources/resource.txt").contains("/static/static.txt") - .contains("/templates/template.txt").contains("Goodbye Mama"); - } - - private static boolean isClassPresent(String name) { - try { - Class.forName(name); - return true; - } - catch (Exception ex) { - return false; - } - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/intTest/java/org/springframework/boot/cli/WarCommandIT.java b/spring-boot-project/spring-boot-cli/src/intTest/java/org/springframework/boot/cli/WarCommandIT.java deleted file mode 100644 index 7571af5f2a9..00000000000 --- a/spring-boot-project/spring-boot-cli/src/intTest/java/org/springframework/boot/cli/WarCommandIT.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli; - -import java.io.File; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -import org.springframework.boot.cli.command.archive.WarCommand; -import org.springframework.boot.cli.infrastructure.CommandLineInvoker; -import org.springframework.boot.cli.infrastructure.CommandLineInvoker.Invocation; -import org.springframework.boot.loader.tools.JavaExecutable; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test for {@link WarCommand}. - * - * @author Andrey Stolyarov - * @author Henri Kerola - */ -class WarCommandIT { - - private CommandLineInvoker cli; - - private File tempDir; - - @BeforeEach - void setup(@TempDir File tempDir) { - this.cli = new CommandLineInvoker(new File("src/intTest/resources/war-command"), tempDir); - this.tempDir = tempDir; - } - - @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.await(); - assertThat(war.exists()).isTrue(); - 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/classes!/root.properties"); - process.destroy(); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/bad.groovy b/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/bad.groovy deleted file mode 100644 index 3118a10e0f8..00000000000 --- a/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/bad.groovy +++ /dev/null @@ -1,6 +0,0 @@ -@GrabResolver(name='clojars.org', root='https://clojars.org/repo') -@Grab('redis.embedded:embedded-redis:0.2') - -@Component -class EmbeddedRedis { -} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/jar.groovy b/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/jar.groovy deleted file mode 100644 index 1f385b4f33e..00000000000 --- a/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/jar.groovy +++ /dev/null @@ -1,27 +0,0 @@ -package org.test - -@EnableGroovyTemplates -@Component -class Example implements CommandLineRunner { - - @Autowired - private MyService myService - - void run(String... args) { - println "Hello ${this.myService.sayWorld()}" - println getClass().getResource('/public/public.txt') - println getClass().getResource('/resources/resource.txt') - println getClass().getResource('/static/static.txt') - println getClass().getResource('/templates/template.txt') - println getClass().getResource('/root.properties') - println template('template.txt', [world:'Mama']) - } -} - -@Service -class MyService { - - String sayWorld() { - return 'World!' - } -} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/public/public.txt b/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/public/public.txt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/resources/resource.txt b/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/resources/resource.txt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/root.properties b/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/root.properties deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/static/static.txt b/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/static/static.txt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/templates/template.txt b/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/templates/template.txt deleted file mode 100644 index ce65c33affd..00000000000 --- a/spring-boot-project/spring-boot-cli/src/intTest/resources/jar-command/templates/template.txt +++ /dev/null @@ -1 +0,0 @@ -Goodbye ${world} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-cli/src/intTest/resources/run-command/quiet.groovy b/spring-boot-project/spring-boot-cli/src/intTest/resources/run-command/quiet.groovy deleted file mode 100644 index 32640370e1a..00000000000 --- a/spring-boot-project/spring-boot-cli/src/intTest/resources/run-command/quiet.groovy +++ /dev/null @@ -1,10 +0,0 @@ -package org.test - -@Component -class Example implements CommandLineRunner { - - void run(String... args) { - print "Ssshh" - } - -} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-cli/src/intTest/resources/war-command/root.properties b/spring-boot-project/spring-boot-cli/src/intTest/resources/war-command/root.properties deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/spring-boot-project/spring-boot-cli/src/intTest/resources/war-command/war.groovy b/spring-boot-project/spring-boot-cli/src/intTest/resources/war-command/war.groovy deleted file mode 100644 index b1a4c75cf20..00000000000 --- a/spring-boot-project/spring-boot-cli/src/intTest/resources/war-command/war.groovy +++ /dev/null @@ -1,17 +0,0 @@ -package org.test - -@RestController -class WarExample implements CommandLineRunner { - - @RequestMapping("/") - public String hello() { - return "Hello" - } - - void run(String... args) { - println getClass().getResource('/org/apache/tomcat/InstanceManager.class') - println getClass().getResource('/root.properties') - throw new RuntimeException("onStart error") - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/DefaultCommandFactory.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/DefaultCommandFactory.java index f730b2ca47a..f4b18b86b58 100644 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/DefaultCommandFactory.java +++ b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/DefaultCommandFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 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. @@ -23,15 +23,9 @@ import java.util.List; import org.springframework.boot.cli.command.Command; import org.springframework.boot.cli.command.CommandFactory; -import org.springframework.boot.cli.command.archive.JarCommand; -import org.springframework.boot.cli.command.archive.WarCommand; import org.springframework.boot.cli.command.core.VersionCommand; import org.springframework.boot.cli.command.encodepassword.EncodePasswordCommand; -import org.springframework.boot.cli.command.grab.GrabCommand; import org.springframework.boot.cli.command.init.InitCommand; -import org.springframework.boot.cli.command.install.InstallCommand; -import org.springframework.boot.cli.command.install.UninstallCommand; -import org.springframework.boot.cli.command.run.RunCommand; /** * Default implementation of {@link CommandFactory}. @@ -46,12 +40,6 @@ public class DefaultCommandFactory implements CommandFactory { static { List defaultCommands = new ArrayList<>(); defaultCommands.add(new VersionCommand()); - defaultCommands.add(new RunCommand()); - defaultCommands.add(new GrabCommand()); - defaultCommands.add(new JarCommand()); - defaultCommands.add(new WarCommand()); - defaultCommands.add(new InstallCommand()); - defaultCommands.add(new UninstallCommand()); defaultCommands.add(new InitCommand()); defaultCommands.add(new EncodePasswordCommand()); DEFAULT_COMMANDS = Collections.unmodifiableList(defaultCommands); diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/app/SpringApplicationLauncher.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/app/SpringApplicationLauncher.java deleted file mode 100644 index ade6ad81f62..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/app/SpringApplicationLauncher.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli.app; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; - -/** - * A launcher for {@code SpringApplication} or a {@code SpringApplication} subclass. The - * class that is used can be configured using the System property - * {@code spring.application.class.name} or the {@code SPRING_APPLICATION_CLASS_NAME} - * environment variable. Uses reflection to allow the launching code to exist in a - * separate ClassLoader from the application code. - * - * @author Andy Wilkinson - * @since 1.2.0 - * @see System#getProperty(String) - * @see System#getenv(String) - */ -public class SpringApplicationLauncher { - - private static final String DEFAULT_SPRING_APPLICATION_CLASS = "org.springframework.boot.SpringApplication"; - - private final ClassLoader classLoader; - - /** - * Creates a new launcher that will use the given {@code classLoader} to load the - * configured {@code SpringApplication} class. - * @param classLoader the {@code ClassLoader} to use - */ - public SpringApplicationLauncher(ClassLoader classLoader) { - this.classLoader = classLoader; - } - - /** - * Launches the application created using the given {@code sources}. The application - * is launched with the given {@code args}. - * @param sources the sources for the application - * @param args the args for the application - * @return the application's {@code ApplicationContext} - * @throws Exception if the launch fails - */ - public Object launch(Class[] sources, String[] args) throws Exception { - Map defaultProperties = new HashMap<>(); - defaultProperties.put("spring.groovy.template.check-template-location", "false"); - Class applicationClass = Class.forName(getSpringApplicationClassName(), false, this.classLoader); - Constructor constructor = applicationClass.getDeclaredConstructor(Class[].class); - constructor.setAccessible(true); - Object application = constructor.newInstance((Object) sources); - applicationClass.getMethod("setDefaultProperties", Map.class).invoke(application, defaultProperties); - Method method = applicationClass.getMethod("run", String[].class); - return method.invoke(application, (Object) args); - } - - private String getSpringApplicationClassName() { - String className = System.getProperty("spring.application.class.name"); - if (className == null) { - className = getEnvironmentVariable("SPRING_APPLICATION_CLASS_NAME"); - } - if (className == null) { - className = DEFAULT_SPRING_APPLICATION_CLASS; - } - return className; - } - - protected String getEnvironmentVariable(String name) { - return System.getenv(name); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/app/SpringApplicationWebApplicationInitializer.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/app/SpringApplicationWebApplicationInitializer.java deleted file mode 100644 index 718b08ffc8f..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/app/SpringApplicationWebApplicationInitializer.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.cli.app; - -import java.io.IOException; -import java.io.InputStream; -import java.util.jar.Manifest; - -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; - -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; - -/** - * {@link SpringBootServletInitializer} for CLI packaged WAR files. - * - * @author Phillip Webb - * @since 1.3.0 - */ -public class SpringApplicationWebApplicationInitializer extends SpringBootServletInitializer { - - /** - * The entry containing the source class. - */ - public static final String SOURCE_ENTRY = "Spring-Application-Source-Classes"; - - private String[] sources; - - @Override - public void onStartup(ServletContext servletContext) throws ServletException { - try { - this.sources = getSources(servletContext); - } - catch (IOException ex) { - throw new IllegalStateException(ex); - } - super.onStartup(servletContext); - } - - private String[] getSources(ServletContext servletContext) throws IOException { - Manifest manifest = getManifest(servletContext); - if (manifest == null) { - throw new IllegalStateException("Unable to read manifest"); - } - String sources = manifest.getMainAttributes().getValue(SOURCE_ENTRY); - return sources.split(","); - } - - private Manifest getManifest(ServletContext servletContext) throws IOException { - InputStream stream = servletContext.getResourceAsStream("/META-INF/MANIFEST.MF"); - return (stream != null) ? new Manifest(stream) : null; - } - - @Override - protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { - try { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - Class[] sourceClasses = new Class[this.sources.length]; - for (int i = 0; i < this.sources.length; i++) { - sourceClasses[i] = Class.forName(this.sources[i], false, classLoader); - } - return builder.sources(sourceClasses).properties("spring.groovy.template.check-template-location=false"); - } - catch (Exception ex) { - throw new IllegalStateException(ex); - } - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/app/package-info.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/app/package-info.java deleted file mode 100644 index 75db8024a6e..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/app/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-2019 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. - */ - -/** - * Support classes for CLI applications. - */ -package org.springframework.boot.cli.app; diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/archive/PackagedSpringApplicationLauncher.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/archive/PackagedSpringApplicationLauncher.java deleted file mode 100644 index 3392498cdf1..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/archive/PackagedSpringApplicationLauncher.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli.archive; - -import java.net.URL; -import java.net.URLClassLoader; -import java.util.Enumeration; -import java.util.jar.Attributes; -import java.util.jar.Manifest; - -import org.springframework.boot.cli.app.SpringApplicationLauncher; - -/** - * A launcher for a CLI application that has been compiled and packaged as a jar file. - * - * @author Andy Wilkinson - * @author Phillip Webb - * @since 1.0.0 - */ -public final class PackagedSpringApplicationLauncher { - - /** - * The entry containing the source class. - */ - public static final String SOURCE_ENTRY = "Spring-Application-Source-Classes"; - - /** - * The entry containing the start class. - */ - public static final String START_CLASS_ENTRY = "Start-Class"; - - private PackagedSpringApplicationLauncher() { - } - - private void run(String[] args) throws Exception { - URLClassLoader classLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader(); - new SpringApplicationLauncher(classLoader).launch(getSources(classLoader), args); - } - - private Class[] getSources(URLClassLoader classLoader) throws Exception { - Enumeration urls = classLoader.getResources("META-INF/MANIFEST.MF"); - while (urls.hasMoreElements()) { - URL url = urls.nextElement(); - Manifest manifest = new Manifest(url.openStream()); - if (isCliPackaged(manifest)) { - String sources = manifest.getMainAttributes().getValue(SOURCE_ENTRY); - return loadClasses(classLoader, sources.split(",")); - } - } - throw new IllegalStateException("Cannot locate " + SOURCE_ENTRY + " in MANIFEST.MF"); - } - - private boolean isCliPackaged(Manifest manifest) { - Attributes attributes = manifest.getMainAttributes(); - String startClass = attributes.getValue(START_CLASS_ENTRY); - return getClass().getName().equals(startClass); - } - - private Class[] loadClasses(ClassLoader classLoader, String[] names) throws ClassNotFoundException { - Class[] classes = new Class[names.length]; - for (int i = 0; i < names.length; i++) { - classes[i] = Class.forName(names[i], false, classLoader); - } - return classes; - } - - public static void main(String[] args) throws Exception { - new PackagedSpringApplicationLauncher().run(args); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/archive/package-info.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/archive/package-info.java deleted file mode 100644 index 1f117563650..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/archive/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2012-2019 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. - */ - -/** - * Class that are packaged as part of CLI generated JARs. - * @see org.springframework.boot.cli.command.archive.JarCommand - */ -package org.springframework.boot.cli.archive; diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/ArchiveCommand.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/ArchiveCommand.java deleted file mode 100644 index fb71db4c1a6..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/ArchiveCommand.java +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.command.archive; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.jar.Manifest; - -import groovy.lang.Grab; -import joptsimple.OptionSet; -import joptsimple.OptionSpec; -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.AnnotatedNode; -import org.codehaus.groovy.ast.AnnotationNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.ModuleNode; -import org.codehaus.groovy.ast.expr.ConstantExpression; -import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.transform.ASTTransformation; - -import org.springframework.boot.cli.app.SpringApplicationLauncher; -import org.springframework.boot.cli.archive.PackagedSpringApplicationLauncher; -import org.springframework.boot.cli.command.Command; -import org.springframework.boot.cli.command.OptionParsingCommand; -import org.springframework.boot.cli.command.archive.ResourceMatcher.MatchedResource; -import org.springframework.boot.cli.command.options.CompilerOptionHandler; -import org.springframework.boot.cli.command.options.OptionHandler; -import org.springframework.boot.cli.command.options.OptionSetGroovyCompilerConfiguration; -import org.springframework.boot.cli.command.options.SourceOptions; -import org.springframework.boot.cli.command.status.ExitStatus; -import org.springframework.boot.cli.compiler.GroovyCompiler; -import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration; -import org.springframework.boot.cli.compiler.RepositoryConfigurationFactory; -import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration; -import org.springframework.boot.loader.tools.JarWriter; -import org.springframework.boot.loader.tools.Layout; -import org.springframework.boot.loader.tools.Library; -import org.springframework.boot.loader.tools.LibraryScope; -import org.springframework.boot.loader.tools.Repackager; -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.util.Assert; - -/** - * Abstract {@link Command} to create a self-contained executable archive file from a CLI - * application. - * - * @author Andy Wilkinson - * @author Phillip Webb - * @author Andrey Stolyarov - * @author Henri Kerola - */ -abstract class ArchiveCommand extends OptionParsingCommand { - - protected ArchiveCommand(String name, String description, OptionHandler optionHandler) { - super(name, description, optionHandler); - } - - @Override - public String getUsageHelp() { - return "[options] <" + getName() + "-name> "; - } - - /** - * Abstract base {@link CompilerOptionHandler} for archive commands. - */ - protected abstract static class ArchiveOptionHandler extends CompilerOptionHandler { - - private final String type; - - private final Layout layout; - - private OptionSpec includeOption; - - private OptionSpec excludeOption; - - public ArchiveOptionHandler(String type, Layout layout) { - this.type = type; - this.layout = layout; - } - - protected Layout getLayout() { - return this.layout; - } - - @Override - protected void doOptions() { - this.includeOption = option("include", - "Pattern applied to directories on the classpath to find files to include in the resulting ") - .withRequiredArg().withValuesSeparatedBy(",").defaultsTo(""); - this.excludeOption = option("exclude", "Pattern applied to directories on the classpath to find files to " - + "exclude from the resulting " + this.type).withRequiredArg().withValuesSeparatedBy(",") - .defaultsTo(""); - } - - @Override - protected ExitStatus run(OptionSet options) throws Exception { - List nonOptionArguments = new ArrayList(options.nonOptionArguments()); - Assert.isTrue(nonOptionArguments.size() >= 2, - () -> "The name of the resulting " + this.type + " and at least one source file must be specified"); - - File output = new File((String) nonOptionArguments.remove(0)); - Assert.isTrue(output.getName().toLowerCase(Locale.ENGLISH).endsWith("." + this.type), - () -> "The output '" + output + "' is not a " + this.type.toUpperCase(Locale.ENGLISH) + " file."); - deleteIfExists(output); - - GroovyCompiler compiler = createCompiler(options); - - List classpath = getClassPathUrls(compiler); - List classpathEntries = findMatchingClasspathEntries(classpath, options); - - String[] sources = new SourceOptions(nonOptionArguments).getSourcesArray(); - Class[] compiledClasses = compiler.compile(sources); - - List dependencies = getClassPathUrls(compiler); - dependencies.removeAll(classpath); - - writeJar(output, compiledClasses, classpathEntries, dependencies); - return ExitStatus.OK; - } - - private void deleteIfExists(File file) { - if (file.exists() && !file.delete()) { - throw new IllegalStateException("Failed to delete existing file " + file.getPath()); - } - } - - private GroovyCompiler createCompiler(OptionSet options) { - List repositoryConfiguration = RepositoryConfigurationFactory - .createDefaultRepositoryConfiguration(); - GroovyCompilerConfiguration configuration = new OptionSetGroovyCompilerConfiguration(options, this, - repositoryConfiguration); - GroovyCompiler groovyCompiler = new GroovyCompiler(configuration); - groovyCompiler.getAstTransformations().add(0, new GrabAnnotationTransform()); - return groovyCompiler; - } - - private List getClassPathUrls(GroovyCompiler compiler) { - return new ArrayList<>(Arrays.asList(compiler.getLoader().getURLs())); - } - - private List findMatchingClasspathEntries(List classpath, OptionSet options) - throws IOException { - ResourceMatcher matcher = new ResourceMatcher(options.valuesOf(this.includeOption), - options.valuesOf(this.excludeOption)); - List roots = new ArrayList<>(); - for (URL classpathEntry : classpath) { - roots.add(new File(URI.create(classpathEntry.toString()))); - } - return matcher.find(roots); - } - - private void writeJar(File file, Class[] compiledClasses, List classpathEntries, - List dependencies) throws IOException, URISyntaxException { - final List libraries; - try (JarWriter writer = new JarWriter(file)) { - addManifest(writer, compiledClasses); - addCliClasses(writer); - for (Class compiledClass : compiledClasses) { - addClass(writer, compiledClass); - } - libraries = addClasspathEntries(writer, classpathEntries); - } - libraries.addAll(createLibraries(dependencies)); - Repackager repackager = new Repackager(file); - repackager.setMainClass(PackagedSpringApplicationLauncher.class.getName()); - repackager.repackage((callback) -> { - for (Library library : libraries) { - callback.library(library); - } - }); - } - - private List createLibraries(List dependencies) throws URISyntaxException { - List libraries = new ArrayList<>(); - for (URL dependency : dependencies) { - File file = new File(dependency.toURI()); - libraries.add(new Library(null, file, getLibraryScope(file), null, false, false, true)); - } - return libraries; - } - - private void addManifest(JarWriter writer, Class[] compiledClasses) throws IOException { - Manifest manifest = new Manifest(); - manifest.getMainAttributes().putValue("Manifest-Version", "1.0"); - manifest.getMainAttributes().putValue(PackagedSpringApplicationLauncher.SOURCE_ENTRY, - commaDelimitedClassNames(compiledClasses)); - writer.writeManifest(manifest); - } - - private String commaDelimitedClassNames(Class[] classes) { - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < classes.length; i++) { - if (i != 0) { - builder.append(','); - } - builder.append(classes[i].getName()); - } - return builder.toString(); - } - - protected void addCliClasses(JarWriter writer) throws IOException { - addClass(writer, PackagedSpringApplicationLauncher.class); - addClass(writer, SpringApplicationLauncher.class); - Resource[] resources = new PathMatchingResourcePatternResolver() - .getResources("org/springframework/boot/groovy/**"); - for (Resource resource : resources) { - String url = resource.getURL().toString(); - addResource(writer, resource, url.substring(url.indexOf("org/springframework/boot/groovy/"))); - } - } - - protected final void addClass(JarWriter writer, Class sourceClass) throws IOException { - addClass(writer, sourceClass.getClassLoader(), sourceClass.getName()); - } - - protected final void addClass(JarWriter writer, ClassLoader classLoader, String sourceClass) - throws IOException { - if (classLoader == null) { - classLoader = Thread.currentThread().getContextClassLoader(); - } - String name = sourceClass.replace('.', '/') + ".class"; - InputStream stream = classLoader.getResourceAsStream(name); - writer.writeEntry(this.layout.getClassesLocation() + name, stream); - } - - private void addResource(JarWriter writer, Resource resource, String name) throws IOException { - InputStream stream = resource.getInputStream(); - writer.writeEntry(name, stream); - } - - private List addClasspathEntries(JarWriter writer, List entries) throws IOException { - List libraries = new ArrayList<>(); - for (MatchedResource entry : entries) { - if (entry.isRoot()) { - libraries.add(new Library(null, entry.getFile(), LibraryScope.COMPILE, null, false, false, true)); - } - else { - writeClasspathEntry(writer, entry); - } - } - return libraries; - } - - protected void writeClasspathEntry(JarWriter writer, MatchedResource entry) throws IOException { - writer.writeEntry(entry.getName(), new FileInputStream(entry.getFile())); - } - - protected abstract LibraryScope getLibraryScope(File file); - - } - - /** - * {@link ASTTransformation} to change {@code @Grab} annotation values. - */ - private static class GrabAnnotationTransform implements ASTTransformation { - - @Override - public void visit(ASTNode[] nodes, SourceUnit source) { - for (ASTNode node : nodes) { - if (node instanceof ModuleNode moduleNode) { - visitModule(moduleNode); - } - } - } - - private void visitModule(ModuleNode module) { - for (ClassNode classNode : module.getClasses()) { - AnnotationNode annotation = new AnnotationNode(new ClassNode(Grab.class)); - annotation.addMember("value", new ConstantExpression("groovy")); - classNode.addAnnotation(annotation); - // We only need to do it at most once - break; - } - // Disable the addition of a static initializer that calls Grape.addResolver - // because all the dependencies are local now - disableGrabResolvers(module.getClasses()); - disableGrabResolvers(module.getImports()); - } - - private void disableGrabResolvers(List nodes) { - for (AnnotatedNode classNode : nodes) { - List annotations = classNode.getAnnotations(); - for (AnnotationNode node : new ArrayList<>(annotations)) { - if (node.getClassNode().getNameWithoutPackage().equals("GrabResolver")) { - node.setMember("initClass", new ConstantExpression(false)); - } - } - } - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/JarCommand.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/JarCommand.java deleted file mode 100644 index b6c57904949..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/JarCommand.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.command.archive; - -import java.io.File; - -import org.springframework.boot.cli.command.Command; -import org.springframework.boot.loader.tools.Layouts; -import org.springframework.boot.loader.tools.LibraryScope; - -/** - * {@link Command} to create a self-contained executable jar file from a CLI application. - * - * @author Andy Wilkinson - * @author Phillip Webb - * @since 1.3.0 - */ -public class JarCommand extends ArchiveCommand { - - public JarCommand() { - super("jar", "Create a self-contained executable jar file from a Spring Groovy script", new JarOptionHandler()); - } - - private static final class JarOptionHandler extends ArchiveOptionHandler { - - JarOptionHandler() { - super("jar", new Layouts.Jar()); - } - - @Override - protected LibraryScope getLibraryScope(File file) { - return LibraryScope.COMPILE; - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/ResourceMatcher.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/ResourceMatcher.java deleted file mode 100644 index 5a608629c49..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/ResourceMatcher.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli.command.archive; - -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.FileSystemResource; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.util.AntPathMatcher; -import org.springframework.util.StringUtils; - -/** - * Used to match resources for inclusion in a CLI application's jar file. - * - * @author Andy Wilkinson - */ -class ResourceMatcher { - - private static final String[] DEFAULT_INCLUDES = { "public/**", "resources/**", "static/**", "templates/**", - "META-INF/**", "*" }; - - private static final String[] DEFAULT_EXCLUDES = { ".*", "repository/**", "build/**", "target/**", "**/*.jar", - "**/*.groovy" }; - - private final AntPathMatcher pathMatcher = new AntPathMatcher(); - - private final List includes; - - private final List excludes; - - ResourceMatcher(List includes, List excludes) { - this.includes = getOptions(includes, DEFAULT_INCLUDES); - this.excludes = getOptions(excludes, DEFAULT_EXCLUDES); - } - - List find(List roots) throws IOException { - List matchedResources = new ArrayList<>(); - for (File root : roots) { - if (root.isFile()) { - matchedResources.add(new MatchedResource(root)); - } - else { - matchedResources.addAll(findInDirectory(root)); - } - } - return matchedResources; - } - - private List findInDirectory(File directory) throws IOException { - List matchedResources = new ArrayList<>(); - - PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver( - new DirectoryResourceLoader(directory)); - - for (String include : this.includes) { - for (Resource candidate : resolver.getResources(include)) { - File file = candidate.getFile(); - if (file.isFile()) { - MatchedResource matchedResource = new MatchedResource(directory, file); - if (!isExcluded(matchedResource)) { - matchedResources.add(matchedResource); - } - } - } - } - - return matchedResources; - } - - private boolean isExcluded(MatchedResource matchedResource) { - for (String exclude : this.excludes) { - if (this.pathMatcher.match(exclude, matchedResource.getName())) { - return true; - } - } - return false; - } - - private List getOptions(List values, String[] defaults) { - Set result = new LinkedHashSet<>(); - Set minus = new LinkedHashSet<>(); - boolean deltasFound = false; - for (String value : values) { - if (value.startsWith("+")) { - deltasFound = true; - value = value.substring(1); - result.add(value); - } - else if (value.startsWith("-")) { - deltasFound = true; - value = value.substring(1); - minus.add(value); - } - else if (!value.trim().isEmpty()) { - result.add(value); - } - } - for (String value : defaults) { - if (!minus.contains(value) || !deltasFound) { - result.add(value); - } - } - return new ArrayList<>(result); - } - - /** - * {@link ResourceLoader} to get load resource from a directory. - */ - private static class DirectoryResourceLoader extends DefaultResourceLoader { - - private final File rootDirectory; - - DirectoryResourceLoader(File root) throws MalformedURLException { - super(new DirectoryClassLoader(root)); - this.rootDirectory = root; - } - - @Override - protected Resource getResourceByPath(String path) { - return new FileSystemResource(new File(this.rootDirectory, path)); - } - - } - - /** - * {@link ClassLoader} backed by a directory. - */ - private static class DirectoryClassLoader extends URLClassLoader { - - DirectoryClassLoader(File rootDirectory) throws MalformedURLException { - super(new URL[] { rootDirectory.toURI().toURL() }); - } - - @Override - public Enumeration getResources(String name) throws IOException { - return findResources(name); - } - - @Override - public URL getResource(String name) { - return findResource(name); - } - - } - - /** - * A single matched resource. - */ - public static final class MatchedResource { - - private final File file; - - private final String name; - - private final boolean root; - - private MatchedResource(File file) { - this.name = file.getName(); - this.file = file; - this.root = this.name.endsWith(".jar"); - } - - private MatchedResource(File rootDirectory, File file) { - String filePath = file.getAbsolutePath(); - String rootDirectoryPath = rootDirectory.getAbsolutePath(); - this.name = StringUtils.cleanPath(filePath.substring(rootDirectoryPath.length() + 1)); - this.file = file; - this.root = false; - } - - private MatchedResource(File resourceFile, String path, boolean root) { - this.file = resourceFile; - this.name = path; - this.root = root; - } - - public String getName() { - return this.name; - } - - public File getFile() { - return this.file; - } - - public boolean isRoot() { - return this.root; - } - - @Override - public String toString() { - return this.file.getAbsolutePath(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/WarCommand.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/WarCommand.java deleted file mode 100644 index a10c87acd42..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/WarCommand.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.command.archive; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; - -import org.springframework.boot.cli.command.Command; -import org.springframework.boot.loader.tools.JarWriter; -import org.springframework.boot.loader.tools.Layouts; -import org.springframework.boot.loader.tools.LibraryScope; - -/** - * {@link Command} to create a self-contained executable jar file from a CLI application. - * - * @author Andrey Stolyarov - * @author Phillip Webb - * @author Henri Kerola - * @since 1.3.0 - */ -public class WarCommand extends ArchiveCommand { - - public WarCommand() { - super("war", "Create a self-contained executable war file from a Spring Groovy script", new WarOptionHandler()); - } - - private static final class WarOptionHandler extends ArchiveOptionHandler { - - WarOptionHandler() { - super("war", new Layouts.War()); - } - - @Override - protected LibraryScope getLibraryScope(File file) { - String fileName = file.getName(); - if (fileName.contains("tomcat-embed") || fileName.contains("spring-boot-starter-tomcat")) { - return LibraryScope.PROVIDED; - } - return LibraryScope.COMPILE; - } - - @Override - protected void addCliClasses(JarWriter writer) throws IOException { - addClass(writer, null, "org.springframework.boot.cli.app.SpringApplicationWebApplicationInitializer"); - super.addCliClasses(writer); - } - - @Override - protected void writeClasspathEntry(JarWriter writer, ResourceMatcher.MatchedResource entry) throws IOException { - writer.writeEntry(getLayout().getClassesLocation() + entry.getName(), new FileInputStream(entry.getFile())); - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/package-info.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/package-info.java deleted file mode 100644 index cd252b15434..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/archive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-2019 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. - */ - -/** - * CLI commands for creating jars and wars. - */ -package org.springframework.boot.cli.command.archive; diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/grab/GrabCommand.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/grab/GrabCommand.java deleted file mode 100644 index bcd38abfee4..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/grab/GrabCommand.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.command.grab; - -import java.util.List; - -import joptsimple.OptionSet; - -import org.springframework.boot.cli.command.Command; -import org.springframework.boot.cli.command.OptionParsingCommand; -import org.springframework.boot.cli.command.options.CompilerOptionHandler; -import org.springframework.boot.cli.command.options.OptionSetGroovyCompilerConfiguration; -import org.springframework.boot.cli.command.options.SourceOptions; -import org.springframework.boot.cli.command.status.ExitStatus; -import org.springframework.boot.cli.compiler.GroovyCompiler; -import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration; -import org.springframework.boot.cli.compiler.RepositoryConfigurationFactory; -import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration; - -/** - * {@link Command} to grab the dependencies of one or more Groovy scripts. - * - * @author Andy Wilkinson - * @since 1.0.0 - */ -public class GrabCommand extends OptionParsingCommand { - - public GrabCommand() { - super("grab", "Download a spring groovy script's dependencies to ./repository", new GrabOptionHandler()); - } - - private static final class GrabOptionHandler extends CompilerOptionHandler { - - @Override - protected ExitStatus run(OptionSet options) throws Exception { - SourceOptions sourceOptions = new SourceOptions(options); - List repositoryConfiguration = RepositoryConfigurationFactory - .createDefaultRepositoryConfiguration(); - GroovyCompilerConfiguration configuration = new OptionSetGroovyCompilerConfiguration(options, this, - repositoryConfiguration); - if (System.getProperty("grape.root") == null) { - System.setProperty("grape.root", "."); - } - GroovyCompiler groovyCompiler = new GroovyCompiler(configuration); - groovyCompiler.compile(sourceOptions.getSourcesArray()); - return ExitStatus.OK; - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/grab/package-info.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/grab/package-info.java deleted file mode 100644 index ab72d9cdce0..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/grab/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-2019 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. - */ - -/** - * CLI command for grabbing dependencies. - */ -package org.springframework.boot.cli.command.grab; diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/DependencyResolver.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/DependencyResolver.java deleted file mode 100644 index 16586c3fd98..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/DependencyResolver.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.command.install; - -import java.io.File; -import java.util.List; - -/** - * Resolve artifact identifiers (typically in the form {@literal group:artifact:version}) - * to {@link File}s. - * - * @author Andy Wilkinson - */ -@FunctionalInterface -interface DependencyResolver { - - /** - * Resolves the given {@code artifactIdentifiers}, typically in the form - * "group:artifact:version", and their dependencies. - * @param artifactIdentifiers the artifacts to resolve - * @return the {@code File}s for the resolved artifacts - * @throws Exception if dependency resolution fails - */ - List resolve(List artifactIdentifiers) throws Exception; - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/GroovyGrabDependencyResolver.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/GroovyGrabDependencyResolver.java deleted file mode 100644 index 7a564683161..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/GroovyGrabDependencyResolver.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.command.install; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.codehaus.groovy.control.CompilationFailedException; - -import org.springframework.boot.cli.compiler.GroovyCompiler; -import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration; - -/** - * A {@code DependencyResolver} implemented using Groovy's {@code @Grab}. - * - * @author Dave Syer - * @author Andy Wilkinson - */ -class GroovyGrabDependencyResolver implements DependencyResolver { - - private final GroovyCompilerConfiguration configuration; - - GroovyGrabDependencyResolver(GroovyCompilerConfiguration configuration) { - this.configuration = configuration; - } - - @Override - public List resolve(List artifactIdentifiers) throws CompilationFailedException, IOException { - GroovyCompiler groovyCompiler = new GroovyCompiler(this.configuration); - List artifactFiles = new ArrayList<>(); - if (!artifactIdentifiers.isEmpty()) { - List initialUrls = getClassPathUrls(groovyCompiler); - groovyCompiler.compile(createSources(artifactIdentifiers)); - List artifactUrls = getClassPathUrls(groovyCompiler); - artifactUrls.removeAll(initialUrls); - for (URL artifactUrl : artifactUrls) { - artifactFiles.add(toFile(artifactUrl)); - } - } - return artifactFiles; - } - - private List getClassPathUrls(GroovyCompiler compiler) { - return new ArrayList<>(Arrays.asList(compiler.getLoader().getURLs())); - } - - private String createSources(List artifactIdentifiers) throws IOException { - File file = File.createTempFile("SpringCLIDependency", ".groovy"); - file.deleteOnExit(); - try (OutputStreamWriter stream = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)) { - for (String artifactIdentifier : artifactIdentifiers) { - stream.write("@Grab('" + artifactIdentifier + "')"); - } - // Dummy class to force compiler to do grab - stream.write("class Installer {}"); - } - // Windows paths get tricky unless you work with URI - return file.getAbsoluteFile().toURI().toString(); - } - - private File toFile(URL url) { - try { - return new File(url.toURI()); - } - catch (URISyntaxException ex) { - return new File(url.getPath()); - } - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/InstallCommand.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/InstallCommand.java deleted file mode 100644 index c1036fbad1a..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/InstallCommand.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.command.install; - -import java.util.List; - -import joptsimple.OptionSet; - -import org.springframework.boot.cli.command.Command; -import org.springframework.boot.cli.command.OptionParsingCommand; -import org.springframework.boot.cli.command.options.CompilerOptionHandler; -import org.springframework.boot.cli.command.status.ExitStatus; -import org.springframework.boot.cli.util.Log; -import org.springframework.util.Assert; - -/** - * {@link Command} to install additional dependencies into the CLI. - * - * @author Dave Syer - * @author Andy Wilkinson - * @since 1.2.0 - */ -public class InstallCommand extends OptionParsingCommand { - - public InstallCommand() { - super("install", "Install dependencies to the lib/ext directory", new InstallOptionHandler()); - } - - @Override - public String getUsageHelp() { - return "[options] "; - } - - private static final class InstallOptionHandler extends CompilerOptionHandler { - - @Override - @SuppressWarnings("unchecked") - protected ExitStatus run(OptionSet options) throws Exception { - List args = (List) options.nonOptionArguments(); - Assert.notEmpty(args, - "Please specify at least one dependency, in the form group:artifact:version, to install"); - try { - new Installer(options, this).install(args); - } - catch (Exception ex) { - String message = ex.getMessage(); - Log.error((message != null) ? message : ex.getClass().toString()); - } - return ExitStatus.OK; - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/Installer.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/Installer.java deleted file mode 100644 index cf96a510a40..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/Installer.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.command.install; - -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.util.List; -import java.util.Properties; - -import joptsimple.OptionSet; - -import org.springframework.boot.cli.command.options.CompilerOptionHandler; -import org.springframework.boot.cli.command.options.OptionSetGroovyCompilerConfiguration; -import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration; -import org.springframework.boot.cli.compiler.RepositoryConfigurationFactory; -import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration; -import org.springframework.boot.cli.util.Log; -import org.springframework.util.FileCopyUtils; -import org.springframework.util.SystemPropertyUtils; - -/** - * Shared logic for the {@link InstallCommand} and {@link UninstallCommand}. - * - * @author Andy Wilkinson - */ -class Installer { - - private final DependencyResolver dependencyResolver; - - private final Properties installCounts; - - Installer(OptionSet options, CompilerOptionHandler compilerOptionHandler) throws IOException { - this(new GroovyGrabDependencyResolver(createCompilerConfiguration(options, compilerOptionHandler))); - } - - Installer(DependencyResolver resolver) throws IOException { - this.dependencyResolver = resolver; - this.installCounts = loadInstallCounts(); - } - - private static GroovyCompilerConfiguration createCompilerConfiguration(OptionSet options, - CompilerOptionHandler compilerOptionHandler) { - List repositoryConfiguration = RepositoryConfigurationFactory - .createDefaultRepositoryConfiguration(); - return new OptionSetGroovyCompilerConfiguration(options, compilerOptionHandler, repositoryConfiguration) { - @Override - public boolean isAutoconfigure() { - return false; - } - }; - } - - private Properties loadInstallCounts() throws IOException { - Properties properties = new Properties(); - File installed = getInstalled(); - if (installed.exists()) { - FileReader reader = new FileReader(installed); - properties.load(reader); - reader.close(); - } - return properties; - } - - private void saveInstallCounts() throws IOException { - try (FileWriter writer = new FileWriter(getInstalled())) { - this.installCounts.store(writer, null); - } - } - - void install(List artifactIdentifiers) throws Exception { - File extDirectory = getDefaultExtDirectory(); - extDirectory.mkdirs(); - Log.info("Installing into: " + extDirectory); - List artifactFiles = this.dependencyResolver.resolve(artifactIdentifiers); - for (File artifactFile : artifactFiles) { - int installCount = getInstallCount(artifactFile); - if (installCount == 0) { - FileCopyUtils.copy(artifactFile, new File(extDirectory, artifactFile.getName())); - } - setInstallCount(artifactFile, installCount + 1); - } - saveInstallCounts(); - } - - private int getInstallCount(File file) { - String countString = this.installCounts.getProperty(file.getName()); - if (countString == null) { - return 0; - } - return Integer.parseInt(countString); - } - - private void setInstallCount(File file, int count) { - if (count == 0) { - this.installCounts.remove(file.getName()); - } - else { - this.installCounts.setProperty(file.getName(), Integer.toString(count)); - } - } - - void uninstall(List artifactIdentifiers) throws Exception { - File extDirectory = getDefaultExtDirectory(); - Log.info("Uninstalling from: " + extDirectory); - List artifactFiles = this.dependencyResolver.resolve(artifactIdentifiers); - for (File artifactFile : artifactFiles) { - int installCount = getInstallCount(artifactFile); - if (installCount <= 1) { - new File(extDirectory, artifactFile.getName()).delete(); - } - setInstallCount(artifactFile, installCount - 1); - } - saveInstallCounts(); - } - - void uninstallAll() throws Exception { - File extDirectory = getDefaultExtDirectory(); - Log.info("Uninstalling from: " + extDirectory); - for (String name : this.installCounts.stringPropertyNames()) { - new File(extDirectory, name).delete(); - } - this.installCounts.clear(); - saveInstallCounts(); - } - - private File getDefaultExtDirectory() { - String home = SystemPropertyUtils.resolvePlaceholders("${spring.home:${SPRING_HOME:.}}"); - File extDirectory = new File(new File(home, "lib"), "ext"); - if (!extDirectory.isDirectory() && !extDirectory.mkdirs()) { - throw new IllegalStateException("Failed to create ext directory " + extDirectory); - } - return extDirectory; - } - - private File getInstalled() { - return new File(getDefaultExtDirectory(), ".installed"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/UninstallCommand.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/UninstallCommand.java deleted file mode 100644 index 892bdfba98f..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/UninstallCommand.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.command.install; - -import java.util.List; - -import joptsimple.OptionSet; -import joptsimple.OptionSpec; - -import org.springframework.boot.cli.command.Command; -import org.springframework.boot.cli.command.OptionParsingCommand; -import org.springframework.boot.cli.command.options.CompilerOptionHandler; -import org.springframework.boot.cli.command.status.ExitStatus; -import org.springframework.boot.cli.util.Log; - -/** - * {@link Command} to uninstall dependencies from the CLI's lib/ext directory. - * - * @author Dave Syer - * @author Andy Wilkinson - * @since 1.2.0 - */ -public class UninstallCommand extends OptionParsingCommand { - - public UninstallCommand() { - super("uninstall", "Uninstall dependencies from the lib/ext directory", new UninstallOptionHandler()); - } - - @Override - public String getUsageHelp() { - return "[options] "; - } - - private static class UninstallOptionHandler extends CompilerOptionHandler { - - private OptionSpec allOption; - - @Override - protected void doOptions() { - this.allOption = option("all", "Uninstall all"); - } - - @Override - @SuppressWarnings("unchecked") - protected ExitStatus run(OptionSet options) throws Exception { - List args = (List) options.nonOptionArguments(); - try { - if (options.has(this.allOption)) { - if (!args.isEmpty()) { - throw new IllegalArgumentException("Please use --all without specifying any dependencies"); - } - new Installer(options, this).uninstallAll(); - } - if (args.isEmpty()) { - throw new IllegalArgumentException( - "Please specify at least one dependency, in the form group:artifact:version, to uninstall"); - } - new Installer(options, this).uninstall(args); - } - catch (Exception ex) { - String message = ex.getMessage(); - Log.error((message != null) ? message : ex.getClass().toString()); - } - return ExitStatus.OK; - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/package-info.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/package-info.java deleted file mode 100644 index 8ce48300888..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/install/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-2019 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. - */ - -/** - * CLI commands for installing and uninstalling CLI dependencies. - */ -package org.springframework.boot.cli.command.install; diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/options/CompilerOptionHandler.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/options/CompilerOptionHandler.java deleted file mode 100644 index 35102545ef0..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/options/CompilerOptionHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.command.options; - -import java.util.Arrays; - -import joptsimple.OptionSpec; - -/** - * An {@link OptionHandler} for commands that result in the compilation of one or more - * Groovy scripts. - * - * @author Andy Wilkinson - * @author Dave Syer - * @since 1.0.0 - */ -public class CompilerOptionHandler extends OptionHandler { - - private OptionSpec noGuessImportsOption; - - private OptionSpec noGuessDependenciesOption; - - private OptionSpec autoconfigureOption; - - private OptionSpec classpathOption; - - @Override - protected final void options() { - this.noGuessImportsOption = option("no-guess-imports", "Do not attempt to guess imports"); - this.noGuessDependenciesOption = option("no-guess-dependencies", "Do not attempt to guess dependencies"); - this.autoconfigureOption = option("autoconfigure", "Add autoconfigure compiler transformations") - .withOptionalArg().ofType(Boolean.class).defaultsTo(true); - this.classpathOption = option(Arrays.asList("classpath", "cp"), "Additional classpath entries") - .withRequiredArg(); - doOptions(); - } - - protected void doOptions() { - } - - public OptionSpec getNoGuessImportsOption() { - return this.noGuessImportsOption; - } - - public OptionSpec getNoGuessDependenciesOption() { - return this.noGuessDependenciesOption; - } - - public OptionSpec getClasspathOption() { - return this.classpathOption; - } - - public OptionSpec getAutoconfigureOption() { - return this.autoconfigureOption; - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/options/OptionSetGroovyCompilerConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/options/OptionSetGroovyCompilerConfiguration.java deleted file mode 100644 index 43ba4286152..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/options/OptionSetGroovyCompilerConfiguration.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.command.options; - -import java.util.List; - -import joptsimple.OptionSet; -import joptsimple.OptionSpec; - -import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration; -import org.springframework.boot.cli.compiler.GroovyCompilerScope; -import org.springframework.boot.cli.compiler.RepositoryConfigurationFactory; -import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration; - -/** - * Simple adapter class to present an {@link OptionSet} as a - * {@link GroovyCompilerConfiguration}. - * - * @author Andy Wilkinson - * @since 1.0.0 - */ -public class OptionSetGroovyCompilerConfiguration implements GroovyCompilerConfiguration { - - private final OptionSet options; - - private final CompilerOptionHandler optionHandler; - - private final List repositoryConfiguration; - - protected OptionSetGroovyCompilerConfiguration(OptionSet optionSet, CompilerOptionHandler compilerOptionHandler) { - this(optionSet, compilerOptionHandler, RepositoryConfigurationFactory.createDefaultRepositoryConfiguration()); - } - - public OptionSetGroovyCompilerConfiguration(OptionSet optionSet, CompilerOptionHandler compilerOptionHandler, - List repositoryConfiguration) { - this.options = optionSet; - this.optionHandler = compilerOptionHandler; - this.repositoryConfiguration = repositoryConfiguration; - } - - protected OptionSet getOptions() { - return this.options; - } - - @Override - public GroovyCompilerScope getScope() { - return GroovyCompilerScope.DEFAULT; - } - - @Override - public boolean isGuessImports() { - return !this.options.has(this.optionHandler.getNoGuessImportsOption()); - } - - @Override - public boolean isGuessDependencies() { - return !this.options.has(this.optionHandler.getNoGuessDependenciesOption()); - } - - @Override - public boolean isAutoconfigure() { - return this.optionHandler.getAutoconfigureOption().value(this.options); - } - - @Override - public String[] getClasspath() { - OptionSpec classpathOption = this.optionHandler.getClasspathOption(); - if (this.options.has(classpathOption)) { - return this.options.valueOf(classpathOption).split(":"); - } - return DEFAULT_CLASSPATH; - } - - @Override - public List getRepositoryConfiguration() { - return this.repositoryConfiguration; - } - - @Override - public boolean isQuiet() { - return false; - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/options/SourceOptions.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/options/SourceOptions.java deleted file mode 100644 index cfca3824986..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/options/SourceOptions.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.command.options; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import joptsimple.OptionSet; - -import org.springframework.boot.cli.util.ResourceUtils; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Extract source file options (anything following '--' in an {@link OptionSet}). - * - * @author Phillip Webb - * @author Dave Syer - * @author Greg Turnquist - * @author Andy Wilkinson - * @since 1.0.0 - */ -public class SourceOptions { - - private final List sources; - - private final List args; - - /** - * Create a new {@link SourceOptions} instance. - * @param options the source option set - */ - public SourceOptions(OptionSet options) { - this(options, null); - } - - /** - * Create a new {@link SourceOptions} instance. - * @param arguments the source arguments - */ - public SourceOptions(List arguments) { - this(arguments, null); - } - - /** - * Create a new {@link SourceOptions} instance. If it is an error to pass options that - * specify non-existent sources, but the default paths are allowed not to exist (the - * paths are tested before use). If default paths are provided and the option set - * contains no source file arguments it is not an error even if none of the default - * paths exist. - * @param optionSet the source option set - * @param classLoader an optional classloader used to try and load files that are not - * found in the local filesystem - */ - public SourceOptions(OptionSet optionSet, ClassLoader classLoader) { - this(optionSet.nonOptionArguments(), classLoader); - } - - private SourceOptions(List nonOptionArguments, ClassLoader classLoader) { - List sources = new ArrayList<>(); - int sourceArgCount = 0; - for (Object option : nonOptionArguments) { - if (option instanceof String filename) { - if ("--".equals(filename)) { - break; - } - List urls = new ArrayList<>(); - File fileCandidate = new File(filename); - if (fileCandidate.isFile()) { - urls.add(fileCandidate.getAbsoluteFile().toURI().toString()); - } - else if (!isAbsoluteWindowsFile(fileCandidate)) { - urls.addAll(ResourceUtils.getUrls(filename, classLoader)); - } - for (String url : urls) { - if (isSource(url)) { - sources.add(url); - } - } - if (isSource(filename)) { - if (urls.isEmpty()) { - throw new IllegalArgumentException("Can't find " + filename); - } - else { - sourceArgCount++; - } - } - } - } - this.args = Collections.unmodifiableList(nonOptionArguments.subList(sourceArgCount, nonOptionArguments.size())); - Assert.isTrue(!sources.isEmpty(), "Please specify at least one file"); - this.sources = Collections.unmodifiableList(sources); - } - - private boolean isAbsoluteWindowsFile(File file) { - return isWindows() && file.isAbsolute(); - } - - private boolean isWindows() { - return File.separatorChar == '\\'; - } - - private boolean isSource(String name) { - return name.endsWith(".java") || name.endsWith(".groovy"); - } - - public List getArgs() { - return this.args; - } - - public String[] getArgsArray() { - return this.args.stream().map(this::asString).toArray(String[]::new); - } - - private String asString(Object arg) { - return (arg != null) ? String.valueOf(arg) : null; - } - - public List getSources() { - return this.sources; - } - - public String[] getSourcesArray() { - return StringUtils.toStringArray(this.sources); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/run/RunCommand.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/run/RunCommand.java deleted file mode 100644 index 6fb408657db..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/run/RunCommand.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli.command.run; - -import java.io.File; -import java.util.Arrays; -import java.util.List; -import java.util.logging.Level; - -import joptsimple.OptionSet; -import joptsimple.OptionSpec; - -import org.springframework.boot.cli.command.Command; -import org.springframework.boot.cli.command.OptionParsingCommand; -import org.springframework.boot.cli.command.options.CompilerOptionHandler; -import org.springframework.boot.cli.command.options.OptionSetGroovyCompilerConfiguration; -import org.springframework.boot.cli.command.options.SourceOptions; -import org.springframework.boot.cli.command.status.ExitStatus; -import org.springframework.boot.cli.compiler.GroovyCompilerScope; -import org.springframework.boot.cli.compiler.RepositoryConfigurationFactory; -import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration; - -/** - * {@link Command} to 'run' a groovy script or scripts. - * - * @author Phillip Webb - * @author Dave Syer - * @author Andy Wilkinson - * @since 1.0.0 - * @see SpringApplicationRunner - */ -public class RunCommand extends OptionParsingCommand { - - public RunCommand() { - super("run", "Run a spring groovy script", new RunOptionHandler()); - } - - @Override - public String getUsageHelp() { - return "[options] [--] [args]"; - } - - public void stop() { - if (getHandler() != null) { - ((RunOptionHandler) getHandler()).stop(); - } - } - - private static class RunOptionHandler extends CompilerOptionHandler { - - private final Object monitor = new Object(); - - private OptionSpec watchOption; - - private OptionSpec verboseOption; - - private OptionSpec quietOption; - - private SpringApplicationRunner runner; - - @Override - protected void doOptions() { - this.watchOption = option("watch", "Watch the specified file for changes"); - this.verboseOption = option(Arrays.asList("verbose", "v"), "Verbose logging of dependency resolution"); - this.quietOption = option(Arrays.asList("quiet", "q"), "Quiet logging"); - } - - void stop() { - synchronized (this.monitor) { - if (this.runner != null) { - this.runner.stop(); - } - this.runner = null; - } - } - - @Override - protected synchronized ExitStatus run(OptionSet options) throws Exception { - synchronized (this.monitor) { - if (this.runner != null) { - throw new RuntimeException( - "Already running. Please stop the current application before running another (use the 'stop' command)."); - } - - SourceOptions sourceOptions = new SourceOptions(options); - - List repositoryConfiguration = RepositoryConfigurationFactory - .createDefaultRepositoryConfiguration(); - repositoryConfiguration.add(0, - new RepositoryConfiguration("local", new File("repository").toURI(), true)); - - SpringApplicationRunnerConfiguration configuration = new SpringApplicationRunnerConfigurationAdapter( - options, this, repositoryConfiguration); - - this.runner = new SpringApplicationRunner(configuration, sourceOptions.getSourcesArray(), - sourceOptions.getArgsArray()); - this.runner.compileAndRun(); - - return ExitStatus.OK; - } - } - - /** - * Simple adapter class to present the {@link OptionSet} as a - * {@link SpringApplicationRunnerConfiguration}. - */ - private class SpringApplicationRunnerConfigurationAdapter extends OptionSetGroovyCompilerConfiguration - implements SpringApplicationRunnerConfiguration { - - SpringApplicationRunnerConfigurationAdapter(OptionSet options, CompilerOptionHandler optionHandler, - List repositoryConfiguration) { - super(options, optionHandler, repositoryConfiguration); - } - - @Override - public GroovyCompilerScope getScope() { - return GroovyCompilerScope.DEFAULT; - } - - @Override - public boolean isWatchForFileChanges() { - return getOptions().has(RunOptionHandler.this.watchOption); - } - - @Override - public Level getLogLevel() { - if (isQuiet()) { - return Level.OFF; - } - if (getOptions().has(RunOptionHandler.this.verboseOption)) { - return Level.FINEST; - } - return Level.INFO; - } - - @Override - public boolean isQuiet() { - return getOptions().has(RunOptionHandler.this.quietOption); - } - - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/run/SpringApplicationRunner.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/run/SpringApplicationRunner.java deleted file mode 100644 index bc9d31b98e5..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/run/SpringApplicationRunner.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.command.run; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; - -import org.springframework.boot.cli.app.SpringApplicationLauncher; -import org.springframework.boot.cli.compiler.GroovyCompiler; -import org.springframework.boot.cli.util.ResourceUtils; - -/** - * Compiles Groovy code running the resulting classes using a {@code SpringApplication}. - * Takes care of threading and class-loading issues and can optionally monitor sources for - * changes. - * - * @author Phillip Webb - * @author Dave Syer - * @since 1.0.0 - */ -public class SpringApplicationRunner { - - private static int watcherCounter = 0; - - private static int runnerCounter = 0; - - private final Object monitor = new Object(); - - private final SpringApplicationRunnerConfiguration configuration; - - private final String[] sources; - - private final String[] args; - - private final GroovyCompiler compiler; - - private RunThread runThread; - - private FileWatchThread fileWatchThread; - - /** - * Create a new {@link SpringApplicationRunner} instance. - * @param configuration the configuration - * @param sources the files to compile/watch - * @param args input arguments - */ - SpringApplicationRunner(SpringApplicationRunnerConfiguration configuration, String[] sources, String... args) { - this.configuration = configuration; - this.sources = sources.clone(); - this.args = args.clone(); - this.compiler = new GroovyCompiler(configuration); - int level = configuration.getLogLevel().intValue(); - if (level <= Level.FINER.intValue()) { - System.setProperty("org.springframework.boot.cli.compiler.grape.ProgressReporter", "detail"); - System.setProperty("trace", "true"); - } - else if (level <= Level.FINE.intValue()) { - System.setProperty("debug", "true"); - } - else if (level == Level.OFF.intValue()) { - System.setProperty("spring.main.banner-mode", "OFF"); - System.setProperty("logging.level.ROOT", "OFF"); - System.setProperty("org.springframework.boot.cli.compiler.grape.ProgressReporter", "none"); - } - } - - /** - * Compile and run the application. - * @throws Exception on error - */ - public void compileAndRun() throws Exception { - synchronized (this.monitor) { - try { - stop(); - Class[] compiledSources = compile(); - monitorForChanges(); - // Run in new thread to ensure that the context classloader is set up - this.runThread = new RunThread(compiledSources); - this.runThread.start(); - this.runThread.join(); - } - catch (Exception ex) { - if (this.fileWatchThread == null) { - throw ex; - } - else { - ex.printStackTrace(); - } - } - } - } - - public void stop() { - synchronized (this.monitor) { - if (this.runThread != null) { - this.runThread.shutdown(); - this.runThread = null; - } - } - } - - private Class[] compile() throws IOException { - Class[] compiledSources = this.compiler.compile(this.sources); - if (compiledSources.length == 0) { - throw new RuntimeException("No classes found in '" + Arrays.toString(this.sources) + "'"); - } - return compiledSources; - } - - private void monitorForChanges() { - if (this.fileWatchThread == null && this.configuration.isWatchForFileChanges()) { - this.fileWatchThread = new FileWatchThread(); - this.fileWatchThread.start(); - } - } - - /** - * Thread used to launch the Spring Application with the correct context classloader. - */ - private class RunThread extends Thread { - - private final Object monitor = new Object(); - - private final Class[] compiledSources; - - private Object applicationContext; - - /** - * Create a new {@link RunThread} instance. - * @param compiledSources the sources to launch - */ - RunThread(Class... compiledSources) { - super("runner-" + (runnerCounter++)); - this.compiledSources = compiledSources; - if (compiledSources.length != 0) { - setContextClassLoader(compiledSources[0].getClassLoader()); - } - setDaemon(true); - } - - @Override - public void run() { - synchronized (this.monitor) { - try { - this.applicationContext = new SpringApplicationLauncher(getContextClassLoader()) - .launch(this.compiledSources, SpringApplicationRunner.this.args); - } - catch (Exception ex) { - ex.printStackTrace(); - } - } - } - - /** - * Shutdown the thread, closing any previously opened application context. - */ - void shutdown() { - synchronized (this.monitor) { - if (this.applicationContext != null) { - try { - Method method = this.applicationContext.getClass().getMethod("close"); - method.invoke(this.applicationContext); - } - catch (NoSuchMethodException ex) { - // Not an application context that we can close - } - catch (Exception ex) { - ex.printStackTrace(); - } - finally { - this.applicationContext = null; - } - } - } - } - - } - - /** - * Thread to watch for file changes and trigger recompile/reload. - */ - private class FileWatchThread extends Thread { - - private long previous; - - private List sources; - - FileWatchThread() { - super("filewatcher-" + (watcherCounter++)); - this.previous = 0; - this.sources = getSourceFiles(); - for (File file : this.sources) { - if (file.exists()) { - long current = file.lastModified(); - if (current > this.previous) { - this.previous = current; - } - } - } - setDaemon(false); - } - - private List getSourceFiles() { - List sources = new ArrayList<>(); - for (String source : SpringApplicationRunner.this.sources) { - List paths = ResourceUtils.getUrls(source, SpringApplicationRunner.this.compiler.getLoader()); - for (String path : paths) { - try { - URL url = new URL(path); - if ("file".equals(url.getProtocol())) { - sources.add(new File(url.getFile())); - } - } - catch (MalformedURLException ex) { - // Ignore - } - } - } - return sources; - } - - @Override - public void run() { - while (true) { - try { - Thread.sleep(TimeUnit.SECONDS.toMillis(1)); - for (File file : this.sources) { - if (file.exists()) { - long current = file.lastModified(); - if (this.previous < current) { - this.previous = current; - compileAndRun(); - } - } - } - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - catch (Exception ex) { - // Swallow, will be reported by compileAndRun - } - } - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/run/SpringApplicationRunnerConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/run/SpringApplicationRunnerConfiguration.java deleted file mode 100644 index 2956f241b27..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/run/SpringApplicationRunnerConfiguration.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.command.run; - -import java.util.logging.Level; - -import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration; - -/** - * Configuration for the {@link SpringApplicationRunner}. - * - * @author Phillip Webb - * @since 1.0.0 - */ -public interface SpringApplicationRunnerConfiguration extends GroovyCompilerConfiguration { - - /** - * Returns {@code true} if the source file should be monitored for changes and - * automatically recompiled. - * @return {@code true} if file watching should be performed, otherwise {@code false} - */ - boolean isWatchForFileChanges(); - - /** - * Returns the logging level to use. - * @return the logging level - */ - Level getLogLevel(); - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/run/package-info.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/run/package-info.java deleted file mode 100644 index c2116824ecd..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/run/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-2019 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. - */ - -/** - * Classes for running CLI applications. - */ -package org.springframework.boot.cli.command.run; diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/AnnotatedNodeASTTransformation.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/AnnotatedNodeASTTransformation.java deleted file mode 100644 index b9f20a2e123..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/AnnotatedNodeASTTransformation.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.AnnotatedNode; -import org.codehaus.groovy.ast.AnnotationNode; -import org.codehaus.groovy.ast.ClassCodeVisitorSupport; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.ImportNode; -import org.codehaus.groovy.ast.ModuleNode; -import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.transform.ASTTransformation; - -/** - * A base class for {@link ASTTransformation AST transformations} that are solely - * interested in {@link AnnotatedNode AnnotatedNodes}. - * - * @author Andy Wilkinson - * @since 1.1.0 - */ -public abstract class AnnotatedNodeASTTransformation implements ASTTransformation { - - private final Set interestingAnnotationNames; - - private final boolean removeAnnotations; - - private SourceUnit sourceUnit; - - protected AnnotatedNodeASTTransformation(Set interestingAnnotationNames, boolean removeAnnotations) { - this.interestingAnnotationNames = interestingAnnotationNames; - this.removeAnnotations = removeAnnotations; - } - - @Override - public void visit(ASTNode[] nodes, SourceUnit source) { - this.sourceUnit = source; - List annotationNodes = new ArrayList<>(); - ClassVisitor classVisitor = new ClassVisitor(source, annotationNodes); - for (ASTNode node : nodes) { - if (node instanceof ModuleNode module) { - visitAnnotatedNode(module.getPackage(), annotationNodes); - for (ImportNode importNode : module.getImports()) { - visitAnnotatedNode(importNode, annotationNodes); - } - for (ImportNode importNode : module.getStarImports()) { - visitAnnotatedNode(importNode, annotationNodes); - } - module.getStaticImports() - .forEach((name, importNode) -> visitAnnotatedNode(importNode, annotationNodes)); - module.getStaticStarImports() - .forEach((name, importNode) -> visitAnnotatedNode(importNode, annotationNodes)); - for (ClassNode classNode : module.getClasses()) { - visitAnnotatedNode(classNode, annotationNodes); - classNode.visitContents(classVisitor); - } - } - } - processAnnotationNodes(annotationNodes); - } - - protected SourceUnit getSourceUnit() { - return this.sourceUnit; - } - - protected abstract void processAnnotationNodes(List annotationNodes); - - private void visitAnnotatedNode(AnnotatedNode annotatedNode, List annotatedNodes) { - if (annotatedNode != null) { - Iterator annotationNodes = annotatedNode.getAnnotations().iterator(); - while (annotationNodes.hasNext()) { - AnnotationNode annotationNode = annotationNodes.next(); - if (this.interestingAnnotationNames.contains(annotationNode.getClassNode().getName())) { - annotatedNodes.add(annotationNode); - if (this.removeAnnotations) { - annotationNodes.remove(); - } - } - } - } - } - - private class ClassVisitor extends ClassCodeVisitorSupport { - - private final SourceUnit source; - - private final List annotationNodes; - - ClassVisitor(SourceUnit source, List annotationNodes) { - this.source = source; - this.annotationNodes = annotationNodes; - } - - @Override - protected SourceUnit getSourceUnit() { - return this.source; - } - - @Override - public void visitAnnotations(AnnotatedNode node) { - visitAnnotatedNode(node, this.annotationNodes); - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/AstUtils.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/AstUtils.java deleted file mode 100644 index 1307af6aea3..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/AstUtils.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.codehaus.groovy.ast.AnnotatedNode; -import org.codehaus.groovy.ast.AnnotationNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.FieldNode; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.ast.expr.ArgumentListExpression; -import org.codehaus.groovy.ast.expr.ClosureExpression; -import org.codehaus.groovy.ast.expr.ConstantExpression; -import org.codehaus.groovy.ast.expr.Expression; -import org.codehaus.groovy.ast.expr.MethodCallExpression; -import org.codehaus.groovy.ast.stmt.BlockStatement; -import org.codehaus.groovy.ast.stmt.ExpressionStatement; -import org.codehaus.groovy.ast.stmt.Statement; - -import org.springframework.util.PatternMatchUtils; - -/** - * General purpose AST utilities. - * - * @author Phillip Webb - * @author Dave Syer - * @author Greg Turnquist - * @since 1.0.0 - */ -public abstract class AstUtils { - - /** - * Determine if a {@link ClassNode} has one or more of the specified annotations on - * the class or any of its methods. N.B. the type names are not normally fully - * qualified. - * @param node the class to examine - * @param annotations the annotations to look for - * @return {@code true} if at least one of the annotations is found, otherwise - * {@code false} - */ - public static boolean hasAtLeastOneAnnotation(ClassNode node, String... annotations) { - if (hasAtLeastOneAnnotation((AnnotatedNode) node, annotations)) { - return true; - } - for (MethodNode method : node.getMethods()) { - if (hasAtLeastOneAnnotation(method, annotations)) { - return true; - } - } - return false; - } - - /** - * Determine if an {@link AnnotatedNode} has one or more of the specified annotations. - * N.B. the annotation type names are not normally fully qualified. - * @param node the node to examine - * @param annotations the annotations to look for - * @return {@code true} if at least one of the annotations is found, otherwise - * {@code false} - */ - public static boolean hasAtLeastOneAnnotation(AnnotatedNode node, String... annotations) { - for (AnnotationNode annotationNode : node.getAnnotations()) { - for (String annotation : annotations) { - if (PatternMatchUtils.simpleMatch(annotation, annotationNode.getClassNode().getName())) { - return true; - } - } - } - return false; - } - - /** - * Determine if a {@link ClassNode} has one or more fields of the specified types or - * method returning one or more of the specified types. N.B. the type names are not - * normally fully qualified. - * @param node the class to examine - * @param types the types to look for - * @return {@code true} if at least one of the types is found, otherwise {@code false} - */ - public static boolean hasAtLeastOneFieldOrMethod(ClassNode node, String... types) { - Set typesSet = new HashSet<>(Arrays.asList(types)); - for (FieldNode field : node.getFields()) { - if (typesSet.contains(field.getType().getName())) { - return true; - } - } - for (MethodNode method : node.getMethods()) { - if (typesSet.contains(method.getReturnType().getName())) { - return true; - } - } - return false; - } - - /** - * Determine if a {@link ClassNode} subclasses any of the specified types N.B. the - * type names are not normally fully qualified. - * @param node the class to examine - * @param types the types that may have been sub-classed - * @return {@code true} if the class subclasses any of the specified types, otherwise - * {@code false} - */ - public static boolean subclasses(ClassNode node, String... types) { - for (String type : types) { - if (node.getSuperClass().getName().equals(type)) { - return true; - } - } - return false; - } - - public static boolean hasAtLeastOneInterface(ClassNode classNode, String... types) { - Set typesSet = new HashSet<>(Arrays.asList(types)); - for (ClassNode inter : classNode.getInterfaces()) { - if (typesSet.contains(inter.getName())) { - return true; - } - } - return false; - } - - /** - * Extract a top-level {@code name} closure from inside this block if there is one, - * optionally removing it from the block at the same time. - * @param block a block statement (class definition) - * @param name the name to look for - * @param remove whether the extracted closure should be removed - * @return a beans Closure if one can be found, null otherwise - */ - public static ClosureExpression getClosure(BlockStatement block, String name, boolean remove) { - for (ExpressionStatement statement : getExpressionStatements(block)) { - Expression expression = statement.getExpression(); - if (expression instanceof MethodCallExpression methodCallExpression) { - ClosureExpression closure = getClosure(name, methodCallExpression); - if (closure != null) { - if (remove) { - block.getStatements().remove(statement); - } - return closure; - } - } - } - return null; - } - - private static List getExpressionStatements(BlockStatement block) { - List statements = new ArrayList<>(); - for (Statement statement : block.getStatements()) { - if (statement instanceof ExpressionStatement expressionStatement) { - statements.add(expressionStatement); - } - } - return statements; - } - - private static ClosureExpression getClosure(String name, MethodCallExpression expression) { - Expression method = expression.getMethod(); - if (method instanceof ConstantExpression constantExpression && name.equals(constantExpression.getValue())) { - return (ClosureExpression) ((ArgumentListExpression) expression.getArguments()).getExpression(0); - } - return null; - } - - public static ClosureExpression getClosure(BlockStatement block, String name) { - return getClosure(block, name, false); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/CompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/CompilerAutoConfiguration.java deleted file mode 100644 index 97603e0c6c1..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/CompilerAutoConfiguration.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler; - -import groovy.lang.GroovyClassLoader; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.classgen.GeneratorContext; -import org.codehaus.groovy.control.CompilationFailedException; -import org.codehaus.groovy.control.CompilePhase; -import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -/** - * Strategy that can be used to apply some auto-configuration during the - * {@link CompilePhase#CONVERSION} Groovy compile phase. - * - * @author Phillip Webb - * @since 1.0.0 - */ -public abstract class CompilerAutoConfiguration { - - /** - * Strategy method used to determine when compiler auto-configuration should be - * applied. Defaults to always. - * @param classNode the class node - * @return {@code true} if the compiler should be auto-configured using this class. If - * this method returns {@code false} no other strategy methods will be called. - */ - public boolean matches(ClassNode classNode) { - return true; - } - - /** - * Apply any dependency customizations. This method will only be called if - * {@link #matches} returns {@code true}. - * @param dependencies dependency customizer - * @throws CompilationFailedException if the dependencies cannot be applied - */ - public void applyDependencies(DependencyCustomizer dependencies) throws CompilationFailedException { - } - - /** - * Apply any import customizations. This method will only be called if - * {@link #matches} returns {@code true}. - * @param imports import customizer - * @throws CompilationFailedException if the imports cannot be applied - */ - public void applyImports(ImportCustomizer imports) throws CompilationFailedException { - } - - /** - * Apply any customizations to the main class. This method will only be called if - * {@link #matches} returns {@code true}. This method is useful when a groovy file - * defines more than one class but customization only applies to the first class. - * @param loader the class loader being used during compilation - * @param configuration the compiler configuration - * @param generatorContext the current context - * @param source the source unit - * @param classNode the main class - * @throws CompilationFailedException if the customizations cannot be applied - */ - public void applyToMainClass(GroovyClassLoader loader, GroovyCompilerConfiguration configuration, - GeneratorContext generatorContext, SourceUnit source, ClassNode classNode) - throws CompilationFailedException { - } - - /** - * Apply any additional configuration. - * @param loader the class loader being used during compilation - * @param configuration the compiler configuration - * @param generatorContext the current context - * @param source the source unit - * @param classNode the class - * @throws CompilationFailedException if the configuration cannot be applied - */ - public void apply(GroovyClassLoader loader, GroovyCompilerConfiguration configuration, - GeneratorContext generatorContext, SourceUnit source, ClassNode classNode) - throws CompilationFailedException { - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/DependencyAutoConfigurationTransformation.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/DependencyAutoConfigurationTransformation.java deleted file mode 100644 index c287652ebdd..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/DependencyAutoConfigurationTransformation.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler; - -import groovy.lang.GroovyClassLoader; -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.ModuleNode; -import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.transform.ASTTransformation; - -import org.springframework.boot.cli.compiler.grape.DependencyResolutionContext; -import org.springframework.core.annotation.Order; - -/** - * {@link ASTTransformation} to apply - * {@link CompilerAutoConfiguration#applyDependencies(DependencyCustomizer) dependency - * auto-configuration}. - * - * @author Phillip Webb - * @author Dave Syer - * @author Andy Wilkinson - * @since 1.0.0 - */ -@Order(DependencyAutoConfigurationTransformation.ORDER) -public class DependencyAutoConfigurationTransformation implements ASTTransformation { - - /** - * The order of the transformation. - */ - public static final int ORDER = DependencyManagementBomTransformation.ORDER + 100; - - private final GroovyClassLoader loader; - - private final DependencyResolutionContext dependencyResolutionContext; - - private final Iterable compilerAutoConfigurations; - - public DependencyAutoConfigurationTransformation(GroovyClassLoader loader, - DependencyResolutionContext dependencyResolutionContext, - Iterable compilerAutoConfigurations) { - this.loader = loader; - this.dependencyResolutionContext = dependencyResolutionContext; - this.compilerAutoConfigurations = compilerAutoConfigurations; - - } - - @Override - public void visit(ASTNode[] nodes, SourceUnit source) { - for (ASTNode astNode : nodes) { - if (astNode instanceof ModuleNode moduleNode) { - visitModule(moduleNode); - } - } - } - - private void visitModule(ModuleNode module) { - DependencyCustomizer dependencies = new DependencyCustomizer(this.loader, module, - this.dependencyResolutionContext); - for (ClassNode classNode : module.getClasses()) { - for (CompilerAutoConfiguration autoConfiguration : this.compilerAutoConfigurations) { - if (autoConfiguration.matches(classNode)) { - autoConfiguration.applyDependencies(dependencies); - } - } - } - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/DependencyCustomizer.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/DependencyCustomizer.java deleted file mode 100644 index 2b2068c54c1..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/DependencyCustomizer.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler; - -import groovy.lang.Grab; -import groovy.lang.GroovyClassLoader; -import org.codehaus.groovy.ast.AnnotationNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.ModuleNode; -import org.codehaus.groovy.ast.expr.ConstantExpression; - -import org.springframework.boot.cli.compiler.dependencies.ArtifactCoordinatesResolver; -import org.springframework.boot.cli.compiler.grape.DependencyResolutionContext; - -/** - * Customizer that allows dependencies to be added during compilation. Adding a dependency - * results in a {@link Grab @Grab} annotation being added to the primary {@link ClassNode - * class} is the {@link ModuleNode module} that's being customized. - *

- * This class provides a fluent API for conditionally adding dependencies. For example: - * {@code dependencies.ifMissing("com.corp.SomeClass").add(module)}. - * - * @author Phillip Webb - * @author Andy Wilkinson - * @since 1.0.0 - */ -public class DependencyCustomizer { - - private final GroovyClassLoader loader; - - private final ClassNode classNode; - - private final DependencyResolutionContext dependencyResolutionContext; - - /** - * Create a new {@link DependencyCustomizer} instance. - * @param loader the current classloader - * @param moduleNode the current module - * @param dependencyResolutionContext the context for dependency resolution - */ - public DependencyCustomizer(GroovyClassLoader loader, ModuleNode moduleNode, - DependencyResolutionContext dependencyResolutionContext) { - this.loader = loader; - this.classNode = moduleNode.getClasses().get(0); - this.dependencyResolutionContext = dependencyResolutionContext; - } - - /** - * Create a new nested {@link DependencyCustomizer}. - * @param parent the parent customizer - */ - protected DependencyCustomizer(DependencyCustomizer parent) { - this.loader = parent.loader; - this.classNode = parent.classNode; - this.dependencyResolutionContext = parent.dependencyResolutionContext; - } - - public String getVersion(String artifactId) { - return getVersion(artifactId, ""); - } - - public String getVersion(String artifactId, String defaultVersion) { - String version = this.dependencyResolutionContext.getArtifactCoordinatesResolver().getVersion(artifactId); - if (version == null) { - version = defaultVersion; - } - return version; - } - - /** - * Create a nested {@link DependencyCustomizer} that only applies if any of the - * specified class names are not on the class path. - * @param classNames the class names to test - * @return a nested {@link DependencyCustomizer} - */ - public DependencyCustomizer ifAnyMissingClasses(String... classNames) { - return new DependencyCustomizer(this) { - @Override - protected boolean canAdd() { - for (String className : classNames) { - try { - Class.forName(className, false, DependencyCustomizer.this.loader); - } - catch (Exception ex) { - return true; - } - } - return false; - } - }; - } - - /** - * Create a nested {@link DependencyCustomizer} that only applies if all the specified - * class names are not on the class path. - * @param classNames the class names to test - * @return a nested {@link DependencyCustomizer} - */ - public DependencyCustomizer ifAllMissingClasses(String... classNames) { - return new DependencyCustomizer(this) { - @Override - protected boolean canAdd() { - for (String className : classNames) { - try { - Class.forName(className, false, DependencyCustomizer.this.loader); - return false; - } - catch (Exception ex) { - // swallow exception and continue - } - } - return DependencyCustomizer.this.canAdd(); - } - }; - } - - /** - * Create a nested {@link DependencyCustomizer} that only applies if the specified - * paths are on the class path. - * @param paths the paths to test - * @return a nested {@link DependencyCustomizer} - */ - public DependencyCustomizer ifAllResourcesPresent(String... paths) { - return new DependencyCustomizer(this) { - @Override - protected boolean canAdd() { - for (String path : paths) { - try { - if (DependencyCustomizer.this.loader.getResource(path) == null) { - return false; - } - } - catch (Exception ex) { - // swallow exception and continue - } - } - return DependencyCustomizer.this.canAdd(); - } - }; - } - - /** - * Create a nested {@link DependencyCustomizer} that only applies at least one of the - * specified paths is on the class path. - * @param paths the paths to test - * @return a nested {@link DependencyCustomizer} - */ - public DependencyCustomizer ifAnyResourcesPresent(String... paths) { - return new DependencyCustomizer(this) { - @Override - protected boolean canAdd() { - for (String path : paths) { - try { - return DependencyCustomizer.this.loader.getResource(path) != null; - } - catch (Exception ex) { - // swallow exception and continue - } - } - return DependencyCustomizer.this.canAdd(); - } - }; - } - - /** - * Add dependencies and all of their dependencies. The group ID and version of the - * dependencies are resolved from the modules using the customizer's - * {@link ArtifactCoordinatesResolver}. - * @param modules the module IDs - * @return this {@link DependencyCustomizer} for continued use - */ - public DependencyCustomizer add(String... modules) { - for (String module : modules) { - add(module, null, null, true); - } - return this; - } - - /** - * Add a single dependency and, optionally, all of its dependencies. The group ID and - * version of the dependency are resolved from the module using the customizer's - * {@link ArtifactCoordinatesResolver}. - * @param module the module ID - * @param transitive {@code true} if the transitive dependencies should also be added, - * otherwise {@code false} - * @return this {@link DependencyCustomizer} for continued use - */ - public DependencyCustomizer add(String module, boolean transitive) { - return add(module, null, null, transitive); - } - - /** - * Add a single dependency with the specified classifier and type and, optionally, all - * of its dependencies. The group ID and version of the dependency are resolved from - * the module by using the customizer's {@link ArtifactCoordinatesResolver}. - * @param module the module ID - * @param classifier the classifier, may be {@code null} - * @param type the type, may be {@code null} - * @param transitive {@code true} if the transitive dependencies should also be added, - * otherwise {@code false} - * @return this {@link DependencyCustomizer} for continued use - */ - public DependencyCustomizer add(String module, String classifier, String type, boolean transitive) { - if (canAdd()) { - ArtifactCoordinatesResolver artifactCoordinatesResolver = this.dependencyResolutionContext - .getArtifactCoordinatesResolver(); - this.classNode.addAnnotation(createGrabAnnotation(artifactCoordinatesResolver.getGroupId(module), - artifactCoordinatesResolver.getArtifactId(module), artifactCoordinatesResolver.getVersion(module), - classifier, type, transitive)); - } - return this; - } - - private AnnotationNode createGrabAnnotation(String group, String module, String version, String classifier, - String type, boolean transitive) { - AnnotationNode annotationNode = new AnnotationNode(new ClassNode(Grab.class)); - annotationNode.addMember("group", new ConstantExpression(group)); - annotationNode.addMember("module", new ConstantExpression(module)); - annotationNode.addMember("version", new ConstantExpression(version)); - if (classifier != null) { - annotationNode.addMember("classifier", new ConstantExpression(classifier)); - } - if (type != null) { - annotationNode.addMember("type", new ConstantExpression(type)); - } - annotationNode.addMember("transitive", new ConstantExpression(transitive)); - annotationNode.addMember("initClass", new ConstantExpression(false)); - return annotationNode; - } - - /** - * Strategy called to test if dependencies can be added. Subclasses override as - * required. Returns {@code true} by default. - * @return {@code true} if dependencies can be added, otherwise {@code false} - */ - protected boolean canAdd() { - return true; - } - - /** - * Returns the {@link DependencyResolutionContext}. - * @return the dependency resolution context - */ - public DependencyResolutionContext getDependencyResolutionContext() { - return this.dependencyResolutionContext; - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/DependencyManagementBomTransformation.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/DependencyManagementBomTransformation.java deleted file mode 100644 index 43c7b56dda8..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/DependencyManagementBomTransformation.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler; - -import java.net.MalformedURLException; -import java.net.URI; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import groovy.grape.Grape; -import org.apache.maven.model.Dependency; -import org.apache.maven.model.Model; -import org.apache.maven.model.Parent; -import org.apache.maven.model.Repository; -import org.apache.maven.model.building.DefaultModelBuilder; -import org.apache.maven.model.building.DefaultModelBuilderFactory; -import org.apache.maven.model.building.DefaultModelBuildingRequest; -import org.apache.maven.model.resolution.InvalidRepositoryException; -import org.apache.maven.model.resolution.ModelResolver; -import org.apache.maven.model.resolution.UnresolvableModelException; -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.AnnotationNode; -import org.codehaus.groovy.ast.expr.ConstantExpression; -import org.codehaus.groovy.ast.expr.Expression; -import org.codehaus.groovy.ast.expr.ListExpression; -import org.codehaus.groovy.control.messages.Message; -import org.codehaus.groovy.control.messages.SyntaxErrorMessage; -import org.codehaus.groovy.syntax.SyntaxException; -import org.codehaus.groovy.transform.ASTTransformation; - -import org.springframework.boot.cli.compiler.dependencies.MavenModelDependencyManagement; -import org.springframework.boot.cli.compiler.grape.DependencyResolutionContext; -import org.springframework.boot.groovy.DependencyManagementBom; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; - -/** - * {@link ASTTransformation} for processing - * {@link DependencyManagementBom @DependencyManagementBom} annotations. - * - * @author Andy Wilkinson - * @since 1.3.0 - */ -@Order(DependencyManagementBomTransformation.ORDER) -@SuppressWarnings("deprecation") -public class DependencyManagementBomTransformation extends AnnotatedNodeASTTransformation { - - /** - * The order of the transformation. - */ - public static final int ORDER = Ordered.HIGHEST_PRECEDENCE + 100; - - private static final Set DEPENDENCY_MANAGEMENT_BOM_ANNOTATION_NAMES = Collections - .unmodifiableSet(new HashSet<>(Arrays.asList(DependencyManagementBom.class.getName(), - DependencyManagementBom.class.getSimpleName()))); - - private final DependencyResolutionContext resolutionContext; - - public DependencyManagementBomTransformation(DependencyResolutionContext resolutionContext) { - super(DEPENDENCY_MANAGEMENT_BOM_ANNOTATION_NAMES, true); - this.resolutionContext = resolutionContext; - } - - @Override - protected void processAnnotationNodes(List annotationNodes) { - if (!annotationNodes.isEmpty()) { - if (annotationNodes.size() > 1) { - for (AnnotationNode annotationNode : annotationNodes) { - handleDuplicateDependencyManagementBomAnnotation(annotationNode); - } - } - else { - processDependencyManagementBomAnnotation(annotationNodes.get(0)); - } - } - } - - private void processDependencyManagementBomAnnotation(AnnotationNode annotationNode) { - Expression valueExpression = annotationNode.getMember("value"); - List> bomDependencies = createDependencyMaps(valueExpression); - updateDependencyResolutionContext(bomDependencies); - } - - private List> createDependencyMaps(Expression valueExpression) { - Map dependency = null; - List constantExpressions = getConstantExpressions(valueExpression); - List> dependencies = new ArrayList<>(constantExpressions.size()); - for (ConstantExpression expression : constantExpressions) { - Object value = expression.getValue(); - if (value instanceof String string) { - String[] components = string.split(":"); - if (components.length == 3) { - dependency = new HashMap<>(); - dependency.put("group", components[0]); - dependency.put("module", components[1]); - dependency.put("version", components[2]); - dependency.put("type", "pom"); - dependencies.add(dependency); - } - else { - handleMalformedDependency(expression); - } - } - } - return dependencies; - } - - private List getConstantExpressions(Expression valueExpression) { - if (valueExpression instanceof ListExpression listExpression) { - return getConstantExpressions(listExpression); - } - if (valueExpression instanceof ConstantExpression constantExpression - && constantExpression.getValue() instanceof String) { - return Arrays.asList(constantExpression); - } - reportError("@DependencyManagementBom requires an inline constant that is a string or a string array", - valueExpression); - return Collections.emptyList(); - } - - private List getConstantExpressions(ListExpression valueExpression) { - List expressions = new ArrayList<>(); - for (Expression expression : valueExpression.getExpressions()) { - if (expression instanceof ConstantExpression constantExpression - && constantExpression.getValue() instanceof String) { - expressions.add(constantExpression); - } - else { - reportError("Each entry in the array must be an inline string constant", expression); - } - } - return expressions; - } - - private void handleMalformedDependency(Expression expression) { - Message message = createSyntaxErrorMessage( - String.format("The string must be of the form \"group:module:version\"%n"), expression); - getSourceUnit().getErrorCollector().addErrorAndContinue(message); - } - - private void updateDependencyResolutionContext(List> bomDependencies) { - URI[] uris = Grape.getInstance().resolve(null, bomDependencies.toArray(new Map[0])); - DefaultModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance(); - for (URI uri : uris) { - try { - DefaultModelBuildingRequest request = new DefaultModelBuildingRequest(); - request.setModelResolver(new GrapeModelResolver()); - request.setModelSource(new org.apache.maven.model.building.UrlModelSource(uri.toURL())); - request.setSystemProperties(System.getProperties()); - Model model = modelBuilder.build(request).getEffectiveModel(); - this.resolutionContext.addDependencyManagement(new MavenModelDependencyManagement(model)); - } - catch (Exception ex) { - throw new IllegalStateException("Failed to build model for '" + uri + "'. Is it a valid Maven bom?", - ex); - } - } - } - - private void handleDuplicateDependencyManagementBomAnnotation(AnnotationNode annotationNode) { - Message message = createSyntaxErrorMessage( - "Duplicate @DependencyManagementBom annotation. It must be declared at most once.", annotationNode); - getSourceUnit().getErrorCollector().addErrorAndContinue(message); - } - - private void reportError(String message, ASTNode node) { - getSourceUnit().getErrorCollector().addErrorAndContinue(createSyntaxErrorMessage(message, node)); - } - - private Message createSyntaxErrorMessage(String message, ASTNode node) { - return new SyntaxErrorMessage(new SyntaxException(message, node.getLineNumber(), node.getColumnNumber(), - node.getLastLineNumber(), node.getLastColumnNumber()), getSourceUnit()); - } - - private static class GrapeModelResolver implements ModelResolver { - - @Override - public org.apache.maven.model.building.ModelSource resolveModel(Parent parent) - throws UnresolvableModelException { - return resolveModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); - } - - @Override - public org.apache.maven.model.building.ModelSource resolveModel(Dependency dependency) - throws UnresolvableModelException { - return resolveModel(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion()); - } - - @Override - public org.apache.maven.model.building.ModelSource resolveModel(String groupId, String artifactId, - String version) throws UnresolvableModelException { - Map dependency = new HashMap<>(); - dependency.put("group", groupId); - dependency.put("module", artifactId); - dependency.put("version", version); - dependency.put("type", "pom"); - try { - return new org.apache.maven.model.building.UrlModelSource( - Grape.getInstance().resolve(null, dependency)[0].toURL()); - } - catch (MalformedURLException ex) { - throw new UnresolvableModelException(ex.getMessage(), groupId, artifactId, version); - } - } - - @Override - public void addRepository(Repository repository) throws InvalidRepositoryException { - } - - @Override - public void addRepository(Repository repository, boolean replace) throws InvalidRepositoryException { - } - - @Override - public ModelResolver newCopy() { - return this; - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/ExtendedGroovyClassLoader.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/ExtendedGroovyClassLoader.java deleted file mode 100644 index 9325849d570..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/ExtendedGroovyClassLoader.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import groovy.lang.GroovyClassLoader; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.CompilerConfiguration; -import org.codehaus.groovy.control.SourceUnit; - -import org.springframework.util.Assert; -import org.springframework.util.FileCopyUtils; -import org.springframework.util.StringUtils; - -/** - * Extension of the {@link GroovyClassLoader} with support for obtaining '.class' files as - * resources. - * - * @author Phillip Webb - * @author Dave Syer - * @since 1.0.0 - */ -public class ExtendedGroovyClassLoader extends GroovyClassLoader { - - private static final String SHARED_PACKAGE = "org.springframework.boot.groovy"; - - private static final URL[] NO_URLS = new URL[] {}; - - private final Map classResources = new HashMap<>(); - - private final GroovyCompilerScope scope; - - private final CompilerConfiguration configuration; - - public ExtendedGroovyClassLoader(GroovyCompilerScope scope) { - this(scope, createParentClassLoader(scope), new CompilerConfiguration()); - } - - private static ClassLoader createParentClassLoader(GroovyCompilerScope scope) { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - if (scope == GroovyCompilerScope.DEFAULT) { - classLoader = new DefaultScopeParentClassLoader(classLoader); - } - return classLoader; - } - - private ExtendedGroovyClassLoader(GroovyCompilerScope scope, ClassLoader parent, - CompilerConfiguration configuration) { - super(parent, configuration); - this.configuration = configuration; - this.scope = scope; - } - - @Override - protected Class findClass(String name) throws ClassNotFoundException { - try { - return super.findClass(name); - } - catch (ClassNotFoundException ex) { - if (this.scope == GroovyCompilerScope.DEFAULT && name.startsWith(SHARED_PACKAGE)) { - Class sharedClass = findSharedClass(name); - if (sharedClass != null) { - return sharedClass; - } - } - throw ex; - } - } - - private Class findSharedClass(String name) { - try { - String path = name.replace('.', '/').concat(".class"); - try (InputStream inputStream = getParent().getResourceAsStream(path)) { - if (inputStream != null) { - return defineClass(name, FileCopyUtils.copyToByteArray(inputStream)); - } - } - return null; - } - catch (Exception ex) { - return null; - } - } - - @Override - public InputStream getResourceAsStream(String name) { - InputStream resourceStream = super.getResourceAsStream(name); - if (resourceStream == null) { - byte[] bytes = this.classResources.get(name); - resourceStream = (bytes != null) ? new ByteArrayInputStream(bytes) : null; - } - return resourceStream; - } - - @Override - public ClassCollector createCollector(CompilationUnit unit, SourceUnit su) { - return new ExtendedClassCollector(getInnerLoader(), unit, su); - } - - private InnerLoader getInnerLoader() { - return new InnerLoader(ExtendedGroovyClassLoader.this) { - - // Don't return URLs from the inner loader so that Tomcat only - // searches the parent. Fixes 'TLD skipped' issues - @Override - public URL[] getURLs() { - return NO_URLS; - } - - }; - } - - public CompilerConfiguration getConfiguration() { - return this.configuration; - } - - /** - * Inner collector class used to track as classes are added. - */ - protected class ExtendedClassCollector extends ClassCollector { - - protected ExtendedClassCollector(InnerLoader loader, CompilationUnit unit, SourceUnit su) { - super(loader, unit, su); - } - - @Override - protected Class createClass(byte[] code, ClassNode classNode) { - Class createdClass = super.createClass(code, classNode); - ExtendedGroovyClassLoader.this.classResources.put(classNode.getName().replace('.', '/') + ".class", code); - return createdClass; - } - - } - - /** - * ClassLoader used for a parent that filters so that only classes from groovy-all.jar - * are exposed. - */ - private static class DefaultScopeParentClassLoader extends ClassLoader { - - private static final String[] GROOVY_JARS_PREFIXES = { "groovy", "antlr", "asm" }; - - private final URLClassLoader groovyOnlyClassLoader; - - DefaultScopeParentClassLoader(ClassLoader parent) { - super(parent); - this.groovyOnlyClassLoader = new URLClassLoader(getGroovyJars(parent), - getClass().getClassLoader().getParent()); - } - - private URL[] getGroovyJars(ClassLoader parent) { - Set urls = new HashSet<>(); - findGroovyJarsDirectly(parent, urls); - if (urls.isEmpty()) { - findGroovyJarsFromClassPath(urls); - } - Assert.state(!urls.isEmpty(), "Unable to find groovy JAR"); - return new ArrayList<>(urls).toArray(new URL[0]); - } - - private void findGroovyJarsDirectly(ClassLoader classLoader, Set urls) { - while (classLoader != null) { - if (classLoader instanceof URLClassLoader urlClassLoader) { - for (URL url : urlClassLoader.getURLs()) { - if (isGroovyJar(url.toString())) { - urls.add(url); - } - } - } - classLoader = classLoader.getParent(); - } - } - - private void findGroovyJarsFromClassPath(Set urls) { - String classpath = System.getProperty("java.class.path"); - String[] entries = classpath.split(System.getProperty("path.separator")); - for (String entry : entries) { - if (isGroovyJar(entry)) { - File file = new File(entry); - if (file.canRead()) { - try { - urls.add(file.toURI().toURL()); - } - catch (MalformedURLException ex) { - // Swallow and continue - } - } - } - } - } - - private boolean isGroovyJar(String entry) { - entry = StringUtils.cleanPath(entry); - for (String jarPrefix : GROOVY_JARS_PREFIXES) { - if (entry.contains("/" + jarPrefix + "-")) { - return true; - } - } - return false; - } - - @Override - public Enumeration getResources(String name) throws IOException { - return this.groovyOnlyClassLoader.getResources(name); - } - - @Override - protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - if (!name.startsWith("java.")) { - Class.forName(name, false, this.groovyOnlyClassLoader); - } - return super.loadClass(name, resolve); - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GenericBomAstTransformation.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GenericBomAstTransformation.java deleted file mode 100644 index 91b10e0a790..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GenericBomAstTransformation.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.AnnotatedNode; -import org.codehaus.groovy.ast.AnnotationNode; -import org.codehaus.groovy.ast.ClassHelper; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.ModuleNode; -import org.codehaus.groovy.ast.PackageNode; -import org.codehaus.groovy.ast.expr.ConstantExpression; -import org.codehaus.groovy.ast.expr.Expression; -import org.codehaus.groovy.ast.expr.ListExpression; -import org.codehaus.groovy.control.CompilePhase; -import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.transform.GroovyASTTransformation; - -import org.springframework.boot.groovy.DependencyManagementBom; -import org.springframework.core.Ordered; - -/** - * A base class that lets plugin authors easily add additional BOMs to all apps. All the - * dependencies in the BOM (and its transitives) will be added to the dependency - * management lookup, so an app can use just the artifact id (e.g. "spring-jdbc") in a - * {@code @Grab}. To install, implement the missing methods and list the class in - * {@code META-INF/services/org.springframework.boot.cli.compiler.SpringBootAstTransformation} - * . The {@link #getOrder()} value needs to be before - * {@link DependencyManagementBomTransformation#ORDER}. - * - * @author Dave Syer - * @since 1.3.0 - */ -@GroovyASTTransformation(phase = CompilePhase.CONVERSION) -public abstract class GenericBomAstTransformation implements SpringBootAstTransformation, Ordered { - - private static final ClassNode BOM = ClassHelper.make(DependencyManagementBom.class); - - @Override - public void visit(ASTNode[] nodes, SourceUnit source) { - for (ASTNode astNode : nodes) { - if (astNode instanceof ModuleNode moduleNode) { - visitModule(moduleNode, getBomModule()); - } - } - } - - /** - * The bom to be added to dependency management in compact form: - * {@code "::"} (like in a {@code @Grab}). - * @return the maven co-ordinates of the BOM to add - */ - protected abstract String getBomModule(); - - private void visitModule(ModuleNode node, String module) { - addDependencyManagementBom(node, module); - } - - private void addDependencyManagementBom(ModuleNode node, String module) { - AnnotatedNode annotated = getAnnotatedNode(node); - if (annotated != null) { - AnnotationNode bom = getAnnotation(annotated); - List expressions = new ArrayList<>(getConstantExpressions(bom.getMember("value"))); - expressions.add(new ConstantExpression(module)); - bom.setMember("value", new ListExpression(expressions)); - } - } - - private AnnotationNode getAnnotation(AnnotatedNode annotated) { - List annotations = annotated.getAnnotations(BOM); - if (!annotations.isEmpty()) { - return annotations.get(0); - } - AnnotationNode annotation = new AnnotationNode(BOM); - annotated.addAnnotation(annotation); - return annotation; - } - - private AnnotatedNode getAnnotatedNode(ModuleNode node) { - PackageNode packageNode = node.getPackage(); - if (packageNode != null && !packageNode.getAnnotations(BOM).isEmpty()) { - return packageNode; - } - if (!node.getClasses().isEmpty()) { - return node.getClasses().get(0); - } - return packageNode; - } - - private List getConstantExpressions(Expression valueExpression) { - if (valueExpression instanceof ListExpression listExpression) { - return getConstantExpressions(listExpression); - } - if (valueExpression instanceof ConstantExpression constantExpression - && constantExpression.getValue() instanceof String) { - return Arrays.asList(constantExpression); - } - return Collections.emptyList(); - } - - private List getConstantExpressions(ListExpression valueExpression) { - List expressions = new ArrayList<>(); - for (Expression expression : valueExpression.getExpressions()) { - if (expression instanceof ConstantExpression constantExpression - && constantExpression.getValue() instanceof String) { - expressions.add(constantExpression); - } - } - return expressions; - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyBeansTransformation.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyBeansTransformation.java deleted file mode 100644 index 6d4cbaf1cda..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyBeansTransformation.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler; - -import java.lang.reflect.Modifier; -import java.util.ArrayList; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.ClassCodeVisitorSupport; -import org.codehaus.groovy.ast.ClassHelper; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.ModuleNode; -import org.codehaus.groovy.ast.PropertyNode; -import org.codehaus.groovy.ast.expr.ClosureExpression; -import org.codehaus.groovy.ast.stmt.BlockStatement; -import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.transform.ASTTransformation; - -import org.springframework.core.annotation.Order; - -/** - * {@link ASTTransformation} to resolve beans declarations inside application source - * files. Users only need to define a beans{} DSL element, and this - * transformation will remove it and make it accessible to the Spring application via an - * interface. - * - * @author Dave Syer - * @since 1.0.0 - */ -@Order(GroovyBeansTransformation.ORDER) -public class GroovyBeansTransformation implements ASTTransformation { - - /** - * The order of the transformation. - */ - public static final int ORDER = DependencyManagementBomTransformation.ORDER + 200; - - @Override - public void visit(ASTNode[] nodes, SourceUnit source) { - for (ASTNode node : nodes) { - if (node instanceof ModuleNode module) { - for (ClassNode classNode : new ArrayList<>(module.getClasses())) { - if (classNode.isScript()) { - classNode.visitContents(new ClassVisitor(source, classNode)); - } - } - } - } - } - - private class ClassVisitor extends ClassCodeVisitorSupport { - - private static final String SOURCE_INTERFACE = "org.springframework.boot.BeanDefinitionLoader.GroovyBeanDefinitionSource"; - - private static final String BEANS = "beans"; - - private final SourceUnit source; - - private final ClassNode classNode; - - private boolean xformed = false; - - ClassVisitor(SourceUnit source, ClassNode classNode) { - this.source = source; - this.classNode = classNode; - } - - @Override - protected SourceUnit getSourceUnit() { - return this.source; - } - - @Override - public void visitBlockStatement(BlockStatement block) { - if (block.isEmpty() || this.xformed) { - return; - } - ClosureExpression closure = beans(block); - if (closure != null) { - // Add a marker interface to the current script - this.classNode.addInterface(ClassHelper.make(SOURCE_INTERFACE)); - // Implement the interface by adding a public read-only property with the - // same name as the method in the interface (getBeans). Make it return the - // closure. - this.classNode.addProperty(new PropertyNode(BEANS, Modifier.PUBLIC | Modifier.FINAL, - ClassHelper.CLOSURE_TYPE.getPlainNodeReference(), this.classNode, closure, null, null)); - // Only do this once per class - this.xformed = true; - } - } - - /** - * Extract a top-level beans{} closure from inside this block if - * there is one. Removes it from the block at the same time. - * @param block a block statement (class definition) - * @return a beans Closure if one can be found, null otherwise - */ - private ClosureExpression beans(BlockStatement block) { - return AstUtils.getClosure(block, BEANS, true); - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompiler.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompiler.java deleted file mode 100644 index 24ef668e9b0..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompiler.java +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Deque; -import java.util.LinkedList; -import java.util.List; -import java.util.ServiceLoader; - -import groovy.grape.GrapeEngine; -import groovy.lang.GroovyClassLoader; -import groovy.lang.GroovyClassLoader.ClassCollector; -import groovy.lang.GroovyCodeSource; -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.classgen.GeneratorContext; -import org.codehaus.groovy.control.CompilationFailedException; -import org.codehaus.groovy.control.CompilationUnit; -import org.codehaus.groovy.control.CompilePhase; -import org.codehaus.groovy.control.CompilerConfiguration; -import org.codehaus.groovy.control.Phases; -import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.control.customizers.CompilationCustomizer; -import org.codehaus.groovy.control.customizers.ImportCustomizer; -import org.codehaus.groovy.transform.ASTTransformation; -import org.codehaus.groovy.transform.ASTTransformationVisitor; - -import org.springframework.boot.cli.compiler.dependencies.SpringBootDependenciesDependencyManagement; -import org.springframework.boot.cli.compiler.grape.DependencyResolutionContext; -import org.springframework.boot.cli.compiler.grape.GrapeEngineInstaller; -import org.springframework.boot.cli.compiler.grape.MavenResolverGrapeEngineFactory; -import org.springframework.boot.cli.util.ResourceUtils; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.util.ClassUtils; - -/** - * Compiler for Groovy sources. Primarily a simple Facade for - * {@link GroovyClassLoader#parseClass(GroovyCodeSource)} with the following additional - * features: - *

    - *
  • {@link CompilerAutoConfiguration} strategies will be read from - * {@code META-INF/services/org.springframework.boot.cli.compiler.CompilerAutoConfiguration} - * (per the standard java {@link ServiceLoader} contract) and applied during compilation - *
  • - * - *
  • Multiple classes can be returned if the Groovy source defines more than one Class - *
  • - * - *
  • Generated class files can also be loaded using - * {@link ClassLoader#getResource(String)}
  • - *
- * - * @author Phillip Webb - * @author Dave Syer - * @author Andy Wilkinson - * @since 1.0.0 - */ -public class GroovyCompiler { - - private final GroovyCompilerConfiguration configuration; - - private final ExtendedGroovyClassLoader loader; - - private final Iterable compilerAutoConfigurations; - - private final List transformations; - - /** - * Create a new {@link GroovyCompiler} instance. - * @param configuration the compiler configuration - */ - public GroovyCompiler(GroovyCompilerConfiguration configuration) { - - this.configuration = configuration; - this.loader = createLoader(configuration); - - DependencyResolutionContext resolutionContext = new DependencyResolutionContext(); - resolutionContext.addDependencyManagement(new SpringBootDependenciesDependencyManagement()); - - GrapeEngine grapeEngine = MavenResolverGrapeEngineFactory.create(this.loader, - configuration.getRepositoryConfiguration(), resolutionContext, configuration.isQuiet()); - - GrapeEngineInstaller.install(grapeEngine); - - this.loader.getConfiguration().addCompilationCustomizers(new CompilerAutoConfigureCustomizer()); - if (configuration.isAutoconfigure()) { - this.compilerAutoConfigurations = ServiceLoader.load(CompilerAutoConfiguration.class); - } - else { - this.compilerAutoConfigurations = Collections.emptySet(); - } - - this.transformations = new ArrayList<>(); - this.transformations.add(new DependencyManagementBomTransformation(resolutionContext)); - this.transformations.add(new DependencyAutoConfigurationTransformation(this.loader, resolutionContext, - this.compilerAutoConfigurations)); - this.transformations.add(new GroovyBeansTransformation()); - if (this.configuration.isGuessDependencies()) { - this.transformations.add(new ResolveDependencyCoordinatesTransformation(resolutionContext)); - } - for (ASTTransformation transformation : ServiceLoader.load(SpringBootAstTransformation.class)) { - this.transformations.add(transformation); - } - this.transformations.sort(AnnotationAwareOrderComparator.INSTANCE); - } - - /** - * Return a mutable list of the {@link ASTTransformation}s to be applied during - * {@link #compile(String...)}. - * @return the AST transformations to apply - */ - public List getAstTransformations() { - return this.transformations; - } - - public ExtendedGroovyClassLoader getLoader() { - return this.loader; - } - - private ExtendedGroovyClassLoader createLoader(GroovyCompilerConfiguration configuration) { - - ExtendedGroovyClassLoader loader = new ExtendedGroovyClassLoader(configuration.getScope()); - - for (URL url : getExistingUrls()) { - loader.addURL(url); - } - - for (String classpath : configuration.getClasspath()) { - loader.addClasspath(classpath); - } - - return loader; - } - - private URL[] getExistingUrls() { - ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - if (tccl instanceof ExtendedGroovyClassLoader groovyClassLoader) { - return groovyClassLoader.getURLs(); - } - else { - return new URL[0]; - } - } - - public void addCompilationCustomizers(CompilationCustomizer... customizers) { - this.loader.getConfiguration().addCompilationCustomizers(customizers); - } - - /** - * Compile the specified Groovy sources, applying any - * {@link CompilerAutoConfiguration}s. All classes defined in the sources will be - * returned from this method. - * @param sources the sources to compile - * @return compiled classes - * @throws CompilationFailedException in case of compilation failures - * @throws IOException in case of I/O errors - * @throws CompilationFailedException in case of compilation errors - */ - public Class[] compile(String... sources) throws CompilationFailedException, IOException { - - this.loader.clearCache(); - List> classes = new ArrayList<>(); - - CompilerConfiguration configuration = this.loader.getConfiguration(); - - CompilationUnit compilationUnit = new CompilationUnit(configuration, null, this.loader); - ClassCollector collector = this.loader.createCollector(compilationUnit, null); - compilationUnit.setClassgenCallback(collector); - - for (String source : sources) { - List paths = ResourceUtils.getUrls(source, this.loader); - for (String path : paths) { - compilationUnit.addSource(new URL(path)); - } - } - - addAstTransformations(compilationUnit); - - compilationUnit.compile(Phases.CLASS_GENERATION); - for (Object loadedClass : collector.getLoadedClasses()) { - classes.add((Class) loadedClass); - } - ClassNode mainClassNode = MainClass.get(compilationUnit); - - Class mainClass = null; - for (Class loadedClass : classes) { - if (mainClassNode.getName().equals(loadedClass.getName())) { - mainClass = loadedClass; - } - } - if (mainClass != null) { - classes.remove(mainClass); - classes.add(0, mainClass); - } - - return ClassUtils.toClassArray(classes); - } - - @SuppressWarnings("rawtypes") - private void addAstTransformations(CompilationUnit compilationUnit) { - Deque[] phaseOperations = getPhaseOperations(compilationUnit); - processConversionOperations((LinkedList) phaseOperations[Phases.CONVERSION]); - } - - @SuppressWarnings("rawtypes") - private Deque[] getPhaseOperations(CompilationUnit compilationUnit) { - try { - Field field = CompilationUnit.class.getDeclaredField("phaseOperations"); - field.setAccessible(true); - return (Deque[]) field.get(compilationUnit); - } - catch (Exception ex) { - throw new IllegalStateException("Phase operations not available from compilation unit"); - } - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void processConversionOperations(LinkedList conversionOperations) { - int index = getIndexOfASTTransformationVisitor(conversionOperations); - conversionOperations.add(index, new CompilationUnit.ISourceUnitOperation() { - @Override - public void call(SourceUnit source) throws CompilationFailedException { - ASTNode[] nodes = new ASTNode[] { source.getAST() }; - for (ASTTransformation transformation : GroovyCompiler.this.transformations) { - transformation.visit(nodes, source); - } - } - }); - } - - private int getIndexOfASTTransformationVisitor(List conversionOperations) { - for (int index = 0; index < conversionOperations.size(); index++) { - if (conversionOperations.get(index).getClass().getName() - .startsWith(ASTTransformationVisitor.class.getName())) { - return index; - } - } - return conversionOperations.size(); - } - - /** - * {@link CompilationCustomizer} to call {@link CompilerAutoConfiguration}s. - */ - private class CompilerAutoConfigureCustomizer extends CompilationCustomizer { - - CompilerAutoConfigureCustomizer() { - super(CompilePhase.CONVERSION); - } - - @Override - public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) - throws CompilationFailedException { - - ImportCustomizer importCustomizer = new SmartImportCustomizer(source); - List classNodes = source.getAST().getClasses(); - ClassNode mainClassNode = MainClass.get(classNodes); - - // Additional auto configuration - for (CompilerAutoConfiguration autoConfiguration : GroovyCompiler.this.compilerAutoConfigurations) { - if (classNodes.stream().anyMatch(autoConfiguration::matches)) { - if (GroovyCompiler.this.configuration.isGuessImports()) { - autoConfiguration.applyImports(importCustomizer); - importCustomizer.call(source, context, classNode); - } - if (classNode.equals(mainClassNode)) { - autoConfiguration.applyToMainClass(GroovyCompiler.this.loader, - GroovyCompiler.this.configuration, context, source, classNode); - } - autoConfiguration.apply(GroovyCompiler.this.loader, GroovyCompiler.this.configuration, context, - source, classNode); - } - } - importCustomizer.call(source, context, classNode); - } - - } - - private static class MainClass { - - static ClassNode get(CompilationUnit source) { - return get(source.getAST().getClasses()); - } - - static ClassNode get(List classes) { - for (ClassNode node : classes) { - if (AstUtils.hasAtLeastOneAnnotation(node, "Enable*AutoConfiguration")) { - return null; // No need to enhance this - } - if (AstUtils.hasAtLeastOneAnnotation(node, "*Controller", "Configuration", "Component", "*Service", - "Repository", "Enable*")) { - return node; - } - } - return classes.isEmpty() ? null : classes.get(0); - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompilerConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompilerConfiguration.java deleted file mode 100644 index 7dd9dbaaddd..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompilerConfiguration.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler; - -import java.util.List; - -import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration; - -/** - * Configuration for the {@link GroovyCompiler}. - * - * @author Phillip Webb - * @author Andy Wilkinson - * @since 1.0.0 - */ -public interface GroovyCompilerConfiguration { - - /** - * Constant to be used when there is no {@link #getClasspath() classpath}. - */ - String[] DEFAULT_CLASSPATH = { "." }; - - /** - * Returns the scope in which the compiler operates. - * @return the scope of the compiler - */ - GroovyCompilerScope getScope(); - - /** - * Returns if import declarations should be guessed. - * @return {@code true} if imports should be guessed, otherwise {@code false} - */ - boolean isGuessImports(); - - /** - * Returns if jar dependencies should be guessed. - * @return {@code true} if dependencies should be guessed, otherwise {@code false} - */ - boolean isGuessDependencies(); - - /** - * Returns true if auto-configuration transformations should be applied. - * @return {@code true} if auto-configuration transformations should be applied, - * otherwise {@code false} - */ - boolean isAutoconfigure(); - - /** - * Returns the classpath for local resources. - * @return a path for local resources - */ - String[] getClasspath(); - - /** - * Returns the configuration for the repositories that will be used by the compiler to - * resolve dependencies. - * @return the repository configurations - */ - List getRepositoryConfiguration(); - - /** - * Returns if running in quiet mode. - * @return {@code true} if running in quiet mode - */ - boolean isQuiet(); - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompilerScope.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompilerScope.java deleted file mode 100644 index adf22b2cb7f..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompilerScope.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler; - -/** - * The scope in which a groovy compiler operates. - * - * @author Phillip Webb - * @since 1.0.0 - */ -public enum GroovyCompilerScope { - - /** - * Default scope, exposes groovy.jar (loaded from the parent) and the shared cli - * package (loaded via groovy classloader). - */ - DEFAULT, - - /** - * Extension scope, allows full access to internal CLI classes. - */ - EXTENSION - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/RepositoryConfigurationFactory.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/RepositoryConfigurationFactory.java deleted file mode 100644 index e20a438a861..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/RepositoryConfigurationFactory.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler; - -import java.io.File; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -import org.apache.maven.settings.Profile; -import org.apache.maven.settings.Repository; -import org.codehaus.plexus.interpolation.InterpolationException; -import org.codehaus.plexus.interpolation.Interpolator; -import org.codehaus.plexus.interpolation.PropertiesBasedValueSource; -import org.codehaus.plexus.interpolation.RegexBasedInterpolator; - -import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration; -import org.springframework.boot.cli.compiler.maven.MavenSettings; -import org.springframework.boot.cli.compiler.maven.MavenSettingsReader; -import org.springframework.util.StringUtils; - -/** - * Factory used to create {@link RepositoryConfiguration}s. - * - * @author Andy Wilkinson - * @author Dave Syer - * @since 1.0.0 - */ -public final class RepositoryConfigurationFactory { - - private static final RepositoryConfiguration MAVEN_CENTRAL = new RepositoryConfiguration("central", - URI.create("https://repo.maven.apache.org/maven2/"), false); - - private static final RepositoryConfiguration SPRING_MILESTONE = new RepositoryConfiguration("spring-milestone", - URI.create("https://repo.spring.io/milestone"), false); - - private static final RepositoryConfiguration SPRING_SNAPSHOT = new RepositoryConfiguration("spring-snapshot", - URI.create("https://repo.spring.io/snapshot"), true); - - private RepositoryConfigurationFactory() { - } - - /** - * Create a new default repository configuration. - * @return the newly-created default repository configuration - */ - public static List createDefaultRepositoryConfiguration() { - MavenSettings mavenSettings = new MavenSettingsReader().readSettings(); - List repositoryConfiguration = new ArrayList<>(); - repositoryConfiguration.add(MAVEN_CENTRAL); - if (!Boolean.getBoolean("disableSpringSnapshotRepos")) { - repositoryConfiguration.add(SPRING_MILESTONE); - repositoryConfiguration.add(SPRING_SNAPSHOT); - } - addDefaultCacheAsRepository(mavenSettings.getLocalRepository(), repositoryConfiguration); - addActiveProfileRepositories(mavenSettings.getActiveProfiles(), repositoryConfiguration); - return repositoryConfiguration; - } - - private static void addDefaultCacheAsRepository(String localRepository, - List repositoryConfiguration) { - RepositoryConfiguration repository = new RepositoryConfiguration("local", - getLocalRepositoryDirectory(localRepository).toURI(), true); - if (!repositoryConfiguration.contains(repository)) { - repositoryConfiguration.add(0, repository); - } - } - - private static void addActiveProfileRepositories(List activeProfiles, - List configurations) { - for (Profile activeProfile : activeProfiles) { - Interpolator interpolator = new RegexBasedInterpolator(); - interpolator.addValueSource(new PropertiesBasedValueSource(activeProfile.getProperties())); - for (Repository repository : activeProfile.getRepositories()) { - configurations.add(getRepositoryConfiguration(interpolator, repository)); - } - } - } - - private static RepositoryConfiguration getRepositoryConfiguration(Interpolator interpolator, - Repository repository) { - String name = interpolate(interpolator, repository.getId()); - String url = interpolate(interpolator, repository.getUrl()); - boolean snapshotsEnabled = false; - if (repository.getSnapshots() != null) { - snapshotsEnabled = repository.getSnapshots().isEnabled(); - } - return new RepositoryConfiguration(name, URI.create(url), snapshotsEnabled); - } - - private static String interpolate(Interpolator interpolator, String value) { - try { - return interpolator.interpolate(value); - } - catch (InterpolationException ex) { - return value; - } - } - - private static File getLocalRepositoryDirectory(String localRepository) { - if (StringUtils.hasText(localRepository)) { - return new File(localRepository); - } - return new File(getM2HomeDirectory(), "repository"); - } - - private static File getM2HomeDirectory() { - String mavenRoot = System.getProperty("maven.home"); - if (StringUtils.hasLength(mavenRoot)) { - return new File(mavenRoot); - } - return new File(System.getProperty("user.home"), ".m2"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/ResolveDependencyCoordinatesTransformation.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/ResolveDependencyCoordinatesTransformation.java deleted file mode 100644 index fe2fc3f4a06..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/ResolveDependencyCoordinatesTransformation.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import groovy.lang.Grab; -import org.codehaus.groovy.ast.AnnotationNode; -import org.codehaus.groovy.ast.expr.ConstantExpression; -import org.codehaus.groovy.ast.expr.Expression; -import org.codehaus.groovy.transform.ASTTransformation; - -import org.springframework.boot.cli.compiler.grape.DependencyResolutionContext; -import org.springframework.core.annotation.Order; - -/** - * {@link ASTTransformation} to resolve {@link Grab @Grab} artifact coordinates. - * - * @author Andy Wilkinson - * @author Phillip Webb - * @since 1.0.0 - */ -@Order(ResolveDependencyCoordinatesTransformation.ORDER) -public class ResolveDependencyCoordinatesTransformation extends AnnotatedNodeASTTransformation { - - /** - * The order of the transformation. - */ - public static final int ORDER = DependencyManagementBomTransformation.ORDER + 300; - - private static final Set GRAB_ANNOTATION_NAMES = Collections - .unmodifiableSet(new HashSet<>(Arrays.asList(Grab.class.getName(), Grab.class.getSimpleName()))); - - private final DependencyResolutionContext resolutionContext; - - public ResolveDependencyCoordinatesTransformation(DependencyResolutionContext resolutionContext) { - super(GRAB_ANNOTATION_NAMES, false); - this.resolutionContext = resolutionContext; - } - - @Override - protected void processAnnotationNodes(List annotationNodes) { - for (AnnotationNode annotationNode : annotationNodes) { - transformGrabAnnotation(annotationNode); - } - } - - private void transformGrabAnnotation(AnnotationNode grabAnnotation) { - grabAnnotation.setMember("initClass", new ConstantExpression(false)); - String value = getValue(grabAnnotation); - if (value != null && !isConvenienceForm(value)) { - applyGroupAndVersion(grabAnnotation, value); - } - } - - private String getValue(AnnotationNode annotation) { - Expression expression = annotation.getMember("value"); - if (expression instanceof ConstantExpression constantExpression) { - Object value = constantExpression.getValue(); - return (value instanceof String string) ? string : null; - } - return null; - } - - private boolean isConvenienceForm(String value) { - return value.contains(":") || value.contains("#"); - } - - private void applyGroupAndVersion(AnnotationNode annotation, String module) { - if (module != null) { - setMember(annotation, "module", module); - } - else { - Expression expression = annotation.getMembers().get("module"); - module = (String) ((ConstantExpression) expression).getValue(); - } - if (annotation.getMember("group") == null) { - setMember(annotation, "group", this.resolutionContext.getArtifactCoordinatesResolver().getGroupId(module)); - } - if (annotation.getMember("version") == null) { - setMember(annotation, "version", - this.resolutionContext.getArtifactCoordinatesResolver().getVersion(module)); - } - } - - private void setMember(AnnotationNode annotation, String name, String value) { - ConstantExpression expression = new ConstantExpression(value); - annotation.setMember(name, expression); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/SmartImportCustomizer.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/SmartImportCustomizer.java deleted file mode 100644 index 39d0a803d1b..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/SmartImportCustomizer.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler; - -import org.codehaus.groovy.ast.ClassHelper; -import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -/** - * Smart extension of {@link ImportCustomizer} that will only add a specific import if a - * class with the same name is not already explicitly imported. - * - * @author Dave Syer - */ -class SmartImportCustomizer extends ImportCustomizer { - - private SourceUnit source; - - SmartImportCustomizer(SourceUnit source) { - this.source = source; - } - - @Override - public ImportCustomizer addImport(String alias, String className) { - if (this.source.getAST().getImport(ClassHelper.make(className).getNameWithoutPackage()) == null) { - super.addImport(alias, className); - } - return this; - } - - @Override - public ImportCustomizer addImports(String... imports) { - for (String alias : imports) { - if (this.source.getAST().getImport(ClassHelper.make(alias).getNameWithoutPackage()) == null) { - super.addImports(alias); - } - } - return this; - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/SpringBootAstTransformation.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/SpringBootAstTransformation.java deleted file mode 100644 index 00fa3f0d3dd..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/SpringBootAstTransformation.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler; - -import org.codehaus.groovy.transform.ASTTransformation; - -/** - * Marker interface for AST transformations that should be installed automatically from - * {@code META-INF/services}. - * - * @author Dave Syer - * @since 1.0.0 - */ -@FunctionalInterface -public interface SpringBootAstTransformation extends ASTTransformation { - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/CachingCompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/CachingCompilerAutoConfiguration.java deleted file mode 100644 index 7c14baba4a8..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/CachingCompilerAutoConfiguration.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.autoconfigure; - -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.control.CompilationFailedException; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -import org.springframework.boot.cli.compiler.AstUtils; -import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; -import org.springframework.boot.cli.compiler.DependencyCustomizer; - -/** - * {@link CompilerAutoConfiguration} for the caching infrastructure. - * - * @author Stephane Nicoll - * @since 1.2.0 - */ -public class CachingCompilerAutoConfiguration extends CompilerAutoConfiguration { - - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableCaching"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) throws CompilationFailedException { - dependencies.add("spring-context-support"); - } - - @Override - public void applyImports(ImportCustomizer imports) throws CompilationFailedException { - imports.addStarImports("org.springframework.cache", "org.springframework.cache.annotation", - "org.springframework.cache.concurrent"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/GroovyTemplatesCompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/GroovyTemplatesCompilerAutoConfiguration.java deleted file mode 100644 index f0060141b6f..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/GroovyTemplatesCompilerAutoConfiguration.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.autoconfigure; - -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -import org.springframework.boot.cli.compiler.AstUtils; -import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; -import org.springframework.boot.cli.compiler.DependencyCustomizer; -import org.springframework.boot.groovy.EnableGroovyTemplates; -import org.springframework.boot.groovy.GroovyTemplate; - -/** - * {@link CompilerAutoConfiguration} for Groovy Templates (outside MVC). - * - * @author Dave Syer - * @since 1.1.0 - */ -public class GroovyTemplatesCompilerAutoConfiguration extends CompilerAutoConfiguration { - - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableGroovyTemplates"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("groovy.text.TemplateEngine").add("groovy-templates"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addStarImports("groovy.text"); - imports.addImports(EnableGroovyTemplates.class.getCanonicalName()); - imports.addStaticImport(GroovyTemplate.class.getName(), "template"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/JdbcCompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/JdbcCompilerAutoConfiguration.java deleted file mode 100644 index abf70a9d925..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/JdbcCompilerAutoConfiguration.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.autoconfigure; - -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -import org.springframework.boot.cli.compiler.AstUtils; -import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; -import org.springframework.boot.cli.compiler.DependencyCustomizer; - -/** - * {@link CompilerAutoConfiguration} for Spring JDBC. - * - * @author Dave Syer - * @since 1.0.0 - */ -public class JdbcCompilerAutoConfiguration extends CompilerAutoConfiguration { - - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneFieldOrMethod(classNode, "JdbcTemplate", "NamedParameterJdbcTemplate", - "DataSource"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.jdbc.core.JdbcTemplate").add("spring-boot-starter-jdbc"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addStarImports("org.springframework.jdbc.core", "org.springframework.jdbc.core.namedparam"); - imports.addImports("javax.sql.DataSource"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/JmsCompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/JmsCompilerAutoConfiguration.java deleted file mode 100644 index 3b0c26d23a7..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/JmsCompilerAutoConfiguration.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.cli.compiler.autoconfigure; - -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.control.CompilationFailedException; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -import org.springframework.boot.cli.compiler.AstUtils; -import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; -import org.springframework.boot.cli.compiler.DependencyCustomizer; - -/** - * {@link CompilerAutoConfiguration} for Spring JMS. - * - * @author Greg Turnquist - * @author Stephane Nicoll - * @since 1.0.0 - */ -public class JmsCompilerAutoConfiguration extends CompilerAutoConfiguration { - - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableJms") - || AstUtils.hasAtLeastOneAnnotation(classNode, "EnableJmsMessaging"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) throws CompilationFailedException { - dependencies.add("spring-jms", "jakarta.jms-api"); - } - - @Override - public void applyImports(ImportCustomizer imports) throws CompilationFailedException { - imports.addStarImports("jakarta.jms", "org.springframework.jms.annotation", "org.springframework.jms.config", - "org.springframework.jms.core", "org.springframework.jms.listener", - "org.springframework.jms.listener.adapter"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/RabbitCompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/RabbitCompilerAutoConfiguration.java deleted file mode 100644 index a7632056c2e..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/RabbitCompilerAutoConfiguration.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.autoconfigure; - -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.control.CompilationFailedException; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -import org.springframework.boot.cli.compiler.AstUtils; -import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; -import org.springframework.boot.cli.compiler.DependencyCustomizer; - -/** - * {@link CompilerAutoConfiguration} for Spring Rabbit. - * - * @author Greg Turnquist - * @author Stephane Nicoll - * @since 1.0.0 - */ -public class RabbitCompilerAutoConfiguration extends CompilerAutoConfiguration { - - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableRabbit") - || AstUtils.hasAtLeastOneAnnotation(classNode, "EnableRabbitMessaging"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) throws CompilationFailedException { - dependencies.add("spring-rabbit"); - - } - - @Override - public void applyImports(ImportCustomizer imports) throws CompilationFailedException { - imports.addStarImports("org.springframework.amqp.rabbit.annotation", "org.springframework.amqp.rabbit.core", - "org.springframework.amqp.rabbit.config", "org.springframework.amqp.rabbit.connection", - "org.springframework.amqp.rabbit.listener", "org.springframework.amqp.rabbit.listener.adapter", - "org.springframework.amqp.core"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringBatchCompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringBatchCompilerAutoConfiguration.java deleted file mode 100644 index bb880fb5f3b..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringBatchCompilerAutoConfiguration.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.autoconfigure; - -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -import org.springframework.boot.cli.compiler.AstUtils; -import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; -import org.springframework.boot.cli.compiler.DependencyCustomizer; - -/** - * {@link CompilerAutoConfiguration} for Spring Batch. - * - * @author Dave Syer - * @author Phillip Webb - * @since 1.0.0 - */ -public class SpringBatchCompilerAutoConfiguration extends CompilerAutoConfiguration { - - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableBatchProcessing"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.batch.core.Job").add("spring-boot-starter-batch"); - dependencies.ifAnyMissingClasses("org.springframework.jdbc.core.JdbcTemplate").add("spring-jdbc"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addImports("org.springframework.batch.repeat.RepeatStatus", - "org.springframework.batch.core.scope.context.ChunkContext", - "org.springframework.batch.core.step.tasklet.Tasklet", - "org.springframework.batch.core.configuration.annotation.StepScope", - "org.springframework.batch.core.configuration.annotation.JobBuilderFactory", - "org.springframework.batch.core.configuration.annotation.StepBuilderFactory", - "org.springframework.batch.core.configuration.annotation.EnableBatchProcessing", - "org.springframework.batch.core.Step", "org.springframework.batch.core.StepExecution", - "org.springframework.batch.core.StepContribution", "org.springframework.batch.core.Job", - "org.springframework.batch.core.JobExecution", "org.springframework.batch.core.JobParameter", - "org.springframework.batch.core.JobParameters", "org.springframework.batch.core.launch.JobLauncher", - "org.springframework.batch.core.converter.JobParametersConverter", - "org.springframework.batch.core.converter.DefaultJobParametersConverter"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringBootCompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringBootCompilerAutoConfiguration.java deleted file mode 100644 index e0a327a9f61..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringBootCompilerAutoConfiguration.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.cli.compiler.autoconfigure; - -import groovy.lang.GroovyClassLoader; -import org.codehaus.groovy.ast.AnnotationNode; -import org.codehaus.groovy.ast.ClassHelper; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.classgen.GeneratorContext; -import org.codehaus.groovy.control.CompilationFailedException; -import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; -import org.springframework.boot.cli.compiler.DependencyCustomizer; -import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration; - -/** - * {@link CompilerAutoConfiguration} for Spring. - * - * @author Dave Syer - * @author Phillip Webb - * @since 1.0.0 - */ -public class SpringBootCompilerAutoConfiguration extends CompilerAutoConfiguration { - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.boot.SpringApplication").add("spring-boot-starter"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addImports("jakarta.annotation.PostConstruct", "jakarta.annotation.PreDestroy", - "groovy.util.logging.Log", "org.springframework.stereotype.Controller", - "org.springframework.stereotype.Service", "org.springframework.stereotype.Component", - "org.springframework.beans.factory.annotation.Autowired", - "org.springframework.beans.factory.annotation.Value", "org.springframework.context.annotation.Import", - "org.springframework.context.annotation.ImportResource", - "org.springframework.context.annotation.Profile", "org.springframework.context.annotation.Scope", - "org.springframework.context.annotation.Configuration", - "org.springframework.context.annotation.ComponentScan", "org.springframework.context.annotation.Bean", - "org.springframework.context.ApplicationContext", "org.springframework.context.MessageSource", - "org.springframework.core.annotation.Order", "org.springframework.core.io.ResourceLoader", - "org.springframework.boot.ApplicationRunner", "org.springframework.boot.ApplicationArguments", - "org.springframework.boot.CommandLineRunner", - "org.springframework.boot.context.properties.ConfigurationProperties", - "org.springframework.boot.context.properties.EnableConfigurationProperties", - "org.springframework.boot.autoconfigure.EnableAutoConfiguration", - "org.springframework.boot.autoconfigure.SpringBootApplication", - "org.springframework.boot.context.properties.ConfigurationProperties", - "org.springframework.boot.context.properties.EnableConfigurationProperties"); - imports.addStarImports("org.springframework.stereotype", "org.springframework.scheduling.annotation"); - } - - @Override - public void applyToMainClass(GroovyClassLoader loader, GroovyCompilerConfiguration configuration, - GeneratorContext generatorContext, SourceUnit source, ClassNode classNode) - throws CompilationFailedException { - addEnableAutoConfigurationAnnotation(classNode); - } - - private void addEnableAutoConfigurationAnnotation(ClassNode classNode) { - if (!hasEnableAutoConfigureAnnotation(classNode)) { - AnnotationNode annotationNode = new AnnotationNode(ClassHelper.make("EnableAutoConfiguration")); - classNode.addAnnotation(annotationNode); - } - } - - private boolean hasEnableAutoConfigureAnnotation(ClassNode classNode) { - for (AnnotationNode node : classNode.getAnnotations()) { - String name = node.getClassNode().getNameWithoutPackage(); - if ("EnableAutoConfiguration".equals(name) || "SpringBootApplication".equals(name)) { - return true; - } - } - return false; - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringIntegrationCompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringIntegrationCompilerAutoConfiguration.java deleted file mode 100644 index ac7a8864c48..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringIntegrationCompilerAutoConfiguration.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.autoconfigure; - -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -import org.springframework.boot.cli.compiler.AstUtils; -import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; -import org.springframework.boot.cli.compiler.DependencyCustomizer; - -/** - * {@link CompilerAutoConfiguration} for Spring Integration. - * - * @author Dave Syer - * @author Artem Bilan - * @since 1.0.0 - */ -public class SpringIntegrationCompilerAutoConfiguration extends CompilerAutoConfiguration { - - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableIntegration") - || AstUtils.hasAtLeastOneAnnotation(classNode, "MessageEndpoint"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.integration.config.EnableIntegration") - .add("spring-boot-starter-integration"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addImports("org.springframework.messaging.Message", "org.springframework.messaging.MessageChannel", - "org.springframework.messaging.PollableChannel", "org.springframework.messaging.SubscribableChannel", - "org.springframework.messaging.MessageHeaders", - "org.springframework.integration.support.MessageBuilder", - "org.springframework.integration.channel.DirectChannel", - "org.springframework.integration.channel.QueueChannel", - "org.springframework.integration.channel.ExecutorChannel", - "org.springframework.integration.core.MessagingTemplate", - "org.springframework.integration.config.EnableIntegration"); - imports.addStarImports("org.springframework.integration.annotation"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringMvcCompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringMvcCompilerAutoConfiguration.java deleted file mode 100644 index 0d5dd70f666..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringMvcCompilerAutoConfiguration.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.autoconfigure; - -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -import org.springframework.boot.cli.compiler.AstUtils; -import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; -import org.springframework.boot.cli.compiler.DependencyCustomizer; -import org.springframework.boot.groovy.GroovyTemplate; - -/** - * {@link CompilerAutoConfiguration} for Spring MVC. - * - * @author Dave Syer - * @author Phillip Webb - * @since 1.0.0 - */ -public class SpringMvcCompilerAutoConfiguration extends CompilerAutoConfiguration { - - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "Controller", "RestController", "EnableWebMvc"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.web.servlet.mvc.Controller") - .add("spring-boot-starter-web"); - dependencies.ifAnyMissingClasses("groovy.text.TemplateEngine").add("groovy-templates"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addStarImports("org.springframework.web.bind.annotation", - "org.springframework.web.servlet.config.annotation", "org.springframework.web.servlet", - "org.springframework.http", "org.springframework.web.servlet.handler", "org.springframework.http", - "org.springframework.ui", "groovy.text"); - imports.addStaticImport(GroovyTemplate.class.getName(), "template"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringRetryCompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringRetryCompilerAutoConfiguration.java deleted file mode 100644 index 6148bd0991f..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringRetryCompilerAutoConfiguration.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.autoconfigure; - -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -import org.springframework.boot.cli.compiler.AstUtils; -import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; -import org.springframework.boot.cli.compiler.DependencyCustomizer; - -/** - * {@link CompilerAutoConfiguration} for Spring Retry. - * - * @author Dave Syer - * @since 1.3.0 - */ -public class SpringRetryCompilerAutoConfiguration extends CompilerAutoConfiguration { - - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableRetry", "Retryable", "Recover"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.retry.annotation.EnableRetry").add("spring-retry", - "spring-boot-starter-aop"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addStarImports("org.springframework.retry.annotation"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringSecurityCompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringSecurityCompilerAutoConfiguration.java deleted file mode 100644 index bc42f54cde3..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringSecurityCompilerAutoConfiguration.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.autoconfigure; - -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -import org.springframework.boot.cli.compiler.AstUtils; -import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; -import org.springframework.boot.cli.compiler.DependencyCustomizer; - -/** - * {@link CompilerAutoConfiguration} for Spring Security. - * - * @author Dave Syer - * @since 1.0.0 - */ -public class SpringSecurityCompilerAutoConfiguration extends CompilerAutoConfiguration { - - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableWebSecurity", "EnableGlobalMethodSecurity"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses( - "org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity") - .add("spring-boot-starter-security"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addImports("org.springframework.security.core.Authentication", - "org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity", - "org.springframework.security.core.authority.AuthorityUtils") - .addStarImports("org.springframework.security.config.annotation.web.configuration", - "org.springframework.security.authentication", - "org.springframework.security.config.annotation.web", - "org.springframework.security.config.annotation.web.builders"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringTestCompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringTestCompilerAutoConfiguration.java deleted file mode 100644 index 891721bbacc..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringTestCompilerAutoConfiguration.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.autoconfigure; - -import groovy.lang.GroovyClassLoader; -import org.codehaus.groovy.ast.AnnotationNode; -import org.codehaus.groovy.ast.ClassHelper; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.expr.ClassExpression; -import org.codehaus.groovy.classgen.GeneratorContext; -import org.codehaus.groovy.control.CompilationFailedException; -import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -import org.springframework.boot.cli.compiler.AstUtils; -import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; -import org.springframework.boot.cli.compiler.DependencyCustomizer; -import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration; - -/** - * {@link CompilerAutoConfiguration} for Spring Test. - * - * @author Dave Syer - * @since 1.1.0 - */ -public class SpringTestCompilerAutoConfiguration extends CompilerAutoConfiguration { - - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "SpringBootTest"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.http.HttpHeaders").add("spring-boot-starter-web"); - } - - @Override - public void apply(GroovyClassLoader loader, GroovyCompilerConfiguration configuration, - GeneratorContext generatorContext, SourceUnit source, ClassNode classNode) - throws CompilationFailedException { - if (!AstUtils.hasAtLeastOneAnnotation(classNode, "RunWith")) { - AnnotationNode runWith = new AnnotationNode(ClassHelper.make("RunWith")); - runWith.addMember("value", new ClassExpression(ClassHelper.make("SpringRunner"))); - classNode.addAnnotation(runWith); - } - } - - @Override - public void applyImports(ImportCustomizer imports) throws CompilationFailedException { - imports.addStarImports("org.junit.runner", "org.springframework.boot.test", - "org.springframework.boot.test.context", "org.springframework.boot.test.web.client", - "org.springframework.http", "org.springframework.test.context.junit4", - "org.springframework.test.annotation") - .addImports("org.springframework.boot.test.context.SpringBootTest.WebEnvironment", - "org.springframework.boot.test.web.client.TestRestTemplate"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringWebsocketCompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringWebsocketCompilerAutoConfiguration.java deleted file mode 100644 index 530aa0acc34..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/SpringWebsocketCompilerAutoConfiguration.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.autoconfigure; - -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -import org.springframework.boot.cli.compiler.AstUtils; -import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; -import org.springframework.boot.cli.compiler.DependencyCustomizer; - -/** - * {@link CompilerAutoConfiguration} for Spring Websocket. - * - * @author Dave Syer - * @since 1.0.0 - */ -public class SpringWebsocketCompilerAutoConfiguration extends CompilerAutoConfiguration { - - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableWebSocket", "EnableWebSocketMessageBroker"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.web.socket.config.annotation.EnableWebSocket") - .add("spring-boot-starter-websocket").add("spring-messaging"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addStarImports("org.springframework.messaging.handler.annotation", - "org.springframework.messaging.simp.config", "org.springframework.web.socket.handler", - "org.springframework.web.socket.sockjs.transport.handler", - "org.springframework.web.socket.config.annotation") - .addImports("org.springframework.web.socket.WebSocketHandler"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/TransactionManagementCompilerAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/TransactionManagementCompilerAutoConfiguration.java deleted file mode 100644 index b75203fa18b..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/TransactionManagementCompilerAutoConfiguration.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.autoconfigure; - -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.control.customizers.ImportCustomizer; - -import org.springframework.boot.cli.compiler.AstUtils; -import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; -import org.springframework.boot.cli.compiler.DependencyCustomizer; - -/** - * {@link CompilerAutoConfiguration} for Spring MVC. - * - * @author Dave Syer - * @author Phillip Webb - * @since 1.0.0 - */ -public class TransactionManagementCompilerAutoConfiguration extends CompilerAutoConfiguration { - - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableTransactionManagement"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.transaction.annotation.Transactional").add("spring-tx", - "spring-boot-starter-aop"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addStarImports("org.springframework.transaction.annotation", "org.springframework.transaction.support"); - imports.addImports("org.springframework.transaction.PlatformTransactionManager", - "org.springframework.transaction.support.AbstractPlatformTransactionManager"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/package-info.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/package-info.java deleted file mode 100644 index ae78a1d83f7..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/autoconfigure/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-2019 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. - */ - -/** - * Classes for auto-configuring the Groovy compiler. - */ -package org.springframework.boot.cli.compiler.autoconfigure; diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/ArtifactCoordinatesResolver.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/ArtifactCoordinatesResolver.java deleted file mode 100644 index 33d0d28cf24..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/ArtifactCoordinatesResolver.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.dependencies; - -/** - * A resolver for artifacts' Maven coordinates, allowing group id, artifact id, or version - * to be obtained from a module identifier. A module identifier may be in the form - * {@code groupId:artifactId:version}, in which case coordinate resolution simply extracts - * the relevant piece from the identifier. Alternatively the identifier may be in the form - * {@code artifactId}, in which case coordinate resolution uses implementation-specific - * metadata to resolve the groupId and version. - * - * @author Andy Wilkinson - * @since 1.0.0 - */ -public interface ArtifactCoordinatesResolver { - - /** - * Gets the group id of the artifact identified by the given {@code module}. Returns - * {@code null} if the artifact is unknown to the resolver. - * @param module the id of the module - * @return the group id of the module - */ - String getGroupId(String module); - - /** - * Gets the artifact id of the artifact identified by the given {@code module}. - * Returns {@code null} if the artifact is unknown to the resolver. - * @param module the id of the module - * @return the artifact id of the module - */ - String getArtifactId(String module); - - /** - * Gets the version of the artifact identified by the given {@code module}. Returns - * {@code null} if the artifact is unknown to the resolver. - * @param module the id of the module - * @return the version of the module - */ - String getVersion(String module); - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/CompositeDependencyManagement.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/CompositeDependencyManagement.java deleted file mode 100644 index 23d501a7c94..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/CompositeDependencyManagement.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.dependencies; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * {@link DependencyManagement} that delegates to one or more {@link DependencyManagement} - * instances. - * - * @author Andy Wilkinson - * @since 1.3.0 - */ -public class CompositeDependencyManagement implements DependencyManagement { - - private final List delegates; - - private final List dependencies = new ArrayList<>(); - - public CompositeDependencyManagement(DependencyManagement... delegates) { - this.delegates = Arrays.asList(delegates); - for (DependencyManagement delegate : delegates) { - this.dependencies.addAll(delegate.getDependencies()); - } - } - - @Override - public List getDependencies() { - return this.dependencies; - } - - @Override - public String getSpringBootVersion() { - for (DependencyManagement delegate : this.delegates) { - String version = delegate.getSpringBootVersion(); - if (version != null) { - return version; - } - } - return null; - } - - @Override - public Dependency find(String artifactId) { - for (DependencyManagement delegate : this.delegates) { - Dependency found = delegate.find(artifactId); - if (found != null) { - return found; - } - } - return null; - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/Dependency.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/Dependency.java deleted file mode 100644 index 05fbabcf373..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/Dependency.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.dependencies; - -import java.util.Collections; -import java.util.List; - -import org.springframework.util.Assert; - -/** - * A single dependency. - * - * @author Phillip Webb - * @since 1.3.0 - */ -public final class Dependency { - - private final String groupId; - - private final String artifactId; - - private final String version; - - private final List exclusions; - - /** - * Create a new {@link Dependency} instance. - * @param groupId the group ID - * @param artifactId the artifact ID - * @param version the version - */ - public Dependency(String groupId, String artifactId, String version) { - this(groupId, artifactId, version, Collections.emptyList()); - } - - /** - * Create a new {@link Dependency} instance. - * @param groupId the group ID - * @param artifactId the artifact ID - * @param version the version - * @param exclusions the exclusions - */ - public Dependency(String groupId, String artifactId, String version, List exclusions) { - Assert.notNull(groupId, "GroupId must not be null"); - Assert.notNull(artifactId, "ArtifactId must not be null"); - Assert.notNull(version, "Version must not be null"); - Assert.notNull(exclusions, "Exclusions must not be null"); - this.groupId = groupId; - this.artifactId = artifactId; - this.version = version; - this.exclusions = Collections.unmodifiableList(exclusions); - } - - /** - * Return the dependency group id. - * @return the group ID - */ - public String getGroupId() { - return this.groupId; - } - - /** - * Return the dependency artifact id. - * @return the artifact ID - */ - public String getArtifactId() { - return this.artifactId; - } - - /** - * Return the dependency version. - * @return the version - */ - public String getVersion() { - return this.version; - } - - /** - * Return the dependency exclusions. - * @return the exclusions - */ - public List getExclusions() { - return this.exclusions; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() == obj.getClass()) { - Dependency other = (Dependency) obj; - boolean result = true; - result = result && this.groupId.equals(other.groupId); - result = result && this.artifactId.equals(other.artifactId); - result = result && this.version.equals(other.version); - result = result && this.exclusions.equals(other.exclusions); - return result; - } - return false; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + this.groupId.hashCode(); - result = prime * result + this.artifactId.hashCode(); - result = prime * result + this.version.hashCode(); - result = prime * result + this.exclusions.hashCode(); - return result; - } - - @Override - public String toString() { - return this.groupId + ":" + this.artifactId + ":" + this.version; - } - - /** - * A dependency exclusion. - */ - public static final class Exclusion { - - private final String groupId; - - private final String artifactId; - - Exclusion(String groupId, String artifactId) { - Assert.notNull(groupId, "GroupId must not be null"); - Assert.notNull(artifactId, "ArtifactId must not be null"); - this.groupId = groupId; - this.artifactId = artifactId; - } - - /** - * Return the exclusion artifact ID. - * @return the exclusion artifact ID - */ - public String getArtifactId() { - return this.artifactId; - } - - /** - * Return the exclusion group ID. - * @return the exclusion group ID - */ - public String getGroupId() { - return this.groupId; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() == obj.getClass()) { - Exclusion other = (Exclusion) obj; - boolean result = true; - result = result && this.groupId.equals(other.groupId); - result = result && this.artifactId.equals(other.artifactId); - return result; - } - return false; - } - - @Override - public int hashCode() { - return this.groupId.hashCode() * 31 + this.artifactId.hashCode(); - } - - @Override - public String toString() { - return this.groupId + ":" + this.artifactId; - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/DependencyManagement.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/DependencyManagement.java deleted file mode 100644 index b635500828a..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/DependencyManagement.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.dependencies; - -import java.util.List; - -/** - * An encapsulation of dependency management information. - * - * @author Andy Wilkinson - * @since 1.3.0 - */ -public interface DependencyManagement { - - /** - * Returns the managed dependencies. - * @return the managed dependencies - */ - List getDependencies(); - - /** - * Returns the managed version of Spring Boot. May be {@code null}. - * @return the Spring Boot version, or {@code null} - */ - String getSpringBootVersion(); - - /** - * Finds the managed dependency with the given {@code artifactId}. - * @param artifactId the artifact ID of the dependency to find - * @return the dependency, or {@code null} - */ - Dependency find(String artifactId); - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/DependencyManagementArtifactCoordinatesResolver.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/DependencyManagementArtifactCoordinatesResolver.java deleted file mode 100644 index 9760f86a1ec..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/DependencyManagementArtifactCoordinatesResolver.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.dependencies; - -import org.springframework.util.StringUtils; - -/** - * {@link ArtifactCoordinatesResolver} backed by - * {@link SpringBootDependenciesDependencyManagement}. - * - * @author Phillip Webb - * @author Andy Wilkinson - * @since 1.0.0 - */ -public class DependencyManagementArtifactCoordinatesResolver implements ArtifactCoordinatesResolver { - - private final DependencyManagement dependencyManagement; - - public DependencyManagementArtifactCoordinatesResolver() { - this(new SpringBootDependenciesDependencyManagement()); - } - - public DependencyManagementArtifactCoordinatesResolver(DependencyManagement dependencyManagement) { - this.dependencyManagement = dependencyManagement; - } - - @Override - public String getGroupId(String artifactId) { - Dependency dependency = find(artifactId); - return (dependency != null) ? dependency.getGroupId() : null; - } - - @Override - public String getArtifactId(String id) { - Dependency dependency = find(id); - return (dependency != null) ? dependency.getArtifactId() : null; - } - - private Dependency find(String id) { - if (StringUtils.countOccurrencesOf(id, ":") == 2) { - String[] tokens = id.split(":"); - return new Dependency(tokens[0], tokens[1], tokens[2]); - } - if (id != null) { - if (id.startsWith("spring-boot")) { - return new Dependency("org.springframework.boot", id, this.dependencyManagement.getSpringBootVersion()); - } - return this.dependencyManagement.find(id); - } - return null; - } - - @Override - public String getVersion(String module) { - Dependency dependency = find(module); - return (dependency != null) ? dependency.getVersion() : null; - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/MavenModelDependencyManagement.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/MavenModelDependencyManagement.java deleted file mode 100644 index 01d8274712f..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/MavenModelDependencyManagement.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.dependencies; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.apache.maven.model.Model; - -import org.springframework.boot.cli.compiler.dependencies.Dependency.Exclusion; - -/** - * {@link DependencyManagement} derived from a Maven {@link Model}. - * - * @author Andy Wilkinson - * @since 1.3.0 - */ -public class MavenModelDependencyManagement implements DependencyManagement { - - private final List dependencies; - - private final Map byArtifactId = new LinkedHashMap<>(); - - public MavenModelDependencyManagement(Model model) { - this.dependencies = extractDependenciesFromModel(model); - for (Dependency dependency : this.dependencies) { - this.byArtifactId.put(dependency.getArtifactId(), dependency); - } - } - - private static List extractDependenciesFromModel(Model model) { - List dependencies = new ArrayList<>(); - for (org.apache.maven.model.Dependency mavenDependency : model.getDependencyManagement().getDependencies()) { - List exclusions = new ArrayList<>(); - for (org.apache.maven.model.Exclusion mavenExclusion : mavenDependency.getExclusions()) { - exclusions.add(new Exclusion(mavenExclusion.getGroupId(), mavenExclusion.getArtifactId())); - } - Dependency dependency = new Dependency(mavenDependency.getGroupId(), mavenDependency.getArtifactId(), - mavenDependency.getVersion(), exclusions); - dependencies.add(dependency); - } - return dependencies; - } - - @Override - public List getDependencies() { - return this.dependencies; - } - - @Override - public String getSpringBootVersion() { - return find("spring-boot").getVersion(); - } - - @Override - public Dependency find(String artifactId) { - return this.byArtifactId.get(artifactId); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/SpringBootDependenciesDependencyManagement.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/SpringBootDependenciesDependencyManagement.java deleted file mode 100644 index 436a3f7e3b2..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/SpringBootDependenciesDependencyManagement.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli.compiler.dependencies; - -import java.io.IOException; - -import org.apache.maven.model.Model; -import org.apache.maven.model.building.DefaultModelProcessor; -import org.apache.maven.model.io.DefaultModelReader; -import org.apache.maven.model.locator.DefaultModelLocator; - -/** - * {@link DependencyManagement} derived from the effective pom of - * {@code spring-boot-dependencies}. - * - * @author Andy Wilkinson - * @since 1.3.0 - */ -public class SpringBootDependenciesDependencyManagement extends MavenModelDependencyManagement { - - public SpringBootDependenciesDependencyManagement() { - super(readModel()); - } - - private static Model readModel() { - DefaultModelProcessor modelProcessor = new DefaultModelProcessor(); - modelProcessor.setModelLocator(new DefaultModelLocator()); - modelProcessor.setModelReader(new DefaultModelReader()); - - try { - 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); - } - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/package-info.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/package-info.java deleted file mode 100644 index 593a6c891e8..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/dependencies/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-2019 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. - */ - -/** - * Classes for dependencies used during compilation. - */ -package org.springframework.boot.cli.compiler.dependencies; diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/CompositeProxySelector.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/CompositeProxySelector.java deleted file mode 100644 index 45655930d75..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/CompositeProxySelector.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.grape; - -import java.util.List; - -import org.eclipse.aether.repository.Proxy; -import org.eclipse.aether.repository.ProxySelector; -import org.eclipse.aether.repository.RemoteRepository; - -/** - * Composite {@link ProxySelector}. - * - * @author Dave Syer - * @since 1.1.0 - */ -public class CompositeProxySelector implements ProxySelector { - - private final List selectors; - - public CompositeProxySelector(List selectors) { - this.selectors = selectors; - } - - @Override - public Proxy getProxy(RemoteRepository repository) { - for (ProxySelector selector : this.selectors) { - Proxy proxy = selector.getProxy(repository); - if (proxy != null) { - return proxy; - } - } - return null; - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DefaultRepositorySystemSessionAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DefaultRepositorySystemSessionAutoConfiguration.java deleted file mode 100644 index c771385b23a..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DefaultRepositorySystemSessionAutoConfiguration.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli.compiler.grape; - -import java.io.File; -import java.util.Arrays; - -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.repository.LocalRepository; -import org.eclipse.aether.repository.LocalRepositoryManager; -import org.eclipse.aether.repository.ProxySelector; -import org.eclipse.aether.util.repository.JreProxySelector; - -import org.springframework.util.StringUtils; - -/** - * A {@link RepositorySystemSessionAutoConfiguration} that, in the absence of any - * configuration, applies sensible defaults. - * - * @author Andy Wilkinson - * @since 1.0.0 - */ -public class DefaultRepositorySystemSessionAutoConfiguration implements RepositorySystemSessionAutoConfiguration { - - @Override - public void apply(DefaultRepositorySystemSession session, RepositorySystem repositorySystem) { - - if (session.getLocalRepositoryManager() == null) { - LocalRepository localRepository = new LocalRepository(getM2RepoDirectory()); - LocalRepositoryManager localRepositoryManager = repositorySystem.newLocalRepositoryManager(session, - localRepository); - session.setLocalRepositoryManager(localRepositoryManager); - } - - ProxySelector existing = session.getProxySelector(); - if (!(existing instanceof CompositeProxySelector)) { - JreProxySelector fallback = new JreProxySelector(); - ProxySelector selector = (existing != null) ? new CompositeProxySelector(Arrays.asList(existing, fallback)) - : fallback; - session.setProxySelector(selector); - } - } - - private File getM2RepoDirectory() { - return new File(getDefaultM2HomeDirectory(), "repository"); - } - - private File getDefaultM2HomeDirectory() { - String mavenRoot = System.getProperty("maven.home"); - if (StringUtils.hasLength(mavenRoot)) { - return new File(mavenRoot); - } - return new File(System.getProperty("user.home"), ".m2"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DependencyResolutionContext.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DependencyResolutionContext.java deleted file mode 100644 index d0f0a8e08e9..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DependencyResolutionContext.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.grape; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.aether.artifact.DefaultArtifact; -import org.eclipse.aether.graph.Dependency; -import org.eclipse.aether.graph.Exclusion; -import org.eclipse.aether.util.artifact.JavaScopes; - -import org.springframework.boot.cli.compiler.dependencies.ArtifactCoordinatesResolver; -import org.springframework.boot.cli.compiler.dependencies.CompositeDependencyManagement; -import org.springframework.boot.cli.compiler.dependencies.DependencyManagement; -import org.springframework.boot.cli.compiler.dependencies.DependencyManagementArtifactCoordinatesResolver; - -/** - * Context used when resolving dependencies. - * - * @author Andy Wilkinson - * @since 1.1.0 - */ -public class DependencyResolutionContext { - - private final Map managedDependencyByGroupAndArtifact = new HashMap<>(); - - private final List managedDependencies = new ArrayList<>(); - - private DependencyManagement dependencyManagement = null; - - private ArtifactCoordinatesResolver artifactCoordinatesResolver; - - private String getIdentifier(Dependency dependency) { - return getIdentifier(dependency.getArtifact().getGroupId(), dependency.getArtifact().getArtifactId()); - } - - private String getIdentifier(String groupId, String artifactId) { - return groupId + ":" + artifactId; - } - - public ArtifactCoordinatesResolver getArtifactCoordinatesResolver() { - return this.artifactCoordinatesResolver; - } - - public String getManagedVersion(String groupId, String artifactId) { - Dependency dependency = getManagedDependency(groupId, artifactId); - if (dependency == null) { - dependency = this.managedDependencyByGroupAndArtifact.get(getIdentifier(groupId, artifactId)); - } - return (dependency != null) ? dependency.getArtifact().getVersion() : null; - } - - public List getManagedDependencies() { - return Collections.unmodifiableList(this.managedDependencies); - } - - private Dependency getManagedDependency(String group, String artifact) { - return this.managedDependencyByGroupAndArtifact.get(getIdentifier(group, artifact)); - } - - public void addManagedDependencies(List dependencies) { - this.managedDependencies.addAll(dependencies); - for (Dependency dependency : dependencies) { - this.managedDependencyByGroupAndArtifact.put(getIdentifier(dependency), dependency); - } - } - - public void addDependencyManagement(DependencyManagement dependencyManagement) { - for (org.springframework.boot.cli.compiler.dependencies.Dependency dependency : dependencyManagement - .getDependencies()) { - List aetherExclusions = new ArrayList<>(); - for (org.springframework.boot.cli.compiler.dependencies.Dependency.Exclusion exclusion : dependency - .getExclusions()) { - aetherExclusions.add(new Exclusion(exclusion.getGroupId(), exclusion.getArtifactId(), "*", "*")); - } - Dependency aetherDependency = new Dependency(new DefaultArtifact(dependency.getGroupId(), - dependency.getArtifactId(), "jar", dependency.getVersion()), JavaScopes.COMPILE, false, - aetherExclusions); - this.managedDependencies.add(0, aetherDependency); - this.managedDependencyByGroupAndArtifact.put(getIdentifier(aetherDependency), aetherDependency); - } - this.dependencyManagement = (this.dependencyManagement != null) - ? new CompositeDependencyManagement(dependencyManagement, this.dependencyManagement) - : dependencyManagement; - this.artifactCoordinatesResolver = new DependencyManagementArtifactCoordinatesResolver( - this.dependencyManagement); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DependencyResolutionFailedException.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DependencyResolutionFailedException.java deleted file mode 100644 index 8b7e5d864af..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DependencyResolutionFailedException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.grape; - -/** - * Thrown to indicate a failure during dependency resolution. - * - * @author Andy Wilkinson - * @since 1.0.0 - */ -@SuppressWarnings("serial") -public class DependencyResolutionFailedException extends RuntimeException { - - /** - * Creates a new {@code DependencyResolutionFailedException} with the given - * {@code cause}. - * @param cause the cause of the resolution failure - */ - public DependencyResolutionFailedException(Throwable cause) { - super(cause); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DetailedProgressReporter.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DetailedProgressReporter.java deleted file mode 100644 index 611ee03378e..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/DetailedProgressReporter.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.grape; - -import java.io.PrintStream; - -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.transfer.AbstractTransferListener; -import org.eclipse.aether.transfer.TransferCancelledException; -import org.eclipse.aether.transfer.TransferEvent; -import org.eclipse.aether.transfer.TransferResource; - -/** - * Provide detailed progress feedback for long running resolves. - * - * @author Andy Wilkinson - */ -final class DetailedProgressReporter implements ProgressReporter { - - DetailedProgressReporter(DefaultRepositorySystemSession session, final PrintStream out) { - - session.setTransferListener(new AbstractTransferListener() { - - @Override - public void transferStarted(TransferEvent event) throws TransferCancelledException { - out.println("Downloading: " + getResourceIdentifier(event.getResource())); - } - - @Override - public void transferSucceeded(TransferEvent event) { - out.printf("Downloaded: %s (%s)%n", getResourceIdentifier(event.getResource()), - getTransferSpeed(event)); - } - }); - } - - private String getResourceIdentifier(TransferResource resource) { - return resource.getRepositoryUrl() + resource.getResourceName(); - } - - private String getTransferSpeed(TransferEvent event) { - long kb = event.getTransferredBytes() / 1024; - float seconds = (System.currentTimeMillis() - event.getResource().getTransferStartTime()) / 1000.0f; - - return String.format("%dKB at %.1fKB/sec", kb, (kb / seconds)); - } - - @Override - public void finished() { - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/GrapeEngineInstaller.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/GrapeEngineInstaller.java deleted file mode 100644 index ad2eb597140..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/GrapeEngineInstaller.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.grape; - -import java.lang.reflect.Field; - -import groovy.grape.Grape; -import groovy.grape.GrapeEngine; - -/** - * Utility to install a specific {@link Grape} engine with Groovy. - * - * @author Andy Wilkinson - * @since 1.0.0 - */ -public abstract class GrapeEngineInstaller { - - public static void install(GrapeEngine engine) { - synchronized (Grape.class) { - try { - Field field = Grape.class.getDeclaredField("instance"); - field.setAccessible(true); - field.set(null, engine); - } - catch (Exception ex) { - throw new IllegalStateException("Failed to install GrapeEngine", ex); - } - } - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfiguration.java deleted file mode 100644 index 9e19c335e14..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfiguration.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.grape; - -import java.io.File; - -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.repository.LocalRepository; -import org.eclipse.aether.repository.LocalRepositoryManager; - -import org.springframework.util.StringUtils; - -/** - * Honours the configuration of {@code grape.root} by customizing the session's local - * repository location. - * - * @author Andy Wilkinson - * @since 1.2.5 - */ -public class GrapeRootRepositorySystemSessionAutoConfiguration implements RepositorySystemSessionAutoConfiguration { - - @Override - public void apply(DefaultRepositorySystemSession session, RepositorySystem repositorySystem) { - String grapeRoot = System.getProperty("grape.root"); - if (StringUtils.hasLength(grapeRoot)) { - configureLocalRepository(session, repositorySystem, grapeRoot); - } - } - - private void configureLocalRepository(DefaultRepositorySystemSession session, RepositorySystem repositorySystem, - String grapeRoot) { - File repositoryDir = new File(grapeRoot, "repository"); - LocalRepository localRepository = new LocalRepository(repositoryDir); - LocalRepositoryManager localRepositoryManager = repositorySystem.newLocalRepositoryManager(session, - localRepository); - session.setLocalRepositoryManager(localRepositoryManager); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/MavenResolverGrapeEngine.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/MavenResolverGrapeEngine.java deleted file mode 100644 index f7b9621a01d..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/MavenResolverGrapeEngine.java +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler.grape; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import groovy.grape.GrapeEngine; -import groovy.lang.GroovyClassLoader; -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.artifact.Artifact; -import org.eclipse.aether.artifact.DefaultArtifact; -import org.eclipse.aether.collection.CollectRequest; -import org.eclipse.aether.graph.Dependency; -import org.eclipse.aether.graph.Exclusion; -import org.eclipse.aether.repository.RemoteRepository; -import org.eclipse.aether.resolution.ArtifactResult; -import org.eclipse.aether.resolution.DependencyRequest; -import org.eclipse.aether.resolution.DependencyResult; -import org.eclipse.aether.util.artifact.JavaScopes; -import org.eclipse.aether.util.filter.DependencyFilterUtils; - -/** - * A {@link GrapeEngine} implementation that uses - * Maven Resolver, the - * dependency resolution system used by Maven. - * - * @author Andy Wilkinson - * @author Phillip Webb - * @since 2.5.9 - */ -@SuppressWarnings("rawtypes") -public class MavenResolverGrapeEngine implements GrapeEngine { - - private static final Collection WILDCARD_EXCLUSION; - - static { - List exclusions = new ArrayList<>(); - exclusions.add(new Exclusion("*", "*", "*", "*")); - WILDCARD_EXCLUSION = Collections.unmodifiableList(exclusions); - } - - private final DependencyResolutionContext resolutionContext; - - private final ProgressReporter progressReporter; - - private final GroovyClassLoader classLoader; - - private final DefaultRepositorySystemSession session; - - private final RepositorySystem repositorySystem; - - private final List repositories; - - public MavenResolverGrapeEngine(GroovyClassLoader classLoader, RepositorySystem repositorySystem, - DefaultRepositorySystemSession repositorySystemSession, List remoteRepositories, - DependencyResolutionContext resolutionContext, boolean quiet) { - this.classLoader = classLoader; - this.repositorySystem = repositorySystem; - this.session = repositorySystemSession; - this.resolutionContext = resolutionContext; - this.repositories = new ArrayList<>(); - List remotes = new ArrayList<>(remoteRepositories); - Collections.reverse(remotes); // priority is reversed in addRepository - for (RemoteRepository repository : remotes) { - addRepository(repository); - } - this.progressReporter = getProgressReporter(this.session, quiet); - } - - private ProgressReporter getProgressReporter(DefaultRepositorySystemSession session, boolean quiet) { - String progressReporter = (quiet ? "none" - : System.getProperty("org.springframework.boot.cli.compiler.grape.ProgressReporter")); - if ("detail".equals(progressReporter) || Boolean.getBoolean("groovy.grape.report.downloads")) { - return new DetailedProgressReporter(session, System.out); - } - if ("none".equals(progressReporter)) { - return () -> { - }; - } - return new SummaryProgressReporter(session, System.out); - } - - @Override - public Object grab(Map args) { - return grab(args, args); - } - - @Override - public Object grab(Map args, Map... dependencyMaps) { - List exclusions = createExclusions(args); - List dependencies = createDependencies(dependencyMaps, exclusions); - try { - List files = resolve(dependencies); - GroovyClassLoader classLoader = getClassLoader(args); - for (File file : files) { - classLoader.addURL(file.toURI().toURL()); - } - } - catch (MalformedURLException ex) { - throw new DependencyResolutionFailedException(ex); - } - return null; - } - - @SuppressWarnings("unchecked") - private List createExclusions(Map args) { - List exclusions = new ArrayList<>(); - if (args != null) { - List> exclusionMaps = (List>) args.get("excludes"); - if (exclusionMaps != null) { - for (Map exclusionMap : exclusionMaps) { - exclusions.add(createExclusion(exclusionMap)); - } - } - } - return exclusions; - } - - private Exclusion createExclusion(Map exclusionMap) { - String group = (String) exclusionMap.get("group"); - String module = (String) exclusionMap.get("module"); - return new Exclusion(group, module, "*", "*"); - } - - private List createDependencies(Map[] dependencyMaps, List exclusions) { - List dependencies = new ArrayList<>(dependencyMaps.length); - for (Map dependencyMap : dependencyMaps) { - dependencies.add(createDependency(dependencyMap, exclusions)); - } - return dependencies; - } - - private Dependency createDependency(Map dependencyMap, List exclusions) { - Artifact artifact = createArtifact(dependencyMap); - if (isTransitive(dependencyMap)) { - return new Dependency(artifact, JavaScopes.COMPILE, false, exclusions); - } - return new Dependency(artifact, JavaScopes.COMPILE, null, WILDCARD_EXCLUSION); - } - - private Artifact createArtifact(Map dependencyMap) { - String group = (String) dependencyMap.get("group"); - String module = (String) dependencyMap.get("module"); - String version = (String) dependencyMap.get("version"); - if (version == null) { - version = this.resolutionContext.getManagedVersion(group, module); - } - String classifier = (String) dependencyMap.get("classifier"); - String type = determineType(dependencyMap); - return new DefaultArtifact(group, module, classifier, type, version); - } - - private String determineType(Map dependencyMap) { - String type = (String) dependencyMap.get("type"); - String ext = (String) dependencyMap.get("ext"); - if (type == null) { - type = ext; - if (type == null) { - type = "jar"; - } - } - else if (ext != null && !type.equals(ext)) { - throw new IllegalArgumentException("If both type and ext are specified they must have the same value"); - } - return type; - } - - private boolean isTransitive(Map dependencyMap) { - Boolean transitive = (Boolean) dependencyMap.get("transitive"); - return (transitive != null) ? transitive : true; - } - - private List getDependencies(DependencyResult dependencyResult) { - List dependencies = new ArrayList<>(); - for (ArtifactResult artifactResult : dependencyResult.getArtifactResults()) { - dependencies.add(new Dependency(artifactResult.getArtifact(), JavaScopes.COMPILE)); - } - return dependencies; - } - - private List getFiles(DependencyResult dependencyResult) { - List files = new ArrayList<>(); - for (ArtifactResult result : dependencyResult.getArtifactResults()) { - files.add(result.getArtifact().getFile()); - } - return files; - } - - private GroovyClassLoader getClassLoader(Map args) { - GroovyClassLoader classLoader = (GroovyClassLoader) args.get("classLoader"); - return (classLoader != null) ? classLoader : this.classLoader; - } - - @Override - public void addResolver(Map args) { - String name = (String) args.get("name"); - String root = (String) args.get("root"); - RemoteRepository.Builder builder = new RemoteRepository.Builder(name, "default", root); - RemoteRepository repository = builder.build(); - addRepository(repository); - } - - protected void addRepository(RemoteRepository repository) { - if (this.repositories.contains(repository)) { - return; - } - repository = getPossibleMirror(repository); - repository = applyProxy(repository); - repository = applyAuthentication(repository); - this.repositories.add(0, repository); - } - - private RemoteRepository getPossibleMirror(RemoteRepository remoteRepository) { - RemoteRepository mirror = this.session.getMirrorSelector().getMirror(remoteRepository); - if (mirror != null) { - return mirror; - } - return remoteRepository; - } - - private RemoteRepository applyProxy(RemoteRepository repository) { - if (repository.getProxy() == null) { - RemoteRepository.Builder builder = new RemoteRepository.Builder(repository); - builder.setProxy(this.session.getProxySelector().getProxy(repository)); - repository = builder.build(); - } - return repository; - } - - private RemoteRepository applyAuthentication(RemoteRepository repository) { - if (repository.getAuthentication() == null) { - RemoteRepository.Builder builder = new RemoteRepository.Builder(repository); - builder.setAuthentication(this.session.getAuthenticationSelector().getAuthentication(repository)); - repository = builder.build(); - } - return repository; - } - - @Override - public Map>> enumerateGrapes() { - throw new UnsupportedOperationException("Grape enumeration is not supported"); - } - - @Override - public URI[] resolve(Map args, Map... dependencyMaps) { - return resolve(args, null, dependencyMaps); - } - - @Override - public URI[] resolve(Map args, List depsInfo, Map... dependencyMaps) { - List exclusions = createExclusions(args); - List dependencies = createDependencies(dependencyMaps, exclusions); - try { - List files = resolve(dependencies); - List uris = new ArrayList<>(files.size()); - for (File file : files) { - uris.add(file.toURI()); - } - return uris.toArray(new URI[0]); - } - catch (Exception ex) { - throw new DependencyResolutionFailedException(ex); - } - } - - private List resolve(List dependencies) { - try { - CollectRequest collectRequest = getCollectRequest(dependencies); - DependencyRequest dependencyRequest = getDependencyRequest(collectRequest); - DependencyResult result = this.repositorySystem.resolveDependencies(this.session, dependencyRequest); - addManagedDependencies(result); - return getFiles(result); - } - catch (Exception ex) { - throw new DependencyResolutionFailedException(ex); - } - finally { - this.progressReporter.finished(); - } - } - - private CollectRequest getCollectRequest(List dependencies) { - CollectRequest collectRequest = new CollectRequest((Dependency) null, dependencies, - new ArrayList<>(this.repositories)); - collectRequest.setManagedDependencies(this.resolutionContext.getManagedDependencies()); - return collectRequest; - } - - private DependencyRequest getDependencyRequest(CollectRequest collectRequest) { - return new DependencyRequest(collectRequest, - DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE, JavaScopes.RUNTIME)); - } - - private void addManagedDependencies(DependencyResult result) { - this.resolutionContext.addManagedDependencies(getDependencies(result)); - } - - @Override - public Map[] listDependencies(ClassLoader classLoader) { - throw new UnsupportedOperationException("Listing dependencies is not supported"); - } - - @Override - public Object grab(String endorsedModule) { - throw new UnsupportedOperationException("Grabbing an endorsed module is not supported"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/MavenResolverGrapeEngineFactory.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/MavenResolverGrapeEngineFactory.java deleted file mode 100644 index 9e2adf63b19..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/MavenResolverGrapeEngineFactory.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler.grape; - -import java.util.ArrayList; -import java.util.List; -import java.util.ServiceLoader; - -import groovy.lang.GroovyClassLoader; -import org.apache.maven.repository.internal.MavenRepositorySystemUtils; -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; -import org.eclipse.aether.impl.DefaultServiceLocator; -import org.eclipse.aether.internal.impl.DefaultRepositorySystem; -import org.eclipse.aether.repository.RemoteRepository; -import org.eclipse.aether.repository.RepositoryPolicy; -import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; -import org.eclipse.aether.spi.connector.transport.TransporterFactory; -import org.eclipse.aether.spi.locator.ServiceLocator; -import org.eclipse.aether.transport.file.FileTransporterFactory; -import org.eclipse.aether.transport.http.HttpTransporterFactory; - -/** - * Utility class to create a pre-configured {@link MavenResolverGrapeEngine}. - * - * @author Andy Wilkinson - * @since 2.5.9 - */ -public abstract class MavenResolverGrapeEngineFactory { - - public static MavenResolverGrapeEngine create(GroovyClassLoader classLoader, - List repositoryConfigurations, - DependencyResolutionContext dependencyResolutionContext, boolean quiet) { - RepositorySystem repositorySystem = createServiceLocator().getService(RepositorySystem.class); - DefaultRepositorySystemSession repositorySystemSession = MavenRepositorySystemUtils.newSession(); - ServiceLoader autoConfigurations = ServiceLoader - .load(RepositorySystemSessionAutoConfiguration.class); - for (RepositorySystemSessionAutoConfiguration autoConfiguration : autoConfigurations) { - autoConfiguration.apply(repositorySystemSession, repositorySystem); - } - new DefaultRepositorySystemSessionAutoConfiguration().apply(repositorySystemSession, repositorySystem); - return new MavenResolverGrapeEngine(classLoader, repositorySystem, repositorySystemSession, - createRepositories(repositoryConfigurations), dependencyResolutionContext, quiet); - } - - private static ServiceLocator createServiceLocator() { - DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); - locator.addService(RepositorySystem.class, DefaultRepositorySystem.class); - locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); - locator.addService(TransporterFactory.class, HttpTransporterFactory.class); - locator.addService(TransporterFactory.class, FileTransporterFactory.class); - return locator; - } - - private static List createRepositories(List repositoryConfigurations) { - List repositories = new ArrayList<>(repositoryConfigurations.size()); - for (RepositoryConfiguration repositoryConfiguration : repositoryConfigurations) { - RemoteRepository.Builder builder = new RemoteRepository.Builder(repositoryConfiguration.getName(), - "default", repositoryConfiguration.getUri().toASCIIString()); - if (!repositoryConfiguration.getSnapshotsEnabled()) { - builder.setSnapshotPolicy(new RepositoryPolicy(false, RepositoryPolicy.UPDATE_POLICY_NEVER, - RepositoryPolicy.CHECKSUM_POLICY_IGNORE)); - } - repositories.add(builder.build()); - } - return repositories; - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/ProgressReporter.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/ProgressReporter.java deleted file mode 100644 index 913595aa825..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/ProgressReporter.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.grape; - -/** - * Reports progress on a dependency resolution operation. - * - * @author Andy Wilkinson - */ -@FunctionalInterface -interface ProgressReporter { - - /** - * Notification that the operation has completed. - */ - void finished(); - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/RepositoryConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/RepositoryConfiguration.java deleted file mode 100644 index 4b3438304c1..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/RepositoryConfiguration.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.grape; - -import java.net.URI; - -import org.springframework.util.ObjectUtils; - -/** - * The configuration of a repository. - * - * @author Andy Wilkinson - * @since 1.0.0 - */ -public final class RepositoryConfiguration { - - private final String name; - - private final URI uri; - - private final boolean snapshotsEnabled; - - /** - * Creates a new {@code RepositoryConfiguration} instance. - * @param name the name of the repository - * @param uri the uri of the repository - * @param snapshotsEnabled {@code true} if the repository should enable access to - * snapshots, {@code false} otherwise - */ - public RepositoryConfiguration(String name, URI uri, boolean snapshotsEnabled) { - this.name = name; - this.uri = uri; - this.snapshotsEnabled = snapshotsEnabled; - } - - /** - * Return the name of the repository. - * @return the repository name - */ - public String getName() { - return this.name; - } - - /** - * Return the URI of the repository. - * @return the repository URI - */ - public URI getUri() { - return this.uri; - } - - /** - * Return if the repository should enable access to snapshots. - * @return {@code true} if snapshot access is enabled - */ - public boolean getSnapshotsEnabled() { - return this.snapshotsEnabled; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - RepositoryConfiguration other = (RepositoryConfiguration) obj; - return ObjectUtils.nullSafeEquals(this.name, other.name); - } - - @Override - public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.name); - } - - @Override - public String toString() { - return "RepositoryConfiguration [name=" + this.name + ", uri=" + this.uri + ", snapshotsEnabled=" - + this.snapshotsEnabled + "]"; - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/RepositorySystemSessionAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/RepositorySystemSessionAutoConfiguration.java deleted file mode 100644 index 6da09826f35..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/RepositorySystemSessionAutoConfiguration.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler.grape; - -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositorySystem; - -/** - * Strategy that can be used to apply some auto-configuration during the installation of a - * {@link MavenResolverGrapeEngine}. - * - * @author Andy Wilkinson - * @since 1.0.0 - */ -@FunctionalInterface -public interface RepositorySystemSessionAutoConfiguration { - - /** - * Apply the configuration. - * @param session the repository system session - * @param repositorySystem the repository system - */ - void apply(DefaultRepositorySystemSession session, RepositorySystem repositorySystem); - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfiguration.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfiguration.java deleted file mode 100644 index 04974810bf4..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfiguration.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.grape; - -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.repository.LocalRepository; - -import org.springframework.boot.cli.compiler.maven.MavenSettings; -import org.springframework.boot.cli.compiler.maven.MavenSettingsReader; - -/** - * Auto-configuration for a RepositorySystemSession that uses Maven's settings.xml to - * determine the configuration settings. - * - * @author Andy Wilkinson - * @since 1.0.0 - */ -public class SettingsXmlRepositorySystemSessionAutoConfiguration implements RepositorySystemSessionAutoConfiguration { - - @Override - public void apply(DefaultRepositorySystemSession session, RepositorySystem repositorySystem) { - MavenSettings settings = getSettings(session); - String localRepository = settings.getLocalRepository(); - if (localRepository != null) { - session.setLocalRepositoryManager( - repositorySystem.newLocalRepositoryManager(session, new LocalRepository(localRepository))); - } - } - - private MavenSettings getSettings(DefaultRepositorySystemSession session) { - MavenSettings settings = new MavenSettingsReader().readSettings(); - session.setOffline(settings.getOffline()); - session.setMirrorSelector(settings.getMirrorSelector()); - session.setAuthenticationSelector(settings.getAuthenticationSelector()); - session.setProxySelector(settings.getProxySelector()); - return settings; - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/SummaryProgressReporter.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/SummaryProgressReporter.java deleted file mode 100644 index d0c7e9af6ad..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/SummaryProgressReporter.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.grape; - -import java.io.PrintStream; -import java.util.concurrent.TimeUnit; - -import org.eclipse.aether.AbstractRepositoryListener; -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositoryEvent; -import org.eclipse.aether.transfer.AbstractTransferListener; -import org.eclipse.aether.transfer.TransferEvent; - -/** - * Provide high-level progress feedback for long running resolves. - * - * @author Phillip Webb - * @author Andy Wilkinson - */ -final class SummaryProgressReporter implements ProgressReporter { - - private static final long INITIAL_DELAY = TimeUnit.SECONDS.toMillis(3); - - private static final long PROGRESS_DELAY = TimeUnit.SECONDS.toMillis(1); - - private final long startTime = System.currentTimeMillis(); - - private final PrintStream out; - - private long lastProgressTime = System.currentTimeMillis(); - - private boolean started; - - private boolean finished; - - SummaryProgressReporter(DefaultRepositorySystemSession session, PrintStream out) { - this.out = out; - session.setTransferListener(new AbstractTransferListener() { - - @Override - public void transferStarted(TransferEvent event) { - reportProgress(); - } - - @Override - public void transferProgressed(TransferEvent event) { - reportProgress(); - } - - }); - session.setRepositoryListener(new AbstractRepositoryListener() { - - @Override - public void artifactResolved(RepositoryEvent event) { - reportProgress(); - } - - }); - } - - private void reportProgress() { - if (!this.finished && System.currentTimeMillis() - this.startTime > INITIAL_DELAY) { - if (!this.started) { - this.started = true; - this.out.print("Resolving dependencies.."); - this.lastProgressTime = System.currentTimeMillis(); - } - else if (System.currentTimeMillis() - this.lastProgressTime > PROGRESS_DELAY) { - this.out.print("."); - this.lastProgressTime = System.currentTimeMillis(); - } - } - } - - @Override - public void finished() { - if (this.started && !this.finished) { - this.finished = true; - this.out.println(); - } - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/package-info.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/package-info.java deleted file mode 100644 index b005bbe648b..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-2019 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. - */ - -/** - * CLI Groovy Grape integration. - */ -package org.springframework.boot.cli.compiler.grape; diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/maven/MavenSettings.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/maven/MavenSettings.java deleted file mode 100644 index 58b80c4d6e1..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/maven/MavenSettings.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler.maven; - -import java.io.BufferedReader; -import java.io.File; -import java.io.PrintWriter; -import java.io.StringReader; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.apache.maven.model.ActivationFile; -import org.apache.maven.model.ActivationOS; -import org.apache.maven.model.ActivationProperty; -import org.apache.maven.model.building.ModelProblemCollector; -import org.apache.maven.model.building.ModelProblemCollectorRequest; -import org.apache.maven.model.path.DefaultPathTranslator; -import org.apache.maven.model.profile.DefaultProfileSelector; -import org.apache.maven.model.profile.ProfileActivationContext; -import org.apache.maven.model.profile.activation.FileProfileActivator; -import org.apache.maven.model.profile.activation.JdkVersionProfileActivator; -import org.apache.maven.model.profile.activation.OperatingSystemProfileActivator; -import org.apache.maven.model.profile.activation.PropertyProfileActivator; -import org.apache.maven.settings.Activation; -import org.apache.maven.settings.Mirror; -import org.apache.maven.settings.Profile; -import org.apache.maven.settings.Proxy; -import org.apache.maven.settings.Server; -import org.apache.maven.settings.Settings; -import org.apache.maven.settings.crypto.SettingsDecryptionResult; -import org.eclipse.aether.repository.Authentication; -import org.eclipse.aether.repository.AuthenticationSelector; -import org.eclipse.aether.repository.MirrorSelector; -import org.eclipse.aether.repository.ProxySelector; -import org.eclipse.aether.util.repository.AuthenticationBuilder; -import org.eclipse.aether.util.repository.ConservativeAuthenticationSelector; -import org.eclipse.aether.util.repository.DefaultAuthenticationSelector; -import org.eclipse.aether.util.repository.DefaultMirrorSelector; -import org.eclipse.aether.util.repository.DefaultProxySelector; - -/** - * An encapsulation of settings read from a user's Maven settings.xml. - * - * @author Andy Wilkinson - * @since 1.3.0 - * @see MavenSettingsReader - */ -public class MavenSettings { - - private final boolean offline; - - private final MirrorSelector mirrorSelector; - - private final AuthenticationSelector authenticationSelector; - - private final ProxySelector proxySelector; - - private final String localRepository; - - private final List activeProfiles; - - /** - * Create a new {@link MavenSettings} instance. - * @param settings the source settings - * @param decryptedSettings the decrypted settings - */ - public MavenSettings(Settings settings, SettingsDecryptionResult decryptedSettings) { - this.offline = settings.isOffline(); - this.mirrorSelector = createMirrorSelector(settings); - this.authenticationSelector = createAuthenticationSelector(decryptedSettings); - this.proxySelector = createProxySelector(decryptedSettings); - this.localRepository = settings.getLocalRepository(); - this.activeProfiles = determineActiveProfiles(settings); - } - - private MirrorSelector createMirrorSelector(Settings settings) { - DefaultMirrorSelector selector = new DefaultMirrorSelector(); - for (Mirror mirror : settings.getMirrors()) { - selector.add(mirror.getId(), mirror.getUrl(), mirror.getLayout(), false, false, mirror.getMirrorOf(), - mirror.getMirrorOfLayouts()); - } - return selector; - } - - private AuthenticationSelector createAuthenticationSelector(SettingsDecryptionResult decryptedSettings) { - DefaultAuthenticationSelector selector = new DefaultAuthenticationSelector(); - for (Server server : decryptedSettings.getServers()) { - AuthenticationBuilder auth = new AuthenticationBuilder(); - auth.addUsername(server.getUsername()).addPassword(server.getPassword()); - auth.addPrivateKey(server.getPrivateKey(), server.getPassphrase()); - selector.add(server.getId(), auth.build()); - } - return new ConservativeAuthenticationSelector(selector); - } - - private ProxySelector createProxySelector(SettingsDecryptionResult decryptedSettings) { - DefaultProxySelector selector = new DefaultProxySelector(); - for (Proxy proxy : decryptedSettings.getProxies()) { - Authentication authentication = new AuthenticationBuilder().addUsername(proxy.getUsername()) - .addPassword(proxy.getPassword()).build(); - selector.add(new org.eclipse.aether.repository.Proxy(proxy.getProtocol(), proxy.getHost(), proxy.getPort(), - authentication), proxy.getNonProxyHosts()); - } - return selector; - } - - private List determineActiveProfiles(Settings settings) { - SpringBootCliModelProblemCollector problemCollector = new SpringBootCliModelProblemCollector(); - List activeModelProfiles = createProfileSelector().getActiveProfiles( - createModelProfiles(settings.getProfiles()), - new SpringBootCliProfileActivationContext(settings.getActiveProfiles()), problemCollector); - if (!problemCollector.getProblems().isEmpty()) { - throw new IllegalStateException(createFailureMessage(problemCollector)); - } - List activeProfiles = new ArrayList<>(); - Map profiles = settings.getProfilesAsMap(); - for (org.apache.maven.model.Profile modelProfile : activeModelProfiles) { - activeProfiles.add(profiles.get(modelProfile.getId())); - } - return activeProfiles; - } - - private String createFailureMessage(SpringBootCliModelProblemCollector problemCollector) { - StringWriter message = new StringWriter(); - PrintWriter printer = new PrintWriter(message); - printer.println("Failed to determine active profiles:"); - for (ModelProblemCollectorRequest problem : problemCollector.getProblems()) { - String location = (problem.getLocation() != null) ? " at " + problem.getLocation() : ""; - printer.println(" " + problem.getMessage() + location); - if (problem.getException() != null) { - printer.println(indentStackTrace(problem.getException(), " ")); - } - } - return message.toString(); - } - - private String indentStackTrace(Exception ex, String indent) { - return indentLines(printStackTrace(ex), indent); - } - - private String printStackTrace(Exception ex) { - StringWriter stackTrace = new StringWriter(); - PrintWriter printer = new PrintWriter(stackTrace); - ex.printStackTrace(printer); - return stackTrace.toString(); - } - - private String indentLines(String input, String indent) { - StringWriter indented = new StringWriter(); - PrintWriter writer = new PrintWriter(indented); - BufferedReader reader = new BufferedReader(new StringReader(input)); - reader.lines().forEach((line) -> writer.println(indent + line)); - return indented.toString(); - } - - private DefaultProfileSelector createProfileSelector() { - DefaultProfileSelector selector = new DefaultProfileSelector(); - - selector.addProfileActivator(new FileProfileActivator().setPathTranslator(new DefaultPathTranslator())); - selector.addProfileActivator(new JdkVersionProfileActivator()); - selector.addProfileActivator(new PropertyProfileActivator()); - selector.addProfileActivator(new OperatingSystemProfileActivator()); - return selector; - } - - private List createModelProfiles(List profiles) { - List modelProfiles = new ArrayList<>(); - for (Profile profile : profiles) { - org.apache.maven.model.Profile modelProfile = new org.apache.maven.model.Profile(); - modelProfile.setId(profile.getId()); - if (profile.getActivation() != null) { - modelProfile.setActivation(createModelActivation(profile.getActivation())); - } - modelProfiles.add(modelProfile); - } - return modelProfiles; - } - - private org.apache.maven.model.Activation createModelActivation(Activation activation) { - org.apache.maven.model.Activation modelActivation = new org.apache.maven.model.Activation(); - modelActivation.setActiveByDefault(activation.isActiveByDefault()); - if (activation.getFile() != null) { - ActivationFile activationFile = new ActivationFile(); - activationFile.setExists(activation.getFile().getExists()); - activationFile.setMissing(activation.getFile().getMissing()); - modelActivation.setFile(activationFile); - } - modelActivation.setJdk(activation.getJdk()); - if (activation.getOs() != null) { - ActivationOS os = new ActivationOS(); - os.setArch(activation.getOs().getArch()); - os.setFamily(activation.getOs().getFamily()); - os.setName(activation.getOs().getName()); - os.setVersion(activation.getOs().getVersion()); - modelActivation.setOs(os); - } - if (activation.getProperty() != null) { - ActivationProperty property = new ActivationProperty(); - property.setName(activation.getProperty().getName()); - property.setValue(activation.getProperty().getValue()); - modelActivation.setProperty(property); - } - return modelActivation; - } - - public boolean getOffline() { - return this.offline; - } - - public MirrorSelector getMirrorSelector() { - return this.mirrorSelector; - } - - public AuthenticationSelector getAuthenticationSelector() { - return this.authenticationSelector; - } - - public ProxySelector getProxySelector() { - return this.proxySelector; - } - - public String getLocalRepository() { - return this.localRepository; - } - - public List getActiveProfiles() { - return this.activeProfiles; - } - - private static final class SpringBootCliProfileActivationContext implements ProfileActivationContext { - - private final List activeProfiles; - - SpringBootCliProfileActivationContext(List activeProfiles) { - this.activeProfiles = activeProfiles; - } - - @Override - public List getActiveProfileIds() { - return this.activeProfiles; - } - - @Override - public List getInactiveProfileIds() { - return Collections.emptyList(); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public Map getSystemProperties() { - return (Map) System.getProperties(); - } - - @Override - public Map getUserProperties() { - return Collections.emptyMap(); - } - - @Override - public File getProjectDirectory() { - return new File("."); - } - - @Override - public Map getProjectProperties() { - return Collections.emptyMap(); - } - - } - - private static final class SpringBootCliModelProblemCollector implements ModelProblemCollector { - - private final List problems = new ArrayList<>(); - - @Override - public void add(ModelProblemCollectorRequest req) { - this.problems.add(req); - } - - List getProblems() { - return this.problems; - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/maven/MavenSettingsReader.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/maven/MavenSettingsReader.java deleted file mode 100644 index 02ce1ec55a9..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/maven/MavenSettingsReader.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli.compiler.maven; - -import java.io.File; - -import org.apache.maven.settings.Settings; -import org.apache.maven.settings.building.DefaultSettingsBuilderFactory; -import org.apache.maven.settings.building.DefaultSettingsBuildingRequest; -import org.apache.maven.settings.building.SettingsBuildingException; -import org.apache.maven.settings.building.SettingsBuildingRequest; -import org.apache.maven.settings.crypto.DefaultSettingsDecrypter; -import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest; -import org.apache.maven.settings.crypto.SettingsDecrypter; -import org.apache.maven.settings.crypto.SettingsDecryptionResult; -import org.sonatype.plexus.components.cipher.DefaultPlexusCipher; -import org.sonatype.plexus.components.cipher.PlexusCipherException; -import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher; - -import org.springframework.boot.cli.util.Log; - -/** - * {@code MavenSettingsReader} reads settings from a user's Maven settings.xml file, - * decrypting them if necessary using settings-security.xml. - * - * @author Andy Wilkinson - * @since 1.3.0 - */ -public class MavenSettingsReader { - - private final String homeDir; - - public MavenSettingsReader() { - this(System.getProperty("user.home")); - } - - public MavenSettingsReader(String homeDir) { - this.homeDir = homeDir; - } - - public MavenSettings readSettings() { - Settings settings = loadSettings(); - SettingsDecryptionResult decrypted = decryptSettings(settings); - if (!decrypted.getProblems().isEmpty()) { - Log.error("Maven settings decryption failed. Some Maven repositories may be inaccessible"); - // Continue - the encrypted credentials may not be used - } - return new MavenSettings(settings, decrypted); - } - - private Settings loadSettings() { - File settingsFile = new File(this.homeDir, ".m2/settings.xml"); - SettingsBuildingRequest request = new DefaultSettingsBuildingRequest(); - request.setUserSettingsFile(settingsFile); - request.setSystemProperties(System.getProperties()); - try { - return new DefaultSettingsBuilderFactory().newInstance().build(request).getEffectiveSettings(); - } - catch (SettingsBuildingException ex) { - throw new IllegalStateException("Failed to build settings from " + settingsFile, ex); - } - } - - private SettingsDecryptionResult decryptSettings(Settings settings) { - DefaultSettingsDecryptionRequest request = new DefaultSettingsDecryptionRequest(settings); - - return createSettingsDecrypter().decrypt(request); - } - - private SettingsDecrypter createSettingsDecrypter() { - return new DefaultSettingsDecrypter(new SpringBootSecDispatcher()); - } - - private class SpringBootSecDispatcher extends DefaultSecDispatcher { - - private static final String SECURITY_XML = ".m2/settings-security.xml"; - - SpringBootSecDispatcher() { - File file = new File(MavenSettingsReader.this.homeDir, SECURITY_XML); - this._configurationFile = file.getAbsolutePath(); - try { - this._cipher = new DefaultPlexusCipher(); - } - catch (PlexusCipherException ex) { - throw new IllegalStateException(ex); - } - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/maven/package-info.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/maven/package-info.java deleted file mode 100644 index ecacd91a8a9..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/maven/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-2019 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. - */ - -/** - * CLI Maven integration. - */ -package org.springframework.boot.cli.compiler.maven; diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/package-info.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/package-info.java deleted file mode 100644 index 47d16e9abf9..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-2019 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. - */ - -/** - * CLI Groovy compiler integration. - */ -package org.springframework.boot.cli.compiler; diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/util/ResourceUtils.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/util/ResourceUtils.java deleted file mode 100644 index 51a27cff57a..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/cli/util/ResourceUtils.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli.util; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.FileSystemResourceLoader; -import org.springframework.core.io.Resource; -import org.springframework.core.io.UrlResource; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; - -/** - * Utilities for manipulating resource paths and URLs. - * - * @author Dave Syer - * @author Phillip Webb - * @since 1.0.0 - */ -public abstract class ResourceUtils { - - /** - * Pseudo URL prefix for loading from the class path: "classpath:". - */ - public static final String CLASSPATH_URL_PREFIX = "classpath:"; - - /** - * Pseudo URL prefix for loading all resources from the class path: "classpath*:". - */ - public static final String ALL_CLASSPATH_URL_PREFIX = "classpath*:"; - - /** - * URL prefix for loading from the file system: "file:". - */ - public static final String FILE_URL_PREFIX = "file:"; - - /** - * Return URLs from a given source path. Source paths can be simple file locations - * (/some/file.java) or wildcard patterns (/some/**). Additionally the prefixes - * "file:", "classpath:" and "classpath*:" can be used for specific path types. - * @param path the source path - * @param classLoader the class loader or {@code null} to use the default - * @return a list of URLs - */ - public static List getUrls(String path, ClassLoader classLoader) { - if (classLoader == null) { - classLoader = ClassUtils.getDefaultClassLoader(); - } - path = StringUtils.cleanPath(path); - try { - return getUrlsFromWildcardPath(path, classLoader); - } - catch (Exception ex) { - throw new IllegalArgumentException("Cannot create URL from path [" + path + "]", ex); - } - } - - private static List getUrlsFromWildcardPath(String path, ClassLoader classLoader) throws IOException { - if (path.contains(":")) { - return getUrlsFromPrefixedWildcardPath(path, classLoader); - } - Set result = new LinkedHashSet<>(); - try { - result.addAll(getUrls(FILE_URL_PREFIX + path, classLoader)); - } - catch (IllegalArgumentException ex) { - // ignore - } - path = stripLeadingSlashes(path); - result.addAll(getUrls(ALL_CLASSPATH_URL_PREFIX + path, classLoader)); - return new ArrayList<>(result); - } - - private static List getUrlsFromPrefixedWildcardPath(String path, ClassLoader classLoader) - throws IOException { - Resource[] resources = new PathMatchingResourcePatternResolver(new FileSearchResourceLoader(classLoader)) - .getResources(path); - List result = new ArrayList<>(); - for (Resource resource : resources) { - if (resource.exists()) { - if ("file".equals(resource.getURI().getScheme()) && resource.getFile().isDirectory()) { - result.addAll(getChildFiles(resource)); - continue; - } - result.add(absolutePath(resource)); - } - } - return result; - } - - private static List getChildFiles(Resource resource) throws IOException { - Resource[] children = new PathMatchingResourcePatternResolver().getResources(resource.getURL() + "/**"); - List childFiles = new ArrayList<>(); - for (Resource child : children) { - if (!child.getFile().isDirectory()) { - childFiles.add(absolutePath(child)); - } - } - return childFiles; - } - - private static String absolutePath(Resource resource) throws IOException { - if (!"file".equals(resource.getURI().getScheme())) { - return resource.getURL().toExternalForm(); - } - return resource.getFile().getAbsoluteFile().toURI().toString(); - } - - private static String stripLeadingSlashes(String path) { - while (path.startsWith("/")) { - path = path.substring(1); - } - return path; - } - - private static class FileSearchResourceLoader extends DefaultResourceLoader { - - private final FileSystemResourceLoader files; - - FileSearchResourceLoader(ClassLoader classLoader) { - super(classLoader); - this.files = new FileSystemResourceLoader(); - } - - @Override - public Resource getResource(String location) { - Assert.notNull(location, "Location must not be null"); - if (location.startsWith(CLASSPATH_URL_PREFIX)) { - return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader()); - } - if (location.startsWith(FILE_URL_PREFIX)) { - return this.files.getResource(location); - } - try { - // Try to parse the location as a URL... - URL url = new URL(location); - return new UrlResource(url); - } - catch (MalformedURLException ex) { - // No URL -> resolve as resource path. - return getResourceByPath(location); - } - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/groovy/DependencyManagementBom.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/groovy/DependencyManagementBom.java deleted file mode 100644 index 7fac16c5f21..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/groovy/DependencyManagementBom.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.groovy; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Provides one or more additional sources of dependency management that is used when - * resolving {@code @Grab} dependencies. - * - * @author Andy Wilkinson - * @since 1.3.0 - */ -@Target({ ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.METHOD, - ElementType.PARAMETER, ElementType.TYPE }) -@Retention(RetentionPolicy.SOURCE) -@Documented -public @interface DependencyManagementBom { - - /** - * One or more sets of colon-separated coordinates ({@code group:module:version}) of a - * Maven bom that contains dependency management that will add to and override the - * default dependency management. - * @return the BOM coordinates - */ - String[] value(); - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/groovy/EnableGroovyTemplates.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/groovy/EnableGroovyTemplates.java deleted file mode 100644 index b90ce6868e9..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/groovy/EnableGroovyTemplates.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.groovy; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.boot.cli.compiler.autoconfigure.GroovyTemplatesCompilerAutoConfiguration; - -/** - * Pseudo annotation used to trigger {@link GroovyTemplatesCompilerAutoConfiguration}. - * - * @author Dave Syer - * @since 1.1.0 - */ -@Target(ElementType.TYPE) -@Documented -@Retention(RetentionPolicy.RUNTIME) -public @interface EnableGroovyTemplates { - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/groovy/GroovyTemplate.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/groovy/GroovyTemplate.java deleted file mode 100644 index 758b752d78d..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/groovy/GroovyTemplate.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.groovy; - -import java.io.File; -import java.io.IOException; -import java.io.StringWriter; -import java.net.URL; -import java.util.Collections; -import java.util.Map; - -import groovy.lang.Writable; -import groovy.text.GStringTemplateEngine; -import groovy.text.Template; -import groovy.text.TemplateEngine; -import org.codehaus.groovy.control.CompilationFailedException; - -/** - * Helpful utilities for working with Groovy {@link Template}s. - * - * @author Dave Syer - * @since 1.0.0 - */ -public abstract class GroovyTemplate { - - public static String template(String name) throws IOException, CompilationFailedException, ClassNotFoundException { - return template(name, Collections.emptyMap()); - } - - public static String template(String name, Map model) - throws IOException, CompilationFailedException, ClassNotFoundException { - return template(new GStringTemplateEngine(), name, model); - } - - public static String template(TemplateEngine engine, String name, Map model) - throws IOException, CompilationFailedException, ClassNotFoundException { - Writable writable = getTemplate(engine, name).make(model); - StringWriter result = new StringWriter(); - writable.writeTo(result); - return result.toString(); - } - - private static Template getTemplate(TemplateEngine engine, String name) - throws CompilationFailedException, ClassNotFoundException, IOException { - - File file = new File("templates", name); - if (file.exists()) { - return engine.createTemplate(file); - } - - ClassLoader classLoader = GroovyTemplate.class.getClassLoader(); - URL resource = classLoader.getResource("templates/" + name); - if (resource != null) { - return engine.createTemplate(resource); - } - - return engine.createTemplate(name); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/groovy/package-info.java b/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/groovy/package-info.java deleted file mode 100644 index 90366637473..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/java/org/springframework/boot/groovy/package-info.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2012-2019 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. - */ - -/** - * Groovy util classes that are "shared" between the CLI and user applications. Classes is - * this package can be loaded from compiled user code. Not under the cli package in case - * we want to extract into a separate jar at a future date. - */ -package org.springframework.boot.groovy; diff --git a/spring-boot-project/spring-boot-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.CompilerAutoConfiguration b/spring-boot-project/spring-boot-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.CompilerAutoConfiguration deleted file mode 100644 index 2e41ce700db..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.CompilerAutoConfiguration +++ /dev/null @@ -1,14 +0,0 @@ -org.springframework.boot.cli.compiler.autoconfigure.SpringBootCompilerAutoConfiguration -org.springframework.boot.cli.compiler.autoconfigure.GroovyTemplatesCompilerAutoConfiguration -org.springframework.boot.cli.compiler.autoconfigure.SpringMvcCompilerAutoConfiguration -org.springframework.boot.cli.compiler.autoconfigure.SpringBatchCompilerAutoConfiguration -org.springframework.boot.cli.compiler.autoconfigure.RabbitCompilerAutoConfiguration -org.springframework.boot.cli.compiler.autoconfigure.CachingCompilerAutoConfiguration -org.springframework.boot.cli.compiler.autoconfigure.JdbcCompilerAutoConfiguration -org.springframework.boot.cli.compiler.autoconfigure.JmsCompilerAutoConfiguration -org.springframework.boot.cli.compiler.autoconfigure.TransactionManagementCompilerAutoConfiguration -org.springframework.boot.cli.compiler.autoconfigure.SpringIntegrationCompilerAutoConfiguration -org.springframework.boot.cli.compiler.autoconfigure.SpringSecurityCompilerAutoConfiguration -org.springframework.boot.cli.compiler.autoconfigure.SpringRetryCompilerAutoConfiguration -org.springframework.boot.cli.compiler.autoconfigure.SpringTestCompilerAutoConfiguration -org.springframework.boot.cli.compiler.autoconfigure.SpringWebsocketCompilerAutoConfiguration diff --git a/spring-boot-project/spring-boot-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.grape.RepositorySystemSessionAutoConfiguration b/spring-boot-project/spring-boot-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.grape.RepositorySystemSessionAutoConfiguration deleted file mode 100644 index cf394a7e183..00000000000 --- a/spring-boot-project/spring-boot-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.grape.RepositorySystemSessionAutoConfiguration +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.cli.compiler.grape.SettingsXmlRepositorySystemSessionAutoConfiguration -org.springframework.boot.cli.compiler.grape.GrapeRootRepositorySystemSessionAutoConfiguration \ No newline at end of file diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/ClassLoaderIntegrationTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/ClassLoaderIntegrationTests.java deleted file mode 100644 index 3365acf5f66..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/ClassLoaderIntegrationTests.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.extension.RegisterExtension; - -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for CLI Classloader issues. - * - * @author Phillip Webb - */ -@ExtendWith(OutputCaptureExtension.class) -class ClassLoaderIntegrationTests { - - @RegisterExtension - CliTester cli; - - ClassLoaderIntegrationTests(CapturedOutput output) { - this.cli = new CliTester("src/test/resources/", output); - } - - @Test - void runWithIsolatedClassLoader() throws Exception { - // CLI classes or dependencies should not be exposed to the app - String output = this.cli.run("classloader-test-app.groovy", SpringCli.class.getName()); - assertThat(output).contains("HasClasses-false-true-false"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/CliTester.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/CliTester.java deleted file mode 100644 index 8840926355a..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/CliTester.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URI; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.Assumptions; -import org.junit.jupiter.api.extension.AfterEachCallback; -import org.junit.jupiter.api.extension.BeforeEachCallback; -import org.junit.jupiter.api.extension.Extension; -import org.junit.jupiter.api.extension.ExtensionContext; - -import org.springframework.boot.cli.command.AbstractCommand; -import org.springframework.boot.cli.command.OptionParsingCommand; -import org.springframework.boot.cli.command.archive.JarCommand; -import org.springframework.boot.cli.command.grab.GrabCommand; -import org.springframework.boot.cli.command.run.RunCommand; -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.testsupport.BuildOutput; -import org.springframework.util.FileCopyUtils; -import org.springframework.util.FileSystemUtils; -import org.springframework.util.StringUtils; - -/** - * JUnit 5 {@link Extension} that can be used to invoke CLI commands. - * - * @author Phillip Webb - * @author Dave Syer - * @author Andy Wilkinson - */ -public class CliTester implements BeforeEachCallback, AfterEachCallback { - - private final File temp; - - private final BuildOutput buildOutput = new BuildOutput(getClass()); - - private final CapturedOutput output; - - private String previousOutput = ""; - - private long timeout = TimeUnit.MINUTES.toMillis(6); - - private final List commands = new ArrayList<>(); - - private final String prefix; - - private File serverPortFile; - - public CliTester(String prefix, CapturedOutput output) { - this.prefix = prefix; - try { - this.temp = Files.createTempDirectory("cli-tester").toFile(); - } - catch (IOException ex) { - throw new IllegalStateException("Failed to create temp directory"); - } - this.output = output; - } - - public void setTimeout(long timeout) { - this.timeout = timeout; - } - - public String run(String... args) throws Exception { - List updatedArgs = new ArrayList<>(); - boolean classpathUpdated = false; - 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() + ":" - + this.buildOutput.getTestResourcesLocation().getAbsolutePath()); - } - Future future = submitCommand(new RunCommand(), StringUtils.toStringArray(updatedArgs)); - this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS)); - return getOutput(); - } - - public String grab(String... args) throws Exception { - Future future = submitCommand(new GrabCommand(), args); - this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS)); - return getOutput(); - } - - public String jar(String... args) throws Exception { - Future future = submitCommand(new JarCommand(), args); - this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS)); - return getOutput(); - } - - public File getTemp() { - return this.temp; - } - - private Future submitCommand(T command, String... args) { - final String[] sources = getSources(args); - return Executors.newSingleThreadExecutor().submit(() -> { - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - System.setProperty("server.port", "0"); - System.setProperty("spring.application.class.name", - "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; - } - finally { - System.clearProperty("server.port"); - System.clearProperty("spring.application.class.name"); - System.clearProperty("portfile"); - System.setProperty("user.home", userHome); - Thread.currentThread().setContextClassLoader(loader); - } - }); - } - - protected String[] getSources(String... args) { - final String[] sources = new String[args.length]; - for (int i = 0; i < args.length; i++) { - String arg = args[i]; - if (!arg.endsWith(".groovy") && !arg.endsWith(".xml")) { - if (new File(this.prefix + arg).isDirectory()) { - sources[i] = this.prefix + arg; - } - else { - sources[i] = arg; - } - } - else { - sources[i] = new File(arg).isAbsolute() ? arg : this.prefix + arg; - } - } - return sources; - } - - private String getOutput() { - String output = this.output.toString().substring(this.previousOutput.length()); - this.previousOutput = output; - return output; - } - - @Override - public void beforeEach(ExtensionContext extensionContext) { - Assumptions.assumeTrue(System.getProperty("spring.profiles.active", "integration").contains("integration"), - "Not running sample integration tests because integration profile not active"); - System.setProperty("disableSpringSnapshotRepos", "false"); - } - - @Override - public void afterEach(ExtensionContext extensionContext) { - for (AbstractCommand command : this.commands) { - if (command instanceof RunCommand runCommand) { - runCommand.stop(); - } - } - System.clearProperty("disableSpringSnapshotRepos"); - FileSystemUtils.deleteRecursively(this.temp); - } - - public String getHttpOutput() { - return getHttpOutput("/"); - } - - public String getHttpOutput(String uri) { - try { - int port = Integer.parseInt(FileCopyUtils.copyToString(new FileReader(this.serverPortFile))); - InputStream stream = URI.create("http://localhost:" + port + uri).toURL().openStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); - return reader.lines().collect(Collectors.joining()); - } - catch (Exception ex) { - throw new IllegalStateException(ex); - } - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/CliTesterSpringApplication.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/CliTesterSpringApplication.java deleted file mode 100644 index dd4a091a70f..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/CliTesterSpringApplication.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.cli; - -import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.web.context.WebServerPortFileWriter; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.util.ClassUtils; - -/** - * Custom {@link SpringApplication} used by {@link CliTester}. - * - * @author Andy Wilkinson - */ -public class CliTesterSpringApplication extends SpringApplication { - - static { - if (ClassUtils.isPresent("org.apache.catalina.webresources.TomcatURLStreamHandlerFactory", - CliTesterSpringApplication.class.getClassLoader())) { - TomcatURLStreamHandlerFactory.disable(); - } - } - - public CliTesterSpringApplication(Class... sources) { - super(sources); - } - - @Override - protected void postProcessApplicationContext(ConfigurableApplicationContext context) { - context.addApplicationListener(new WebServerPortFileWriter()); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/DirectorySourcesIntegrationTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/DirectorySourcesIntegrationTests.java deleted file mode 100644 index 9cdec31e6eb..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/DirectorySourcesIntegrationTests.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.extension.RegisterExtension; - -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for code in directories. - * - * @author Dave Syer - */ -@ExtendWith(OutputCaptureExtension.class) -class DirectorySourcesIntegrationTests { - - @RegisterExtension - CliTester cli; - - DirectorySourcesIntegrationTests(CapturedOutput output) { - this.cli = new CliTester("src/test/resources/dir-sample/", output); - } - - @Test - void runDirectory() throws Exception { - assertThat(this.cli.run("code")).contains("Hello World"); - } - - @Test - void runDirectoryRecursive() throws Exception { - assertThat(this.cli.run("")).contains("Hello World"); - } - - @Test - void runPathPattern() throws Exception { - assertThat(this.cli.run("**/*.groovy")).contains("Hello World"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/GrabCommandIntegrationTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/GrabCommandIntegrationTests.java deleted file mode 100644 index 6c8874e0d5b..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/GrabCommandIntegrationTests.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli; - -import java.io.File; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.extension.RegisterExtension; - -import org.springframework.boot.cli.command.grab.GrabCommand; -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.util.FileSystemUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -/** - * Integration tests for {@link GrabCommand} - * - * @author Andy Wilkinson - * @author Dave Syer - */ -@ExtendWith(OutputCaptureExtension.class) -class GrabCommandIntegrationTests { - - @RegisterExtension - CliTester cli; - - GrabCommandIntegrationTests(CapturedOutput output) { - this.cli = new CliTester("src/test/resources/grab-samples/", output); - } - - @BeforeEach - @AfterEach - void deleteLocalRepository() { - System.clearProperty("grape.root"); - System.clearProperty("groovy.grape.report.downloads"); - } - - @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/com/fasterxml/jackson/core/jackson-core")).isDirectory(); - assertThat(output).contains("Downloading: "); - } - - @Test - void duplicateDependencyManagementBomAnnotationsProducesAnError() { - assertThatExceptionOfType(Exception.class) - .isThrownBy(() -> this.cli.grab("duplicateDependencyManagementBom.groovy")) - .withMessageContaining("Duplicate @DependencyManagementBom annotation"); - } - - @Test - void customMetadata() throws Exception { - System.setProperty("grape.root", this.cli.getTemp().getAbsolutePath()); - File repository = new File(this.cli.getTemp().getAbsolutePath(), "repository"); - FileSystemUtils.copyRecursively(new File("src/test/resources/grab-samples/repository"), repository); - this.cli.grab("customDependencyManagement.groovy", "--autoconfigure=false"); - assertThat(new File(repository, "javax/ejb/ejb-api/3.0")).isDirectory(); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/ReproIntegrationTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/ReproIntegrationTests.java deleted file mode 100644 index 36b10c7e641..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/ReproIntegrationTests.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.cli; - -import java.util.concurrent.ExecutionException; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.extension.RegisterExtension; - -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -/** - * Integration tests to exercise and reproduce specific issues. - * - * @author Phillip Webb - * @author Andy Wilkinson - * @author Stephane Nicoll - */ -@ExtendWith(OutputCaptureExtension.class) -class ReproIntegrationTests { - - @RegisterExtension - CliTester cli; - - ReproIntegrationTests(CapturedOutput output) { - this.cli = new CliTester("src/test/resources/repro-samples/", output); - } - - @Test - void grabAntBuilder() throws Exception { - this.cli.run("grab-ant-builder.groovy"); - assertThat(this.cli.getHttpOutput()).contains("{\"message\":\"Hello World\"}"); - } - - // Security depends on old versions of Spring so if the dependencies aren't pinned - // this will fail - @Test - void securityDependencies() throws Exception { - assertThat(this.cli.run("secure.groovy")).contains("Hello World"); - } - - @Test - void dataJpaDependencies() throws Exception { - assertThat(this.cli.run("data-jpa.groovy")).contains("Hello World"); - } - - @Test - void jarFileExtensionNeeded() { - assertThatExceptionOfType(ExecutionException.class) - .isThrownBy(() -> this.cli.jar("secure.groovy", "data-jpa.groovy")) - .withMessageContaining("is not a JAR file"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/RunCommandIntegrationTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/RunCommandIntegrationTests.java deleted file mode 100644 index e7e07cfc666..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/RunCommandIntegrationTests.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli; - -import java.util.Properties; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.extension.RegisterExtension; - -import org.springframework.boot.cli.command.run.RunCommand; -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for {@link RunCommand}. - * - * @author Andy Wilkinson - */ -@ExtendWith(OutputCaptureExtension.class) -class RunCommandIntegrationTests { - - @RegisterExtension - CliTester cli; - - RunCommandIntegrationTests(CapturedOutput output) { - this.cli = new CliTester("src/test/resources/run-command/", output); - } - - private Properties systemProperties = new Properties(); - - @BeforeEach - void captureSystemProperties() { - this.systemProperties.putAll(System.getProperties()); - } - - @AfterEach - void restoreSystemProperties() { - System.setProperties(this.systemProperties); - } - - @Test - void bannerAndLoggingIsOutputByDefault() throws Exception { - String output = this.cli.run("quiet.groovy"); - assertThat(output).contains(" :: Spring Boot ::"); - assertThat(output).contains("Starting application"); - assertThat(output).contains("Ssshh"); - } - - @Test - void quietModeSuppressesAllCliOutput() throws Exception { - this.cli.run("quiet.groovy"); - String output = this.cli.run("quiet.groovy", "-q"); - assertThat(output).isEqualTo("Ssshh"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/SampleIntegrationTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/SampleIntegrationTests.java deleted file mode 100644 index ce03a5ba699..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/SampleIntegrationTests.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli; - -import java.io.File; -import java.net.URI; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.extension.RegisterExtension; - -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests to exercise the samples. - * - * @author Dave Syer - * @author Greg Turnquist - * @author Roy Clarkson - * @author Phillip Webb - */ -@ExtendWith(OutputCaptureExtension.class) -class SampleIntegrationTests { - - @RegisterExtension - CliTester cli; - - SampleIntegrationTests(CapturedOutput output) { - this.cli = new CliTester("samples/", output); - } - - @Test - void retrySample() throws Exception { - String output = this.cli.run("retry.groovy"); - URI scriptUri = new File("samples/retry.groovy").toURI(); - assertThat(output).contains("Hello World! From " + scriptUri); - } - - @Test - void beansSample() throws Exception { - this.cli.run("beans.groovy"); - String output = this.cli.getHttpOutput(); - assertThat(output).contains("Hello World!"); - } - - @Test - void templateSample() throws Exception { - String output = this.cli.run("template.groovy"); - assertThat(output).contains("Hello World!"); - } - - @Test - void jobSample() throws Exception { - String output = this.cli.run("job.groovy", "foo=bar"); - assertThat(output).contains("completed with the following parameters"); - } - - @Test - void jobWebSample() throws Exception { - String output = this.cli.run("job.groovy", "web.groovy", "foo=bar"); - assertThat(output).contains("completed with the following parameters"); - String result = this.cli.getHttpOutput(); - assertThat(result).isEqualTo("World!"); - } - - @Test - void webSample() throws Exception { - this.cli.run("web.groovy"); - assertThat(this.cli.getHttpOutput()).isEqualTo("World!"); - } - - @Test - void uiSample() throws Exception { - this.cli.run("ui.groovy", "--classpath=.:src/test/resources"); - String result = this.cli.getHttpOutput(); - assertThat(result).contains("Hello World"); - result = this.cli.getHttpOutput("/css/bootstrap.min.css"); - assertThat(result).contains("container"); - } - - @Test - void actuatorSample() throws Exception { - this.cli.run("actuator.groovy"); - assertThat(this.cli.getHttpOutput()).isEqualTo("{\"message\":\"Hello World!\"}"); - } - - @Test - void httpSample() throws Exception { - String output = this.cli.run("http.groovy"); - assertThat(output).contains("Hello World"); - } - - @Test - void integrationSample() throws Exception { - String output = this.cli.run("integration.groovy"); - assertThat(output).contains("Hello, World"); - } - - @Test - void xmlSample() throws Exception { - String output = this.cli.run("runner.xml", "runner.groovy"); - assertThat(output).contains("Hello World"); - } - - @Test - void txSample() throws Exception { - String output = this.cli.run("tx.groovy"); - assertThat(output).contains("Foo count="); - } - - @Test - void jmsSample() throws Exception { - System.setProperty("spring.artemis.embedded.queues", "spring-boot"); - try { - String output = this.cli.run("jms.groovy"); - assertThat(output).contains("Received Greetings from Spring Boot via Artemis"); - } - finally { - System.clearProperty("spring.artemis.embedded.queues"); - } - } - - @Test - @Disabled("Requires RabbitMQ to be run, so disable it by default") - void rabbitSample() throws Exception { - String output = this.cli.run("rabbit.groovy"); - assertThat(output).contains("Received Greetings from Spring Boot via RabbitMQ"); - } - - @Test - void caching() throws Exception { - assertThat(this.cli.run("caching.groovy")).contains("Hello World"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/app/SpringApplicationLauncherTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/app/SpringApplicationLauncherTests.java deleted file mode 100644 index 2df55b6a7ee..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/app/SpringApplicationLauncherTests.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.app; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link SpringApplicationLauncher} - * - * @author Andy Wilkinson - */ -class SpringApplicationLauncherTests { - - private Map env = new HashMap<>(); - - @AfterEach - void cleanUp() { - System.clearProperty("spring.application.class.name"); - } - - @Test - void defaultLaunch() { - assertThat(launch()).contains("org.springframework.boot.SpringApplication"); - } - - @Test - void launchWithClassConfiguredBySystemProperty() { - System.setProperty("spring.application.class.name", "system.property.SpringApplication"); - assertThat(launch()).contains("system.property.SpringApplication"); - } - - @Test - void launchWithClassConfiguredByEnvironmentVariable() { - this.env.put("SPRING_APPLICATION_CLASS_NAME", "environment.variable.SpringApplication"); - assertThat(launch()).contains("environment.variable.SpringApplication"); - } - - @Test - void systemPropertyOverridesEnvironmentVariable() { - System.setProperty("spring.application.class.name", "system.property.SpringApplication"); - this.env.put("SPRING_APPLICATION_CLASS_NAME", "environment.variable.SpringApplication"); - assertThat(launch()).contains("system.property.SpringApplication"); - - } - - @Test - void sourcesDefaultPropertiesAndArgsAreUsedToLaunch() throws Exception { - System.setProperty("spring.application.class.name", TestSpringApplication.class.getName()); - Class[] sources = new Class[0]; - String[] args = new String[0]; - new SpringApplicationLauncher(getClass().getClassLoader()).launch(sources, args); - - assertThat(sources == TestSpringApplication.sources).isTrue(); - assertThat(args == TestSpringApplication.args).isTrue(); - - Map defaultProperties = TestSpringApplication.defaultProperties; - assertThat(defaultProperties).hasSize(1).containsEntry("spring.groovy.template.check-template-location", - "false"); - } - - private Set launch() { - TestClassLoader classLoader = new TestClassLoader(getClass().getClassLoader()); - try { - new TestSpringApplicationLauncher(classLoader).launch(new Class[0], new String[0]); - } - catch (Exception ex) { - // Launch will fail, but we can still check that the launcher tried to use - // the right class - } - return classLoader.classes; - } - - static class TestClassLoader extends ClassLoader { - - private Set classes = new HashSet<>(); - - TestClassLoader(ClassLoader parent) { - super(parent); - } - - @Override - protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - this.classes.add(name); - return super.loadClass(name, resolve); - } - - @Override - protected Class findClass(String name) throws ClassNotFoundException { - this.classes.add(name); - return super.findClass(name); - } - - } - - public static class TestSpringApplication { - - private static Object[] sources; - - private static Map defaultProperties; - - private static String[] args; - - TestSpringApplication(Class[] sources) { - TestSpringApplication.sources = sources; - } - - public void setDefaultProperties(Map defaultProperties) { - TestSpringApplication.defaultProperties = defaultProperties; - } - - public void run(String[] args) { - TestSpringApplication.args = args; - } - - } - - private class TestSpringApplicationLauncher extends SpringApplicationLauncher { - - TestSpringApplicationLauncher(ClassLoader classLoader) { - super(classLoader); - } - - @Override - protected String getEnvironmentVariable(String name) { - String variable = SpringApplicationLauncherTests.this.env.get(name); - if (variable == null) { - variable = super.getEnvironmentVariable(name); - } - return variable; - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/archive/ResourceMatcherTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/archive/ResourceMatcherTests.java deleted file mode 100644 index 3b53eb236af..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/archive/ResourceMatcherTests.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.command.archive; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.assertj.core.api.Condition; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.cli.command.archive.ResourceMatcher.MatchedResource; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ResourceMatcher}. - * - * @author Andy Wilkinson - */ -class ResourceMatcherTests { - - @Test - void nonExistentRoot() throws IOException { - ResourceMatcher resourceMatcher = new ResourceMatcher(Arrays.asList("alpha/**", "bravo/*", "*"), - Arrays.asList(".*", "alpha/**/excluded")); - List matchedResources = resourceMatcher.find(Arrays.asList(new File("does-not-exist"))); - assertThat(matchedResources).isEmpty(); - } - - @SuppressWarnings("unchecked") - @Test - void defaults() { - ResourceMatcher resourceMatcher = new ResourceMatcher(Arrays.asList(""), Arrays.asList("")); - Collection includes = (Collection) ReflectionTestUtils.getField(resourceMatcher, "includes"); - Collection excludes = (Collection) ReflectionTestUtils.getField(resourceMatcher, "excludes"); - assertThat(includes).contains("static/**"); - assertThat(excludes).contains("**/*.jar"); - } - - @Test - void excludedWins() throws Exception { - ResourceMatcher resourceMatcher = new ResourceMatcher(Arrays.asList("*"), Arrays.asList("**/*.jar")); - List found = resourceMatcher.find(Arrays.asList(new File("src/test/resources"))); - assertThat(found).areNot(new Condition() { - - @Override - public boolean matches(MatchedResource value) { - return value.getFile().getName().equals("foo.jar"); - } - - }); - } - - @SuppressWarnings("unchecked") - @Test - void includedDeltas() { - ResourceMatcher resourceMatcher = new ResourceMatcher(Arrays.asList("-static/**"), Arrays.asList("")); - Collection includes = (Collection) ReflectionTestUtils.getField(resourceMatcher, "includes"); - assertThat(includes).contains("templates/**"); - assertThat(includes).doesNotContain("static/**"); - } - - @SuppressWarnings("unchecked") - @Test - void includedDeltasAndNewEntries() { - ResourceMatcher resourceMatcher = new ResourceMatcher(Arrays.asList("-static/**", "foo.jar"), - Arrays.asList("-**/*.jar")); - Collection includes = (Collection) ReflectionTestUtils.getField(resourceMatcher, "includes"); - Collection excludes = (Collection) ReflectionTestUtils.getField(resourceMatcher, "excludes"); - assertThat(includes).contains("foo.jar"); - assertThat(includes).contains("templates/**"); - assertThat(includes).doesNotContain("static/**"); - assertThat(excludes).doesNotContain("**/*.jar"); - } - - @SuppressWarnings("unchecked") - @Test - void excludedDeltas() { - ResourceMatcher resourceMatcher = new ResourceMatcher(Arrays.asList(""), Arrays.asList("-**/*.jar")); - Collection excludes = (Collection) ReflectionTestUtils.getField(resourceMatcher, "excludes"); - assertThat(excludes).doesNotContain("**/*.jar"); - } - - @Test - void jarFileAlwaysMatches() throws Exception { - ResourceMatcher resourceMatcher = new ResourceMatcher(Arrays.asList("*"), Arrays.asList("**/*.jar")); - List found = resourceMatcher - .find(Arrays.asList(new File("src/test/resources/templates"), new File("src/test/resources/foo.jar"))); - assertThat(found).areAtLeastOne(new Condition() { - - @Override - public boolean matches(MatchedResource value) { - return value.getFile().getName().equals("foo.jar") && value.isRoot(); - } - - }); - } - - @Test - void resourceMatching() throws IOException { - ResourceMatcher resourceMatcher = new ResourceMatcher(Arrays.asList("alpha/**", "bravo/*", "*"), - Arrays.asList(".*", "alpha/**/excluded")); - List matchedResources = resourceMatcher - .find(Arrays.asList(new File("src/test/resources/resource-matcher/one"), - new File("src/test/resources/resource-matcher/two"), - new File("src/test/resources/resource-matcher/three"))); - List paths = new ArrayList<>(); - for (MatchedResource resource : matchedResources) { - paths.add(resource.getName()); - } - assertThat(paths).containsOnly("alpha/nested/fileA", "bravo/fileC", "fileD", "bravo/fileE", "fileF", "three"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/install/GroovyGrabDependencyResolverTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/install/GroovyGrabDependencyResolverTests.java deleted file mode 100644 index 49851cc01de..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/install/GroovyGrabDependencyResolverTests.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.command.install; - -import java.io.File; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration; -import org.springframework.boot.cli.compiler.GroovyCompilerScope; -import org.springframework.boot.cli.compiler.RepositoryConfigurationFactory; -import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link GroovyGrabDependencyResolver}. - * - * @author Andy Wilkinson - */ -class GroovyGrabDependencyResolverTests { - - private DependencyResolver resolver; - - @BeforeEach - void setupResolver() { - GroovyCompilerConfiguration configuration = new GroovyCompilerConfiguration() { - - @Override - public boolean isGuessImports() { - return true; - } - - @Override - public boolean isGuessDependencies() { - return true; - } - - @Override - public boolean isAutoconfigure() { - return false; - } - - @Override - public GroovyCompilerScope getScope() { - return GroovyCompilerScope.DEFAULT; - } - - @Override - public List getRepositoryConfiguration() { - return RepositoryConfigurationFactory.createDefaultRepositoryConfiguration(); - } - - @Override - public String[] getClasspath() { - return new String[] { "." }; - } - - @Override - public boolean isQuiet() { - return false; - } - - }; - this.resolver = new GroovyGrabDependencyResolver(configuration); - } - - @Test - void resolveArtifactWithNoDependencies() throws Exception { - List resolved = this.resolver.resolve(Arrays.asList("commons-logging:commons-logging:1.1.3")); - assertThat(resolved).hasSize(1); - assertThat(getNames(resolved)).containsOnly("commons-logging-1.1.3.jar"); - } - - @Test - void resolveArtifactWithDependencies() throws Exception { - List resolved = this.resolver.resolve(Arrays.asList("org.springframework:spring-core:4.1.1.RELEASE")); - assertThat(resolved).hasSize(2); - assertThat(getNames(resolved)).containsOnly("commons-logging-1.1.3.jar", "spring-core-4.1.1.RELEASE.jar"); - } - - @Test - void resolveShorthandArtifactWithDependencies() throws Exception { - List resolved = this.resolver.resolve(Arrays.asList("spring-beans")); - assertThat(resolved).hasSize(3); - Set names = getNames(resolved); - assertThat(names).anyMatch((name) -> name.startsWith("spring-core-")); - assertThat(names).anyMatch((name) -> name.startsWith("spring-beans-")); - assertThat(names).anyMatch((name) -> name.startsWith("spring-jcl-")); - } - - @Test - void resolveMultipleArtifacts() throws Exception { - List resolved = this.resolver - .resolve(Arrays.asList("junit:junit:4.11", "commons-logging:commons-logging:1.1.3")); - assertThat(resolved).hasSize(4); - assertThat(getNames(resolved)).containsOnly("junit-4.11.jar", "commons-logging-1.1.3.jar", - "hamcrest-core-2.2.jar", "hamcrest-2.2.jar"); - } - - Set getNames(Collection files) { - Set names = new HashSet<>(files.size()); - for (File file : files) { - names.add(file.getName()); - } - return names; - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/install/InstallerTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/install/InstallerTests.java deleted file mode 100644 index cdca50d0c8f..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/install/InstallerTests.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.command.install; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link Installer} - * - * @author Andy Wilkinson - */ -class InstallerTests { - - private final DependencyResolver resolver = mock(DependencyResolver.class); - - @TempDir - File tempDir; - - private Installer installer; - - @BeforeEach - void setUp() throws IOException { - System.setProperty("spring.home", this.tempDir.getAbsolutePath()); - this.installer = new Installer(this.resolver); - } - - @AfterEach - void cleanUp() { - System.clearProperty("spring.home"); - } - - @Test - void installNewDependency() throws Exception { - File foo = createTemporaryFile("foo.jar"); - given(this.resolver.resolve(Arrays.asList("foo"))).willReturn(Arrays.asList(foo)); - this.installer.install(Arrays.asList("foo")); - assertThat(getNamesOfFilesInLibExt()).containsOnly("foo.jar", ".installed"); - } - - @Test - void installAndUninstall() throws Exception { - File foo = createTemporaryFile("foo.jar"); - given(this.resolver.resolve(Arrays.asList("foo"))).willReturn(Arrays.asList(foo)); - this.installer.install(Arrays.asList("foo")); - this.installer.uninstall(Arrays.asList("foo")); - assertThat(getNamesOfFilesInLibExt()).contains(".installed"); - } - - @Test - void installAndUninstallWithCommonDependencies() throws Exception { - File alpha = createTemporaryFile("alpha.jar"); - File bravo = createTemporaryFile("bravo.jar"); - File charlie = createTemporaryFile("charlie.jar"); - given(this.resolver.resolve(Arrays.asList("bravo"))).willReturn(Arrays.asList(bravo, alpha)); - given(this.resolver.resolve(Arrays.asList("charlie"))).willReturn(Arrays.asList(charlie, alpha)); - this.installer.install(Arrays.asList("bravo")); - assertThat(getNamesOfFilesInLibExt()).containsOnly("alpha.jar", "bravo.jar", ".installed"); - this.installer.install(Arrays.asList("charlie")); - assertThat(getNamesOfFilesInLibExt()).containsOnly("alpha.jar", "bravo.jar", "charlie.jar", ".installed"); - this.installer.uninstall(Arrays.asList("bravo")); - assertThat(getNamesOfFilesInLibExt()).containsOnly("alpha.jar", "charlie.jar", ".installed"); - this.installer.uninstall(Arrays.asList("charlie")); - assertThat(getNamesOfFilesInLibExt()).containsOnly(".installed"); - } - - @Test - void uninstallAll() throws Exception { - File alpha = createTemporaryFile("alpha.jar"); - File bravo = createTemporaryFile("bravo.jar"); - File charlie = createTemporaryFile("charlie.jar"); - given(this.resolver.resolve(Arrays.asList("bravo"))).willReturn(Arrays.asList(bravo, alpha)); - given(this.resolver.resolve(Arrays.asList("charlie"))).willReturn(Arrays.asList(charlie, alpha)); - this.installer.install(Arrays.asList("bravo")); - this.installer.install(Arrays.asList("charlie")); - assertThat(getNamesOfFilesInLibExt()).containsOnly("alpha.jar", "bravo.jar", "charlie.jar", ".installed"); - this.installer.uninstallAll(); - assertThat(getNamesOfFilesInLibExt()).containsOnly(".installed"); - } - - private Set getNamesOfFilesInLibExt() { - Set names = new HashSet<>(); - for (File file : new File(this.tempDir, "lib/ext").listFiles()) { - names.add(file.getName()); - } - return names; - } - - private File createTemporaryFile(String name) throws IOException { - File temporaryFile = new File(this.tempDir, name); - temporaryFile.createNewFile(); - return temporaryFile; - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/run/SpringApplicationRunnerTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/run/SpringApplicationRunnerTests.java deleted file mode 100644 index a0679245e76..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/command/run/SpringApplicationRunnerTests.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.cli.command.run; - -import java.util.logging.Level; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link SpringApplicationRunner}. - * - * @author Andy Wilkinson - */ -class SpringApplicationRunnerTests { - - @Test - void exceptionMessageWhenSourcesContainsNoClasses() { - SpringApplicationRunnerConfiguration configuration = mock(SpringApplicationRunnerConfiguration.class); - given(configuration.getClasspath()).willReturn(new String[] { "foo", "bar" }); - given(configuration.getLogLevel()).willReturn(Level.INFO); - assertThatExceptionOfType(RuntimeException.class) - .isThrownBy( - () -> new SpringApplicationRunner(configuration, new String[] { "foo", "bar" }).compileAndRun()) - .withMessage("No classes found in '[foo, bar]'"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/DependencyCustomizerTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/DependencyCustomizerTests.java deleted file mode 100644 index 23990bb7d87..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/DependencyCustomizerTests.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli.compiler; - -import java.util.List; - -import groovy.lang.Grab; -import groovy.lang.GroovyClassLoader; -import org.codehaus.groovy.ast.AnnotationNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.ModuleNode; -import org.codehaus.groovy.ast.expr.ConstantExpression; -import org.codehaus.groovy.control.SourceUnit; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.boot.cli.compiler.dependencies.ArtifactCoordinatesResolver; -import org.springframework.boot.cli.compiler.grape.DependencyResolutionContext; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Tests for {@link DependencyCustomizer} - * - * @author Andy Wilkinson - */ -@ExtendWith(MockitoExtension.class) -class DependencyCustomizerTests { - - private final ModuleNode moduleNode = new ModuleNode((SourceUnit) null); - - private final ClassNode classNode = new ClassNode(DependencyCustomizerTests.class); - - @Mock - private ArtifactCoordinatesResolver resolver; - - private DependencyCustomizer dependencyCustomizer; - - @BeforeEach - void setUp() { - this.moduleNode.addClass(this.classNode); - this.dependencyCustomizer = new DependencyCustomizer(new GroovyClassLoader(getClass().getClassLoader()), - this.moduleNode, new DependencyResolutionContext() { - - @Override - public ArtifactCoordinatesResolver getArtifactCoordinatesResolver() { - return DependencyCustomizerTests.this.resolver; - } - - }); - } - - @Test - void basicAdd() { - given(this.resolver.getGroupId("spring-boot-starter-logging")).willReturn("org.springframework.boot"); - given(this.resolver.getArtifactId("spring-boot-starter-logging")).willReturn("spring-boot-starter-logging"); - given(this.resolver.getVersion("spring-boot-starter-logging")).willReturn("1.2.3"); - this.dependencyCustomizer.add("spring-boot-starter-logging"); - List grabAnnotations = this.classNode.getAnnotations(new ClassNode(Grab.class)); - assertThat(grabAnnotations).hasSize(1); - AnnotationNode annotationNode = grabAnnotations.get(0); - assertGrabAnnotation(annotationNode, "org.springframework.boot", "spring-boot-starter-logging", "1.2.3", null, - null, true); - } - - @Test - void nonTransitiveAdd() { - given(this.resolver.getGroupId("spring-boot-starter-logging")).willReturn("org.springframework.boot"); - given(this.resolver.getArtifactId("spring-boot-starter-logging")).willReturn("spring-boot-starter-logging"); - given(this.resolver.getVersion("spring-boot-starter-logging")).willReturn("1.2.3"); - this.dependencyCustomizer.add("spring-boot-starter-logging", false); - List grabAnnotations = this.classNode.getAnnotations(new ClassNode(Grab.class)); - assertThat(grabAnnotations).hasSize(1); - AnnotationNode annotationNode = grabAnnotations.get(0); - assertGrabAnnotation(annotationNode, "org.springframework.boot", "spring-boot-starter-logging", "1.2.3", null, - null, false); - } - - @Test - void fullyCustomized() { - given(this.resolver.getGroupId("spring-boot-starter-logging")).willReturn("org.springframework.boot"); - given(this.resolver.getArtifactId("spring-boot-starter-logging")).willReturn("spring-boot-starter-logging"); - given(this.resolver.getVersion("spring-boot-starter-logging")).willReturn("1.2.3"); - this.dependencyCustomizer.add("spring-boot-starter-logging", "my-classifier", "my-type", false); - List grabAnnotations = this.classNode.getAnnotations(new ClassNode(Grab.class)); - assertThat(grabAnnotations).hasSize(1); - AnnotationNode annotationNode = grabAnnotations.get(0); - assertGrabAnnotation(annotationNode, "org.springframework.boot", "spring-boot-starter-logging", "1.2.3", - "my-classifier", "my-type", false); - } - - @Test - void anyMissingClassesWithMissingClassesPerformsAdd() { - this.dependencyCustomizer.ifAnyMissingClasses("does.not.Exist").add("spring-boot-starter-logging"); - assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).hasSize(1); - } - - @Test - void anyMissingClassesWithMixtureOfClassesPerformsAdd() { - this.dependencyCustomizer.ifAnyMissingClasses(getClass().getName(), "does.not.Exist") - .add("spring-boot-starter-logging"); - assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).hasSize(1); - } - - @Test - void anyMissingClassesWithNoMissingClassesDoesNotPerformAdd() { - this.dependencyCustomizer.ifAnyMissingClasses(getClass().getName()).add("spring-boot-starter-logging"); - assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).isEmpty(); - } - - @Test - void allMissingClassesWithNoMissingClassesDoesNotPerformAdd() { - this.dependencyCustomizer.ifAllMissingClasses(getClass().getName()).add("spring-boot-starter-logging"); - assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).isEmpty(); - } - - @Test - void allMissingClassesWithMixtureOfClassesDoesNotPerformAdd() { - this.dependencyCustomizer.ifAllMissingClasses(getClass().getName(), "does.not.Exist") - .add("spring-boot-starter-logging"); - assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).isEmpty(); - } - - @Test - void allMissingClassesWithAllClassesMissingPerformsAdd() { - this.dependencyCustomizer.ifAllMissingClasses("does.not.Exist", "does.not.exist.Either") - .add("spring-boot-starter-logging"); - assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).hasSize(1); - } - - @Test - void allResourcesPresentWithAllResourcesPresentPerformsAdd() { - this.dependencyCustomizer.ifAllResourcesPresent("dependency-customizer-tests/resource1.txt", - "dependency-customizer-tests/resource2.txt").add("spring-boot-starter-logging"); - assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).hasSize(1); - } - - @Test - void allResourcesPresentWithSomeResourcesPresentDoesNotPerformAdd() { - this.dependencyCustomizer.ifAllResourcesPresent("dependency-customizer-tests/resource1.txt", - "dependency-customizer-tests/does-not-exist.txt").add("spring-boot-starter-logging"); - assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).isEmpty(); - } - - @Test - void allResourcesPresentWithNoResourcesPresentDoesNotPerformAdd() { - this.dependencyCustomizer.ifAllResourcesPresent("dependency-customizer-tests/does-not-exist", - "dependency-customizer-tests/does-not-exist-either.txt").add("spring-boot-starter-logging"); - assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).isEmpty(); - } - - @Test - void anyResourcesPresentWithAllResourcesPresentPerformsAdd() { - this.dependencyCustomizer.ifAnyResourcesPresent("dependency-customizer-tests/resource1.txt", - "dependency-customizer-tests/resource2.txt").add("spring-boot-starter-logging"); - assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).hasSize(1); - } - - @Test - void anyResourcesPresentWithSomeResourcesPresentPerforms() { - this.dependencyCustomizer.ifAnyResourcesPresent("dependency-customizer-tests/resource1.txt", - "dependency-customizer-tests/does-not-exist.txt").add("spring-boot-starter-logging"); - assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).hasSize(1); - } - - @Test - void anyResourcesPresentWithNoResourcesPresentDoesNotPerformAdd() { - this.dependencyCustomizer.ifAnyResourcesPresent("dependency-customizer-tests/does-not-exist", - "dependency-customizer-tests/does-not-exist-either.txt").add("spring-boot-starter-logging"); - assertThat(this.classNode.getAnnotations(new ClassNode(Grab.class))).isEmpty(); - } - - private void assertGrabAnnotation(AnnotationNode annotationNode, String group, String module, String version, - String classifier, String type, boolean transitive) { - assertThat(getMemberValue(annotationNode, "group")).isEqualTo(group); - assertThat(getMemberValue(annotationNode, "module")).isEqualTo(module); - assertThat(getMemberValue(annotationNode, "version")).isEqualTo(version); - if (type == null) { - assertThat(annotationNode.getMember("type")).isNull(); - } - else { - assertThat(getMemberValue(annotationNode, "type")).isEqualTo(type); - } - if (classifier == null) { - assertThat(annotationNode.getMember("classifier")).isNull(); - } - else { - assertThat(getMemberValue(annotationNode, "classifier")).isEqualTo(classifier); - } - assertThat(getMemberValue(annotationNode, "transitive")).isEqualTo(transitive); - } - - private Object getMemberValue(AnnotationNode annotationNode, String member) { - return ((ConstantExpression) annotationNode.getMember(member)).getValue(); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/ExtendedGroovyClassLoaderTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/ExtendedGroovyClassLoaderTests.java deleted file mode 100644 index d61bc90e690..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/ExtendedGroovyClassLoaderTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli.compiler; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -/** - * Tests for {@link ExtendedGroovyClassLoader}. - * - * @author Phillip Webb - */ -class ExtendedGroovyClassLoaderTests { - - private final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); - - private final ExtendedGroovyClassLoader defaultScopeGroovyClassLoader = new ExtendedGroovyClassLoader( - GroovyCompilerScope.DEFAULT); - - @Test - void loadsGroovyFromSameClassLoader() throws Exception { - Class c1 = Class.forName("groovy.lang.Script", false, this.contextClassLoader); - Class c2 = Class.forName("groovy.lang.Script", false, this.defaultScopeGroovyClassLoader); - assertThat(c1.getClassLoader()).isSameAs(c2.getClassLoader()); - } - - @Test - void filtersNonGroovy() throws Exception { - Class.forName("org.springframework.util.StringUtils", false, this.contextClassLoader); - assertThatExceptionOfType(ClassNotFoundException.class).isThrownBy( - () -> Class.forName("org.springframework.util.StringUtils", false, this.defaultScopeGroovyClassLoader)); - } - - @Test - void loadsJavaTypes() throws Exception { - Class.forName("java.lang.Boolean", false, this.defaultScopeGroovyClassLoader); - } - - @Test - void loadsSqlTypes() throws Exception { - Class.forName("java.sql.SQLException", false, this.contextClassLoader); - Class.forName("java.sql.SQLException", false, this.defaultScopeGroovyClassLoader); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/GenericBomAstTransformationTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/GenericBomAstTransformationTests.java deleted file mode 100644 index 5b4d864cd6d..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/GenericBomAstTransformationTests.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler; - -import java.util.ArrayList; -import java.util.List; - -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.AnnotationNode; -import org.codehaus.groovy.ast.ClassHelper; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.ModuleNode; -import org.codehaus.groovy.ast.PackageNode; -import org.codehaus.groovy.ast.expr.ConstantExpression; -import org.codehaus.groovy.ast.expr.Expression; -import org.codehaus.groovy.ast.expr.ListExpression; -import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.control.io.ReaderSource; -import org.codehaus.groovy.transform.ASTTransformation; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.groovy.DependencyManagementBom; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ResolveDependencyCoordinatesTransformation} - * - * @author Andy Wilkinson - * @author Dave Syer - */ -final class GenericBomAstTransformationTests { - - private final SourceUnit sourceUnit = new SourceUnit((String) null, (ReaderSource) null, null, null, null); - - private final ModuleNode moduleNode = new ModuleNode(this.sourceUnit); - - private final ASTTransformation transformation = new GenericBomAstTransformation() { - - @Override - public int getOrder() { - return DependencyManagementBomTransformation.ORDER - 10; - } - - @Override - protected String getBomModule() { - return "test:child:1.0.0"; - } - - }; - - @Test - void transformationOfEmptyPackage() { - this.moduleNode.setPackage(new PackageNode("foo")); - this.transformation.visit(new ASTNode[] { this.moduleNode }, this.sourceUnit); - assertThat(getValue().toString()).isEqualTo("[test:child:1.0.0]"); - } - - @Test - void transformationOfClass() { - this.moduleNode.addClass(ClassHelper.make("MyClass")); - this.transformation.visit(new ASTNode[] { this.moduleNode }, this.sourceUnit); - assertThat(getValue().toString()).isEqualTo("[test:child:1.0.0]"); - } - - @Test - void transformationOfClassWithExistingManagedDependencies() { - this.moduleNode.setPackage(new PackageNode("foo")); - ClassNode cls = ClassHelper.make("MyClass"); - this.moduleNode.addClass(cls); - AnnotationNode annotation = new AnnotationNode(ClassHelper.make(DependencyManagementBom.class)); - annotation.addMember("value", new ConstantExpression("test:parent:1.0.0")); - cls.addAnnotation(annotation); - this.transformation.visit(new ASTNode[] { this.moduleNode }, this.sourceUnit); - assertThat(getValue().toString()).isEqualTo("[test:parent:1.0.0, test:child:1.0.0]"); - } - - private List getValue() { - Expression expression = findAnnotation().getMember("value"); - if (expression instanceof ListExpression listExpression) { - List list = new ArrayList<>(); - for (Expression ex : listExpression.getExpressions()) { - list.add((String) ((ConstantExpression) ex).getValue()); - } - return list; - } - else if (expression == null) { - return null; - } - else { - throw new IllegalStateException("Member 'value' is not a ListExpression"); - } - } - - private AnnotationNode findAnnotation() { - PackageNode packageNode = this.moduleNode.getPackage(); - ClassNode bom = ClassHelper.make(DependencyManagementBom.class); - if (packageNode != null) { - if (!packageNode.getAnnotations(bom).isEmpty()) { - return packageNode.getAnnotations(bom).get(0); - } - } - if (!this.moduleNode.getClasses().isEmpty()) { - return this.moduleNode.getClasses().get(0).getAnnotations(bom).get(0); - } - throw new IllegalStateException("No package or class node found"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/RepositoryConfigurationFactoryTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/RepositoryConfigurationFactoryTests.java deleted file mode 100644 index b784f3d422c..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/RepositoryConfigurationFactoryTests.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration; -import org.springframework.boot.test.util.TestPropertyValues; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link RepositoryConfigurationFactory} - * - * @author Andy Wilkinson - */ -class RepositoryConfigurationFactoryTests { - - @Test - void defaultRepositories() { - TestPropertyValues.of("user.home:src/test/resources/maven-settings/basic").applyToSystemProperties(() -> { - List repositoryConfiguration = RepositoryConfigurationFactory - .createDefaultRepositoryConfiguration(); - assertRepositoryConfiguration(repositoryConfiguration, "central", "local", "spring-snapshot", - "spring-milestone"); - return null; - }); - } - - @Test - void snapshotRepositoriesDisabled() { - TestPropertyValues.of("user.home:src/test/resources/maven-settings/basic", "disableSpringSnapshotRepos:true") - .applyToSystemProperties(() -> { - List repositoryConfiguration = RepositoryConfigurationFactory - .createDefaultRepositoryConfiguration(); - assertRepositoryConfiguration(repositoryConfiguration, "central", "local"); - return null; - }); - } - - @Test - void activeByDefaultProfileRepositories() { - TestPropertyValues.of("user.home:src/test/resources/maven-settings/active-profile-repositories") - .applyToSystemProperties(() -> { - List repositoryConfiguration = RepositoryConfigurationFactory - .createDefaultRepositoryConfiguration(); - assertRepositoryConfiguration(repositoryConfiguration, "central", "local", "spring-snapshot", - "spring-milestone", "active-by-default"); - return null; - }); - } - - @Test - void activeByPropertyProfileRepositories() { - TestPropertyValues.of("user.home:src/test/resources/maven-settings/active-profile-repositories", "foo:bar") - .applyToSystemProperties(() -> { - List repositoryConfiguration = RepositoryConfigurationFactory - .createDefaultRepositoryConfiguration(); - assertRepositoryConfiguration(repositoryConfiguration, "central", "local", "spring-snapshot", - "spring-milestone", "active-by-property"); - return null; - }); - } - - @Test - void interpolationProfileRepositories() { - TestPropertyValues - .of("user.home:src/test/resources/maven-settings/active-profile-repositories", "interpolate:true") - .applyToSystemProperties(() -> { - List repositoryConfiguration = RepositoryConfigurationFactory - .createDefaultRepositoryConfiguration(); - assertRepositoryConfiguration(repositoryConfiguration, "central", "local", "spring-snapshot", - "spring-milestone", "interpolate-releases", "interpolate-snapshots"); - return null; - }); - } - - private void assertRepositoryConfiguration(List configurations, String... expectedNames) { - assertThat(configurations).hasSize(expectedNames.length); - Set actualNames = new HashSet<>(); - for (RepositoryConfiguration configuration : configurations) { - actualNames.add(configuration.getName()); - } - assertThat(actualNames).containsOnly(expectedNames); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/ResolveDependencyCoordinatesTransformationTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/ResolveDependencyCoordinatesTransformationTests.java deleted file mode 100644 index 8a5d49f0ae4..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/ResolveDependencyCoordinatesTransformationTests.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler; - -import java.util.Arrays; - -import groovy.lang.Grab; -import org.codehaus.groovy.ast.ASTNode; -import org.codehaus.groovy.ast.AnnotationNode; -import org.codehaus.groovy.ast.ClassNode; -import org.codehaus.groovy.ast.ConstructorNode; -import org.codehaus.groovy.ast.FieldNode; -import org.codehaus.groovy.ast.MethodNode; -import org.codehaus.groovy.ast.ModuleNode; -import org.codehaus.groovy.ast.PackageNode; -import org.codehaus.groovy.ast.Parameter; -import org.codehaus.groovy.ast.VariableScope; -import org.codehaus.groovy.ast.expr.ConstantExpression; -import org.codehaus.groovy.ast.expr.DeclarationExpression; -import org.codehaus.groovy.ast.expr.Expression; -import org.codehaus.groovy.ast.expr.VariableExpression; -import org.codehaus.groovy.ast.stmt.BlockStatement; -import org.codehaus.groovy.ast.stmt.ExpressionStatement; -import org.codehaus.groovy.control.SourceUnit; -import org.codehaus.groovy.control.io.ReaderSource; -import org.codehaus.groovy.transform.ASTTransformation; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.cli.compiler.dependencies.ArtifactCoordinatesResolver; -import org.springframework.boot.cli.compiler.dependencies.SpringBootDependenciesDependencyManagement; -import org.springframework.boot.cli.compiler.grape.DependencyResolutionContext; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link ResolveDependencyCoordinatesTransformation} - * - * @author Andy Wilkinson - */ -final class ResolveDependencyCoordinatesTransformationTests { - - private final SourceUnit sourceUnit = new SourceUnit((String) null, (ReaderSource) null, null, null, null); - - private final ModuleNode moduleNode = new ModuleNode(this.sourceUnit); - - private final AnnotationNode grabAnnotation = createGrabAnnotation(); - - private final ArtifactCoordinatesResolver coordinatesResolver = mock(ArtifactCoordinatesResolver.class); - - private final DependencyResolutionContext resolutionContext = new DependencyResolutionContext() { - - { - addDependencyManagement(new SpringBootDependenciesDependencyManagement()); - } - - @Override - public ArtifactCoordinatesResolver getArtifactCoordinatesResolver() { - return ResolveDependencyCoordinatesTransformationTests.this.coordinatesResolver; - } - - }; - - private final ASTTransformation transformation = new ResolveDependencyCoordinatesTransformation( - this.resolutionContext); - - @BeforeEach - void setUpExpectations() { - given(this.coordinatesResolver.getGroupId("spring-core")).willReturn("org.springframework"); - } - - @Test - void transformationOfAnnotationOnImport() { - ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); - this.moduleNode.addImport("alias", classNode, Arrays.asList(this.grabAnnotation)); - assertGrabAnnotationHasBeenTransformed(); - } - - @Test - void transformationOfAnnotationOnStarImport() { - this.moduleNode.addStarImport("org.springframework.util", Arrays.asList(this.grabAnnotation)); - - assertGrabAnnotationHasBeenTransformed(); - } - - @Test - void transformationOfAnnotationOnStaticImport() { - ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); - this.moduleNode.addStaticImport(classNode, "field", "alias", Arrays.asList(this.grabAnnotation)); - - assertGrabAnnotationHasBeenTransformed(); - } - - @Test - void transformationOfAnnotationOnStaticStarImport() { - ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); - this.moduleNode.addStaticStarImport("test", classNode, Arrays.asList(this.grabAnnotation)); - - assertGrabAnnotationHasBeenTransformed(); - } - - @Test - void transformationOfAnnotationOnPackage() { - PackageNode packageNode = new PackageNode("test"); - packageNode.addAnnotation(this.grabAnnotation); - this.moduleNode.setPackage(packageNode); - - assertGrabAnnotationHasBeenTransformed(); - } - - @Test - void transformationOfAnnotationOnClass() { - ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); - classNode.addAnnotation(this.grabAnnotation); - this.moduleNode.addClass(classNode); - - assertGrabAnnotationHasBeenTransformed(); - } - - @Test - void transformationOfAnnotationOnAnnotation() { - } - - @Test - void transformationOfAnnotationOnField() { - ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); - this.moduleNode.addClass(classNode); - - FieldNode fieldNode = new FieldNode("test", 0, new ClassNode(Object.class), classNode, null); - classNode.addField(fieldNode); - - fieldNode.addAnnotation(this.grabAnnotation); - - assertGrabAnnotationHasBeenTransformed(); - } - - @Test - void transformationOfAnnotationOnConstructor() { - ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); - this.moduleNode.addClass(classNode); - - ConstructorNode constructorNode = new ConstructorNode(0, null); - constructorNode.addAnnotation(this.grabAnnotation); - classNode.addMethod(constructorNode); - - assertGrabAnnotationHasBeenTransformed(); - } - - @Test - void transformationOfAnnotationOnMethod() { - ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); - this.moduleNode.addClass(classNode); - - MethodNode methodNode = new MethodNode("test", 0, new ClassNode(Void.class), new Parameter[0], new ClassNode[0], - null); - methodNode.addAnnotation(this.grabAnnotation); - classNode.addMethod(methodNode); - - assertGrabAnnotationHasBeenTransformed(); - } - - @Test - void transformationOfAnnotationOnMethodParameter() { - ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); - this.moduleNode.addClass(classNode); - - Parameter parameter = new Parameter(new ClassNode(Object.class), "test"); - parameter.addAnnotation(this.grabAnnotation); - - MethodNode methodNode = new MethodNode("test", 0, new ClassNode(Void.class), new Parameter[] { parameter }, - new ClassNode[0], null); - classNode.addMethod(methodNode); - - assertGrabAnnotationHasBeenTransformed(); - } - - @Test - void transformationOfAnnotationOnLocalVariable() { - ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); - this.moduleNode.addClass(classNode); - - DeclarationExpression declarationExpression = new DeclarationExpression(new VariableExpression("test"), null, - new ConstantExpression("test")); - declarationExpression.addAnnotation(this.grabAnnotation); - - BlockStatement code = new BlockStatement(Arrays.asList(new ExpressionStatement(declarationExpression)), - new VariableScope()); - - MethodNode methodNode = new MethodNode("test", 0, new ClassNode(Void.class), new Parameter[0], new ClassNode[0], - code); - - classNode.addMethod(methodNode); - - assertGrabAnnotationHasBeenTransformed(); - } - - private AnnotationNode createGrabAnnotation() { - ClassNode classNode = new ClassNode(Grab.class); - AnnotationNode annotationNode = new AnnotationNode(classNode); - annotationNode.addMember("value", new ConstantExpression("spring-core")); - return annotationNode; - } - - private void assertGrabAnnotationHasBeenTransformed() { - this.transformation.visit(new ASTNode[] { this.moduleNode }, this.sourceUnit); - assertThat(getGrabAnnotationMemberAsString("group")).isEqualTo("org.springframework"); - assertThat(getGrabAnnotationMemberAsString("module")).isEqualTo("spring-core"); - } - - private Object getGrabAnnotationMemberAsString(String memberName) { - Expression expression = this.grabAnnotation.getMember(memberName); - if (expression instanceof ConstantExpression constantExpression) { - return constantExpression.getValue(); - } - else if (expression == null) { - return null; - } - else { - throw new IllegalStateException("Member '" + memberName + "' is not a ConstantExpression"); - } - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/dependencies/CompositeDependencyManagementTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/dependencies/CompositeDependencyManagementTests.java deleted file mode 100644 index 27bf9104601..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/dependencies/CompositeDependencyManagementTests.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli.compiler.dependencies; - -import java.util.Arrays; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; - -/** - * Tests for {@link CompositeDependencyManagement} - * - * @author Andy Wilkinson - */ -@ExtendWith(MockitoExtension.class) -class CompositeDependencyManagementTests { - - @Mock - private DependencyManagement dependencyManagement1; - - @Mock - private DependencyManagement dependencyManagement2; - - @Test - void unknownSpringBootVersion() { - given(this.dependencyManagement1.getSpringBootVersion()).willReturn(null); - given(this.dependencyManagement2.getSpringBootVersion()).willReturn(null); - assertThat(new CompositeDependencyManagement(this.dependencyManagement1, this.dependencyManagement2) - .getSpringBootVersion()).isNull(); - } - - @Test - void knownSpringBootVersion() { - given(this.dependencyManagement1.getSpringBootVersion()).willReturn("1.2.3"); - assertThat(new CompositeDependencyManagement(this.dependencyManagement1, this.dependencyManagement2) - .getSpringBootVersion()).isEqualTo("1.2.3"); - } - - @Test - void unknownDependency() { - given(this.dependencyManagement1.find("artifact")).willReturn(null); - given(this.dependencyManagement2.find("artifact")).willReturn(null); - assertThat(new CompositeDependencyManagement(this.dependencyManagement1, this.dependencyManagement2) - .find("artifact")).isNull(); - } - - @Test - void knownDependency() { - given(this.dependencyManagement1.find("artifact")).willReturn(new Dependency("test", "artifact", "1.2.3")); - assertThat(new CompositeDependencyManagement(this.dependencyManagement1, this.dependencyManagement2) - .find("artifact")).isEqualTo(new Dependency("test", "artifact", "1.2.3")); - } - - @Test - void getDependencies() { - given(this.dependencyManagement1.getDependencies()) - .willReturn(Arrays.asList(new Dependency("test", "artifact", "1.2.3"))); - given(this.dependencyManagement2.getDependencies()) - .willReturn(Arrays.asList(new Dependency("test", "artifact", "1.2.4"))); - assertThat(new CompositeDependencyManagement(this.dependencyManagement1, this.dependencyManagement2) - .getDependencies()).containsOnly(new Dependency("test", "artifact", "1.2.3"), - new Dependency("test", "artifact", "1.2.4")); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/dependencies/DependencyManagementArtifactCoordinatesResolverTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/dependencies/DependencyManagementArtifactCoordinatesResolverTests.java deleted file mode 100644 index abe2756b4d1..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/dependencies/DependencyManagementArtifactCoordinatesResolverTests.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler.dependencies; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; - -/** - * Tests for {@link DependencyManagementArtifactCoordinatesResolver}. - * - * @author Phillip Webb - * @author Andy Wilkinson - */ -class DependencyManagementArtifactCoordinatesResolverTests { - - private DependencyManagement dependencyManagement; - - private DependencyManagementArtifactCoordinatesResolver resolver; - - @BeforeEach - void setup() { - this.dependencyManagement = mock(DependencyManagement.class); - given(this.dependencyManagement.find("a1")).willReturn(new Dependency("g1", "a1", "0")); - given(this.dependencyManagement.getSpringBootVersion()).willReturn("1"); - this.resolver = new DependencyManagementArtifactCoordinatesResolver(this.dependencyManagement); - } - - @Test - void getGroupIdForBootArtifact() { - assertThat(this.resolver.getGroupId("spring-boot-something")).isEqualTo("org.springframework.boot"); - then(this.dependencyManagement).should(never()).find(anyString()); - } - - @Test - void getGroupIdFound() { - assertThat(this.resolver.getGroupId("a1")).isEqualTo("g1"); - } - - @Test - void getGroupIdNotFound() { - assertThat(this.resolver.getGroupId("a2")).isNull(); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/dependencies/SpringBootDependenciesDependencyManagementTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/dependencies/SpringBootDependenciesDependencyManagementTests.java deleted file mode 100644 index 1f585a4bb33..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/dependencies/SpringBootDependenciesDependencyManagementTests.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli.compiler.dependencies; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link SpringBootDependenciesDependencyManagement} - * - * @author Andy Wilkinson - */ -class SpringBootDependenciesDependencyManagementTests { - - private final DependencyManagement dependencyManagement = new SpringBootDependenciesDependencyManagement(); - - @Test - void springBootVersion() { - assertThat(this.dependencyManagement.getSpringBootVersion()).isNotNull(); - } - - @Test - void find() { - Dependency dependency = this.dependencyManagement.find("spring-boot"); - assertThat(dependency).isNotNull(); - assertThat(dependency.getGroupId()).isEqualTo("org.springframework.boot"); - assertThat(dependency.getArtifactId()).isEqualTo("spring-boot"); - } - - @Test - void getDependencies() { - assertThat(this.dependencyManagement.getDependencies()).isNotEmpty(); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/DependencyResolutionContextTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/DependencyResolutionContextTests.java deleted file mode 100644 index fa4bbc37599..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/DependencyResolutionContextTests.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.grape; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.cli.compiler.dependencies.SpringBootDependenciesDependencyManagement; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link DependencyResolutionContext}. - * - * @author Dave Syer - */ -class DependencyResolutionContextTests { - - @Test - void defaultDependenciesEmpty() { - assertThat(new DependencyResolutionContext().getManagedDependencies()).isEmpty(); - } - - @Test - void canAddSpringBootDependencies() { - DependencyResolutionContext dependencyResolutionContext = new DependencyResolutionContext(); - dependencyResolutionContext.addDependencyManagement(new SpringBootDependenciesDependencyManagement()); - assertThat(dependencyResolutionContext.getManagedDependencies()).isNotEmpty(); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/DetailedProgressReporterTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/DetailedProgressReporterTests.java deleted file mode 100644 index 0ecfb31e801..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/DetailedProgressReporterTests.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.compiler.grape; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.transfer.TransferCancelledException; -import org.eclipse.aether.transfer.TransferEvent; -import org.eclipse.aether.transfer.TransferResource; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link DetailedProgressReporter}. - * - * @author Andy Wilkinson - */ -final class DetailedProgressReporterTests { - - private static final String REPOSITORY = "https://repo.example.com/"; - - private static final String ARTIFACT = "org/alpha/bravo/charlie/1.2.3/charlie-1.2.3.jar"; - - private final TransferResource resource = new TransferResource(null, REPOSITORY, ARTIFACT, null, null); - - private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - private final PrintStream out = new PrintStream(this.baos); - - private final DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(); - - @BeforeEach - void initialize() { - new DetailedProgressReporter(this.session, this.out); - } - - @Test - void downloading() throws TransferCancelledException { - TransferEvent startedEvent = new TransferEvent.Builder(this.session, this.resource).build(); - this.session.getTransferListener().transferStarted(startedEvent); - assertThat(new String(this.baos.toByteArray())) - .isEqualTo(String.format("Downloading: %s%s%n", REPOSITORY, ARTIFACT)); - } - - @Test - void downloaded() throws InterruptedException { - // Ensure some transfer time - Thread.sleep(100); - TransferEvent completedEvent = new TransferEvent.Builder(this.session, this.resource).addTransferredBytes(4096) - .build(); - this.session.getTransferListener().transferSucceeded(completedEvent); - String message = new String(this.baos.toByteArray()).replace("\\", "/"); - assertThat(message).startsWith("Downloaded: " + REPOSITORY + ARTIFACT); - assertThat(message).contains("4KB at"); - assertThat(message).contains("KB/sec"); - assertThat(message).endsWith("\n"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfigurationTests.java deleted file mode 100644 index 001c79e642f..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfigurationTests.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler.grape; - -import java.io.File; - -import org.apache.maven.repository.internal.MavenRepositorySystemUtils; -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; -import org.eclipse.aether.repository.LocalRepository; -import org.eclipse.aether.repository.LocalRepositoryManager; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.stubbing.Answer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.never; - -/** - * Tests for {@link GrapeRootRepositorySystemSessionAutoConfiguration} - * - * @author Andy Wilkinson - */ -@ExtendWith(MockitoExtension.class) -class GrapeRootRepositorySystemSessionAutoConfigurationTests { - - private DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); - - @Mock - private RepositorySystem repositorySystem; - - @Test - void noLocalRepositoryWhenNoGrapeRoot() { - new GrapeRootRepositorySystemSessionAutoConfiguration().apply(this.session, this.repositorySystem); - then(this.repositorySystem).should(never()).newLocalRepositoryManager(eq(this.session), - any(LocalRepository.class)); - assertThat(this.session.getLocalRepository()).isNull(); - } - - @Test - void grapeRootConfiguresLocalRepositoryLocation() { - given(this.repositorySystem.newLocalRepositoryManager(eq(this.session), any(LocalRepository.class))) - .willAnswer(new LocalRepositoryManagerAnswer()); - - System.setProperty("grape.root", "foo"); - try { - new GrapeRootRepositorySystemSessionAutoConfiguration().apply(this.session, this.repositorySystem); - } - finally { - System.clearProperty("grape.root"); - } - - then(this.repositorySystem).should().newLocalRepositoryManager(eq(this.session), any(LocalRepository.class)); - - assertThat(this.session.getLocalRepository()).isNotNull(); - assertThat(this.session.getLocalRepository().getBasedir().getAbsolutePath()) - .endsWith(File.separatorChar + "foo" + File.separatorChar + "repository"); - } - - private class LocalRepositoryManagerAnswer implements Answer { - - @Override - public LocalRepositoryManager answer(InvocationOnMock invocation) throws Throwable { - LocalRepository localRepository = invocation.getArgument(1); - return new SimpleLocalRepositoryManagerFactory() - .newInstance(GrapeRootRepositorySystemSessionAutoConfigurationTests.this.session, localRepository); - } - - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/MavenResolverGrapeEngineTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/MavenResolverGrapeEngineTests.java deleted file mode 100644 index f2401b3a311..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/MavenResolverGrapeEngineTests.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright 2012-2022 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.boot.cli.compiler.grape; - -import java.io.File; -import java.net.URI; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import groovy.grape.GrapeEngine; -import groovy.lang.GroovyClassLoader; -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.repository.Authentication; -import org.eclipse.aether.repository.RemoteRepository; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.cli.compiler.dependencies.SpringBootDependenciesDependencyManagement; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -/** - * Tests for {@link MavenResolverGrapeEngine}. - * - * @author Andy Wilkinson - */ -class MavenResolverGrapeEngineTests { - - private final GroovyClassLoader groovyClassLoader = new GroovyClassLoader(); - - private final RepositoryConfiguration springMilestone = new RepositoryConfiguration("spring-milestone", - URI.create("https://repo.spring.io/milestone"), false); - - private final RepositoryConfiguration springSnapshot = new RepositoryConfiguration("spring-snapshot", - URI.create("https://repo.spring.io/snapshot"), true); - - private GrapeEngine createGrapeEngine(RepositoryConfiguration... additionalRepositories) { - List repositoryConfigurations = new ArrayList<>(); - repositoryConfigurations - .add(new RepositoryConfiguration("central", URI.create("https://repo1.maven.org/maven2"), false)); - repositoryConfigurations.addAll(Arrays.asList(additionalRepositories)); - DependencyResolutionContext dependencyResolutionContext = new DependencyResolutionContext(); - dependencyResolutionContext.addDependencyManagement(new SpringBootDependenciesDependencyManagement()); - return MavenResolverGrapeEngineFactory.create(this.groovyClassLoader, repositoryConfigurations, - dependencyResolutionContext, false); - } - - @Test - void dependencyResolution() { - Map args = new HashMap<>(); - createGrapeEngine(this.springMilestone, this.springSnapshot).grab(args, - createDependency("org.springframework", "spring-jdbc", null)); - assertThat(this.groovyClassLoader.getURLs()).hasSize(5); - } - - @Test - void proxySelector() { - doWithCustomUserHome(() -> { - GrapeEngine grapeEngine = createGrapeEngine(); - DefaultRepositorySystemSession session = (DefaultRepositorySystemSession) ReflectionTestUtils - .getField(grapeEngine, "session"); - - assertThat(session.getProxySelector() instanceof CompositeProxySelector).isTrue(); - }); - } - - @Test - void repositoryMirrors() { - doWithCustomUserHome(() -> { - List repositories = getRepositories(); - assertThat(repositories).hasSize(1); - assertThat(repositories.get(0).getId()).isEqualTo("central-mirror"); - }); - } - - @Test - void repositoryAuthentication() { - doWithCustomUserHome(() -> { - List repositories = getRepositories(); - assertThat(repositories).hasSize(1); - Authentication authentication = repositories.get(0).getAuthentication(); - assertThat(authentication).isNotNull(); - }); - } - - @Test - void dependencyResolutionWithExclusions() { - Map args = new HashMap<>(); - args.put("excludes", Arrays.asList(createExclusion("org.springframework", "spring-core"))); - - createGrapeEngine(this.springMilestone, this.springSnapshot).grab(args, - createDependency("org.springframework", "spring-jdbc", "3.2.4.RELEASE"), - createDependency("org.springframework", "spring-beans", "3.2.4.RELEASE")); - - assertThat(this.groovyClassLoader.getURLs()).hasSize(3); - } - - @Test - void nonTransitiveDependencyResolution() { - Map args = new HashMap<>(); - - createGrapeEngine().grab(args, createDependency("org.springframework", "spring-jdbc", "3.2.4.RELEASE", false)); - - assertThat(this.groovyClassLoader.getURLs()).hasSize(1); - } - - @Test - void dependencyResolutionWithCustomClassLoader() { - Map args = new HashMap<>(); - GroovyClassLoader customClassLoader = new GroovyClassLoader(); - args.put("classLoader", customClassLoader); - - createGrapeEngine(this.springMilestone, this.springSnapshot).grab(args, - createDependency("org.springframework", "spring-jdbc", null)); - - assertThat(this.groovyClassLoader.getURLs()).isEmpty(); - assertThat(customClassLoader.getURLs()).hasSize(5); - } - - @Test - void resolutionWithCustomResolver() { - Map args = new HashMap<>(); - GrapeEngine grapeEngine = createGrapeEngine(); - grapeEngine.addResolver(createResolver("spring-releases", "https://repo.spring.io/release")); - Map dependency = createDependency("io.spring.docresources", "spring-doc-resources", - "0.1.1.RELEASE"); - dependency.put("ext", "zip"); - grapeEngine.grab(args, dependency); - assertThat(this.groovyClassLoader.getURLs()).hasSize(1); - } - - @Test - void differingTypeAndExt() { - Map dependency = createDependency("org.grails", "grails-dependencies", "2.4.0"); - dependency.put("type", "foo"); - dependency.put("ext", "bar"); - GrapeEngine grapeEngine = createGrapeEngine(); - assertThatIllegalArgumentException().isThrownBy(() -> grapeEngine.grab(Collections.emptyMap(), dependency)); - } - - @Test - void pomDependencyResolutionViaType() { - Map args = new HashMap<>(); - Map dependency = createDependency("org.springframework", "spring-framework-bom", - "4.0.5.RELEASE"); - dependency.put("type", "pom"); - createGrapeEngine().grab(args, dependency); - URL[] urls = this.groovyClassLoader.getURLs(); - assertThat(urls).hasSize(1); - assertThat(urls[0].toExternalForm().endsWith(".pom")).isTrue(); - } - - @Test - void pomDependencyResolutionViaExt() { - Map args = new HashMap<>(); - Map dependency = createDependency("org.springframework", "spring-framework-bom", - "4.0.5.RELEASE"); - dependency.put("ext", "pom"); - createGrapeEngine().grab(args, dependency); - URL[] urls = this.groovyClassLoader.getURLs(); - assertThat(urls).hasSize(1); - assertThat(urls[0].toExternalForm().endsWith(".pom")).isTrue(); - } - - @Test - void resolutionWithClassifier() { - Map args = new HashMap<>(); - - Map dependency = createDependency("org.springframework", "spring-jdbc", "3.2.4.RELEASE", false); - dependency.put("classifier", "sources"); - createGrapeEngine().grab(args, dependency); - - URL[] urls = this.groovyClassLoader.getURLs(); - assertThat(urls).hasSize(1); - assertThat(urls[0].toExternalForm().endsWith("-sources.jar")).isTrue(); - } - - @SuppressWarnings("unchecked") - private List getRepositories() { - GrapeEngine grapeEngine = createGrapeEngine(); - return (List) ReflectionTestUtils.getField(grapeEngine, "repositories"); - } - - private Map createDependency(String group, String module, String version) { - Map dependency = new HashMap<>(); - dependency.put("group", group); - dependency.put("module", module); - dependency.put("version", version); - return dependency; - } - - private Map createDependency(String group, String module, String version, boolean transitive) { - Map dependency = createDependency(group, module, version); - dependency.put("transitive", transitive); - return dependency; - } - - private Map createResolver(String name, String url) { - Map resolver = new HashMap<>(); - resolver.put("name", name); - resolver.put("root", url); - return resolver; - } - - private Map createExclusion(String group, String module) { - Map exclusion = new HashMap<>(); - exclusion.put("group", group); - exclusion.put("module", module); - return exclusion; - } - - private void doWithCustomUserHome(Runnable action) { - doWithSystemProperty("user.home", new File("src/test/resources").getAbsolutePath(), action); - } - - private void doWithSystemProperty(String key, String value, Runnable action) { - String previousValue = setOrClearSystemProperty(key, value); - try { - action.run(); - } - finally { - setOrClearSystemProperty(key, previousValue); - } - } - - private String setOrClearSystemProperty(String key, String value) { - if (value != null) { - return System.setProperty(key, value); - } - return System.clearProperty(key); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfigurationTests.java deleted file mode 100644 index a7cb253f836..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfigurationTests.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2012-2020 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.boot.cli.compiler.grape; - -import java.io.File; - -import org.apache.maven.repository.internal.MavenRepositorySystemUtils; -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; -import org.eclipse.aether.repository.Authentication; -import org.eclipse.aether.repository.AuthenticationContext; -import org.eclipse.aether.repository.LocalRepository; -import org.eclipse.aether.repository.Proxy; -import org.eclipse.aether.repository.RemoteRepository; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.boot.test.util.TestPropertyValues; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; - -/** - * Tests for {@link SettingsXmlRepositorySystemSessionAutoConfiguration}. - * - * @author Andy Wilkinson - */ -@ExtendWith(MockitoExtension.class) -class SettingsXmlRepositorySystemSessionAutoConfigurationTests { - - @Mock - private RepositorySystem repositorySystem; - - @Test - void basicSessionCustomization() { - assertSessionCustomization("src/test/resources/maven-settings/basic"); - } - - @Test - void encryptedSettingsSessionCustomization() { - assertSessionCustomization("src/test/resources/maven-settings/encrypted"); - } - - @Test - void propertyInterpolation() { - final DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); - given(this.repositorySystem.newLocalRepositoryManager(eq(session), any(LocalRepository.class))) - .willAnswer((invocation) -> { - LocalRepository localRepository = invocation.getArgument(1); - return new SimpleLocalRepositoryManagerFactory().newInstance(session, localRepository); - }); - TestPropertyValues.of("user.home:src/test/resources/maven-settings/property-interpolation", "foo:bar") - .applyToSystemProperties(() -> { - new SettingsXmlRepositorySystemSessionAutoConfiguration().apply(session, - SettingsXmlRepositorySystemSessionAutoConfigurationTests.this.repositorySystem); - return null; - }); - assertThat(session.getLocalRepository().getBasedir().getAbsolutePath()) - .endsWith(File.separatorChar + "bar" + File.separatorChar + "repository"); - } - - private void assertSessionCustomization(String userHome) { - final DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); - TestPropertyValues.of("user.home:" + userHome).applyToSystemProperties(() -> { - new SettingsXmlRepositorySystemSessionAutoConfiguration().apply(session, - SettingsXmlRepositorySystemSessionAutoConfigurationTests.this.repositorySystem); - return null; - }); - RemoteRepository repository = new RemoteRepository.Builder("my-server", "default", "https://maven.example.com") - .build(); - assertMirrorSelectorConfiguration(session, repository); - assertProxySelectorConfiguration(session, repository); - assertAuthenticationSelectorConfiguration(session, repository); - } - - private void assertProxySelectorConfiguration(DefaultRepositorySystemSession session, RemoteRepository repository) { - Proxy proxy = session.getProxySelector().getProxy(repository); - repository = new RemoteRepository.Builder(repository).setProxy(proxy).build(); - AuthenticationContext authenticationContext = AuthenticationContext.forProxy(session, repository); - assertThat(proxy.getHost()).isEqualTo("proxy.example.com"); - assertThat(authenticationContext.get(AuthenticationContext.USERNAME)).isEqualTo("proxyuser"); - assertThat(authenticationContext.get(AuthenticationContext.PASSWORD)).isEqualTo("somepassword"); - } - - private void assertMirrorSelectorConfiguration(DefaultRepositorySystemSession session, - RemoteRepository repository) { - RemoteRepository mirror = session.getMirrorSelector().getMirror(repository); - assertThat(mirror).as("Mirror configured for repository " + repository.getId()).isNotNull(); - assertThat(mirror.getHost()).isEqualTo("maven.example.com"); - } - - private void assertAuthenticationSelectorConfiguration(DefaultRepositorySystemSession session, - RemoteRepository repository) { - Authentication authentication = session.getAuthenticationSelector().getAuthentication(repository); - repository = new RemoteRepository.Builder(repository).setAuthentication(authentication).build(); - AuthenticationContext authenticationContext = AuthenticationContext.forRepository(session, repository); - assertThat(authenticationContext.get(AuthenticationContext.USERNAME)).isEqualTo("tester"); - assertThat(authenticationContext.get(AuthenticationContext.PASSWORD)).isEqualTo("secret"); - } - -} diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/util/ResourceUtilsTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/util/ResourceUtilsTests.java deleted file mode 100644 index 12ab21f012b..00000000000 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/util/ResourceUtilsTests.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.cli.util; - -import java.io.File; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.List; - -import org.junit.jupiter.api.Test; - -import org.springframework.util.ClassUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ResourceUtils}. - * - * @author Dave Syer - */ -class ResourceUtilsTests { - - @Test - void explicitClasspathResource() { - List urls = ResourceUtils.getUrls("classpath:init.groovy", ClassUtils.getDefaultClassLoader()); - assertThat(urls).hasSize(1); - assertThat(urls.get(0).startsWith("file:")).isTrue(); - } - - @Test - void duplicateResource() throws Exception { - URLClassLoader loader = new URLClassLoader(new URL[] { new URL("file:./src/test/resources/"), - new File("src/test/resources/").getAbsoluteFile().toURI().toURL() }); - List urls = ResourceUtils.getUrls("classpath:init.groovy", loader); - assertThat(urls).hasSize(1); - assertThat(urls.get(0).startsWith("file:")).isTrue(); - } - - @Test - void explicitClasspathResourceWithSlash() { - List urls = ResourceUtils.getUrls("classpath:/init.groovy", ClassUtils.getDefaultClassLoader()); - assertThat(urls).hasSize(1); - assertThat(urls.get(0).startsWith("file:")).isTrue(); - } - - @Test - void implicitClasspathResource() { - List urls = ResourceUtils.getUrls("init.groovy", ClassUtils.getDefaultClassLoader()); - assertThat(urls).hasSize(1); - assertThat(urls.get(0).startsWith("file:")).isTrue(); - } - - @Test - void implicitClasspathResourceWithSlash() { - List urls = ResourceUtils.getUrls("/init.groovy", ClassUtils.getDefaultClassLoader()); - assertThat(urls).hasSize(1); - assertThat(urls.get(0).startsWith("file:")).isTrue(); - } - - @Test - void nonexistentClasspathResource() { - List urls = ResourceUtils.getUrls("classpath:nonexistent.groovy", null); - assertThat(urls).isEmpty(); - } - - @Test - void explicitFile() { - List urls = ResourceUtils.getUrls("file:src/test/resources/init.groovy", - ClassUtils.getDefaultClassLoader()); - assertThat(urls).hasSize(1); - assertThat(urls.get(0).startsWith("file:")).isTrue(); - } - - @Test - void implicitFile() { - List urls = ResourceUtils.getUrls("src/test/resources/init.groovy", ClassUtils.getDefaultClassLoader()); - assertThat(urls).hasSize(1); - assertThat(urls.get(0).startsWith("file:")).isTrue(); - } - - @Test - void nonexistentFile() { - List urls = ResourceUtils.getUrls("file:nonexistent.groovy", null); - assertThat(urls).isEmpty(); - } - - @Test - void recursiveFiles() { - List urls = ResourceUtils.getUrls("src/test/resources/dir-sample", ClassUtils.getDefaultClassLoader()); - assertThat(urls).hasSize(1); - assertThat(urls.get(0).startsWith("file:")).isTrue(); - } - - @Test - void recursiveFilesByPatternWithPrefix() { - List urls = ResourceUtils.getUrls("file:src/test/resources/dir-sample/**/*.groovy", - ClassUtils.getDefaultClassLoader()); - assertThat(urls).hasSize(1); - assertThat(urls.get(0).startsWith("file:")).isTrue(); - } - - @Test - void recursiveFilesByPattern() { - List urls = ResourceUtils.getUrls("src/test/resources/dir-sample/**/*.groovy", - ClassUtils.getDefaultClassLoader()); - assertThat(urls).hasSize(1); - assertThat(urls.get(0).startsWith("file:")).isTrue(); - } - - @Test - void directoryOfFilesWithPrefix() { - List urls = ResourceUtils.getUrls("file:src/test/resources/dir-sample/code/*", - ClassUtils.getDefaultClassLoader()); - assertThat(urls).hasSize(1); - assertThat(urls.get(0).startsWith("file:")).isTrue(); - } - - @Test - void directoryOfFiles() { - List urls = ResourceUtils.getUrls("src/test/resources/dir-sample/code/*", - ClassUtils.getDefaultClassLoader()); - assertThat(urls).hasSize(1); - assertThat(urls.get(0).startsWith("file:")).isTrue(); - } - -} diff --git a/spring-boot-project/spring-boot-cli/test-samples/app.groovy b/spring-boot-project/spring-boot-cli/test-samples/app.groovy deleted file mode 100644 index ff7e6d66c4d..00000000000 --- a/spring-boot-project/spring-boot-cli/test-samples/app.groovy +++ /dev/null @@ -1,17 +0,0 @@ -@Configuration(proxyBeanMethods = false) -class App { - - @Bean - MyService myService() { - return new MyService() - } - -} - -class MyService { - - String sayWorld() { - return "World!" - } - -} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-cli/test-samples/book.groovy b/spring-boot-project/spring-boot-cli/test-samples/book.groovy deleted file mode 100644 index 0d3192b66fb..00000000000 --- a/spring-boot-project/spring-boot-cli/test-samples/book.groovy +++ /dev/null @@ -1,4 +0,0 @@ -class Book { - String author - String title -} diff --git a/spring-boot-project/spring-boot-cli/test-samples/book_and_tests.groovy b/spring-boot-project/spring-boot-cli/test-samples/book_and_tests.groovy deleted file mode 100644 index 8424fe5344c..00000000000 --- a/spring-boot-project/spring-boot-cli/test-samples/book_and_tests.groovy +++ /dev/null @@ -1,12 +0,0 @@ -class Book { - String author - String title -} - -class BookTests { - @Test - void testBooks() { - Book book = new Book(author: "Tom Clancy", title: "Threat Vector") - assertEquals("Tom Clancy", book.author) - } -} diff --git a/spring-boot-project/spring-boot-cli/test-samples/empty.groovy b/spring-boot-project/spring-boot-cli/test-samples/empty.groovy deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/spring-boot-project/spring-boot-cli/test-samples/failures.groovy b/spring-boot-project/spring-boot-cli/test-samples/failures.groovy deleted file mode 100644 index ffb7bfc4219..00000000000 --- a/spring-boot-project/spring-boot-cli/test-samples/failures.groovy +++ /dev/null @@ -1,36 +0,0 @@ -class FailingJUnitTests { - @Test - void passingTest() { - assertTrue(true) - } - - @Test - void failureByAssertion() { - assertTrue(false) - } - - @Test - void failureByException() { - throw new RuntimeException("This should also be handled") - } -} - -class FailingSpockTest extends Specification { - def "this should pass"() { - expect: - name.size() == length - - where: - name | length - "Spock" | 5 - } - - def "this should fail on purpose as well"() { - when: - String text = "Greetings" - - then: - //throw new RuntimeException("This should fail!") - true == false - } -} diff --git a/spring-boot-project/spring-boot-cli/test-samples/integration.groovy b/spring-boot-project/spring-boot-cli/test-samples/integration.groovy deleted file mode 100644 index d40a37025ee..00000000000 --- a/spring-boot-project/spring-boot-cli/test-samples/integration.groovy +++ /dev/null @@ -1,22 +0,0 @@ -@SpringBootTest(classes=Application) -class BookTests { - @Autowired - Book book - @Test - void testBooks() { - assertEquals("Tom Clancy", book.author) - } -} - -@Configuration(proxyBeanMethods = false) -class Application { - @Bean - Book book() { - new Book(author: "Tom Clancy", title: "Threat Vector") - } -} - -class Book { - String author - String title -} diff --git a/spring-boot-project/spring-boot-cli/test-samples/integration_auto.groovy b/spring-boot-project/spring-boot-cli/test-samples/integration_auto.groovy deleted file mode 100644 index f05b9639e82..00000000000 --- a/spring-boot-project/spring-boot-cli/test-samples/integration_auto.groovy +++ /dev/null @@ -1,21 +0,0 @@ -package com.example - -@SpringBootApplication -@SpringBootTest(classes=RestTests, webEnvironment=WebEnvironment.RANDOM_PORT) -class RestTests { - - @Autowired - TestRestTemplate testRestTemplate - - @Test - void testHome() { - assertEquals('Hello', testRestTemplate.getForObject('/', String)) - } - - @RestController - static class Application { - @RequestMapping('/') - String hello() { 'Hello' } - } - -} diff --git a/spring-boot-project/spring-boot-cli/test-samples/integration_auto_test.groovy b/spring-boot-project/spring-boot-cli/test-samples/integration_auto_test.groovy deleted file mode 100644 index b5ac561cd4b..00000000000 --- a/spring-boot-project/spring-boot-cli/test-samples/integration_auto_test.groovy +++ /dev/null @@ -1,12 +0,0 @@ -@SpringBootTest(classes=App) -class AppTests { - - @Autowired - MyService myService - - @Test - void test() { - assertNotNull(myService) - } - -} diff --git a/spring-boot-project/spring-boot-cli/test-samples/jms.groovy b/spring-boot-project/spring-boot-cli/test-samples/jms.groovy deleted file mode 100644 index 7b3fae617b5..00000000000 --- a/spring-boot-project/spring-boot-cli/test-samples/jms.groovy +++ /dev/null @@ -1,31 +0,0 @@ -@Grab("spring-boot-starter-artemis") -@Grab("artemis-jakarta-server") -import java.util.concurrent.CountDownLatch - -@Log -@Configuration(proxyBeanMethods = false) -@EnableJms -class JmsExample implements CommandLineRunner { - - private CountDownLatch latch = new CountDownLatch(1) - - @Autowired - JmsTemplate jmsTemplate - - void run(String... args) { - def messageCreator = { session -> - session.createObjectMessage("Greetings from Spring Boot via Artemis") - } as MessageCreator - log.info "Sending JMS message..." - jmsTemplate.send("spring-boot", messageCreator) - log.info "Send JMS message, waiting..." - latch.await() - } - - @JmsListener(destination = 'spring-boot') - def receive(String message) { - log.info "Received ${message}" - latch.countDown() - } - -} diff --git a/spring-boot-project/spring-boot-cli/test-samples/spock.groovy b/spring-boot-project/spring-boot-cli/test-samples/spock.groovy deleted file mode 100644 index 1bfcdb88149..00000000000 --- a/spring-boot-project/spring-boot-cli/test-samples/spock.groovy +++ /dev/null @@ -1,12 +0,0 @@ -class HelloSpock extends Specification { - def "length of Spock's and his friends' names"() { - expect: - name.size() == length - - where: - name | length - "Spock" | 5 - "Kirk" | 4 - "Scotty" | 6 - } -} diff --git a/spring-boot-project/spring-boot-cli/test-samples/test.groovy b/spring-boot-project/spring-boot-cli/test-samples/test.groovy deleted file mode 100644 index a08b8668854..00000000000 --- a/spring-boot-project/spring-boot-cli/test-samples/test.groovy +++ /dev/null @@ -1,7 +0,0 @@ -class BookTests { - @Test - void testBooks() { - Book book = new Book(author: "Tom Clancy", title: "Threat Vector") - assertEquals("Tom Clancy", book.author) - } -} diff --git a/spring-boot-project/spring-boot-docs/build.gradle b/spring-boot-project/spring-boot-docs/build.gradle index 6401b472104..ca2c4503b7c 100644 --- a/spring-boot-project/spring-boot-docs/build.gradle +++ b/spring-boot-project/spring-boot-docs/build.gradle @@ -1,6 +1,5 @@ plugins { id "java" - id "groovy" id "org.asciidoctor.jvm.convert" id "org.springframework.boot.conventions" id "org.springframework.boot.deployed" diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli.adoc index e573303d9c6..fbf719066c1 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli.adoc @@ -3,18 +3,10 @@ include::attributes.adoc[] -The Spring Boot CLI is a command line tool that you can use if you want to quickly develop a Spring application. -It lets you run Groovy scripts, which means that you have a familiar Java-like syntax without so much boilerplate code. -You can also bootstrap a new project or write your own command for it. +The Spring Boot CLI is a command line tool that you can use to bootstrap a new project from https://start.spring.io or encode a password. include::cli/installation.adoc[] include::cli/using-the-cli.adoc[] - -include::cli/groovy-beans-dsl.adoc[] - -include::cli/maven-setting.adoc[] - -include::cli/whats-next.adoc[] diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli/groovy-beans-dsl.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli/groovy-beans-dsl.adoc deleted file mode 100644 index b523e3d30b1..00000000000 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli/groovy-beans-dsl.adoc +++ /dev/null @@ -1,30 +0,0 @@ -[[cli.groovy-beans-dsl]] -== Developing Applications with the Groovy Beans DSL -Spring Framework 4.0 has native support for a `beans{}` "`DSL`" (borrowed from https://grails.org/[Grails]), and you can embed bean definitions in your Groovy application scripts by using the same format. -This is sometimes a good way to include external features like middleware declarations, as shown in the following example: - -[source,groovy,pending-extract=true,indent=0,subs="verbatim"] ----- - @Configuration(proxyBeanMethods = false) - class Application implements CommandLineRunner { - - @Autowired - SharedService service - - @Override - void run(String... args) { - println service.message - } - - } - - import my.company.SharedService - - beans { - service(SharedService) { - message = "Hello World" - } - } ----- - -You can mix class declarations with `beans{}` in the same file as long as they stay at the top level, or, if you prefer, you can put the beans DSL in a separate file. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli/maven-setting.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli/maven-setting.adoc deleted file mode 100644 index 6be011286e4..00000000000 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli/maven-setting.adoc +++ /dev/null @@ -1,16 +0,0 @@ -[[cli.maven-setting]] -== Configuring the CLI with settings.xml -The Spring Boot CLI uses Maven Resolver, Maven's dependency resolution engine, to resolve dependencies. -The CLI makes use of the Maven configuration found in `~/.m2/settings.xml` to configure Maven Resolver. -The following configuration settings are honored by the CLI: - -* Offline -* Mirrors -* Servers -* Proxies -* Profiles -** Activation -** Repositories -* Active profiles - -See https://maven.apache.org/settings.html[Maven's settings documentation] for further information. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli/using-the-cli.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli/using-the-cli.adoc index 066472a4767..062060728c1 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli/using-the-cli.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli/using-the-cli.adoc @@ -11,32 +11,78 @@ If you run `spring` without any arguments, a help screen is displayed, as follow Available commands are: - run [options] [--] [args] - Run a spring groovy script + init [options] [location] + Initialize a new project using Spring Initializr (start.spring.io) - _... more command help is shown here_ + encodepassword [options] + Encode a password for use with Spring Security + + shell + Start a nested shell + + Common options: + + --debug Verbose mode + Print additional status information for the command you are running + + + See 'spring help ' for more information on a specific command. ---- You can type `spring help` to get more details about any of the supported commands, as shown in the following example: [source,shell,indent=0,subs="verbatim"] ---- - $ spring help run - spring run - Run a spring groovy script + $ spring help init + spring init - Initialize a new project using Spring Initializr (start.spring.io) - usage: spring run [options] [--] [args] + usage: spring init [options] [location] - Option Description - ------ ----------- - --autoconfigure [Boolean] Add autoconfigure compiler - transformations (default: true) - --classpath, -cp Additional classpath entries - --no-guess-dependencies Do not attempt to guess dependencies - --no-guess-imports Do not attempt to guess imports - -q, --quiet Quiet logging - -v, --verbose Verbose logging of dependency - resolution - --watch Watch the specified file for changes + Option Description + ------ ----------- + -a, --artifact-id Project coordinates; infer archive name (for + example 'test') + -b, --boot-version Spring Boot version (for example '1.2.0.RELEASE') + --build Build system to use (for example 'maven' or + 'gradle') (default: maven) + -d, --dependencies Comma-separated list of dependency identifiers to + include in the generated project + --description Project description + -f, --force Force overwrite of existing files + --format Format of the generated content (for example + 'build' for a build file, 'project' for a + project archive) (default: project) + -g, --group-id Project coordinates (for example 'org.test') + -j, --java-version Language level (for example '1.8') + -l, --language Programming language (for example 'java') + --list List the capabilities of the service. Use it to + discover the dependencies and the types that are + available + -n, --name Project name; infer application name + -p, --packaging Project packaging (for example 'jar') + --package-name Package name + -t, --type Project type. Not normally needed if you use -- + build and/or --format. Check the capabilities of + the service (--list) for more details + --target URL of the service to use (default: https://start. + spring.io) + -v, --version Project version (for example '0.0.1-SNAPSHOT') + -x, --extract Extract the project archive. Inferred if a + location is specified without an extension + + examples: + + To list all the capabilities of the service: + $ spring init --list + + To creates a default project: + $ spring init + + To create a web my-app.zip: + $ spring init -d=web my-app.zip + + To create a web/data-jpa gradle project unpacked: + $ spring init -d=web,jpa --build=gradle my-dir ---- The `version` command provides a quick way to check which version of Spring Boot you are using, as follows: @@ -49,196 +95,6 @@ The `version` command provides a quick way to check which version of Spring Boot -[[cli.using-the-cli.run]] -=== Running Applications with the CLI -You can compile and run Groovy source code by using the `run` command. -The Spring Boot CLI is completely self-contained, so you do not need any external Groovy installation. - -The following example shows a "`hello world`" web application written in Groovy: - -.hello.groovy -[source,groovy,indent=0,subs="verbatim"] ----- -include::{docs-groovy}/cli/usingthecli/run/WebApplication.groovy[tag=*] ----- - -To compile and run the application, type the following command: - -[source,shell,indent=0,subs="verbatim"] ----- - $ spring run hello.groovy ----- - -To pass command-line arguments to the application, use `--` to separate the commands from the "`spring`" command arguments, as shown in the following example: - -[source,shell,indent=0,subs="verbatim"] ----- - $ spring run hello.groovy -- --server.port=9000 ----- - -To set JVM command line arguments, you can use the `JAVA_OPTS` environment variable, as shown in the following example: - -[source,shell,indent=0,subs="verbatim"] ----- - $ JAVA_OPTS=-Xmx1024m spring run hello.groovy ----- - -NOTE: When setting `JAVA_OPTS` on Microsoft Windows, make sure to quote the entire instruction, such as `set "JAVA_OPTS=-Xms256m -Xmx2048m"`. -Doing so ensures the values are properly passed to the process. - - - -[[cli.using-the-cli.run.deduced-grab-annotations]] -==== Deduced "`grab`" Dependencies -Standard Groovy includes a `@Grab` annotation, which lets you declare dependencies on third-party libraries. -This useful technique lets Groovy download jars in the same way as Maven or Gradle would but without requiring you to use a build tool. - -Spring Boot extends this technique further and tries to deduce which libraries to "`grab`" based on your code. -For example, since the `WebApplication` code shown previously uses `@RestController` annotations, Spring Boot grabs "Tomcat" and "Spring MVC". - -The following items are used as "`grab hints`": - -|=== -| Items | Grabs - -| `JdbcTemplate`, `NamedParameterJdbcTemplate`, `DataSource` -| JDBC Application. - -| `@EnableJms` -| JMS Application. - -| `@EnableCaching` -| Caching abstraction. - -| `@Test` -| JUnit. - -| `@EnableRabbit` -| RabbitMQ. - -| extends `Specification` -| Spock test. - -| `@EnableBatchProcessing` -| Spring Batch. - -| `@MessageEndpoint` `@EnableIntegration` -| Spring Integration. - -| `@Controller` `@RestController` `@EnableWebMvc` -| Spring MVC + Embedded Tomcat. - -| `@EnableWebSecurity` -| Spring Security. - -| `@EnableTransactionManagement` -| Spring Transaction Management. -|=== - -TIP: See subclasses of {spring-boot-cli-module-code}/compiler/CompilerAutoConfiguration.java[`CompilerAutoConfiguration`] in the Spring Boot CLI source code to understand exactly how customizations are applied. - - - -[[cli.using-the-cli.run.deduced-grab-coordinates]] -==== Deduced "`grab`" Coordinates -Spring Boot extends Groovy's standard `@Grab` support by letting you specify a dependency without a group or version (for example, `@Grab('freemarker')`). -Doing so consults Spring Boot's default dependency metadata to deduce the artifact's group and version. - -NOTE: The default metadata is tied to the version of the CLI that you use. -It changes only when you move to a new version of the CLI, putting you in control of when the versions of your dependencies may change. -A table showing the dependencies and their versions that are included in the default metadata can be found in the <>. - - - -[[cli.using-the-cli.run.default-import-statements]] -==== Default Import Statements -To help reduce the size of your Groovy code, several `import` statements are automatically included. -Notice how the preceding example refers to `@Component`, `@RestController`, and `@RequestMapping` without needing to use fully-qualified names or `import` statements. - -TIP: Many Spring annotations work without using `import` statements. -Try running your application to see what fails before adding imports. - - - -[[cli.using-the-cli.run.automatic-main-method]] -==== Automatic Main Method -Unlike the equivalent Java application, you do not need to include a `public static void main(String[] args)` method with your `Groovy` scripts. -A `SpringApplication` is automatically created, with your compiled code acting as the `source`. - - - -[[cli.using-the-cli.run.custom-dependency-management]] -==== Custom Dependency Management -By default, the CLI uses the dependency management declared in `spring-boot-dependencies` when resolving `@Grab` dependencies. -Additional dependency management, which overrides the default dependency management, can be configured by using the `@DependencyManagementBom` annotation. -The annotation's value should specify the coordinates (`groupId:artifactId:version`) of one or more Maven BOMs. - -For example, consider the following declaration: - -[source,groovy,indent=0,subs="verbatim"] ----- -include::{docs-groovy}/cli/usingthecli/run/customdependencymanagement/single/CustomDependencyManagement.groovy[tag=*] ----- - -The preceding declaration picks up `custom-bom-1.0.0.pom` in a Maven repository under `com/example/custom-versions/1.0.0/`. - -When you specify multiple BOMs, they are applied in the order in which you declare them, as shown in the following example: - -[source,groovy,indent=0,subs="verbatim"] ----- -include::{docs-groovy}/cli/usingthecli/run/customdependencymanagement/multiple/CustomDependencyManagement.groovy[tag=*] ----- - -The preceding example indicates that the dependency management in `another-bom` overrides the dependency management in `custom-bom`. - -You can use `@DependencyManagementBom` anywhere that you can use `@Grab`. -However, to ensure consistent ordering of the dependency management, you can use `@DependencyManagementBom` at most once in your application. - - - -[[cli.using-the-cli.multiple-source-files]] -=== Applications with Multiple Source Files -You can use "`shell globbing`" with all commands that accept file input. -Doing so lets you use multiple files from a single directory, as shown in the following example: - -[source,shell,indent=0,subs="verbatim"] ----- - $ spring run *.groovy ----- - - - -[[cli.using-the-cli.packaging]] -=== Packaging Your Application -You can use the `jar` command to package your application into a self-contained executable jar file, as shown in the following example: - -[source,shell,indent=0,subs="verbatim"] ----- - $ spring jar my-app.jar *.groovy ----- - -The resulting jar contains the classes produced by compiling the application and all of the application's dependencies so that it can then be run by using `java -jar`. -The jar file also contains entries from the application's classpath. -You can add and remove explicit paths to the jar by using `--include` and `--exclude`. -Both are comma-separated, and both accept prefixes, in the form of "`+`" and "`-`", to signify that they should be removed from the defaults. -The default includes are as follows: - -[indent=0] ----- - public/**, resources/**, static/**, templates/**, META-INF/**, * ----- - -The default excludes are as follows: - -[indent=0] ----- - .*, repository/**, build/**, target/**, **/*.jar, **/*.groovy ----- - -Type `spring help jar` on the command line for more information. - - - [[cli.using-the-cli.initialize-new-project]] === Initialize a New Project The `init` command lets you create a new project by using https://start.spring.io without leaving the shell, as shown in the following example: @@ -316,32 +172,3 @@ If you need to run a native command, you can use the `!` prefix. To exit the embedded shell, press `ctrl-c`. - -[[cli.using-the-cli.extensions]] -=== Adding Extensions to the CLI -You can add extensions to the CLI by using the `install` command. -The command takes one or more sets of artifact coordinates in the format `group:artifact:version`, as shown in the following example: - -[source,shell,indent=0,subs="verbatim"] ----- - $ spring install com.example:spring-boot-cli-extension:1.0.0.RELEASE ----- - -In addition to installing the artifacts identified by the coordinates you supply, all of the artifacts' dependencies are also installed. - -To uninstall a dependency, use the `uninstall` command. -As with the `install` command, it takes one or more sets of artifact coordinates in the format of `group:artifact:version`, as shown in the following example: - -[source,shell,indent=0,subs="verbatim"] ----- - $ spring uninstall com.example:spring-boot-cli-extension:1.0.0.RELEASE ----- - -It uninstalls the artifacts identified by the coordinates you supply and their dependencies. - -To uninstall all additional dependencies, you can use the `--all` option, as shown in the following example: - -[source,shell,indent=0,subs="verbatim"] ----- - $ spring uninstall --all ----- diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli/whats-next.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli/whats-next.adoc deleted file mode 100644 index f3d05acbfed..00000000000 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/cli/whats-next.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[[cli.whats-next]] -== What to Read Next -There are some {spring-boot-code}/spring-boot-project/spring-boot-cli/samples[sample groovy scripts] available from the GitHub repository that you can use to try out the Spring Boot CLI. -There is also extensive Javadoc throughout the {spring-boot-cli-module-code}[source code]. - -If you find that you reach the limit of the CLI tool, you probably want to look at converting your application to a full Gradle or Maven built "`Groovy project`". -The next section covers Spring Boot's "<>", which you can use with Gradle or Maven. diff --git a/spring-boot-project/spring-boot-docs/src/main/groovy/org/springframework/boot/docs/cli/usingthecli/run/WebApplication.groovy b/spring-boot-project/spring-boot-docs/src/main/groovy/org/springframework/boot/docs/cli/usingthecli/run/WebApplication.groovy deleted file mode 100644 index 91154cc9a52..00000000000 --- a/spring-boot-project/spring-boot-docs/src/main/groovy/org/springframework/boot/docs/cli/usingthecli/run/WebApplication.groovy +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.docs.cli.usingthecli.run - -import org.springframework.web.bind.annotation.RestController -import org.springframework.web.bind.annotation.RequestMapping - -// tag::code[] -@RestController -class WebApplication { - - @RequestMapping("/") - String home() { - "Hello World!" - } - -} -// end::code[] diff --git a/spring-boot-project/spring-boot-docs/src/main/groovy/org/springframework/boot/docs/cli/usingthecli/run/customdependencymanagement/multiple/CustomDependencyManagement.groovy b/spring-boot-project/spring-boot-docs/src/main/groovy/org/springframework/boot/docs/cli/usingthecli/run/customdependencymanagement/multiple/CustomDependencyManagement.groovy deleted file mode 100644 index 969e4f290cc..00000000000 --- a/spring-boot-project/spring-boot-docs/src/main/groovy/org/springframework/boot/docs/cli/usingthecli/run/customdependencymanagement/multiple/CustomDependencyManagement.groovy +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.docs.cli.usingthecli.run.customdependencymanagement.multiple - -import org.springframework.boot.groovy.DependencyManagementBom - -// tag::code[] -@DependencyManagementBom([ - "com.example.custom-bom:1.0.0", - "com.example.another-bom:1.0.0"]) -// end::code[] -class CustomDependencyManagement { - -} diff --git a/spring-boot-project/spring-boot-docs/src/main/groovy/org/springframework/boot/docs/cli/usingthecli/run/customdependencymanagement/single/CustomDependencyManagement.groovy b/spring-boot-project/spring-boot-docs/src/main/groovy/org/springframework/boot/docs/cli/usingthecli/run/customdependencymanagement/single/CustomDependencyManagement.groovy deleted file mode 100644 index e8a3d81a621..00000000000 --- a/spring-boot-project/spring-boot-docs/src/main/groovy/org/springframework/boot/docs/cli/usingthecli/run/customdependencymanagement/single/CustomDependencyManagement.groovy +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.docs.cli.usingthecli.run.customdependencymanagement.single - -import org.springframework.boot.groovy.DependencyManagementBom - -// tag::code[] -@DependencyManagementBom("com.example.custom-bom:1.0.0") -// end::code[] -class CustomDependencyManagement { - -}