Add grab command to collect script's dependencies

Previously, run --local could be used to collect a script's
dependencies in ./repository. However, with this mechanism it wasn't
possible to collect the dependencies without running the application.

This commit adds a new command, grab, that can be used to collect
a script's dependencies in ./repository without having to run it.
run is configured with ./repository as a location in which it can find
its dependencies so that the previously collected dependencies
can be used when subsequently running the app.

As part of this work RunCommand and TestCommand have been refactored
to use common code for their common options:

	--no-guess-imports
	--no-guess-dependencies
	--classpath

Previously, the declaration and handling of the options was duplicated
in the two classes. GrabCommand also has these three options and uses
the same common code.
This commit is contained in:
Andy Wilkinson
2013-11-11 17:07:22 +00:00
parent c50fe0733b
commit 820f43d3bc
17 changed files with 525 additions and 162 deletions

View File

@@ -34,6 +34,8 @@ import org.junit.runners.model.Statement;
import org.springframework.boot.OutputCapture;
import org.springframework.boot.cli.command.AbstractCommand;
import org.springframework.boot.cli.command.CleanCommand;
import org.springframework.boot.cli.command.GrabCommand;
import org.springframework.boot.cli.command.OptionParsingCommand;
import org.springframework.boot.cli.command.RunCommand;
import org.springframework.boot.cli.command.TestCommand;
@@ -42,6 +44,7 @@ import org.springframework.boot.cli.command.TestCommand;
*
* @author Phillip Webb
* @author Dave Syer
* @author Andy Wilkinson
*/
public class CliTester implements TestRule {
@@ -62,35 +65,35 @@ public class CliTester implements TestRule {
}
public String run(String... args) throws Exception {
final String[] sources = getSources(args);
Future<RunCommand> future = Executors.newSingleThreadExecutor().submit(
new Callable<RunCommand>() {
@Override
public RunCommand call() throws Exception {
RunCommand command = new RunCommand();
command.run(sources);
return command;
}
});
Future<RunCommand> future = submitCommand(new RunCommand(), args);
this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS));
return getOutput();
}
public String test(String... args) throws Exception {
final String[] sources = getSources(args);
Future<TestCommand> future = Executors.newSingleThreadExecutor().submit(
new Callable<TestCommand>() {
@Override
public TestCommand call() throws Exception {
TestCommand command = new TestCommand();
command.run(sources);
return command;
}
});
Future<TestCommand> future = submitCommand(new TestCommand(), args);
this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS));
return getOutput();
}
public String grab(String... args) throws Exception {
Future<GrabCommand> future = submitCommand(new GrabCommand(), args);
this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS));
return getOutput();
}
private <T extends OptionParsingCommand> Future<T> submitCommand(final T command,
String... args) {
final String[] sources = getSources(args);
return Executors.newSingleThreadExecutor().submit(new Callable<T>() {
@Override
public T call() throws Exception {
command.run(sources);
return command;
}
});
}
protected String[] getSources(String... args) {
final String[] sources = new String[args.length];
for (int i = 0; i < args.length; i++) {

View File

@@ -0,0 +1,62 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.cli;
import java.io.File;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.cli.command.GrabCommand;
import org.springframework.util.FileSystemUtils;
import static org.junit.Assert.assertTrue;
/**
* Integration tests for {@link GrabCommand}
*
* @author Andy Wilkinson
*/
public class GrabCommandIntegrationTests {
@Rule
public CliTester cli = new CliTester("grab-samples/");
@Before
@After
public void deleteLocalRepository() {
FileSystemUtils.deleteRecursively(new File("target/repository"));
}
@Test
public void grab() throws Exception {
System.setProperty("grape.root", "target");
System.setProperty("groovy.grape.report.downloads", "true");
try {
String output = this.cli.grab("grab.groovy");
assertTrue(output.contains("Downloading: file:"));
assertTrue(new File("target/repository/org/springframework/spring-jdbc")
.isDirectory());
}
finally {
System.clearProperty("grape.root");
System.clearProperty("groovy.grape.report.downloads");
}
}
}

View File

@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.aether.repository.RemoteRepository;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
@@ -36,7 +37,8 @@ public class AetherGrapeEngineTests {
private final GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
private final AetherGrapeEngine grapeEngine = new AetherGrapeEngine(
this.groovyClassLoader);
this.groovyClassLoader, Arrays.asList(new RemoteRepository.Builder("central",
"default", "http://repo1.maven.org/maven2/").build()));
@Test
public void dependencyResolution() {