package org.nodeclipse.enide.gradle.launch;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
import org.eclipse.debug.core.model.RuntimeProcess;
import org.eclipse.jface.preference.IPreferenceStore;
import org.nodeclipse.common.preferences.CommonDialogs;
import org.nodeclipse.enide.gradle.Activator;
import org.nodeclipse.enide.gradle.preferences.GradleConstants;
import org.nodeclipse.enide.gradle.util.NodeclipseLogger;
import org.nodeclipse.enide.gradle.util.VariablesUtil;
/**
* `build.gradle` Run As gradle build<br>
* see LaunchConfigurationDelegate in .debug and .phantomjs, .jjs, .enide.maven module for comparison.
*
* @since 0.10
* @author Paul Verest
*/
public class LaunchConfigurationDelegate implements ILaunchConfigurationDelegate {
IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore();
boolean isWindows = Platform.getOS().startsWith("win");
private boolean warned = false;
//specific
protected void specialOptions(ILaunchConfiguration configuration,
IPreferenceStore preferenceStore, List<String> cmdLine) throws CoreException {
cmdLine.add("build");
}
@Override
public void launch(ILaunchConfiguration configuration, String mode,
ILaunch launch, IProgressMonitor monitor) throws CoreException {
IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore(); //NPE!
// Using configuration to build command line
List<String> cmdLine = new ArrayList<String>();
String gradlePath = null;
boolean useWrapper = preferenceStore.getBoolean(GradleConstants.GRADLE_USE_WRAPPER);
if (useWrapper){
String file1 = configuration.getAttribute(GradleConstants.KEY_FILE_PATH, "");
IPath ipath = ResourcesPlugin.getWorkspace().getRoot().findMember(file1).getLocation();
String filePath1 = ipath.removeLastSegments(1).toOSString();
gradlePath = filePath1 + (isWindows?"\\gradlew.bat":"/gradlew");
File gradlewFile = (new File(gradlePath));
useWrapper = gradlewFile.exists();
}
if (!useWrapper){
// Gradle installation path should be stored in preference.
String gradleHomeToUse = preferenceStore.getString(GradleConstants.GRADLE_HOME_TO_USE); //NPE!
gradlePath = gradleHomeToUse + (isWindows?"\\bin\\gradle.bat":"/bin/gradle");
// Check if the gradle location is correctly configured
File gradleFile = new File(gradlePath);
if( ("".equals(gradleHomeToUse)) || (!gradleFile.exists()) ){
// If the location is not valid than show a dialog which prompts the user to goto the preferences page
CommonDialogs.showPreferencesDialog(GradleConstants.PREFERENCES_PAGE,
"Gradle installation is not correctly configured.\n\n"
+ "Please goto Window -> Preferences -> "+GradleConstants.PREFERENCE_PAGE_NAME
+" and configure the correct location");
return;
}
}
cmdLine.add(gradlePath);
//{ TODO should be special as --gui mode is likely doesn't care
if (preferenceStore.getBoolean(GradleConstants.GRADLE_OPTION_DEBUG))
cmdLine.add("-d");
if (preferenceStore.getBoolean(GradleConstants.GRADLE_OPTION_INFO))
cmdLine.add("-i");
if (preferenceStore.getBoolean(GradleConstants.GRADLE_OPTION_QUIET))
cmdLine.add("-q");
if (preferenceStore.getBoolean(GradleConstants.GRADLE_OPTION_OFFLINE))
cmdLine.add("--offline");
if (preferenceStore.getBoolean(GradleConstants.GRADLE_OPTION_TEST_SKIP)){
cmdLine.add("--exclude-task");
cmdLine.add("test");
}
if (preferenceStore.getBoolean(GradleConstants.GRADLE_OPTION_DAEMON))
cmdLine.add("--daemon");
String nodeOptions= preferenceStore.getString(GradleConstants.GRADLE_OPTIONS);
if(!nodeOptions.equals("")) {
String[] sa = nodeOptions.split(" ");
for(String s : sa) {
cmdLine.add(s);
}
}
//{
String file = configuration.getAttribute(GradleConstants.KEY_FILE_PATH, "");
String filePath = ResourcesPlugin.getWorkspace().getRoot().findMember(file).getLocation().toOSString();
// path is relative, so cannot find it, unless get absolute path
cmdLine.add("-b"); // -b, --build-file Specifies the build file.
cmdLine.add(filePath);
//cmdLine.add("build");
specialOptions(configuration, preferenceStore, cmdLine);
File workingPath = null;
String workingDirectory = configuration.getAttribute(GradleConstants.ATTR_WORKING_DIRECTORY, "");
if(workingDirectory.length() > 0) {
workingDirectory = VariablesUtil.resolveValue(workingDirectory);
if(workingDirectory != null) {
workingPath = new File(workingDirectory);
}
}
if (workingPath == null){
workingPath = (new File(filePath)).getParentFile();
}
//env
String[] envp = getEnvironmentVariables(configuration);
StringBuilder sb = new StringBuilder(100);
for(String s : cmdLine) sb.append(s).append(' ');
NodeclipseLogger.log(sb.append('\n').toString());
String[] cmds = {};
cmds = cmdLine.toArray(cmds);
// Launch a process to debug.eg,
Process p = DebugPlugin.exec(cmds, workingPath, envp);
RuntimeProcess process = (RuntimeProcess)DebugPlugin.newProcess(launch, p, GradleConstants.PROCESS_MESSAGE);
}
/** Get EnvironmentVariables from ILaunchConfiguration
* and adds JAVA_HOME, GRADLE_HOME, PATH, TEMP, SystemDrive, HOME
* @param configuration ILaunchConfiguration
* @return String[]
* @throws CoreException
*/
protected String[] getEnvironmentVariables(ILaunchConfiguration configuration) throws CoreException {
Map<String, String> envm = new HashMap<String, String>();
envm = configuration.getAttribute(GradleConstants.ATTR_ENVIRONMENT_VARIABLES, envm);
int envmSizeDelta = (2+2+1) + 4 + 2;
Map<String,String> all = null;
IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore();
boolean passAndroidSigningEnvVars = preferenceStore.getBoolean(GradleConstants.PASS_ANDROID_SIGNING_ENVIRONMENT_VARIABLES);//@since 0.12
boolean passAllEnvVars = preferenceStore.getBoolean(GradleConstants.PASS_ALL_ENVIRONMENT_VARIABLES);//@since 0.12
if (passAndroidSigningEnvVars){
passAllEnvVars = false; // make passAllEnvVars incompatible with passAndroidSigningEnvVars to simplify things //TODO logic
envmSizeDelta+=4;
} else {
if (passAllEnvVars){
all = System.getenv();
envmSizeDelta = all.size();
}
}
String[] envp = new String[envm.size() + envmSizeDelta];
int idx = 0;
for(String key : envm.keySet()) {
String value = envm.get(key);
envp[idx++] = key + "=" + value;
}
// #137
String javaHomeToUse = preferenceStore.getString(GradleConstants.GRADLE_JAVA_HOME_TO_USE);//@since 0.15
if(!javaHomeToUse.equals("")) {
envp[idx++] = "JAVA_HOME=" + javaHomeToUse;
}else{
envp[idx++] = "JAVA_HOME=" + System.getProperty("java.home"); //System.getenv("JAVA_HOME");
}
//FAILURE: Build failed with an exception.
//
//* What went wrong:
//java.lang.ExceptionInInitializerError (no error message)
//
//* Try:
//Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
envp[idx++] = "GRADLE_HOME=" + preferenceStore.getString(GradleConstants.GRADLE_HOME_TO_USE);
envp[idx++] = "GRADLE_OPTS=" + preferenceStore.getString(GradleConstants.GRADLE_OPTS);
envp[idx++] = getEnvVariableEqualsString("JAVA_OPTS");
//+ #125
// String alternativeAndroidHome = preferenceStore.getString(GradleConstants.GRADLE_ENVVAR_ALTERNATIVE_ANDROID_HOME);
// if (""!=alternativeAndroidHome){
// envp[idx++] = "ANDROID_HOME=" + alternativeAndroidHome;
// } else {
// envp[idx++] = getEnvVariableEqualsString("ANDROID_HOME");
// }
envp[idx++] = getEnvVariableEqualsStringIfNoAlternativeSpecified("ANDROID_HOME",
preferenceStore.getString(GradleConstants.GRADLE_ENVVAR_ALTERNATIVE_ANDROID_HOME));
//+ #129
if (passAndroidSigningEnvVars){
envp[idx++] = getEnvVariableEqualsStringIfNoAlternativeSpecified("KEYSTORE",
preferenceStore.getString(GradleConstants.GRADLE_ENVVAR_ALTERNATIVE_ANDROID_KEYSTORE_FILE));
envp[idx++] = getEnvVariableEqualsStringIfNoAlternativeSpecified("KEYSTORE_PASSWORD",
preferenceStore.getString(GradleConstants.GRADLE_ENVVAR_ALTERNATIVE_ANDROID_KEYSTORE_PASSWORD));
envp[idx++] = getEnvVariableEqualsStringIfNoAlternativeSpecified("KEY_ALIAS",
preferenceStore.getString(GradleConstants.GRADLE_ENVVAR_ALTERNATIVE_ANDROID_KEY_ALIAS));
envp[idx++] = getEnvVariableEqualsStringIfNoAlternativeSpecified("KEY_PASSWORD",
preferenceStore.getString(GradleConstants.GRADLE_ENVVAR_ALTERNATIVE_ANDROID_KEY_PASSWORD));
}
if (passAllEnvVars){
for (Map.Entry<String, String> entry : all.entrySet())
{
//System.out.println(entry.getKey() + "/" + entry.getValue());
envp[idx++] = entry.getKey() + "=" + entry.getValue();
}
}else{
//+ #81
envp[idx++] = getEnvVariableEqualsString("PATH");
envp[idx++] = getEnvVariableEqualsString("TEMP");
envp[idx++] = getEnvVariableEqualsString("TMP");
envp[idx++] = getEnvVariableEqualsString("SystemDrive");
//+
envp[idx++] = getEnvVariableEqualsString("HOME");
envp[idx++] = getEnvVariableEqualsString("USERPROFILE");
}
if (!warned ){
NodeclipseLogger.log(" Warning: JAVA_HOME, GRADLE_HOME and others environment variables will be applied automatically to every `gradle` launch.\n");
StringBuilder sb = new StringBuilder(100);
for(int i=0; i<envp.length; i++){
sb.append(" ").append(envp[i]).append('\n');
}
NodeclipseLogger.log(sb.toString());
warned = true;
}
return envp;
}
private String getEnvVariableEqualsStringIfNoAlternativeSpecified(String envvarName, String alternativeValue) {
if (""!=alternativeValue){
return envvarName + "=" + alternativeValue;
} else {
return getEnvVariableEqualsString(envvarName);
}
}
protected String getEnvVariableEqualsString(String envvarName){
String envvarValue = System.getenv(envvarName);
if (envvarValue==null) envvarValue = "";
return envvarName + "=" + envvarValue;
}
}