IDEA-94341 Launch Multiple "Run/Debug Configurations" At Once

This commit is contained in:
Vassiliy.Kudryashov
2015-07-04 00:05:09 +03:00
parent 9712ae7820
commit 68aade1bf9
11 changed files with 348 additions and 19 deletions
@@ -0,0 +1,142 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* 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.intellij.execution.compound;
import com.intellij.execution.*;
import com.intellij.execution.configurations.*;
import com.intellij.execution.impl.RunManagerImpl;
import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ExecutionEnvironmentBuilder;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.WriteExternalException;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
public class CompoundRunConfiguration extends RunConfigurationBase implements WithoutOwnBeforeRunSteps {
static final Comparator<RunConfiguration> COMPARATOR = new Comparator<RunConfiguration>() {
@Override
public int compare(RunConfiguration o1, RunConfiguration o2) {
int i = o1.getType().getDisplayName().compareTo(o2.getType().getDisplayName());
return (i != 0) ? i : o1.getName().compareTo(o2.getName());
}
};
private final Set<Pair<String, String>> myPairs = new HashSet<Pair<String, String>>();
private final Set<RunConfiguration> mySetToRun = new TreeSet<RunConfiguration>(COMPARATOR);
private boolean myInitialized = false;
public CompoundRunConfiguration(Project project, @NotNull CompoundRunConfigurationType type, String name) {
super(project, type.getConfigurationFactories()[0], name);
}
public Set<RunConfiguration> getSetToRun() {
initIfNeed();
return mySetToRun;
}
private void initIfNeed() {
if (myInitialized) return;
mySetToRun.clear();
RunManagerImpl manager = RunManagerImpl.getInstanceImpl(getProject());
for (Pair<String, String> pair : myPairs) {
RunnerAndConfigurationSettings settings = manager.findConfigurationByTypeAndName(pair.first, pair.second);
if (settings != null) {
mySetToRun.add(settings.getConfiguration());
}
}
myInitialized = true;
}
@NotNull
@Override
public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
return new CompoundRunConfigurationSettingsEditor(getProject());
}
@Override
public void checkConfiguration() throws RuntimeConfigurationException {
if (getSetToRun().isEmpty()) throw new RuntimeConfigurationException("There is nothing to run");
for (RunConfiguration configuration : getSetToRun()) {
configuration.checkConfiguration();
}
}
@Nullable
@Override
public RunProfileState getState(@NotNull Executor executor, @NotNull final ExecutionEnvironment environment) throws ExecutionException {
try {
checkConfiguration();
}
catch (RuntimeConfigurationException e) {
throw new ExecutionException(e.getMessage());
}
return new RunProfileState() {
@Nullable
@Override
public ExecutionResult execute(final Executor executor, @NotNull ProgramRunner runner) throws ExecutionException {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
RunManagerImpl manager = RunManagerImpl.getInstanceImpl(getProject());
for (RunConfiguration configuration : getSetToRun()) {
RunnerAndConfigurationSettings settings = new RunnerAndConfigurationSettingsImpl(manager, configuration, false);
ExecutionEnvironmentBuilder builder = ExecutionEnvironmentBuilder.createOrNull(executor, settings);
if (builder != null) {
ExecutionManager.getInstance(getProject())
.restartRunProfile(builder.activeTarget().dataContext(null).build());
}
}
}
});
return null;
}
};
}
@Override
public void readExternal(Element element) throws InvalidDataException {
super.readExternal(element);
myPairs.clear();
List<Element> children = element.getChildren("toRun");
for (Element child : children) {
String type = child.getAttributeValue("type");
String name = child.getAttributeValue("name");
if (type != null && name != null) {
myPairs.add(Pair.create(type, name));
}
}
}
@Override
public void writeExternal(Element element) throws WriteExternalException {
super.writeExternal(element);
initIfNeed();
for (RunConfiguration configuration : getSetToRun()) {
Element child = new Element("toRun");
child.setAttribute("type", configuration.getType().getId());
child.setAttribute("name", configuration.getName());
element.addContent(child);
}
}
}
@@ -0,0 +1,111 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* 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.intellij.execution.compound;
import com.intellij.execution.BeforeRunTask;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.impl.RunConfigurationBeforeRunProvider;
import com.intellij.execution.impl.RunManagerImpl;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.ui.CheckBoxList;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.*;
public class CompoundRunConfigurationSettingsEditor extends SettingsEditor<CompoundRunConfiguration>{
@NotNull private final Project myProject;
private final CheckBoxList<RunConfiguration> myList;
private List<RunConfiguration> myChecked = new ArrayList<RunConfiguration>();
private final RunManagerImpl myRunManager;
public CompoundRunConfigurationSettingsEditor(@NotNull Project project) {
myProject = project;
myRunManager = RunManagerImpl.getInstanceImpl(myProject);
myList = new CheckBoxList<RunConfiguration>() {
@Override
protected void adjustRendering(JCheckBox checkBox, int index, boolean selected, boolean hasFocus) {
RunConfiguration configuration = getItemAt(index);
assert configuration != null;
checkBox.setText(configuration.getType().getDisplayName() + " '"+configuration.getName()+"'");
}
};
myList.setVisibleRowCount(100);
}
private void updateModel(@NotNull CompoundRunConfiguration s) {
List<RunConfiguration> list = myRunManager.getAllConfigurationsList();
Collections.sort(list, CompoundRunConfiguration.COMPARATOR);
for (RunConfiguration configuration : list) {
if (canBeAdded(configuration, s)) {
myList.addItem(configuration, configuration.getName(), myChecked.contains(configuration));
}
}
}
private boolean canBeAdded(@NotNull RunConfiguration candidate, @NotNull final CompoundRunConfiguration root) {
if (candidate == root) return false;
List<BeforeRunTask> tasks = myRunManager.getBeforeRunTasks(candidate);
for (BeforeRunTask task : tasks) {
if (task instanceof RunConfigurationBeforeRunProvider.RunConfigurableBeforeRunTask) {
RunConfigurationBeforeRunProvider.RunConfigurableBeforeRunTask runTask
= (RunConfigurationBeforeRunProvider.RunConfigurableBeforeRunTask)task;
RunnerAndConfigurationSettings settings = runTask.getSettings();
if (settings != null) {
if (!canBeAdded(settings.getConfiguration(), root)) return false;
}
}
}
if (candidate instanceof CompoundRunConfiguration) {
Set<RunConfiguration> set = ((CompoundRunConfiguration)candidate).getSetToRun();
for (RunConfiguration configuration : set) {
if (!canBeAdded(configuration, root)) return false;
}
}
return true;
}
@Override
protected void resetEditorFrom(CompoundRunConfiguration s) {
myChecked.clear();
myChecked.addAll(s.getSetToRun());
updateModel(s);
}
@Override
protected void applyEditorTo(CompoundRunConfiguration s) throws ConfigurationException {
Set<RunConfiguration> checked = new HashSet<RunConfiguration>();
for (int i = 0; i < myList.getItemsCount(); i++) {
RunConfiguration configuration = myList.getItemAt(i);
if (myList.isItemSelected(configuration)) {
checked.add(configuration);
}
}
Set<RunConfiguration> toRun = s.getSetToRun();
toRun.clear();
toRun.addAll(checked);
}
@NotNull
@Override
protected JComponent createEditor() {
return myList;//new JBScrollPane(myList, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
}
}
@@ -0,0 +1,51 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* 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.intellij.execution.compound;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.ConfigurationTypeBase;
import com.intellij.execution.configurations.ConfigurationTypeUtil;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
import com.intellij.ui.LayeredIcon;
public class CompoundRunConfigurationType extends ConfigurationTypeBase {
public static CompoundRunConfigurationType getInstance() {
return ConfigurationTypeUtil.findConfigurationType(CompoundRunConfigurationType.class);
}
public CompoundRunConfigurationType() {
super("CompoundRunConfigurationType",
"Compound Run Configuration",
"It runs batch of run configurations at once",
LayeredIcon.create(AllIcons.Nodes.Folder, AllIcons.Nodes.RunnableMark));
addFactory(new ConfigurationFactory(this) {
@Override
public RunConfiguration createTemplateConfiguration(Project project) {
return new CompoundRunConfiguration(project, CompoundRunConfigurationType.this, "Compound Run Configuration");
}
@Override
public String getName() {
return super.getName();
}
});
}
}