/* * Copyright 2013-2016 Sergey Ignatov, Alexander Zolotov, Florin Patan * * 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 com.goide.runconfig; import com.goide.sdk.GoSdkService; import com.goide.sdk.GoSdkUtil; import com.intellij.execution.ExecutionBundle; import com.intellij.execution.ExecutionException; import com.intellij.execution.Executor; import com.intellij.execution.configuration.EnvironmentVariablesComponent; import com.intellij.execution.configurations.*; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.RunConfigurationWithSuppressedDefaultRunAction; import com.intellij.openapi.module.Module; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMExternalizerUtil; import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.util.PathUtil; import com.intellij.util.containers.ContainerUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Map; public abstract class GoRunConfigurationBase<RunningState extends GoRunningState> extends ModuleBasedConfiguration<GoModuleBasedConfiguration> implements RunConfigurationWithSuppressedDefaultRunAction, RunConfigurationWithSuppressedDefaultDebugAction { private static final String WORKING_DIRECTORY_NAME = "working_directory"; private static final String GO_PARAMETERS_NAME = "go_parameters"; private static final String PARAMETERS_NAME = "parameters"; private static final String PASS_PARENT_ENV = "pass_parent_env"; @NotNull private String myWorkingDirectory = ""; @NotNull private String myGoParams = ""; @NotNull private String myParams = ""; @NotNull private final Map<String, String> myCustomEnvironment = ContainerUtil.newHashMap(); private boolean myPassParentEnvironment = true; public GoRunConfigurationBase(String name, GoModuleBasedConfiguration configurationModule, ConfigurationFactory factory) { super(name, configurationModule, factory); Module module = configurationModule.getModule(); if (module == null) { Collection<Module> modules = getValidModules(); if (modules.size() == 1) { module = ContainerUtil.getFirstItem(modules); getConfigurationModule().setModule(module); } } if (module != null) { if (FileUtil.exists(module.getModuleFilePath())) { myWorkingDirectory = StringUtil.trimEnd(PathUtil.getParentPath(module.getModuleFilePath()), ".idea"); } } else { myWorkingDirectory = StringUtil.notNullize(configurationModule.getProject().getBasePath()); } } @Nullable @Override public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment environment) throws ExecutionException { return createRunningState(environment); } @NotNull @Override public Collection<Module> getValidModules() { return GoSdkUtil.getGoModules(getProject()); } @Override public void checkConfiguration() throws RuntimeConfigurationException { GoModuleBasedConfiguration configurationModule = getConfigurationModule(); Module module = configurationModule.getModule(); if (module != null) { if (GoSdkService.getInstance(module.getProject()).getSdkHomePath(module) == null) { throw new RuntimeConfigurationWarning("Go SDK is not specified for module '" + module.getName() + "'"); } } else { String moduleName = configurationModule.getModuleName(); if (moduleName != null) { throw new RuntimeConfigurationError(ExecutionBundle.message("module.doesn.t.exist.in.project.error.text", moduleName)); } throw new RuntimeConfigurationError(ExecutionBundle.message("module.not.specified.error.text")); } if (myWorkingDirectory.isEmpty()) { throw new RuntimeConfigurationError("Working directory is not specified"); } } @Override public void writeExternal(Element element) throws WriteExternalException { super.writeExternal(element); writeModule(element); addNonEmptyElement(element, WORKING_DIRECTORY_NAME, myWorkingDirectory); addNonEmptyElement(element, GO_PARAMETERS_NAME, myGoParams); addNonEmptyElement(element, PARAMETERS_NAME, myParams); if (!myCustomEnvironment.isEmpty()) { EnvironmentVariablesComponent.writeExternal(element, myCustomEnvironment); } if (!myPassParentEnvironment) { JDOMExternalizerUtil.addElementWithValueAttribute(element, PASS_PARENT_ENV, "false"); } } protected void addNonEmptyElement(@NotNull Element element, @NotNull String attributeName, @Nullable String value) { if (StringUtil.isNotEmpty(value)) { JDOMExternalizerUtil.addElementWithValueAttribute(element, attributeName, value); } } @Override public void readExternal(@NotNull Element element) throws InvalidDataException { super.readExternal(element); readModule(element); myGoParams = StringUtil.notNullize(JDOMExternalizerUtil.getFirstChildValueAttribute(element, GO_PARAMETERS_NAME)); myParams = StringUtil.notNullize(JDOMExternalizerUtil.getFirstChildValueAttribute(element, PARAMETERS_NAME)); String workingDirectoryValue = JDOMExternalizerUtil.getFirstChildValueAttribute(element, WORKING_DIRECTORY_NAME); if (workingDirectoryValue != null) { myWorkingDirectory = workingDirectoryValue; } EnvironmentVariablesComponent.readExternal(element, myCustomEnvironment); String passEnvValue = JDOMExternalizerUtil.getFirstChildValueAttribute(element, PASS_PARENT_ENV); myPassParentEnvironment = passEnvValue == null || Boolean.valueOf(passEnvValue); } @NotNull private RunningState createRunningState(ExecutionEnvironment env) throws ExecutionException { GoModuleBasedConfiguration configuration = getConfigurationModule(); Module module = configuration.getModule(); if (module == null) { throw new ExecutionException("Go isn't configured for run configuration: " + getName()); } return newRunningState(env, module); } @Nullable protected VirtualFile findFile(@NotNull String filePath) { VirtualFile virtualFile = VirtualFileManager.getInstance().findFileByUrl(VfsUtilCore.pathToUrl(filePath)); if (virtualFile == null) { String path = FileUtil.join(getWorkingDirectory(), filePath); virtualFile = VirtualFileManager.getInstance().findFileByUrl(VfsUtilCore.pathToUrl(path)); } return virtualFile; } @NotNull protected abstract RunningState newRunningState(ExecutionEnvironment env, Module module); @NotNull public String getGoToolParams() { return myGoParams; } @NotNull public String getParams() { return myParams; } public void setGoParams(@NotNull String params) { myGoParams = params; } public void setParams(@NotNull String params) { myParams = params; } @NotNull public Map<String, String> getCustomEnvironment() { return myCustomEnvironment; } public void setCustomEnvironment(@NotNull Map<String, String> customEnvironment) { myCustomEnvironment.clear(); myCustomEnvironment.putAll(customEnvironment); } public void setPassParentEnvironment(boolean passParentEnvironment) { myPassParentEnvironment = passParentEnvironment; } public boolean isPassParentEnvironment() { return myPassParentEnvironment; } @NotNull public String getWorkingDirectory() { return myWorkingDirectory; } @NotNull public String getWorkingDirectoryUrl() { return VfsUtilCore.pathToUrl(myWorkingDirectory); } public void setWorkingDirectory(@NotNull String workingDirectory) { myWorkingDirectory = workingDirectory; } }