[intellij-sh] IDEA-215997 Add implementation for BeforeRunProvider

GitOrigin-RevId: 025a54c5c389b18fdee59789e5cd1de67ecec180
This commit is contained in:
Mikhail Mazurkevich
2019-09-16 19:02:03 +00:00
committed by intellij-monorepo-bot
parent ada6cb0671
commit e39eebc594
4 changed files with 187 additions and 7 deletions
+2
View File
@@ -37,7 +37,9 @@ Adds support for working with shell script files
<lang.braceMatcher language="Shell Script" implementationClass="com.intellij.sh.ShBraceMatcher"/>
<lang.documentationProvider language="Shell Script" implementationClass="com.intellij.sh.ShDocumentationProvider"/>
<runLineMarkerContributor language="Shell Script" implementationClass="com.intellij.sh.run.ShRunLineMarkerContributor"/>
<configurationType implementation="com.intellij.sh.run.ShConfigurationType"/>
<stepsBeforeRunProvider implementation="com.intellij.sh.run.ShBeforeRunTaskProvider"/>
<defaultLiveTemplatesProvider implementation="com.intellij.sh.template.ShTemplateProvider"/>
<liveTemplateContext implementation="com.intellij.sh.template.ShContextType"/>
@@ -0,0 +1,167 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sh.run;
import com.intellij.execution.BeforeRunTask;
import com.intellij.execution.BeforeRunTaskProvider;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.compound.ConfigurationSelectionUtil;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.impl.RunConfigurationBeforeRunProvider;
import com.intellij.execution.impl.RunManagerImpl;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.sh.ShLanguage;
import com.intellij.util.containers.ContainerUtil;
import icons.SHIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.concurrency.AsyncPromise;
import org.jetbrains.concurrency.Promise;
import javax.swing.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ShBeforeRunTaskProvider extends BeforeRunTaskProvider<ShBeforeRunTaskProvider.ShBeforeRunTask> {
private static final String SH_BEFORE_KEY_PREFIX = "Sh.BeforeRunTask";
private static final Key<ShBeforeRunTask> ID = Key.create(SH_BEFORE_KEY_PREFIX);
private static final Map<String, Key<Boolean>> KEY_MAP = new HashMap<>();
@Override
public Key<ShBeforeRunTask> getId() {
return ID;
}
@Override
public String getName() {
return "Run " + ShLanguage.INSTANCE.getID();
}
@Override
public String getDescription(ShBeforeRunTask task) {
RunnerAndConfigurationSettings configurationSettings = task.getSettings();
return configurationSettings != null ? "Run " + ShLanguage.INSTANCE.getID() + " '" + configurationSettings.getName() + "'"
: "Run " + ShLanguage.INSTANCE.getID();
}
@Nullable
@Override
public Icon getIcon() {
return SHIcons.ShFile;
}
@Nullable
@Override
public Icon getTaskIcon(ShBeforeRunTask task) {
return SHIcons.ShFile;
}
@Nullable
@Override
public ShBeforeRunTask createTask(@NotNull RunConfiguration runConfiguration) {
return new ShBeforeRunTask(runConfiguration.getProject());
}
@Override
public boolean isConfigurable() {
return true;
}
@Override
public Promise<Boolean> configureTask(@NotNull DataContext context,
@NotNull RunConfiguration currentConfig,
@NotNull ShBeforeRunTask task) {
AsyncPromise<Boolean> result = new AsyncPromise<>();
Project project = currentConfig.getProject();
if (project == null || !project.isInitialized()) {
result.setResult(false);
return result;
}
RunManagerImpl runManager = RunManagerImpl.getInstanceImpl(project);
List<RunConfiguration> configurations = RunManagerImpl.getInstanceImpl(project).getAllSettings().stream()
.map(RunnerAndConfigurationSettings::getConfiguration)
.filter(config -> config instanceof ShRunConfiguration && config != currentConfig)
.collect(Collectors.toList());
ConfigurationSelectionUtil.createPopup(project, runManager, configurations, (selectedConfigs, selectedTarget) -> {
RunConfiguration selectedConfig = ContainerUtil.getFirstItem(selectedConfigs);
RunnerAndConfigurationSettings selectedSettings = selectedConfig == null ? null : runManager.getSettings(selectedConfig);
if (selectedSettings != null) {
task.setSettings(selectedSettings);
result.setResult(true);
}
else {
result.setResult(false);
}
}).showInBestPositionFor(context);
return result;
}
@Override
public boolean executeTask(@NotNull DataContext context,
@NotNull RunConfiguration configuration,
@NotNull ExecutionEnvironment env,
@NotNull ShBeforeRunTask task) {
RunnerAndConfigurationSettings configurationSettings = task.getSettings();
if (configurationSettings == null) return false;
Key<Boolean> userDataKey = getRunBeforeUserDataKey(configurationSettings.getConfiguration());
configuration.getProject().putUserData(userDataKey, true);
boolean result = RunConfigurationBeforeRunProvider.doExecuteTask(env, configurationSettings, null);
configuration.getProject().putUserData(userDataKey, false);
return result;
}
static Key<Boolean> getRunBeforeUserDataKey(@NotNull RunConfiguration runConfiguration) {
return KEY_MAP.computeIfAbsent(runConfiguration.getName(), key -> Key.create(SH_BEFORE_KEY_PREFIX + "_" + key));
}
static class ShBeforeRunTask extends BeforeRunTask<ShBeforeRunTask> implements PersistentStateComponent<ShBeforeRunTaskState> {
private ShBeforeRunTaskState myState = new ShBeforeRunTaskState();
private RunnerAndConfigurationSettings mySettings;
private final Project myProject;
protected ShBeforeRunTask(@NotNull Project project) {
super(ID);
myProject = project;
}
@Nullable
@Override
public ShBeforeRunTaskState getState() {
return myState;
}
@Override
public void loadState(@NotNull ShBeforeRunTaskState state) {
state.resetModificationCount();
myState = state;
}
public void setSettings(@Nullable RunnerAndConfigurationSettings settings) {
mySettings = settings;
if (settings == null) {
myState.setRunConfigType("");
myState.setRunConfigName("");
return;
}
myState.setRunConfigType(settings.getType().getId());
myState.setRunConfigName(settings.getName());
}
@Nullable
public RunnerAndConfigurationSettings getSettings() {
if (mySettings != null) return mySettings;
return myState != null && myState.getRunConfigType() != null && myState.getRunConfigName() != null
? mySettings = RunManagerImpl.getInstanceImpl(myProject).findConfigurationByTypeAndName(myState.getRunConfigType(), myState.getRunConfigName())
: null;
}
}
}
@@ -0,0 +1,12 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sh.run
import com.intellij.openapi.components.BaseState
import com.intellij.util.xmlb.annotations.Attribute
class ShBeforeRunTaskState : BaseState() {
@get:Attribute("RUN_CONFIG_TYPE")
var runConfigType by string()
@get:Attribute("RUN_CONFIG_NAME")
var runConfigName by string()
}
@@ -1,11 +1,7 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sh.run;
import com.intellij.execution.DefaultExecutionResult;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionResult;
import com.intellij.execution.Executor;
import com.intellij.execution.Platform;
import com.intellij.execution.*;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.PtyCommandLine;
import com.intellij.execution.configurations.RunProfileState;
@@ -16,6 +12,7 @@ import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -32,7 +29,6 @@ import java.util.Arrays;
import static com.intellij.sh.ShStringUtil.quote;
public class ShRunConfigurationProfileState implements RunProfileState {
private static final String WHITESPACE = " ";
private final Project myProject;
private final ShRunConfiguration myRunConfiguration;
@@ -44,8 +40,11 @@ public class ShRunConfigurationProfileState implements RunProfileState {
@Nullable
@Override
public ExecutionResult execute(Executor executor, @NotNull ProgramRunner runner) throws ExecutionException {
Key<Boolean> userDataKey = ShBeforeRunTaskProvider.getRunBeforeUserDataKey(myRunConfiguration);
Boolean userDataValue = myProject.getUserData(userDataKey);
boolean isRunBeforeConfig = userDataValue != null && userDataValue.booleanValue();
ShRunner shRunner = ServiceManager.getService(myProject, ShRunner.class);
if (shRunner == null || !shRunner.isAvailable(myProject)) {
if (shRunner == null || !shRunner.isAvailable(myProject) || isRunBeforeConfig) {
return buildExecutionResult();
}
shRunner.run(buildCommand(), myRunConfiguration.getScriptWorkingDirectory());