Skip to content

Commit 820f43d

Browse files
committed
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.
1 parent c50fe07 commit 820f43d

17 files changed

+525
-162
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@Grab('spring-jdbc')
2+
class GrabTest {
3+
4+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2012-2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.cli.command;
18+
19+
import joptsimple.OptionSpec;
20+
21+
import static java.util.Arrays.asList;
22+
23+
/**
24+
* An {@link OptionHandler} for commands that result in the compilation of one or more
25+
* Groovy scripts
26+
*
27+
* @author Andy Wilkinson
28+
*/
29+
public class CompilerOptionHandler extends OptionHandler {
30+
31+
private OptionSpec<Void> noGuessImportsOption;
32+
33+
private OptionSpec<Void> noGuessDependenciesOption;
34+
35+
private OptionSpec<String> classpathOption;
36+
37+
@Override
38+
protected final void options() {
39+
this.noGuessImportsOption = option("no-guess-imports",
40+
"Do not attempt to guess imports");
41+
this.noGuessDependenciesOption = option("no-guess-dependencies",
42+
"Do not attempt to guess dependencies");
43+
this.classpathOption = option(asList("classpath", "cp"),
44+
"Additional classpath entries").withRequiredArg();
45+
doOptions();
46+
}
47+
48+
protected void doOptions() {
49+
}
50+
51+
public OptionSpec<Void> getNoGuessImportsOption() {
52+
return this.noGuessImportsOption;
53+
}
54+
55+
public OptionSpec<Void> getNoGuessDependenciesOption() {
56+
return this.noGuessDependenciesOption;
57+
}
58+
59+
public OptionSpec<String> getClasspathOption() {
60+
return this.classpathOption;
61+
}
62+
63+
}

spring-boot-cli/src/main/java/org/springframework/boot/cli/command/DefaultCommandFactory.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
*/
3131
public class DefaultCommandFactory implements CommandFactory {
3232

33-
private static final List<Command> DEFAULT_COMMANDS = Arrays
34-
.<Command> asList(new VersionCommand(), new RunCommand(), new CleanCommand(),
35-
new TestCommand());
33+
private static final List<Command> DEFAULT_COMMANDS = Arrays.<Command> asList(
34+
new VersionCommand(), new RunCommand(), new CleanCommand(),
35+
new TestCommand(), new GrabCommand());
3636

3737
@Override
3838
public Collection<Command> getCommands() {
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright 2012-2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.cli.command;
18+
19+
import java.io.File;
20+
import java.util.List;
21+
22+
import joptsimple.OptionSet;
23+
24+
import org.springframework.boot.cli.Command;
25+
import org.springframework.boot.cli.compiler.GroovyCompiler;
26+
import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration;
27+
import org.springframework.boot.cli.compiler.GroovyCompilerConfigurationAdapter;
28+
import org.springframework.boot.cli.compiler.RepositoryConfigurationFactory;
29+
import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration;
30+
import org.springframework.util.StringUtils;
31+
32+
/**
33+
* {@link Command} to grab the dependencies of one or more Groovy scripts
34+
*
35+
* @author Andy Wilkinson
36+
*/
37+
public class GrabCommand extends OptionParsingCommand {
38+
39+
public GrabCommand() {
40+
super("grab", "Download a spring groovy script's dependencies to ./repository",
41+
new GrabOptionHandler());
42+
}
43+
44+
private static final class GrabOptionHandler extends CompilerOptionHandler {
45+
46+
@Override
47+
protected void run(OptionSet options) throws Exception {
48+
FileOptions fileOptions = new FileOptions(options);
49+
50+
List<RepositoryConfiguration> repositoryConfiguration = RepositoryConfigurationFactory
51+
.createDefaultRepositoryConfiguration();
52+
repositoryConfiguration.add(0, new RepositoryConfiguration("local", new File(
53+
getM2HomeDirectory(), "repository").toURI(), true));
54+
55+
GroovyCompilerConfiguration configuration = new GroovyCompilerConfigurationAdapter(
56+
options, this, repositoryConfiguration);
57+
58+
if (System.getProperty("grape.root") == null) {
59+
System.setProperty("grape.root", ".");
60+
}
61+
62+
GroovyCompiler groovyCompiler = new GroovyCompiler(configuration);
63+
groovyCompiler.compile(fileOptions.getFilesArray());
64+
}
65+
66+
private File getM2HomeDirectory() {
67+
String mavenRoot = System.getProperty("maven.home");
68+
if (StringUtils.hasLength(mavenRoot)) {
69+
return new File(mavenRoot);
70+
}
71+
return new File(System.getProperty("user.home"), ".m2");
72+
}
73+
}
74+
}

spring-boot-cli/src/main/java/org/springframework/boot/cli/command/RunCommand.java

Lines changed: 23 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,18 @@
1717
package org.springframework.boot.cli.command;
1818

1919
import java.awt.Desktop;
20+
import java.io.File;
21+
import java.util.List;
2022
import java.util.logging.Level;
2123

2224
import joptsimple.OptionSet;
2325
import joptsimple.OptionSpec;
2426

2527
import org.springframework.boot.cli.Command;
28+
import org.springframework.boot.cli.compiler.GroovyCompilerConfigurationAdapter;
2629
import org.springframework.boot.cli.compiler.GroovyCompilerScope;
30+
import org.springframework.boot.cli.compiler.RepositoryConfigurationFactory;
31+
import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration;
2732
import org.springframework.boot.cli.runner.SpringApplicationRunner;
2833
import org.springframework.boot.cli.runner.SpringApplicationRunnerConfiguration;
2934

@@ -53,41 +58,25 @@ public void stop() {
5358
}
5459
}
5560

56-
private static class RunOptionHandler extends OptionHandler {
61+
private static class RunOptionHandler extends CompilerOptionHandler {
5762

5863
private OptionSpec<Void> watchOption;
5964

6065
private OptionSpec<Void> editOption;
6166

62-
private OptionSpec<Void> noGuessImportsOption;
63-
64-
private OptionSpec<Void> noGuessDependenciesOption;
65-
6667
private OptionSpec<Void> verboseOption;
6768

6869
private OptionSpec<Void> quietOption;
6970

70-
private OptionSpec<Void> localOption;
71-
72-
private OptionSpec<String> classpathOption;
73-
7471
private SpringApplicationRunner runner;
7572

7673
@Override
77-
protected void options() {
74+
protected void doOptions() {
7875
this.watchOption = option("watch", "Watch the specified file for changes");
79-
this.localOption = option("local",
80-
"Accumulate the dependencies in a local folder (./repository)");
8176
this.editOption = option(asList("edit", "e"),
8277
"Open the file with the default system editor");
83-
this.noGuessImportsOption = option("no-guess-imports",
84-
"Do not attempt to guess imports");
85-
this.noGuessDependenciesOption = option("no-guess-dependencies",
86-
"Do not attempt to guess dependencies");
8778
this.verboseOption = option(asList("verbose", "v"), "Verbose logging");
8879
this.quietOption = option(asList("quiet", "q"), "Quiet logging");
89-
this.classpathOption = option(asList("classpath", "cp"),
90-
"Additional classpath entries").withRequiredArg();
9180
}
9281

9382
@Override
@@ -98,11 +87,14 @@ protected void run(OptionSet options) throws Exception {
9887
Desktop.getDesktop().edit(fileOptions.getFiles().get(0));
9988
}
10089

90+
List<RepositoryConfiguration> repositoryConfiguration = RepositoryConfigurationFactory
91+
.createDefaultRepositoryConfiguration();
92+
repositoryConfiguration.add(0, new RepositoryConfiguration("local", new File(
93+
"repository").toURI(), true));
94+
10195
SpringApplicationRunnerConfiguration configuration = new SpringApplicationRunnerConfigurationAdapter(
102-
options);
103-
if (configuration.isLocal() && System.getProperty("grape.root") == null) {
104-
System.setProperty("grape.root", ".");
105-
}
96+
options, this, repositoryConfiguration);
97+
10698
this.runner = new SpringApplicationRunner(configuration,
10799
fileOptions.getFilesArray(), fileOptions.getArgsArray());
108100
this.runner.compileAndRun();
@@ -112,13 +104,14 @@ protected void run(OptionSet options) throws Exception {
112104
* Simple adapter class to present the {@link OptionSet} as a
113105
* {@link SpringApplicationRunnerConfiguration}.
114106
*/
115-
private class SpringApplicationRunnerConfigurationAdapter implements
107+
private class SpringApplicationRunnerConfigurationAdapter extends
108+
GroovyCompilerConfigurationAdapter implements
116109
SpringApplicationRunnerConfiguration {
117110

118-
private OptionSet options;
119-
120-
public SpringApplicationRunnerConfigurationAdapter(OptionSet options) {
121-
this.options = options;
111+
public SpringApplicationRunnerConfigurationAdapter(OptionSet options,
112+
CompilerOptionHandler optionHandler,
113+
List<RepositoryConfiguration> repositoryConfiguration) {
114+
super(options, optionHandler, repositoryConfiguration);
122115
}
123116

124117
@Override
@@ -128,44 +121,19 @@ public GroovyCompilerScope getScope() {
128121

129122
@Override
130123
public boolean isWatchForFileChanges() {
131-
return this.options.has(RunOptionHandler.this.watchOption);
132-
}
133-
134-
@Override
135-
public boolean isGuessImports() {
136-
return !this.options.has(RunOptionHandler.this.noGuessImportsOption);
137-
}
138-
139-
@Override
140-
public boolean isGuessDependencies() {
141-
return !this.options.has(RunOptionHandler.this.noGuessDependenciesOption);
142-
}
143-
144-
@Override
145-
public boolean isLocal() {
146-
return this.options.has(RunOptionHandler.this.localOption);
124+
return getOptions().has(RunOptionHandler.this.watchOption);
147125
}
148126

149127
@Override
150128
public Level getLogLevel() {
151-
if (this.options.has(RunOptionHandler.this.verboseOption)) {
129+
if (getOptions().has(RunOptionHandler.this.verboseOption)) {
152130
return Level.FINEST;
153131
}
154-
if (this.options.has(RunOptionHandler.this.quietOption)) {
132+
if (getOptions().has(RunOptionHandler.this.quietOption)) {
155133
return Level.OFF;
156134
}
157135
return Level.INFO;
158136
}
159-
160-
@Override
161-
public String[] getClasspath() {
162-
if (this.options.has(RunOptionHandler.this.classpathOption)) {
163-
return this.options.valueOf(RunOptionHandler.this.classpathOption)
164-
.split(":");
165-
}
166-
return NO_CLASSPATH;
167-
}
168-
169137
}
170138
}
171139

spring-boot-cli/src/main/java/org/springframework/boot/cli/command/ScriptCommand.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.net.URL;
2929
import java.util.Collection;
3030
import java.util.Collections;
31+
import java.util.List;
3132

3233
import joptsimple.OptionParser;
3334

@@ -37,6 +38,8 @@
3738
import org.springframework.boot.cli.compiler.GroovyCompiler;
3839
import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration;
3940
import org.springframework.boot.cli.compiler.GroovyCompilerScope;
41+
import org.springframework.boot.cli.compiler.RepositoryConfigurationFactory;
42+
import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration;
4043
import org.springframework.util.FileCopyUtils;
4144

4245
/**
@@ -271,6 +274,11 @@ public String[] getClasspath() {
271274
return NO_CLASSPATH;
272275
}
273276

277+
@Override
278+
public List<RepositoryConfiguration> getRepositoryConfiguration() {
279+
return RepositoryConfigurationFactory.createDefaultRepositoryConfiguration();
280+
}
281+
274282
}
275283

276284
}

0 commit comments

Comments
 (0)