Move spring-boot-cli into spring-boot-tools
Closes gh-32492
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 cli.command;
|
||||
|
||||
import org.springframework.boot.cli.command.AbstractCommand;
|
||||
import org.springframework.boot.cli.command.status.ExitStatus;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class CustomCommand extends AbstractCommand {
|
||||
|
||||
public CustomCommand() {
|
||||
super("custom", "Custom command added in tests");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExitStatus run(String... args) throws Exception {
|
||||
System.err.println("Custom Command Hello");
|
||||
return ExitStatus.OK;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 cli.command;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.boot.cli.command.Command;
|
||||
import org.springframework.boot.cli.command.CommandFactory;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class CustomCommandFactory implements CommandFactory {
|
||||
|
||||
@Override
|
||||
public Collection<Command> getCommands() {
|
||||
return Collections.singleton(new CustomCommand());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.cli.command.status.ExitStatus;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link CommandRunner}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class CommandRunnerIntegrationTests {
|
||||
|
||||
@BeforeEach
|
||||
void clearDebug() {
|
||||
System.clearProperty("debug");
|
||||
}
|
||||
|
||||
@Test
|
||||
void debugEnabledAndArgumentRemovedWhenNotAnApplicationArgument() {
|
||||
CommandRunner runner = new CommandRunner("spring");
|
||||
ArgHandlingCommand command = new ArgHandlingCommand();
|
||||
runner.addCommand(command);
|
||||
runner.runAndHandleErrors("args", "samples/app.groovy", "--debug");
|
||||
assertThat(command.args).containsExactly("samples/app.groovy");
|
||||
assertThat(System.getProperty("debug")).isEqualTo("true");
|
||||
}
|
||||
|
||||
@Test
|
||||
void debugNotEnabledAndArgumentRetainedWhenAnApplicationArgument() {
|
||||
CommandRunner runner = new CommandRunner("spring");
|
||||
ArgHandlingCommand command = new ArgHandlingCommand();
|
||||
runner.addCommand(command);
|
||||
runner.runAndHandleErrors("args", "samples/app.groovy", "--", "--debug");
|
||||
assertThat(command.args).containsExactly("samples/app.groovy", "--", "--debug");
|
||||
assertThat(System.getProperty("debug")).isNull();
|
||||
}
|
||||
|
||||
static class ArgHandlingCommand extends AbstractCommand {
|
||||
|
||||
private String[] args;
|
||||
|
||||
ArgHandlingCommand() {
|
||||
super("args", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExitStatus run(String... args) throws Exception {
|
||||
this.args = args;
|
||||
return ExitStatus.OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.EnumSet;
|
||||
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.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import org.springframework.boot.cli.command.core.HelpCommand;
|
||||
import org.springframework.boot.cli.command.core.HintCommand;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.BDDMockito.willThrow;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
|
||||
/**
|
||||
* Tests for {@link CommandRunner}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CommandRunnerTests {
|
||||
|
||||
private CommandRunner commandRunner;
|
||||
|
||||
@Mock
|
||||
private Command regularCommand;
|
||||
|
||||
@Mock
|
||||
private Command anotherCommand;
|
||||
|
||||
private final Set<Call> calls = EnumSet.noneOf(Call.class);
|
||||
|
||||
private ClassLoader loader;
|
||||
|
||||
@AfterEach
|
||||
void close() {
|
||||
Thread.currentThread().setContextClassLoader(this.loader);
|
||||
System.clearProperty("debug");
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.loader = Thread.currentThread().getContextClassLoader();
|
||||
this.commandRunner = new CommandRunner("spring") {
|
||||
|
||||
@Override
|
||||
protected void showUsage() {
|
||||
CommandRunnerTests.this.calls.add(Call.SHOW_USAGE);
|
||||
super.showUsage();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean errorMessage(String message) {
|
||||
CommandRunnerTests.this.calls.add(Call.ERROR_MESSAGE);
|
||||
return super.errorMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void printStackTrace(Exception ex) {
|
||||
CommandRunnerTests.this.calls.add(Call.PRINT_STACK_TRACE);
|
||||
super.printStackTrace(ex);
|
||||
}
|
||||
};
|
||||
lenient().doReturn("another").when(this.anotherCommand).getName();
|
||||
lenient().doReturn("command").when(this.regularCommand).getName();
|
||||
lenient().doReturn("A regular command").when(this.regularCommand).getDescription();
|
||||
this.commandRunner.addCommand(this.regularCommand);
|
||||
this.commandRunner.addCommand(new HelpCommand(this.commandRunner));
|
||||
this.commandRunner.addCommand(new HintCommand(this.commandRunner));
|
||||
}
|
||||
|
||||
@Test
|
||||
void runWithoutArguments() {
|
||||
assertThatExceptionOfType(NoArgumentsException.class).isThrownBy(this.commandRunner::run);
|
||||
}
|
||||
|
||||
@Test
|
||||
void runCommand() throws Exception {
|
||||
this.commandRunner.run("command", "--arg1", "arg2");
|
||||
then(this.regularCommand).should().run("--arg1", "arg2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void missingCommand() {
|
||||
assertThatExceptionOfType(NoSuchCommandException.class).isThrownBy(() -> this.commandRunner.run("missing"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void appArguments() throws Exception {
|
||||
this.commandRunner.runAndHandleErrors("command", "--", "--debug", "bar");
|
||||
then(this.regularCommand).should().run("--", "--debug", "bar");
|
||||
// When handled by the command itself it shouldn't cause the system property to be
|
||||
// set
|
||||
assertThat(System.getProperty("debug")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void handlesSuccess() {
|
||||
int status = this.commandRunner.runAndHandleErrors("command");
|
||||
assertThat(status).isEqualTo(0);
|
||||
assertThat(this.calls).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void handlesNoSuchCommand() {
|
||||
int status = this.commandRunner.runAndHandleErrors("missing");
|
||||
assertThat(status).isEqualTo(1);
|
||||
assertThat(this.calls).containsOnly(Call.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void handlesRegularExceptionWithMessage() throws Exception {
|
||||
willThrow(new RuntimeException("With Message")).given(this.regularCommand).run();
|
||||
int status = this.commandRunner.runAndHandleErrors("command");
|
||||
assertThat(status).isEqualTo(1);
|
||||
assertThat(this.calls).containsOnly(Call.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void handlesRegularExceptionWithoutMessage() throws Exception {
|
||||
willThrow(new RuntimeException()).given(this.regularCommand).run();
|
||||
int status = this.commandRunner.runAndHandleErrors("command");
|
||||
assertThat(status).isEqualTo(1);
|
||||
assertThat(this.calls).containsOnly(Call.ERROR_MESSAGE, Call.PRINT_STACK_TRACE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void handlesExceptionWithDashDashDebug() throws Exception {
|
||||
willThrow(new RuntimeException()).given(this.regularCommand).run();
|
||||
int status = this.commandRunner.runAndHandleErrors("command", "--debug");
|
||||
assertThat(System.getProperty("debug")).isEqualTo("true");
|
||||
assertThat(status).isEqualTo(1);
|
||||
assertThat(this.calls).containsOnly(Call.ERROR_MESSAGE, Call.PRINT_STACK_TRACE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void exceptionMessages() {
|
||||
assertThat(new NoSuchCommandException("name").getMessage())
|
||||
.isEqualTo("'name' is not a valid command. See 'help'.");
|
||||
}
|
||||
|
||||
@Test
|
||||
void help() throws Exception {
|
||||
this.commandRunner.run("help", "command");
|
||||
then(this.regularCommand).should().getHelp();
|
||||
}
|
||||
|
||||
@Test
|
||||
void helpNoCommand() {
|
||||
assertThatExceptionOfType(NoHelpCommandArgumentsException.class)
|
||||
.isThrownBy(() -> this.commandRunner.run("help"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void helpUnknownCommand() {
|
||||
assertThatExceptionOfType(NoSuchCommandException.class)
|
||||
.isThrownBy(() -> this.commandRunner.run("help", "missing"));
|
||||
}
|
||||
|
||||
private enum Call {
|
||||
|
||||
SHOW_USAGE, ERROR_MESSAGE, PRINT_STACK_TRACE
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.cli.command.options.OptionHandler;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link OptionParsingCommand}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
class OptionParsingCommandTests {
|
||||
|
||||
@Test
|
||||
void optionHelp() {
|
||||
OptionHandler handler = new OptionHandler();
|
||||
handler.option("bar", "Bar");
|
||||
OptionParsingCommand command = new TestOptionParsingCommand("foo", "Foo", handler);
|
||||
assertThat(command.getHelp()).contains("--bar");
|
||||
}
|
||||
|
||||
static class TestOptionParsingCommand extends OptionParsingCommand {
|
||||
|
||||
TestOptionParsingCommand(String name, String description, OptionHandler handler) {
|
||||
super(name, description, handler);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.encodepassword;
|
||||
|
||||
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.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import org.springframework.boot.cli.command.status.ExitStatus;
|
||||
import org.springframework.boot.cli.util.MockLog;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
|
||||
/**
|
||||
* Tests for {@link EncodePasswordCommand}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class EncodePasswordCommandTests {
|
||||
|
||||
private MockLog log;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<String> message;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.log = MockLog.attach();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
MockLog.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
void encodeWithNoAlgorithmShouldUseBcrypt() throws Exception {
|
||||
EncodePasswordCommand command = new EncodePasswordCommand();
|
||||
ExitStatus status = command.run("boot");
|
||||
then(this.log).should().info(this.message.capture());
|
||||
assertThat(this.message.getValue()).startsWith("{bcrypt}");
|
||||
assertThat(PasswordEncoderFactories.createDelegatingPasswordEncoder().matches("boot", this.message.getValue()))
|
||||
.isTrue();
|
||||
assertThat(status).isEqualTo(ExitStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void encodeWithBCryptShouldUseBCrypt() throws Exception {
|
||||
EncodePasswordCommand command = new EncodePasswordCommand();
|
||||
ExitStatus status = command.run("-a", "bcrypt", "boot");
|
||||
then(this.log).should().info(this.message.capture());
|
||||
assertThat(this.message.getValue()).doesNotStartWith("{");
|
||||
assertThat(new BCryptPasswordEncoder().matches("boot", this.message.getValue())).isTrue();
|
||||
assertThat(status).isEqualTo(ExitStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void encodeWithPbkdf2ShouldUsePbkdf2() throws Exception {
|
||||
EncodePasswordCommand command = new EncodePasswordCommand();
|
||||
ExitStatus status = command.run("-a", "pbkdf2", "boot");
|
||||
then(this.log).should().info(this.message.capture());
|
||||
assertThat(this.message.getValue()).doesNotStartWith("{");
|
||||
assertThat(new Pbkdf2PasswordEncoder().matches("boot", this.message.getValue())).isTrue();
|
||||
assertThat(status).isEqualTo(ExitStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void encodeWithUnknownAlgorithmShouldExitWithError() throws Exception {
|
||||
EncodePasswordCommand command = new EncodePasswordCommand();
|
||||
ExitStatus status = command.run("--algorithm", "bad", "boot");
|
||||
then(this.log).should().error("Unknown algorithm, valid options are: default,bcrypt,pbkdf2");
|
||||
assertThat(status).isEqualTo(ExitStatus.ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 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.init;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mockito.ArgumentMatcher;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.isA;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Abstract base class for tests that use a mock {@link CloseableHttpClient}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public abstract class AbstractHttpClientMockTests {
|
||||
|
||||
protected final CloseableHttpClient http = mock(CloseableHttpClient.class);
|
||||
|
||||
protected void mockSuccessfulMetadataTextGet() throws IOException {
|
||||
mockSuccessfulMetadataGet("metadata/service-metadata-2.1.0.txt", "text/plain", true);
|
||||
}
|
||||
|
||||
protected void mockSuccessfulMetadataGet(boolean serviceCapabilities) throws IOException {
|
||||
mockSuccessfulMetadataGet("metadata/service-metadata-2.1.0.json", "application/vnd.initializr.v2.1+json",
|
||||
serviceCapabilities);
|
||||
}
|
||||
|
||||
protected void mockSuccessfulMetadataGetV2(boolean serviceCapabilities) throws IOException {
|
||||
mockSuccessfulMetadataGet("metadata/service-metadata-2.0.0.json", "application/vnd.initializr.v2+json",
|
||||
serviceCapabilities);
|
||||
}
|
||||
|
||||
protected void mockSuccessfulMetadataGet(String contentPath, String contentType, boolean serviceCapabilities)
|
||||
throws IOException {
|
||||
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
|
||||
byte[] content = readClasspathResource(contentPath);
|
||||
mockHttpEntity(response, content, contentType);
|
||||
mockStatus(response, 200);
|
||||
given(this.http.execute(argThat(getForMetadata(serviceCapabilities)))).willReturn(response);
|
||||
}
|
||||
|
||||
protected byte[] readClasspathResource(String contentPath) throws IOException {
|
||||
Resource resource = new ClassPathResource(contentPath);
|
||||
return StreamUtils.copyToByteArray(resource.getInputStream());
|
||||
}
|
||||
|
||||
protected void mockSuccessfulProjectGeneration(MockHttpProjectGenerationRequest request) throws IOException {
|
||||
// Required for project generation as the metadata is read first
|
||||
mockSuccessfulMetadataGet(false);
|
||||
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
|
||||
mockHttpEntity(response, request.content, request.contentType);
|
||||
mockStatus(response, 200);
|
||||
String header = (request.fileName != null) ? contentDispositionValue(request.fileName) : null;
|
||||
mockHttpHeader(response, "Content-Disposition", header);
|
||||
given(this.http.execute(argThat(getForNonMetadata()))).willReturn(response);
|
||||
}
|
||||
|
||||
protected void mockProjectGenerationError(int status, String message) throws IOException, JSONException {
|
||||
// Required for project generation as the metadata is read first
|
||||
mockSuccessfulMetadataGet(false);
|
||||
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
|
||||
mockHttpEntity(response, createJsonError(status, message).getBytes(), "application/json");
|
||||
mockStatus(response, status);
|
||||
given(this.http.execute(isA(HttpGet.class))).willReturn(response);
|
||||
}
|
||||
|
||||
protected void mockMetadataGetError(int status, String message) throws IOException, JSONException {
|
||||
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
|
||||
mockHttpEntity(response, createJsonError(status, message).getBytes(), "application/json");
|
||||
mockStatus(response, status);
|
||||
given(this.http.execute(isA(HttpGet.class))).willReturn(response);
|
||||
}
|
||||
|
||||
protected HttpEntity mockHttpEntity(CloseableHttpResponse response, byte[] content, String contentType) {
|
||||
try {
|
||||
HttpEntity entity = mock(HttpEntity.class);
|
||||
given(entity.getContent()).willReturn(new ByteArrayInputStream(content));
|
||||
Header contentTypeHeader = (contentType != null) ? new BasicHeader("Content-Type", contentType) : null;
|
||||
given(entity.getContentType()).willReturn(contentTypeHeader);
|
||||
given(response.getEntity()).willReturn(entity);
|
||||
return entity;
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException("Should not happen", ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected void mockStatus(CloseableHttpResponse response, int status) {
|
||||
StatusLine statusLine = mock(StatusLine.class);
|
||||
given(statusLine.getStatusCode()).willReturn(status);
|
||||
given(response.getStatusLine()).willReturn(statusLine);
|
||||
}
|
||||
|
||||
protected void mockHttpHeader(CloseableHttpResponse response, String headerName, String value) {
|
||||
Header header = (value != null) ? new BasicHeader(headerName, value) : null;
|
||||
given(response.getFirstHeader(headerName)).willReturn(header);
|
||||
}
|
||||
|
||||
private ArgumentMatcher<HttpGet> getForMetadata(boolean serviceCapabilities) {
|
||||
if (!serviceCapabilities) {
|
||||
return new HasAcceptHeader(InitializrService.ACCEPT_META_DATA, true);
|
||||
}
|
||||
return new HasAcceptHeader(InitializrService.ACCEPT_SERVICE_CAPABILITIES, true);
|
||||
}
|
||||
|
||||
private ArgumentMatcher<HttpGet> getForNonMetadata() {
|
||||
return new HasAcceptHeader(InitializrService.ACCEPT_META_DATA, false);
|
||||
}
|
||||
|
||||
private String contentDispositionValue(String fileName) {
|
||||
return "attachment; filename=\"" + fileName + "\"";
|
||||
}
|
||||
|
||||
private String createJsonError(int status, String message) throws JSONException {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("status", status);
|
||||
if (message != null) {
|
||||
json.put("message", message);
|
||||
}
|
||||
return json.toString();
|
||||
}
|
||||
|
||||
static class MockHttpProjectGenerationRequest {
|
||||
|
||||
String contentType;
|
||||
|
||||
String fileName;
|
||||
|
||||
byte[] content = new byte[] { 0, 0, 0, 0 };
|
||||
|
||||
MockHttpProjectGenerationRequest(String contentType, String fileName) {
|
||||
this(contentType, fileName, new byte[] { 0, 0, 0, 0 });
|
||||
}
|
||||
|
||||
MockHttpProjectGenerationRequest(String contentType, String fileName, byte[] content) {
|
||||
this.contentType = contentType;
|
||||
this.fileName = fileName;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class HasAcceptHeader implements ArgumentMatcher<HttpGet> {
|
||||
|
||||
private final String value;
|
||||
|
||||
private final boolean shouldMatch;
|
||||
|
||||
HasAcceptHeader(String value, boolean shouldMatch) {
|
||||
this.value = value;
|
||||
this.shouldMatch = shouldMatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(HttpGet get) {
|
||||
if (get == null) {
|
||||
return false;
|
||||
}
|
||||
Header acceptHeader = get.getFirstHeader(HttpHeaders.ACCEPT);
|
||||
if (this.shouldMatch) {
|
||||
return acceptHeader != null && this.value.equals(acceptHeader.getValue());
|
||||
}
|
||||
return acceptHeader == null || !this.value.equals(acceptHeader.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,437 @@
|
||||
/*
|
||||
* 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.init;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import joptsimple.OptionSet;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import org.springframework.boot.cli.command.status.ExitStatus;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
|
||||
/**
|
||||
* Tests for {@link InitCommand}
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Eddú Meléndez
|
||||
* @author Vignesh Thangavel Ilangovan
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class InitCommandTests extends AbstractHttpClientMockTests {
|
||||
|
||||
private final TestableInitCommandOptionHandler handler;
|
||||
|
||||
private final InitCommand command;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<HttpUriRequest> requestCaptor;
|
||||
|
||||
InitCommandTests() {
|
||||
InitializrService initializrService = new InitializrService(this.http);
|
||||
this.handler = new TestableInitCommandOptionHandler(initializrService);
|
||||
this.command = new InitCommand(this.handler);
|
||||
}
|
||||
|
||||
@Test
|
||||
void listServiceCapabilitiesText() throws Exception {
|
||||
mockSuccessfulMetadataTextGet();
|
||||
this.command.run("--list", "--target=https://fake-service");
|
||||
}
|
||||
|
||||
@Test
|
||||
void listServiceCapabilities() throws Exception {
|
||||
mockSuccessfulMetadataGet(true);
|
||||
this.command.run("--list", "--target=https://fake-service");
|
||||
}
|
||||
|
||||
@Test
|
||||
void listServiceCapabilitiesV2() throws Exception {
|
||||
mockSuccessfulMetadataGetV2(true);
|
||||
this.command.run("--list", "--target=https://fake-service");
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateProject() throws Exception {
|
||||
String fileName = UUID.randomUUID().toString() + ".zip";
|
||||
File file = new File(fileName);
|
||||
assertThat(file.exists()).as("file should not exist").isFalse();
|
||||
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest("application/zip", fileName);
|
||||
mockSuccessfulProjectGeneration(request);
|
||||
try {
|
||||
assertThat(this.command.run()).isEqualTo(ExitStatus.OK);
|
||||
assertThat(file.exists()).as("file should have been created").isTrue();
|
||||
}
|
||||
finally {
|
||||
assertThat(file.delete()).as("failed to delete test file").isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateProjectNoFileNameAvailable() throws Exception {
|
||||
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest("application/zip", null);
|
||||
mockSuccessfulProjectGeneration(request);
|
||||
assertThat(this.command.run()).isEqualTo(ExitStatus.ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateProjectAndExtract(@TempDir File tempDir) throws Exception {
|
||||
byte[] archive = createFakeZipArchive("test.txt", "Fake content");
|
||||
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest("application/zip", "demo.zip",
|
||||
archive);
|
||||
mockSuccessfulProjectGeneration(request);
|
||||
assertThat(this.command.run("--extract", tempDir.getAbsolutePath())).isEqualTo(ExitStatus.OK);
|
||||
File archiveFile = new File(tempDir, "test.txt");
|
||||
assertThat(archiveFile).exists();
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateProjectAndExtractWillNotWriteEntriesOutsideOutputLocation(@TempDir File tempDir) throws Exception {
|
||||
byte[] archive = createFakeZipArchive("../outside.txt", "Fake content");
|
||||
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest("application/zip", "demo.zip",
|
||||
archive);
|
||||
mockSuccessfulProjectGeneration(request);
|
||||
assertThat(this.command.run("--extract", tempDir.getAbsolutePath())).isEqualTo(ExitStatus.ERROR);
|
||||
File archiveFile = new File(tempDir.getParentFile(), "outside.txt");
|
||||
assertThat(archiveFile).doesNotExist();
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateProjectAndExtractWithConvention(@TempDir File tempDir) throws Exception {
|
||||
byte[] archive = createFakeZipArchive("test.txt", "Fake content");
|
||||
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest("application/zip", "demo.zip",
|
||||
archive);
|
||||
mockSuccessfulProjectGeneration(request);
|
||||
assertThat(this.command.run(tempDir.getAbsolutePath() + "/")).isEqualTo(ExitStatus.OK);
|
||||
File archiveFile = new File(tempDir, "test.txt");
|
||||
assertThat(archiveFile).exists();
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateProjectArchiveExtractedByDefault() throws Exception {
|
||||
String fileName = UUID.randomUUID().toString();
|
||||
assertThat(fileName.contains(".")).as("No dot in filename").isFalse();
|
||||
byte[] archive = createFakeZipArchive("test.txt", "Fake content");
|
||||
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest("application/zip", "demo.zip",
|
||||
archive);
|
||||
mockSuccessfulProjectGeneration(request);
|
||||
File file = new File(fileName);
|
||||
File archiveFile = new File(file, "test.txt");
|
||||
try {
|
||||
assertThat(this.command.run(fileName)).isEqualTo(ExitStatus.OK);
|
||||
assertThat(archiveFile).exists();
|
||||
}
|
||||
finally {
|
||||
archiveFile.delete();
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateProjectFileSavedAsFileByDefault() throws Exception {
|
||||
String fileName = UUID.randomUUID().toString();
|
||||
String content = "Fake Content";
|
||||
byte[] archive = content.getBytes();
|
||||
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest("application/octet-stream",
|
||||
"pom.xml", archive);
|
||||
mockSuccessfulProjectGeneration(request);
|
||||
File file = new File(fileName);
|
||||
try {
|
||||
assertThat(this.command.run(fileName)).isEqualTo(ExitStatus.OK);
|
||||
assertThat(file.exists()).as("File not saved properly").isTrue();
|
||||
assertThat(file.isFile()).as("Should not be a directory").isTrue();
|
||||
}
|
||||
finally {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateProjectAndExtractUnsupportedArchive(@TempDir File tempDir) throws Exception {
|
||||
String fileName = UUID.randomUUID().toString() + ".zip";
|
||||
File file = new File(fileName);
|
||||
assertThat(file.exists()).as("file should not exist").isFalse();
|
||||
try {
|
||||
byte[] archive = createFakeZipArchive("test.txt", "Fake content");
|
||||
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest("application/foobar",
|
||||
fileName, archive);
|
||||
mockSuccessfulProjectGeneration(request);
|
||||
assertThat(this.command.run("--extract", tempDir.getAbsolutePath())).isEqualTo(ExitStatus.OK);
|
||||
assertThat(file.exists()).as("file should have been saved instead").isTrue();
|
||||
}
|
||||
finally {
|
||||
assertThat(file.delete()).as("failed to delete test file").isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateProjectAndExtractUnknownContentType(@TempDir File tempDir) throws Exception {
|
||||
String fileName = UUID.randomUUID().toString() + ".zip";
|
||||
File file = new File(fileName);
|
||||
assertThat(file.exists()).as("file should not exist").isFalse();
|
||||
try {
|
||||
byte[] archive = createFakeZipArchive("test.txt", "Fake content");
|
||||
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest(null, fileName, archive);
|
||||
mockSuccessfulProjectGeneration(request);
|
||||
assertThat(this.command.run("--extract", tempDir.getAbsolutePath())).isEqualTo(ExitStatus.OK);
|
||||
assertThat(file.exists()).as("file should have been saved instead").isTrue();
|
||||
}
|
||||
finally {
|
||||
assertThat(file.delete()).as("failed to delete test file").isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void fileNotOverwrittenByDefault(@TempDir File tempDir) throws Exception {
|
||||
File file = new File(tempDir, "test.file");
|
||||
file.createNewFile();
|
||||
long fileLength = file.length();
|
||||
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest("application/zip",
|
||||
file.getAbsolutePath());
|
||||
mockSuccessfulProjectGeneration(request);
|
||||
assertThat(this.command.run()).as("Should have failed").isEqualTo(ExitStatus.ERROR);
|
||||
assertThat(file.length()).as("File should not have changed").isEqualTo(fileLength);
|
||||
}
|
||||
|
||||
@Test
|
||||
void overwriteFile(@TempDir File tempDir) throws Exception {
|
||||
File file = new File(tempDir, "test.file");
|
||||
file.createNewFile();
|
||||
long fileLength = file.length();
|
||||
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest("application/zip",
|
||||
file.getAbsolutePath());
|
||||
mockSuccessfulProjectGeneration(request);
|
||||
assertThat(this.command.run("--force")).isEqualTo(ExitStatus.OK);
|
||||
assertThat(fileLength != file.length()).as("File should have changed").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void fileInArchiveNotOverwrittenByDefault(@TempDir File tempDir) throws Exception {
|
||||
File conflict = new File(tempDir, "test.txt");
|
||||
assertThat(conflict.createNewFile()).as("Should have been able to create file").isTrue();
|
||||
long fileLength = conflict.length();
|
||||
// also contains test.txt
|
||||
byte[] archive = createFakeZipArchive("test.txt", "Fake content");
|
||||
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest("application/zip", "demo.zip",
|
||||
archive);
|
||||
mockSuccessfulProjectGeneration(request);
|
||||
assertThat(this.command.run("--extract", tempDir.getAbsolutePath())).isEqualTo(ExitStatus.ERROR);
|
||||
assertThat(conflict.length()).as("File should not have changed").isEqualTo(fileLength);
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseProjectOptions() throws Exception {
|
||||
this.handler.disableProjectGeneration();
|
||||
this.command.run("-g=org.demo", "-a=acme", "-v=1.2.3-SNAPSHOT", "-n=acme-sample",
|
||||
"--description=Acme sample project", "--package-name=demo.foo", "-t=ant-project", "--build=grunt",
|
||||
"--format=web", "-p=war", "-j=1.9", "-l=groovy", "-b=1.2.0.RELEASE", "-d=web,data-jpa");
|
||||
assertThat(this.handler.lastRequest.getGroupId()).isEqualTo("org.demo");
|
||||
assertThat(this.handler.lastRequest.getArtifactId()).isEqualTo("acme");
|
||||
assertThat(this.handler.lastRequest.getVersion()).isEqualTo("1.2.3-SNAPSHOT");
|
||||
assertThat(this.handler.lastRequest.getName()).isEqualTo("acme-sample");
|
||||
assertThat(this.handler.lastRequest.getDescription()).isEqualTo("Acme sample project");
|
||||
assertThat(this.handler.lastRequest.getPackageName()).isEqualTo("demo.foo");
|
||||
assertThat(this.handler.lastRequest.getType()).isEqualTo("ant-project");
|
||||
assertThat(this.handler.lastRequest.getBuild()).isEqualTo("grunt");
|
||||
assertThat(this.handler.lastRequest.getFormat()).isEqualTo("web");
|
||||
assertThat(this.handler.lastRequest.getPackaging()).isEqualTo("war");
|
||||
assertThat(this.handler.lastRequest.getJavaVersion()).isEqualTo("1.9");
|
||||
assertThat(this.handler.lastRequest.getLanguage()).isEqualTo("groovy");
|
||||
assertThat(this.handler.lastRequest.getBootVersion()).isEqualTo("1.2.0.RELEASE");
|
||||
List<String> dependencies = this.handler.lastRequest.getDependencies();
|
||||
assertThat(dependencies).hasSize(2);
|
||||
assertThat(dependencies.contains("web")).isTrue();
|
||||
assertThat(dependencies.contains("data-jpa")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseProjectWithCamelCaseOptions() throws Exception {
|
||||
this.handler.disableProjectGeneration();
|
||||
this.command.run("--groupId=org.demo", "--artifactId=acme", "--version=1.2.3-SNAPSHOT", "--name=acme-sample",
|
||||
"--description=Acme sample project", "--packageName=demo.foo", "--type=ant-project", "--build=grunt",
|
||||
"--format=web", "--packaging=war", "--javaVersion=1.9", "--language=groovy",
|
||||
"--bootVersion=1.2.0.RELEASE", "--dependencies=web,data-jpa");
|
||||
assertThat(this.handler.lastRequest.getGroupId()).isEqualTo("org.demo");
|
||||
assertThat(this.handler.lastRequest.getArtifactId()).isEqualTo("acme");
|
||||
assertThat(this.handler.lastRequest.getVersion()).isEqualTo("1.2.3-SNAPSHOT");
|
||||
assertThat(this.handler.lastRequest.getName()).isEqualTo("acme-sample");
|
||||
assertThat(this.handler.lastRequest.getDescription()).isEqualTo("Acme sample project");
|
||||
assertThat(this.handler.lastRequest.getPackageName()).isEqualTo("demo.foo");
|
||||
assertThat(this.handler.lastRequest.getType()).isEqualTo("ant-project");
|
||||
assertThat(this.handler.lastRequest.getBuild()).isEqualTo("grunt");
|
||||
assertThat(this.handler.lastRequest.getFormat()).isEqualTo("web");
|
||||
assertThat(this.handler.lastRequest.getPackaging()).isEqualTo("war");
|
||||
assertThat(this.handler.lastRequest.getJavaVersion()).isEqualTo("1.9");
|
||||
assertThat(this.handler.lastRequest.getLanguage()).isEqualTo("groovy");
|
||||
assertThat(this.handler.lastRequest.getBootVersion()).isEqualTo("1.2.0.RELEASE");
|
||||
List<String> dependencies = this.handler.lastRequest.getDependencies();
|
||||
assertThat(dependencies).hasSize(2);
|
||||
assertThat(dependencies.contains("web")).isTrue();
|
||||
assertThat(dependencies.contains("data-jpa")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseProjectWithKebabCaseOptions() throws Exception {
|
||||
this.handler.disableProjectGeneration();
|
||||
this.command.run("--group-id=org.demo", "--artifact-id=acme", "--version=1.2.3-SNAPSHOT", "--name=acme-sample",
|
||||
"--description=Acme sample project", "--package-name=demo.foo", "--type=ant-project", "--build=grunt",
|
||||
"--format=web", "--packaging=war", "--java-version=1.9", "--language=groovy",
|
||||
"--boot-version=1.2.0.RELEASE", "--dependencies=web,data-jpa");
|
||||
assertThat(this.handler.lastRequest.getGroupId()).isEqualTo("org.demo");
|
||||
assertThat(this.handler.lastRequest.getArtifactId()).isEqualTo("acme");
|
||||
assertThat(this.handler.lastRequest.getVersion()).isEqualTo("1.2.3-SNAPSHOT");
|
||||
assertThat(this.handler.lastRequest.getName()).isEqualTo("acme-sample");
|
||||
assertThat(this.handler.lastRequest.getDescription()).isEqualTo("Acme sample project");
|
||||
assertThat(this.handler.lastRequest.getPackageName()).isEqualTo("demo.foo");
|
||||
assertThat(this.handler.lastRequest.getType()).isEqualTo("ant-project");
|
||||
assertThat(this.handler.lastRequest.getBuild()).isEqualTo("grunt");
|
||||
assertThat(this.handler.lastRequest.getFormat()).isEqualTo("web");
|
||||
assertThat(this.handler.lastRequest.getPackaging()).isEqualTo("war");
|
||||
assertThat(this.handler.lastRequest.getJavaVersion()).isEqualTo("1.9");
|
||||
assertThat(this.handler.lastRequest.getLanguage()).isEqualTo("groovy");
|
||||
assertThat(this.handler.lastRequest.getBootVersion()).isEqualTo("1.2.0.RELEASE");
|
||||
List<String> dependencies = this.handler.lastRequest.getDependencies();
|
||||
assertThat(dependencies).hasSize(2);
|
||||
assertThat(dependencies.contains("web")).isTrue();
|
||||
assertThat(dependencies.contains("data-jpa")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void overwriteFileInArchive(@TempDir File tempDir) throws Exception {
|
||||
File conflict = new File(tempDir, "test.txt");
|
||||
assertThat(conflict.createNewFile()).as("Should have been able to create file").isTrue();
|
||||
long fileLength = conflict.length();
|
||||
// also contains test.txt
|
||||
byte[] archive = createFakeZipArchive("test.txt", "Fake content");
|
||||
MockHttpProjectGenerationRequest request = new MockHttpProjectGenerationRequest("application/zip", "demo.zip",
|
||||
archive);
|
||||
mockSuccessfulProjectGeneration(request);
|
||||
assertThat(this.command.run("--force", "--extract", tempDir.getAbsolutePath())).isEqualTo(ExitStatus.OK);
|
||||
assertThat(fileLength != conflict.length()).as("File should have changed").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseTypeOnly() throws Exception {
|
||||
this.handler.disableProjectGeneration();
|
||||
this.command.run("-t=ant-project");
|
||||
assertThat(this.handler.lastRequest.getBuild()).isEqualTo("maven");
|
||||
assertThat(this.handler.lastRequest.getFormat()).isEqualTo("project");
|
||||
assertThat(this.handler.lastRequest.isDetectType()).isFalse();
|
||||
assertThat(this.handler.lastRequest.getType()).isEqualTo("ant-project");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseBuildOnly() throws Exception {
|
||||
this.handler.disableProjectGeneration();
|
||||
this.command.run("--build=ant");
|
||||
assertThat(this.handler.lastRequest.getBuild()).isEqualTo("ant");
|
||||
assertThat(this.handler.lastRequest.getFormat()).isEqualTo("project");
|
||||
assertThat(this.handler.lastRequest.isDetectType()).isTrue();
|
||||
assertThat(this.handler.lastRequest.getType()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseFormatOnly() throws Exception {
|
||||
this.handler.disableProjectGeneration();
|
||||
this.command.run("--format=web");
|
||||
assertThat(this.handler.lastRequest.getBuild()).isEqualTo("maven");
|
||||
assertThat(this.handler.lastRequest.getFormat()).isEqualTo("web");
|
||||
assertThat(this.handler.lastRequest.isDetectType()).isTrue();
|
||||
assertThat(this.handler.lastRequest.getType()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseLocation() throws Exception {
|
||||
this.handler.disableProjectGeneration();
|
||||
this.command.run("foobar.zip");
|
||||
assertThat(this.handler.lastRequest.getOutput()).isEqualTo("foobar.zip");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseLocationWithSlash() throws Exception {
|
||||
this.handler.disableProjectGeneration();
|
||||
this.command.run("foobar/");
|
||||
assertThat(this.handler.lastRequest.getOutput()).isEqualTo("foobar");
|
||||
assertThat(this.handler.lastRequest.isExtract()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseMoreThanOneArg() throws Exception {
|
||||
this.handler.disableProjectGeneration();
|
||||
assertThat(this.command.run("foobar", "barfoo")).isEqualTo(ExitStatus.ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void userAgent() throws Exception {
|
||||
this.command.run("--list", "--target=https://fake-service");
|
||||
then(this.http).should().execute(this.requestCaptor.capture());
|
||||
Header agent = this.requestCaptor.getValue().getHeaders("User-Agent")[0];
|
||||
assertThat(agent.getValue()).startsWith("SpringBootCli/");
|
||||
}
|
||||
|
||||
private byte[] createFakeZipArchive(String fileName, String content) throws IOException {
|
||||
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
|
||||
try (ZipOutputStream zos = new ZipOutputStream(bos)) {
|
||||
ZipEntry entry = new ZipEntry(fileName);
|
||||
zos.putNextEntry(entry);
|
||||
zos.write(content.getBytes());
|
||||
zos.closeEntry();
|
||||
return bos.toByteArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class TestableInitCommandOptionHandler extends InitCommand.InitOptionHandler {
|
||||
|
||||
private boolean disableProjectGeneration;
|
||||
|
||||
private ProjectGenerationRequest lastRequest;
|
||||
|
||||
TestableInitCommandOptionHandler(InitializrService initializrService) {
|
||||
super(initializrService);
|
||||
}
|
||||
|
||||
void disableProjectGeneration() {
|
||||
this.disableProjectGeneration = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateProject(OptionSet options) throws IOException {
|
||||
this.lastRequest = createProjectGenerationRequest(options);
|
||||
if (!this.disableProjectGeneration) {
|
||||
super.generateProject(options);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.init;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link InitializrServiceMetadata}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class InitializrServiceMetadataTests {
|
||||
|
||||
@Test
|
||||
void parseDefaults() throws Exception {
|
||||
InitializrServiceMetadata metadata = createInstance("2.0.0");
|
||||
assertThat(metadata.getDefaults().get("bootVersion")).isEqualTo("1.1.8.RELEASE");
|
||||
assertThat(metadata.getDefaults().get("javaVersion")).isEqualTo("1.7");
|
||||
assertThat(metadata.getDefaults().get("groupId")).isEqualTo("org.test");
|
||||
assertThat(metadata.getDefaults().get("name")).isEqualTo("demo");
|
||||
assertThat(metadata.getDefaults().get("description")).isEqualTo("Demo project for Spring Boot");
|
||||
assertThat(metadata.getDefaults().get("packaging")).isEqualTo("jar");
|
||||
assertThat(metadata.getDefaults().get("language")).isEqualTo("java");
|
||||
assertThat(metadata.getDefaults().get("artifactId")).isEqualTo("demo");
|
||||
assertThat(metadata.getDefaults().get("packageName")).isEqualTo("demo");
|
||||
assertThat(metadata.getDefaults().get("type")).isEqualTo("maven-project");
|
||||
assertThat(metadata.getDefaults().get("version")).isEqualTo("0.0.1-SNAPSHOT");
|
||||
assertThat(metadata.getDefaults()).as("Wrong number of defaults").hasSize(11);
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseDependencies() throws Exception {
|
||||
InitializrServiceMetadata metadata = createInstance("2.0.0");
|
||||
assertThat(metadata.getDependencies()).hasSize(5);
|
||||
|
||||
// Security description
|
||||
assertThat(metadata.getDependency("aop").getName()).isEqualTo("AOP");
|
||||
assertThat(metadata.getDependency("security").getName()).isEqualTo("Security");
|
||||
assertThat(metadata.getDependency("security").getDescription()).isEqualTo("Security description");
|
||||
assertThat(metadata.getDependency("jdbc").getName()).isEqualTo("JDBC");
|
||||
assertThat(metadata.getDependency("data-jpa").getName()).isEqualTo("JPA");
|
||||
assertThat(metadata.getDependency("data-mongodb").getName()).isEqualTo("MongoDB");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseTypes() throws Exception {
|
||||
InitializrServiceMetadata metadata = createInstance("2.0.0");
|
||||
ProjectType projectType = metadata.getProjectTypes().get("maven-project");
|
||||
assertThat(projectType).isNotNull();
|
||||
assertThat(projectType.getTags().get("build")).isEqualTo("maven");
|
||||
assertThat(projectType.getTags().get("format")).isEqualTo("project");
|
||||
}
|
||||
|
||||
private static InitializrServiceMetadata createInstance(String version) throws JSONException {
|
||||
try {
|
||||
return new InitializrServiceMetadata(readJson(version));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException("Failed to read json", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static JSONObject readJson(String version) throws IOException, JSONException {
|
||||
Resource resource = new ClassPathResource("metadata/service-metadata-" + version + ".json");
|
||||
try (InputStream stream = resource.getInputStream()) {
|
||||
return new JSONObject(StreamUtils.copyToString(stream, StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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.init;
|
||||
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.mockito.ArgumentMatchers.isA;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link InitializrService}
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class InitializrServiceTests extends AbstractHttpClientMockTests {
|
||||
|
||||
private final InitializrService invoker = new InitializrService(this.http);
|
||||
|
||||
@Test
|
||||
void loadMetadata() throws Exception {
|
||||
mockSuccessfulMetadataGet(false);
|
||||
InitializrServiceMetadata metadata = this.invoker.loadMetadata("https://foo/bar");
|
||||
assertThat(metadata).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateSimpleProject() throws Exception {
|
||||
ProjectGenerationRequest request = new ProjectGenerationRequest();
|
||||
MockHttpProjectGenerationRequest mockHttpRequest = new MockHttpProjectGenerationRequest("application/xml",
|
||||
"foo.zip");
|
||||
ProjectGenerationResponse entity = generateProject(request, mockHttpRequest);
|
||||
assertProjectEntity(entity, mockHttpRequest.contentType, mockHttpRequest.fileName);
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateProjectCustomTargetFilename() throws Exception {
|
||||
ProjectGenerationRequest request = new ProjectGenerationRequest();
|
||||
request.setOutput("bar.zip");
|
||||
MockHttpProjectGenerationRequest mockHttpRequest = new MockHttpProjectGenerationRequest("application/xml",
|
||||
null);
|
||||
ProjectGenerationResponse entity = generateProject(request, mockHttpRequest);
|
||||
assertProjectEntity(entity, mockHttpRequest.contentType, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateProjectNoDefaultFileName() throws Exception {
|
||||
ProjectGenerationRequest request = new ProjectGenerationRequest();
|
||||
MockHttpProjectGenerationRequest mockHttpRequest = new MockHttpProjectGenerationRequest("application/xml",
|
||||
null);
|
||||
ProjectGenerationResponse entity = generateProject(request, mockHttpRequest);
|
||||
assertProjectEntity(entity, mockHttpRequest.contentType, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateProjectBadRequest() throws Exception {
|
||||
String jsonMessage = "Unknown dependency foo:bar";
|
||||
mockProjectGenerationError(400, jsonMessage);
|
||||
ProjectGenerationRequest request = new ProjectGenerationRequest();
|
||||
request.getDependencies().add("foo:bar");
|
||||
assertThatExceptionOfType(ReportableException.class).isThrownBy(() -> this.invoker.generate(request))
|
||||
.withMessageContaining(jsonMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateProjectBadRequestNoExtraMessage() throws Exception {
|
||||
mockProjectGenerationError(400, null);
|
||||
ProjectGenerationRequest request = new ProjectGenerationRequest();
|
||||
assertThatExceptionOfType(ReportableException.class).isThrownBy(() -> this.invoker.generate(request))
|
||||
.withMessageContaining("unexpected 400 error");
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateProjectNoContent() throws Exception {
|
||||
mockSuccessfulMetadataGet(false);
|
||||
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
|
||||
mockStatus(response, 500);
|
||||
given(this.http.execute(isA(HttpGet.class))).willReturn(response);
|
||||
ProjectGenerationRequest request = new ProjectGenerationRequest();
|
||||
assertThatExceptionOfType(ReportableException.class).isThrownBy(() -> this.invoker.generate(request))
|
||||
.withMessageContaining("No content received from server");
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadMetadataBadRequest() throws Exception {
|
||||
String jsonMessage = "whatever error on the server";
|
||||
mockMetadataGetError(500, jsonMessage);
|
||||
ProjectGenerationRequest request = new ProjectGenerationRequest();
|
||||
assertThatExceptionOfType(ReportableException.class).isThrownBy(() -> this.invoker.generate(request))
|
||||
.withMessageContaining(jsonMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadMetadataInvalidJson() throws Exception {
|
||||
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
|
||||
mockHttpEntity(response, "Foo-Bar-Not-JSON".getBytes(), "application/json");
|
||||
mockStatus(response, 200);
|
||||
given(this.http.execute(isA(HttpGet.class))).willReturn(response);
|
||||
ProjectGenerationRequest request = new ProjectGenerationRequest();
|
||||
assertThatExceptionOfType(ReportableException.class).isThrownBy(() -> this.invoker.generate(request))
|
||||
.withMessageContaining("Invalid content received from server");
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadMetadataNoContent() throws Exception {
|
||||
CloseableHttpResponse response = mock(CloseableHttpResponse.class);
|
||||
mockStatus(response, 500);
|
||||
given(this.http.execute(isA(HttpGet.class))).willReturn(response);
|
||||
ProjectGenerationRequest request = new ProjectGenerationRequest();
|
||||
assertThatExceptionOfType(ReportableException.class).isThrownBy(() -> this.invoker.generate(request))
|
||||
.withMessageContaining("No content received from server");
|
||||
}
|
||||
|
||||
private ProjectGenerationResponse generateProject(ProjectGenerationRequest request,
|
||||
MockHttpProjectGenerationRequest mockRequest) throws Exception {
|
||||
mockSuccessfulProjectGeneration(mockRequest);
|
||||
ProjectGenerationResponse entity = this.invoker.generate(request);
|
||||
assertThat(entity.getContent()).as("wrong body content").isEqualTo(mockRequest.content);
|
||||
return entity;
|
||||
}
|
||||
|
||||
private static void assertProjectEntity(ProjectGenerationResponse entity, String mimeType, String fileName) {
|
||||
if (mimeType == null) {
|
||||
assertThat(entity.getContentType()).isNull();
|
||||
}
|
||||
else {
|
||||
assertThat(entity.getContentType().getMimeType()).isEqualTo(mimeType);
|
||||
}
|
||||
assertThat(entity.getFileName()).isEqualTo(fileName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* 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.init;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Tests for {@link ProjectGenerationRequest}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
class ProjectGenerationRequestTests {
|
||||
|
||||
public static final Map<String, String> EMPTY_TAGS = Collections.emptyMap();
|
||||
|
||||
private final ProjectGenerationRequest request = new ProjectGenerationRequest();
|
||||
|
||||
@Test
|
||||
void defaultSettings() {
|
||||
assertThat(this.request.generateUrl(createDefaultMetadata())).isEqualTo(createDefaultUrl("?type=test-type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customServer() throws URISyntaxException {
|
||||
String customServerUrl = "https://foo:8080/initializr";
|
||||
this.request.setServiceUrl(customServerUrl);
|
||||
this.request.getDependencies().add("security");
|
||||
assertThat(this.request.generateUrl(createDefaultMetadata()))
|
||||
.isEqualTo(new URI(customServerUrl + "/starter.zip?dependencies=security&type=test-type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customBootVersion() {
|
||||
this.request.setBootVersion("1.2.0.RELEASE");
|
||||
assertThat(this.request.generateUrl(createDefaultMetadata()))
|
||||
.isEqualTo(createDefaultUrl("?type=test-type&bootVersion=1.2.0.RELEASE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void singleDependency() {
|
||||
this.request.getDependencies().add("web");
|
||||
assertThat(this.request.generateUrl(createDefaultMetadata()))
|
||||
.isEqualTo(createDefaultUrl("?dependencies=web&type=test-type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleDependencies() {
|
||||
this.request.getDependencies().add("web");
|
||||
this.request.getDependencies().add("data-jpa");
|
||||
assertThat(this.request.generateUrl(createDefaultMetadata()))
|
||||
.isEqualTo(createDefaultUrl("?dependencies=web%2Cdata-jpa&type=test-type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customJavaVersion() {
|
||||
this.request.setJavaVersion("1.8");
|
||||
assertThat(this.request.generateUrl(createDefaultMetadata()))
|
||||
.isEqualTo(createDefaultUrl("?type=test-type&javaVersion=1.8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customPackageName() {
|
||||
this.request.setPackageName("demo.foo");
|
||||
assertThat(this.request.generateUrl(createDefaultMetadata()))
|
||||
.isEqualTo(createDefaultUrl("?packageName=demo.foo&type=test-type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customType() throws URISyntaxException {
|
||||
ProjectType projectType = new ProjectType("custom", "Custom Type", "/foo", true, EMPTY_TAGS);
|
||||
InitializrServiceMetadata metadata = new InitializrServiceMetadata(projectType);
|
||||
this.request.setType("custom");
|
||||
this.request.getDependencies().add("data-rest");
|
||||
assertThat(this.request.generateUrl(metadata)).isEqualTo(
|
||||
new URI(ProjectGenerationRequest.DEFAULT_SERVICE_URL + "/foo?dependencies=data-rest&type=custom"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customPackaging() {
|
||||
this.request.setPackaging("war");
|
||||
assertThat(this.request.generateUrl(createDefaultMetadata()))
|
||||
.isEqualTo(createDefaultUrl("?type=test-type&packaging=war"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customLanguage() {
|
||||
this.request.setLanguage("groovy");
|
||||
assertThat(this.request.generateUrl(createDefaultMetadata()))
|
||||
.isEqualTo(createDefaultUrl("?type=test-type&language=groovy"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customProjectInfo() {
|
||||
this.request.setGroupId("org.acme");
|
||||
this.request.setArtifactId("sample");
|
||||
this.request.setVersion("1.0.1-SNAPSHOT");
|
||||
this.request.setDescription("Spring Boot Test");
|
||||
assertThat(this.request.generateUrl(createDefaultMetadata()))
|
||||
.isEqualTo(createDefaultUrl("?groupId=org.acme&artifactId=sample&version=1.0.1-SNAPSHOT"
|
||||
+ "&description=Spring+Boot+Test&type=test-type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void outputCustomizeArtifactId() {
|
||||
this.request.setOutput("my-project");
|
||||
assertThat(this.request.generateUrl(createDefaultMetadata()))
|
||||
.isEqualTo(createDefaultUrl("?artifactId=my-project&type=test-type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void outputArchiveCustomizeArtifactId() {
|
||||
this.request.setOutput("my-project.zip");
|
||||
assertThat(this.request.generateUrl(createDefaultMetadata()))
|
||||
.isEqualTo(createDefaultUrl("?artifactId=my-project&type=test-type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void outputArchiveWithDotsCustomizeArtifactId() {
|
||||
this.request.setOutput("my.nice.project.zip");
|
||||
assertThat(this.request.generateUrl(createDefaultMetadata()))
|
||||
.isEqualTo(createDefaultUrl("?artifactId=my.nice.project&type=test-type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void outputDoesNotOverrideCustomArtifactId() {
|
||||
this.request.setOutput("my-project");
|
||||
this.request.setArtifactId("my-id");
|
||||
assertThat(this.request.generateUrl(createDefaultMetadata()))
|
||||
.isEqualTo(createDefaultUrl("?artifactId=my-id&type=test-type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildNoMatch() throws Exception {
|
||||
InitializrServiceMetadata metadata = readMetadata();
|
||||
setBuildAndFormat("does-not-exist", null);
|
||||
assertThatExceptionOfType(ReportableException.class).isThrownBy(() -> this.request.generateUrl(metadata))
|
||||
.withMessageContaining("does-not-exist");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildMultipleMatch() throws Exception {
|
||||
InitializrServiceMetadata metadata = readMetadata("types-conflict");
|
||||
setBuildAndFormat("gradle", null);
|
||||
assertThatExceptionOfType(ReportableException.class).isThrownBy(() -> this.request.generateUrl(metadata))
|
||||
.withMessageContaining("gradle-project").withMessageContaining("gradle-project-2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildOneMatch() throws Exception {
|
||||
InitializrServiceMetadata metadata = readMetadata();
|
||||
setBuildAndFormat("gradle", null);
|
||||
assertThat(this.request.generateUrl(metadata)).isEqualTo(createDefaultUrl("?type=gradle-project"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void typeAndBuildAndFormat() throws Exception {
|
||||
InitializrServiceMetadata metadata = readMetadata();
|
||||
setBuildAndFormat("gradle", "project");
|
||||
this.request.setType("maven-build");
|
||||
assertThat(this.request.generateUrl(metadata)).isEqualTo(createUrl("/pom.xml?type=maven-build"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void invalidType() {
|
||||
this.request.setType("does-not-exist");
|
||||
assertThatExceptionOfType(ReportableException.class)
|
||||
.isThrownBy(() -> this.request.generateUrl(createDefaultMetadata()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void noTypeAndNoDefault() {
|
||||
assertThatExceptionOfType(ReportableException.class)
|
||||
.isThrownBy(() -> this.request.generateUrl(readMetadata("types-conflict")))
|
||||
.withMessageContaining("no default is defined");
|
||||
}
|
||||
|
||||
private static URI createUrl(String actionAndParam) {
|
||||
try {
|
||||
return new URI(ProjectGenerationRequest.DEFAULT_SERVICE_URL + actionAndParam);
|
||||
}
|
||||
catch (URISyntaxException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static URI createDefaultUrl(String param) {
|
||||
return createUrl("/starter.zip" + param);
|
||||
}
|
||||
|
||||
void setBuildAndFormat(String build, String format) {
|
||||
this.request.setBuild((build != null) ? build : "maven");
|
||||
this.request.setFormat((format != null) ? format : "project");
|
||||
this.request.setDetectType(true);
|
||||
}
|
||||
|
||||
private static InitializrServiceMetadata createDefaultMetadata() {
|
||||
ProjectType projectType = new ProjectType("test-type", "The test type", "/starter.zip", true, EMPTY_TAGS);
|
||||
return new InitializrServiceMetadata(projectType);
|
||||
}
|
||||
|
||||
private static InitializrServiceMetadata readMetadata() throws JSONException {
|
||||
return readMetadata("2.0.0");
|
||||
}
|
||||
|
||||
private static InitializrServiceMetadata readMetadata(String version) throws JSONException {
|
||||
try {
|
||||
Resource resource = new ClassPathResource("metadata/service-metadata-" + version + ".json");
|
||||
String content = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);
|
||||
JSONObject json = new JSONObject(content);
|
||||
return new InitializrServiceMetadata(json);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException("Failed to read metadata", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.init;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ServiceCapabilitiesReportGenerator}
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class ServiceCapabilitiesReportGeneratorTests extends AbstractHttpClientMockTests {
|
||||
|
||||
private final ServiceCapabilitiesReportGenerator command = new ServiceCapabilitiesReportGenerator(
|
||||
new InitializrService(this.http));
|
||||
|
||||
@Test
|
||||
void listMetadataFromServer() throws IOException {
|
||||
mockSuccessfulMetadataTextGet();
|
||||
String expected = new String(readClasspathResource("metadata/service-metadata-2.1.0.txt"));
|
||||
String content = this.command.generate("http://localhost");
|
||||
assertThat(content).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void listMetadata() throws IOException {
|
||||
mockSuccessfulMetadataGet(true);
|
||||
doTestGenerateCapabilitiesFromJson();
|
||||
}
|
||||
|
||||
@Test
|
||||
void listMetadataV2() throws IOException {
|
||||
mockSuccessfulMetadataGetV2(true);
|
||||
doTestGenerateCapabilitiesFromJson();
|
||||
}
|
||||
|
||||
private void doTestGenerateCapabilitiesFromJson() throws IOException {
|
||||
String content = this.command.generate("http://localhost");
|
||||
assertThat(content).contains("aop - AOP");
|
||||
assertThat(content).contains("security - Security: Security description");
|
||||
assertThat(content).contains("type: maven-project");
|
||||
assertThat(content).contains("packaging: jar");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.shell;
|
||||
|
||||
import jline.console.completer.ArgumentCompleter.ArgumentList;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link EscapeAwareWhiteSpaceArgumentDelimiter}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class EscapeAwareWhiteSpaceArgumentDelimiterTests {
|
||||
|
||||
private final EscapeAwareWhiteSpaceArgumentDelimiter delimiter = new EscapeAwareWhiteSpaceArgumentDelimiter();
|
||||
|
||||
@Test
|
||||
void simple() {
|
||||
String s = "one two";
|
||||
assertThat(this.delimiter.delimit(s, 0).getArguments()).containsExactly("one", "two");
|
||||
assertThat(this.delimiter.parseArguments(s)).containsExactly("one", "two");
|
||||
assertThat(this.delimiter.isDelimiter(s, 2)).isFalse();
|
||||
assertThat(this.delimiter.isDelimiter(s, 3)).isTrue();
|
||||
assertThat(this.delimiter.isDelimiter(s, 4)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void escaped() {
|
||||
String s = "o\\ ne two";
|
||||
assertThat(this.delimiter.delimit(s, 0).getArguments()).containsExactly("o\\ ne", "two");
|
||||
assertThat(this.delimiter.parseArguments(s)).containsExactly("o ne", "two");
|
||||
assertThat(this.delimiter.isDelimiter(s, 2)).isFalse();
|
||||
assertThat(this.delimiter.isDelimiter(s, 3)).isFalse();
|
||||
assertThat(this.delimiter.isDelimiter(s, 4)).isFalse();
|
||||
assertThat(this.delimiter.isDelimiter(s, 5)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void quoted() {
|
||||
String s = "'o ne' 't w o'";
|
||||
assertThat(this.delimiter.delimit(s, 0).getArguments()).containsExactly("'o ne'", "'t w o'");
|
||||
assertThat(this.delimiter.parseArguments(s)).containsExactly("o ne", "t w o");
|
||||
}
|
||||
|
||||
@Test
|
||||
void doubleQuoted() {
|
||||
String s = "\"o ne\" \"t w o\"";
|
||||
assertThat(this.delimiter.delimit(s, 0).getArguments()).containsExactly("\"o ne\"", "\"t w o\"");
|
||||
assertThat(this.delimiter.parseArguments(s)).containsExactly("o ne", "t w o");
|
||||
}
|
||||
|
||||
@Test
|
||||
void nestedQuotes() {
|
||||
String s = "\"o 'n''e\" 't \"w o'";
|
||||
assertThat(this.delimiter.delimit(s, 0).getArguments()).containsExactly("\"o 'n''e\"", "'t \"w o'");
|
||||
assertThat(this.delimiter.parseArguments(s)).containsExactly("o 'n''e", "t \"w o");
|
||||
}
|
||||
|
||||
@Test
|
||||
void escapedQuotes() {
|
||||
String s = "\\'a b";
|
||||
ArgumentList argumentList = this.delimiter.delimit(s, 0);
|
||||
assertThat(argumentList.getArguments()).isEqualTo(new String[] { "\\'a", "b" });
|
||||
assertThat(this.delimiter.parseArguments(s)).containsExactly("'a", "b");
|
||||
}
|
||||
|
||||
@Test
|
||||
void escapes() {
|
||||
String s = "\\ \\\\.\\\\\\t";
|
||||
assertThat(this.delimiter.parseArguments(s)).containsExactly(" \\.\\\t");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Mock log for testing message output.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public interface MockLog extends LogListener {
|
||||
|
||||
static MockLog attach() {
|
||||
MockLog log = mock(MockLog.class);
|
||||
Log.setListener(log);
|
||||
return log;
|
||||
}
|
||||
|
||||
static void clear() {
|
||||
Log.setListener(null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
cli.command.CustomCommandFactory
|
||||
Binary file not shown.
@@ -0,0 +1,30 @@
|
||||
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
|
||||
https://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||
<localRepository>build/local-m2-repository</localRepository>
|
||||
<mirrors>
|
||||
<mirror>
|
||||
<id>central-mirror</id>
|
||||
<url>https://central-mirror.example.com/maven2</url>
|
||||
<mirrorOf>central</mirrorOf>
|
||||
</mirror>
|
||||
</mirrors>
|
||||
<servers>
|
||||
<server>
|
||||
<id>central-mirror</id>
|
||||
<username>user</username>
|
||||
<password>password</password>
|
||||
</server>
|
||||
</servers>
|
||||
<proxies>
|
||||
<proxy>
|
||||
<active>true</active>
|
||||
<protocol>http</protocol>
|
||||
<host>proxy.example.com</host>
|
||||
<port>3128</port>
|
||||
<username>user</username>
|
||||
<password>password</password>
|
||||
</proxy>
|
||||
</proxies>
|
||||
</settings>
|
||||
@@ -0,0 +1,13 @@
|
||||
import org.springframework.util.*
|
||||
|
||||
@Component
|
||||
public class Test implements CommandLineRunner {
|
||||
|
||||
public void run(String... args) throws Exception {
|
||||
println "HasClasses-" + ClassUtils.isPresent("missing", null) + "-" +
|
||||
ClassUtils.isPresent("org.springframework.boot.SpringApplication", null) + "-" +
|
||||
ClassUtils.isPresent(args[0], null)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<settings>
|
||||
<localRepository>build/local-m2-repository</localRepository>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>cli-test-repo</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>local.central</id>
|
||||
<url>file:build/test-repository</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-snapshot</id>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
</profile>
|
||||
</profiles>
|
||||
</settings>
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.
|
||||
*/
|
||||
|
||||
command("foo") { args ->
|
||||
println "Hello Foo"
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.test.command
|
||||
|
||||
class TestCommand implements Command {
|
||||
|
||||
String name = "foo"
|
||||
|
||||
String description = "My script command"
|
||||
|
||||
String help = "No options"
|
||||
|
||||
String usageHelp = "Not very useful"
|
||||
|
||||
Collection<String> optionsHelp = ["No options"]
|
||||
|
||||
boolean optionCommand = false
|
||||
|
||||
void run(String... args) {
|
||||
println "Hello ${args[0]}"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.test.command
|
||||
|
||||
@Grab("org.eclipse.jgit:org.eclipse.jgit:2.3.1.201302201838-r")
|
||||
import org.eclipse.jgit.api.Git
|
||||
|
||||
|
||||
class TestCommand extends OptionHandler {
|
||||
|
||||
String name = "foo"
|
||||
|
||||
void options() {
|
||||
option "foo", "Foo set"
|
||||
}
|
||||
|
||||
void run(OptionSet options) {
|
||||
// Demonstrate use of Grape.grab to load dependencies before running
|
||||
println "Clean: " + Git.open(".." as File).status().call().isClean()
|
||||
println "Hello ${options.nonOptionArguments()}: ${options.has('foo')}"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.
|
||||
*/
|
||||
|
||||
def foo() {
|
||||
"Foo"
|
||||
}
|
||||
|
||||
command("foo") {
|
||||
|
||||
options {
|
||||
option "foo", "A foo of type String"
|
||||
option "bar", "Bar has a value" withOptionalArg() ofType Integer
|
||||
}
|
||||
|
||||
run { options ->
|
||||
println "Hello ${foo()}: bar=${options.valueOf('bar')}"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
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!"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>foo</groupId>
|
||||
<artifactId>foo</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,5 @@
|
||||
@DependencyManagementBom('test:child:1.0.0')
|
||||
@Grab('ejb-api')
|
||||
class CustomDependencyManagement {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
@DependencyManagementBom("foo:bar:1.0")
|
||||
@DependencyManagementBom("alpha:bravo:2.0")
|
||||
class DuplicateDependencyManagement {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
@Grab('jackson-core')
|
||||
class GrabTest {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<project>
|
||||
<parent>
|
||||
<groupId>test</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>child</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
</project>
|
||||
@@ -0,0 +1,18 @@
|
||||
<project>
|
||||
<groupId>test</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javax.ejb</groupId>
|
||||
<artifactId>ejb-api</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
</project>
|
||||
@@ -0,0 +1,6 @@
|
||||
@GrabResolver(name="test", root="file:./src/test/plugins")
|
||||
@Grab("custom:custom:0.0.1")
|
||||
@Controller
|
||||
class Foo {}
|
||||
|
||||
println "Hello Grab"
|
||||
@@ -0,0 +1 @@
|
||||
println "Hello Init"
|
||||
@@ -0,0 +1,97 @@
|
||||
<settings>
|
||||
|
||||
<mirrors>
|
||||
<mirror>
|
||||
<id>my-mirror</id>
|
||||
<url>https://maven.example.com/mirror</url>
|
||||
<mirrorOf>my-server</mirrorOf>
|
||||
</mirror>
|
||||
</mirrors>
|
||||
|
||||
<servers>
|
||||
<server>
|
||||
<id>my-server</id>
|
||||
<username>tester</username>
|
||||
<password>secret</password>
|
||||
</server>
|
||||
</servers>
|
||||
|
||||
<proxies>
|
||||
<proxy>
|
||||
<id>my-proxy</id>
|
||||
<active>true</active>
|
||||
<protocol>http</protocol>
|
||||
<host>proxy.example.com</host>
|
||||
<port>8080</port>
|
||||
<username>proxyuser</username>
|
||||
<password>somepassword</password>
|
||||
</proxy>
|
||||
</proxies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>active-by-default</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>active-by-default</id>
|
||||
<url>maven.example.com/activeByDefault</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>active-by-property</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>foo</name>
|
||||
<value>bar</value>
|
||||
</property>
|
||||
</activation>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>active-by-property</id>
|
||||
<url>maven.example.com/activeByProperty</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>interpolation-profile</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>interpolate</name>
|
||||
<value>true</value>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<repo.base>maven.example.com</repo.base>
|
||||
<repo.content>${repo.base}/content</repo.content>
|
||||
</properties>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>interpolate-releases</id>
|
||||
<url>${repo.content}/releases</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
<updatePolicy>never</updatePolicy>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>interpolate-snapshots</id>
|
||||
<url>${repo.content}/snapshots</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</settings>
|
||||
@@ -0,0 +1,48 @@
|
||||
<settings>
|
||||
|
||||
<mirrors>
|
||||
<mirror>
|
||||
<id>my-mirror</id>
|
||||
<url>https://maven.example.com/mirror</url>
|
||||
<mirrorOf>my-server</mirrorOf>
|
||||
</mirror>
|
||||
</mirrors>
|
||||
|
||||
<servers>
|
||||
<server>
|
||||
<id>my-server</id>
|
||||
<username>tester</username>
|
||||
<password>secret</password>
|
||||
</server>
|
||||
</servers>
|
||||
|
||||
<proxies>
|
||||
<proxy>
|
||||
<id>my-proxy</id>
|
||||
<active>true</active>
|
||||
<protocol>http</protocol>
|
||||
<host>proxy.example.com</host>
|
||||
<port>8080</port>
|
||||
<username>proxyuser</username>
|
||||
<password>somepassword</password>
|
||||
</proxy>
|
||||
</proxies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>test-profile</id>
|
||||
<activation>
|
||||
<file>
|
||||
<exists>${user.home}/.m2/some_file</exists>
|
||||
</file>
|
||||
</activation>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>example-repository</id>
|
||||
<url>https://repo.example.com</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</settings>
|
||||
@@ -0,0 +1,3 @@
|
||||
<settingsSecurity>
|
||||
<master>{oAyWuFO63U8HHgiplpqtgXih0/pwcRA0d+uA+Z7TBEk=}</master>
|
||||
</settingsSecurity>
|
||||
@@ -0,0 +1,31 @@
|
||||
<settings>
|
||||
|
||||
<mirrors>
|
||||
<mirror>
|
||||
<id>my-mirror</id>
|
||||
<url>https://maven.example.com/mirror</url>
|
||||
<mirrorOf>my-server</mirrorOf>
|
||||
</mirror>
|
||||
</mirrors>
|
||||
|
||||
<servers>
|
||||
<server>
|
||||
<id>my-server</id>
|
||||
<username>tester</username>
|
||||
<password>{Ur5BpeQGlYUHhXsHahO/HbMBcPSFSUtN5gbWuFFPYGw=}</password>
|
||||
</server>
|
||||
</servers>
|
||||
|
||||
<proxies>
|
||||
<proxy>
|
||||
<id>my-proxy</id>
|
||||
<active>true</active>
|
||||
<protocol>http</protocol>
|
||||
<host>proxy.example.com</host>
|
||||
<port>8080</port>
|
||||
<username>proxyuser</username>
|
||||
<password>{3iRQQyaIUgQHwH8uzTvr9/52pZAjLOTWz/SlWDB7CM4=}</password>
|
||||
</proxy>
|
||||
</proxies>
|
||||
|
||||
</settings>
|
||||
@@ -0,0 +1,8 @@
|
||||
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
|
||||
https://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||
|
||||
<localRepository>${foo}/repository</localRepository>
|
||||
|
||||
</settings>
|
||||
@@ -0,0 +1,190 @@
|
||||
{
|
||||
"_links": {
|
||||
"maven-build": {
|
||||
"href": "http://localhost:8080/pom.xml?{dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"maven-project": {
|
||||
"href": "http://localhost:8080/starter.zip{?dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"gradle-build": {
|
||||
"href": "http://localhost:8080/build.gradle{?dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"gradle-project": {
|
||||
"href": "http://localhost:8080/starter.zip{?dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "hierarchical-multi-select",
|
||||
"values": [
|
||||
{
|
||||
"name": "Core",
|
||||
"values": [
|
||||
{
|
||||
"name": "Security",
|
||||
"id": "security",
|
||||
"description": "Security description"
|
||||
},
|
||||
{
|
||||
"name": "AOP",
|
||||
"id": "aop"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Data",
|
||||
"values": [
|
||||
{
|
||||
"name": "JDBC",
|
||||
"id": "jdbc"
|
||||
},
|
||||
{
|
||||
"name": "JPA",
|
||||
"id": "data-jpa"
|
||||
},
|
||||
{
|
||||
"name": "MongoDB",
|
||||
"id": "data-mongodb"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"type": "action",
|
||||
"default": "maven-project",
|
||||
"values": [
|
||||
{
|
||||
"id": "maven-build",
|
||||
"name": "Maven POM",
|
||||
"action": "/pom.xml",
|
||||
"tags": {
|
||||
"build": "maven",
|
||||
"format": "build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "maven-project",
|
||||
"name": "Maven Project",
|
||||
"action": "/starter.zip",
|
||||
"tags": {
|
||||
"build": "maven",
|
||||
"format": "project"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "gradle-build",
|
||||
"name": "Gradle Config",
|
||||
"action": "/build.gradle",
|
||||
"tags": {
|
||||
"build": "gradle",
|
||||
"format": "build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "gradle-project",
|
||||
"name": "Gradle Project",
|
||||
"action": "/starter.zip",
|
||||
"tags": {
|
||||
"build": "gradle",
|
||||
"format": "project"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"packaging": {
|
||||
"type": "single-select",
|
||||
"default": "jar",
|
||||
"values": [
|
||||
{
|
||||
"id": "jar",
|
||||
"name": "Jar"
|
||||
},
|
||||
{
|
||||
"id": "war",
|
||||
"name": "War"
|
||||
}
|
||||
]
|
||||
},
|
||||
"javaVersion": {
|
||||
"type": "single-select",
|
||||
"default": "1.7",
|
||||
"values": [
|
||||
{
|
||||
"id": "1.6",
|
||||
"name": "1.6"
|
||||
},
|
||||
{
|
||||
"id": "1.7",
|
||||
"name": "1.7"
|
||||
},
|
||||
{
|
||||
"id": "1.8",
|
||||
"name": "1.8"
|
||||
}
|
||||
]
|
||||
},
|
||||
"language": {
|
||||
"type": "single-select",
|
||||
"default": "java",
|
||||
"values": [
|
||||
{
|
||||
"id": "groovy",
|
||||
"name": "Groovy"
|
||||
},
|
||||
{
|
||||
"id": "java",
|
||||
"name": "Java"
|
||||
}
|
||||
]
|
||||
},
|
||||
"bootVersion": {
|
||||
"type": "single-select",
|
||||
"default": "1.1.8.RELEASE",
|
||||
"values": [
|
||||
{
|
||||
"id": "1.2.0.BUILD-SNAPSHOT",
|
||||
"name": "1.2.0 (SNAPSHOT)"
|
||||
},
|
||||
{
|
||||
"id": "1.1.8.RELEASE",
|
||||
"name": "1.1.8"
|
||||
},
|
||||
{
|
||||
"id": "1.1.8.BUILD-SNAPSHOT",
|
||||
"name": "1.1.8 (SNAPSHOT)"
|
||||
},
|
||||
{
|
||||
"id": "1.0.2.RELEASE",
|
||||
"name": "1.0.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
"groupId": {
|
||||
"type": "text",
|
||||
"default": "org.test"
|
||||
},
|
||||
"artifactId": {
|
||||
"type": "text",
|
||||
"default": "demo"
|
||||
},
|
||||
"version": {
|
||||
"type": "text",
|
||||
"default": "0.0.1-SNAPSHOT"
|
||||
},
|
||||
"name": {
|
||||
"type": "text",
|
||||
"default": "demo"
|
||||
},
|
||||
"description": {
|
||||
"type": "text",
|
||||
"default": "Demo project for Spring Boot"
|
||||
},
|
||||
"packageName": {
|
||||
"type": "text",
|
||||
"default": "demo"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
{
|
||||
"_links": {
|
||||
"maven-build": {
|
||||
"href": "http://localhost:8080/pom.xml?type=maven-build{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"maven-project": {
|
||||
"href": "http://localhost:8080/starter.zip?type=maven-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"gradle-build": {
|
||||
"href": "http://localhost:8080/build.gradle?type=gradle-build{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"gradle-project": {
|
||||
"href": "http://localhost:8080/starter.zip?type=gradle-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "hierarchical-multi-select",
|
||||
"values": [
|
||||
{
|
||||
"name": "Core",
|
||||
"values": [
|
||||
{
|
||||
"name": "Security",
|
||||
"id": "security",
|
||||
"description": "Security description"
|
||||
},
|
||||
{
|
||||
"name": "AOP",
|
||||
"id": "aop"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Data",
|
||||
"values": [
|
||||
{
|
||||
"name": "JDBC",
|
||||
"id": "jdbc"
|
||||
},
|
||||
{
|
||||
"name": "JPA",
|
||||
"id": "data-jpa"
|
||||
},
|
||||
{
|
||||
"name": "MongoDB",
|
||||
"id": "data-mongodb",
|
||||
"versionRange": "1.1.7.RELEASE"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"type": "action",
|
||||
"default": "maven-project",
|
||||
"values": [
|
||||
{
|
||||
"id": "maven-build",
|
||||
"name": "Maven POM",
|
||||
"action": "/pom.xml",
|
||||
"tags": {
|
||||
"build": "maven",
|
||||
"format": "build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "maven-project",
|
||||
"name": "Maven Project",
|
||||
"action": "/starter.zip",
|
||||
"tags": {
|
||||
"build": "maven",
|
||||
"format": "project"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "gradle-build",
|
||||
"name": "Gradle Config",
|
||||
"action": "/build.gradle",
|
||||
"tags": {
|
||||
"build": "gradle",
|
||||
"format": "build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "gradle-project",
|
||||
"name": "Gradle Project",
|
||||
"action": "/starter.zip",
|
||||
"tags": {
|
||||
"build": "gradle",
|
||||
"format": "project"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"packaging": {
|
||||
"type": "single-select",
|
||||
"default": "jar",
|
||||
"values": [
|
||||
{
|
||||
"id": "jar",
|
||||
"name": "Jar"
|
||||
},
|
||||
{
|
||||
"id": "war",
|
||||
"name": "War"
|
||||
}
|
||||
]
|
||||
},
|
||||
"javaVersion": {
|
||||
"type": "single-select",
|
||||
"default": "1.7",
|
||||
"values": [
|
||||
{
|
||||
"id": "1.6",
|
||||
"name": "1.6"
|
||||
},
|
||||
{
|
||||
"id": "1.7",
|
||||
"name": "1.7"
|
||||
},
|
||||
{
|
||||
"id": "1.8",
|
||||
"name": "1.8"
|
||||
}
|
||||
]
|
||||
},
|
||||
"language": {
|
||||
"type": "single-select",
|
||||
"default": "java",
|
||||
"values": [
|
||||
{
|
||||
"id": "groovy",
|
||||
"name": "Groovy"
|
||||
},
|
||||
{
|
||||
"id": "java",
|
||||
"name": "Java"
|
||||
}
|
||||
]
|
||||
},
|
||||
"bootVersion": {
|
||||
"type": "single-select",
|
||||
"default": "1.1.8.RELEASE",
|
||||
"values": [
|
||||
{
|
||||
"id": "1.2.0.BUILD-SNAPSHOT",
|
||||
"name": "1.2.0 (SNAPSHOT)"
|
||||
},
|
||||
{
|
||||
"id": "1.1.8.RELEASE",
|
||||
"name": "1.1.8"
|
||||
},
|
||||
{
|
||||
"id": "1.1.8.BUILD-SNAPSHOT",
|
||||
"name": "1.1.8 (SNAPSHOT)"
|
||||
},
|
||||
{
|
||||
"id": "1.0.2.RELEASE",
|
||||
"name": "1.0.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
"groupId": {
|
||||
"type": "text",
|
||||
"default": "org.test"
|
||||
},
|
||||
"artifactId": {
|
||||
"type": "text",
|
||||
"default": "demo"
|
||||
},
|
||||
"version": {
|
||||
"type": "text",
|
||||
"default": "0.0.1-SNAPSHOT"
|
||||
},
|
||||
"name": {
|
||||
"type": "text",
|
||||
"default": "demo"
|
||||
},
|
||||
"description": {
|
||||
"type": "text",
|
||||
"default": "Demo project for Spring Boot"
|
||||
},
|
||||
"packageName": {
|
||||
"type": "text",
|
||||
"default": "demo"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
{
|
||||
"_links": {
|
||||
"maven-build": {
|
||||
"href": "http://localhost:8080/pom.xml?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"maven-project": {
|
||||
"href": "http://localhost:8080/starter.zip?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"gradle-build": {
|
||||
"href": "http://localhost:8080/build.gradle?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"gradle-project": {
|
||||
"href": "http://localhost:8080/starter.zip?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "hierarchical-multi-select",
|
||||
"values": [
|
||||
{
|
||||
"name": "Core",
|
||||
"values": [
|
||||
{
|
||||
"name": "Security",
|
||||
"id": "security",
|
||||
"description": "Security description"
|
||||
},
|
||||
{
|
||||
"name": "AOP",
|
||||
"id": "aop"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Data",
|
||||
"values": [
|
||||
{
|
||||
"name": "JDBC",
|
||||
"id": "jdbc"
|
||||
},
|
||||
{
|
||||
"name": "JPA",
|
||||
"id": "data-jpa"
|
||||
},
|
||||
{
|
||||
"name": "MongoDB",
|
||||
"id": "data-mongodb"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"type": "action",
|
||||
"values": [
|
||||
{
|
||||
"id": "maven-build",
|
||||
"name": "Maven POM",
|
||||
"action": "/pom.xml",
|
||||
"tags": {
|
||||
"build": "maven",
|
||||
"format": "build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "maven-project",
|
||||
"name": "Maven Project",
|
||||
"action": "/starter.zip",
|
||||
"tags": {
|
||||
"build": "maven",
|
||||
"format": "project"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "maven-project-2",
|
||||
"name": "Another Maven Project",
|
||||
"action": "/starter.zip",
|
||||
"tags": {
|
||||
"build": "maven",
|
||||
"format": "project"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "gradle-build",
|
||||
"name": "Gradle Config",
|
||||
"action": "/build.gradle",
|
||||
"tags": {
|
||||
"build": "gradle",
|
||||
"format": "build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "gradle-project",
|
||||
"name": "Gradle Project",
|
||||
"action": "/starter.zip",
|
||||
"tags": {
|
||||
"build": "gradle",
|
||||
"format": "project"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "gradle-project-2",
|
||||
"name": "Another Gradle Project",
|
||||
"action": "/starter.zip",
|
||||
"tags": {
|
||||
"build": "gradle",
|
||||
"format": "project"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"packaging": {
|
||||
"type": "single-select",
|
||||
"default": "jar",
|
||||
"values": [
|
||||
{
|
||||
"id": "jar",
|
||||
"name": "Jar"
|
||||
},
|
||||
{
|
||||
"id": "war",
|
||||
"name": "War"
|
||||
}
|
||||
]
|
||||
},
|
||||
"javaVersion": {
|
||||
"type": "single-select",
|
||||
"default": "1.7",
|
||||
"values": [
|
||||
{
|
||||
"id": "1.6",
|
||||
"name": "1.6"
|
||||
},
|
||||
{
|
||||
"id": "1.7",
|
||||
"name": "1.7"
|
||||
},
|
||||
{
|
||||
"id": "1.8",
|
||||
"name": "1.8"
|
||||
}
|
||||
]
|
||||
},
|
||||
"language": {
|
||||
"type": "single-select",
|
||||
"default": "java",
|
||||
"values": [
|
||||
{
|
||||
"id": "groovy",
|
||||
"name": "Groovy"
|
||||
},
|
||||
{
|
||||
"id": "java",
|
||||
"name": "Java"
|
||||
}
|
||||
]
|
||||
},
|
||||
"bootVersion": {
|
||||
"type": "single-select",
|
||||
"default": "1.1.8.RELEASE",
|
||||
"values": [
|
||||
{
|
||||
"id": "1.2.0.BUILD-SNAPSHOT",
|
||||
"name": "1.2.0 (SNAPSHOT)"
|
||||
},
|
||||
{
|
||||
"id": "1.1.8.RELEASE",
|
||||
"name": "1.1.8"
|
||||
},
|
||||
{
|
||||
"id": "1.1.8.BUILD-SNAPSHOT",
|
||||
"name": "1.1.8 (SNAPSHOT)"
|
||||
},
|
||||
{
|
||||
"id": "1.0.2.RELEASE",
|
||||
"name": "1.0.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
"groupId": {
|
||||
"type": "text",
|
||||
"default": "org.test"
|
||||
},
|
||||
"artifactId": {
|
||||
"type": "text",
|
||||
"default": "demo"
|
||||
},
|
||||
"version": {
|
||||
"type": "text",
|
||||
"default": "0.0.1-SNAPSHOT"
|
||||
},
|
||||
"name": {
|
||||
"type": "text",
|
||||
"default": "demo"
|
||||
},
|
||||
"description": {
|
||||
"type": "text",
|
||||
"default": "Demo project for Spring Boot"
|
||||
},
|
||||
"packageName": {
|
||||
"type": "text",
|
||||
"default": "demo"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
@Grab('spring-boot-starter-data-jpa')
|
||||
@Grab('h2')
|
||||
class Sample implements CommandLineRunner {
|
||||
|
||||
// No Data JPA-based logic. We just want to check that the dependencies are
|
||||
// resolved correctly and that the app runs
|
||||
|
||||
@Override
|
||||
void run(String... args) {
|
||||
println "Hello World"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
@Grab("org.apache.groovy:groovy-ant:4.0.1")
|
||||
import groovy.ant.AntBuilder
|
||||
|
||||
@RestController
|
||||
class MainController {
|
||||
|
||||
@RequestMapping("/")
|
||||
def home() {
|
||||
new AntBuilder().echo(message:"Hello world")
|
||||
[message: "Hello World"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.test
|
||||
|
||||
// No security features added just a test that the dependencies are resolved
|
||||
@Grab("spring-boot-starter-security")
|
||||
|
||||
@Controller
|
||||
class Sample implements CommandLineRunner {
|
||||
|
||||
@Override
|
||||
void run(String... args) {
|
||||
println "Hello World"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.test
|
||||
|
||||
@Component
|
||||
class Example implements CommandLineRunner {
|
||||
|
||||
void run(String... args) {
|
||||
print "Ssshh"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
CREATE TABLE FOO (
|
||||
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
name VARCHAR(30)
|
||||
);
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.
|
||||
*/
|
||||
|
||||
def foo() {
|
||||
"Foo"
|
||||
}
|
||||
|
||||
command("foo") { options ->
|
||||
def foo = foo()
|
||||
println "Hello ${foo} ${options.nonOptionArguments()}: ${options.has('foo')} ${options.valueOf('bar')}"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.test.command
|
||||
|
||||
import java.util.Collection
|
||||
|
||||
class TestCommand implements Command {
|
||||
|
||||
String name = "foo"
|
||||
|
||||
String description = "My script command"
|
||||
|
||||
String help = "No options"
|
||||
|
||||
String usageHelp = "Not very useful"
|
||||
|
||||
Collection<String> optionsHelp = ["No options"]
|
||||
|
||||
boolean optionCommand = false
|
||||
|
||||
void run(String... args) {
|
||||
println "Hello ${args[0]}"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.
|
||||
*/
|
||||
|
||||
command("foo") { args ->
|
||||
|
||||
println "Hello Command"
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.test.command
|
||||
|
||||
@Grab("org.eclipse.jgit:org.eclipse.jgit:2.3.1.201302201838-r")
|
||||
import org.eclipse.jgit.api.Git
|
||||
|
||||
|
||||
class TestCommand extends OptionHandler {
|
||||
|
||||
String name = "foo"
|
||||
|
||||
void options() {
|
||||
option "foo", "Foo set"
|
||||
}
|
||||
|
||||
void run(OptionSet options) {
|
||||
// Demonstrate use of Grape.grab to load dependencies before running
|
||||
println "Clean: " + Git.open(".." as File).status().call().isClean()
|
||||
println "Hello ${options.nonOptionArguments()}: ${options.has('foo')}"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.
|
||||
*/
|
||||
|
||||
command("foo") {
|
||||
options {
|
||||
option "foo", "Some foo description" withOptionalArg()
|
||||
option "bar", "Some bar" withOptionalArg()
|
||||
}
|
||||
run { options -> println "Hello ${options.nonOptionArguments()}: ${options.has('foo')} ${options.valueOf('bar')}" }
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="https://www.thymeleaf.org">
|
||||
<head>
|
||||
<title th:text="${title}">Title</title>
|
||||
<link rel="stylesheet" th:href="@{/resources/css/bootstrap.min.css}"
|
||||
href="../../resources/css/bootstrap.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="navbar">
|
||||
<div class="navbar-inner">
|
||||
<a class="brand" href="https://www.thymeleaf.org"> Thymeleaf -
|
||||
Plain </a>
|
||||
<ul class="nav">
|
||||
<li><a th:href="@{/}" href="home.html"> Home </a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<h1 th:text="${title}">Title</h1>
|
||||
<div th:text="${message}">Fake content</div>
|
||||
<div id="created" th:text="${#dates.format(date)}">July 11,
|
||||
2012 2:17:16 PM CDT</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Hello ${message}!
|
||||
Reference in New Issue
Block a user