Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GRADLE-3084 escaping of $ in unix scripts #422

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -39,6 +39,11 @@ class StartScriptGenerator {
String mainClassName

Iterable<String> defaultJvmOpts = []

/**
* Flag to turn on escaping of meta characters like $ in default jvm opts
*/
Boolean escapeMetaCharactersInDefaultJvmOpts = false

/**
* The classpath, relative to the application home directory.
Expand Down Expand Up @@ -73,6 +78,7 @@ class StartScriptGenerator {
scriptGenerationDetails.applicationName = applicationName
scriptGenerationDetails.mainClassName = mainClassName
scriptGenerationDetails.defaultJvmOpts = defaultJvmOpts
scriptGenerationDetails.escapeMetaCharactersInDefaultJvmOpts = escapeMetaCharactersInDefaultJvmOpts
scriptGenerationDetails.optsEnvironmentVar = optsEnvironmentVar
scriptGenerationDetails.exitEnvironmentVar = exitEnvironmentVar
scriptGenerationDetails.classpath = classpath
Expand Down
Expand Up @@ -102,6 +102,7 @@ class ApplicationPlugin implements Plugin<Project> {
startScripts.conventionMapping.applicationName = { pluginConvention.applicationName }
startScripts.conventionMapping.outputDir = { new File(project.buildDir, 'scripts') }
startScripts.conventionMapping.defaultJvmOpts = { pluginConvention.applicationDefaultJvmArgs }
startScripts.conventionMapping.escapeMetaCharactersInDefaultJvmOpts = { pluginConvention.escapeMetaCharactersInDefaultJvmOpts }
}

private Task addInstallAppTask(Distribution distribution) {
Expand Down
Expand Up @@ -47,6 +47,13 @@ public class CreateStartScripts extends ConventionTask {
@Input
@Optional
Iterable<String> defaultJvmOpts = []

/**
* If script should escape meta characters like $
*/
@Input
@Optional
Boolean escapeMetaCharactersInDefaultJvmOpts = false;

/**
* The application's name.
Expand Down Expand Up @@ -115,6 +122,7 @@ public class CreateStartScripts extends ConventionTask {
generator.applicationName = getApplicationName()
generator.mainClassName = getMainClassName()
generator.defaultJvmOpts = getDefaultJvmOpts()
generator.escapeMetaCharactersInDefaultJvmOpts = getEscapeMetaCharactersInDefaultJvmOpts()
generator.optsEnvironmentVar = getOptsEnvironmentVar()
generator.exitEnvironmentVar = getExitEnvironmentVar()
generator.classpath = getClasspath().collect { "lib/${it.name}".toString() }
Expand Down
Expand Up @@ -39,7 +39,8 @@ public Map<String, String> createBinding(JavaAppStartScriptGenerationDetails det
binding.put("applicationName", details.getApplicationName());
binding.put("optsEnvironmentVar", details.getOptsEnvironmentVar());
binding.put("mainClassName", details.getMainClassName());
binding.put("defaultJvmOpts", createJoinedDefaultJvmOpts(details.getDefaultJvmOpts()));
binding.put("defaultJvmOpts", createJoinedDefaultJvmOpts(details.getDefaultJvmOpts(), details.getEscapeMetaCharactersInDefaultJvmOpts()));
binding.put("escapeMetaCharactersInDefaultJvmOpts", String.valueOf(details.getEscapeMetaCharactersInDefaultJvmOpts()));
binding.put("appNameSystemProperty", details.getAppNameSystemProperty());
binding.put("appHomeRelativePath", createJoinedAppHomeRelativePath(details.getScriptRelPath()));
binding.put("classpath", createJoinedClasspath(details.getClasspath()));
Expand All @@ -58,15 +59,17 @@ public String apply(String input) {
}));
}

private String createJoinedDefaultJvmOpts(Iterable<String> defaultJvmOpts) {
private String createJoinedDefaultJvmOpts(Iterable<String> defaultJvmOpts, final Boolean escapeMetaCharactersInDefaultJvmOpts) {
Iterable<String> quotedDefaultJvmOpts = Iterables.transform(defaultJvmOpts, new Function<String, String>() {
public String apply(String jvmOpt) {
//quote ', ", \, $. Probably not perfect. TODO: identify non-working cases, fail-fast on them
jvmOpt = jvmOpt.replace("\\", "\\\\");
jvmOpt = jvmOpt.replace("\"", "\\\"");
jvmOpt = jvmOpt.replace("'", "'\"'\"'");
jvmOpt = jvmOpt.replace("`", "'\"`\"'");
jvmOpt = jvmOpt.replace("$", "\\$");
if(escapeMetaCharactersInDefaultJvmOpts){
jvmOpt = jvmOpt.replace("$", "\\$");
}
StringBuilder quotedJvmOpt = new StringBuilder();
quotedJvmOpt.append("\"");
quotedJvmOpt.append(jvmOpt);
Expand Down
Expand Up @@ -40,6 +40,8 @@ public class JavaAppStartScriptGenerationDetails implements ScriptGenerationDeta
private String mainClassName;

private Iterable<String> defaultJvmOpts = new ArrayList<String>();

private Boolean escapeMetaCharactersInDefaultJvmOpts = false;

/**
* The classpath, relative to the application home directory.
Expand Down Expand Up @@ -96,6 +98,14 @@ public void setDefaultJvmOpts(Iterable<String> defaultJvmOpts) {
this.defaultJvmOpts = defaultJvmOpts;
}

public Boolean getEscapeMetaCharactersInDefaultJvmOpts() {
return escapeMetaCharactersInDefaultJvmOpts;
}

public void setEscapeMetaCharactersInDefaultJvmOpts(Boolean escapeMetaCharactersInDefaultJvmOpts) {
this.escapeMetaCharactersInDefaultJvmOpts = escapeMetaCharactersInDefaultJvmOpts;
}

public Iterable<String> getClasspath() {
return classpath;
}
Expand Down
Expand Up @@ -111,7 +111,7 @@ class UnixStartScriptGeneratorTest extends Specification {
generator.generateScript(details, destination)

then:
destination.toString().contains(/DEFAULT_JVM_OPTS='"-Dfoo=b\\ar baz" "-Xint/ + '\\$PATH' + /"'/)
destination.toString().contains(/DEFAULT_JVM_OPTS='"-Dfoo=b\\ar baz" "-Xint/ + '$PATH' + /"'/)
}

def "defaultJvmOpts is expanded properly in unix script -- empty list"() {
Expand Down