Commit cf78c484 authored by Vladislav.Soroka's avatar Vladislav.Soroka
Browse files

External System + Gradle: support for running a task before launch of another configuration added.

Related issue for Gradle: IDEA-113437 'Before Launch' should support running a Gradle task
parent 6396cd89
Showing with 484 additions and 25 deletions
+484 -25
......@@ -66,4 +66,9 @@ run.text.starting.multiple.task={0}: Executing external tasks ''{1}''...\n
run.text.starting.single.task={0}: Executing external task ''{1}''...\n
run.text.ended.multiple.task={0}: External tasks execution finished ''{1}''.\n
run.text.ended.single.task={0}: External task execution finished ''{1}''.\n
run.error.undefined.task=No task to execute is specified
\ No newline at end of file
run.error.undefined.task=No task to execute is specified
tasks.select.task.title=Select {0} task
tasks.edit.task.title=Edit {0} Task
tasks.before.run.empty=Run {0} task
tasks.before.run=Run {0} task ''{1}''
\ No newline at end of file
......@@ -162,6 +162,9 @@ public abstract class AbstractExternalSystemTaskConfigurationType implements Con
if (!StringUtil.isEmptyOrSpaces(projectName)) {
buffer.append(projectName);
buffer.append(" ");
} else {
buffer.append(externalProjectPath);
buffer.append(" ");
}
buffer.append("[");
......
/*
* Copyright 2000-2014 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.openapi.externalSystem.service.execution;
import com.intellij.execution.BeforeRunTask;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
/**
* @author Vladislav.Soroka
* @since 5/30/2014
*/
public class ExternalSystemBeforeRunTask extends BeforeRunTask<ExternalSystemBeforeRunTask> {
@NotNull
private final ExternalSystemTaskExecutionSettings myTaskExecutionSettings;
public ExternalSystemBeforeRunTask(@NotNull Key<ExternalSystemBeforeRunTask> providerId, @NotNull ProjectSystemId systemId) {
super(providerId);
myTaskExecutionSettings = new ExternalSystemTaskExecutionSettings();
myTaskExecutionSettings.setExternalSystemIdString(systemId.getId());
}
@NotNull
public ExternalSystemTaskExecutionSettings getTaskExecutionSettings() {
return myTaskExecutionSettings;
}
@Override
public void writeExternal(Element element) {
super.writeExternal(element);
element.setAttribute("tasks", StringUtil.join(myTaskExecutionSettings.getTaskNames(), " "));
if (myTaskExecutionSettings.getExternalProjectPath() != null) {
element.setAttribute("externalProjectPath", myTaskExecutionSettings.getExternalProjectPath());
}
if (myTaskExecutionSettings.getVmOptions() != null) element.setAttribute("vmOptions", myTaskExecutionSettings.getVmOptions());
if (myTaskExecutionSettings.getScriptParameters() != null) {
element.setAttribute("scriptParameters", myTaskExecutionSettings.getScriptParameters());
}
}
@Override
public void readExternal(Element element) {
super.readExternal(element);
myTaskExecutionSettings.setTaskNames(StringUtil.split(StringUtil.notNullize(element.getAttributeValue("tasks")), " "));
myTaskExecutionSettings.setExternalProjectPath(element.getAttributeValue("externalProjectPath"));
myTaskExecutionSettings.setVmOptions(element.getAttributeValue("vmOptions"));
myTaskExecutionSettings.setScriptParameters(element.getAttributeValue("scriptParameters"));
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ExternalSystemBeforeRunTask)) return false;
if (!super.equals(o)) return false;
ExternalSystemBeforeRunTask task = (ExternalSystemBeforeRunTask)o;
if (!myTaskExecutionSettings.equals(task.myTaskExecutionSettings)) return false;
return true;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + myTaskExecutionSettings.hashCode();
return result;
}
}
/*
* Copyright 2000-2014 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.openapi.externalSystem.service.execution;
import com.intellij.execution.*;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author Vladislav.Soroka
* @since 5/30/2014
*/
public abstract class ExternalSystemBeforeRunTaskProvider extends BeforeRunTaskProvider<ExternalSystemBeforeRunTask> {
private static final Logger LOG = Logger.getInstance(ExternalSystemBeforeRunTaskProvider.class);
@NotNull private final ProjectSystemId mySystemId;
@NotNull private final Project myProject;
@NotNull private final Key<ExternalSystemBeforeRunTask> myId;
public ExternalSystemBeforeRunTaskProvider(@NotNull ProjectSystemId systemId,
@NotNull Project project,
@NotNull Key<ExternalSystemBeforeRunTask> id) {
mySystemId = systemId;
myProject = project;
myId = id;
}
@NotNull
public Key<ExternalSystemBeforeRunTask> getId() {
return myId;
}
@Override
public String getName() {
return ExternalSystemBundle.message("tasks.before.run.empty", mySystemId.getReadableName());
}
@Override
public boolean isConfigurable() {
return true;
}
@Override
public boolean configureTask(RunConfiguration runConfiguration, ExternalSystemBeforeRunTask task) {
ExternalSystemEditTaskDialog dialog = new ExternalSystemEditTaskDialog(myProject, task.getTaskExecutionSettings(), mySystemId);
dialog.setTitle(ExternalSystemBundle.message("tasks.select.task.title", mySystemId.getReadableName()));
dialog.show();
if (!dialog.isOK()) return false;
return true;
}
@Override
public boolean canExecuteTask(RunConfiguration configuration, ExternalSystemBeforeRunTask beforeRunTask) {
final ExternalSystemTaskExecutionSettings executionSettings = beforeRunTask.getTaskExecutionSettings();
final List<ExternalTaskPojo> tasks = ContainerUtilRt.newArrayList();
for (String taskName : executionSettings.getTaskNames()) {
tasks.add(new ExternalTaskPojo(taskName, executionSettings.getExternalProjectPath(), null));
}
if (tasks.isEmpty()) return true;
final Pair<ProgramRunner, ExecutionEnvironment> pair =
ExternalSystemUtil.createRunner(executionSettings, DefaultRunExecutor.EXECUTOR_ID, myProject, mySystemId);
if (pair == null) return false;
final ProgramRunner runner = pair.first;
final ExecutionEnvironment environment = pair.second;
return runner.canRun(DefaultRunExecutor.EXECUTOR_ID, environment.getRunProfile());
}
@Override
public boolean executeTask(DataContext context,
RunConfiguration configuration,
ExecutionEnvironment env,
ExternalSystemBeforeRunTask beforeRunTask) {
final ExternalSystemTaskExecutionSettings executionSettings = beforeRunTask.getTaskExecutionSettings();
final List<ExternalTaskPojo> tasks = ContainerUtilRt.newArrayList();
for (String taskName : executionSettings.getTaskNames()) {
tasks.add(new ExternalTaskPojo(taskName, executionSettings.getExternalProjectPath(), null));
}
if (tasks.isEmpty()) return true;
final Pair<ProgramRunner, ExecutionEnvironment> pair =
ExternalSystemUtil.createRunner(executionSettings, DefaultRunExecutor.EXECUTOR_ID, myProject, mySystemId);
if (pair == null) return false;
final ProgramRunner runner = pair.first;
final ExecutionEnvironment environment = pair.second;
environment.setExecutionId(env.getExecutionId());
final Semaphore targetDone = new Semaphore();
final Ref<Boolean> result = new Ref<Boolean>(false);
final Disposable disposable = Disposer.newDisposable();
final Executor executor = DefaultRunExecutor.getRunExecutorInstance();
final String executorId = executor.getId();
myProject.getMessageBus().connect(disposable).subscribe(ExecutionManager.EXECUTION_TOPIC, new ExecutionAdapter() {
public void processStartScheduled(final String executorIdLocal, final ExecutionEnvironment environmentLocal) {
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
targetDone.down();
}
}
public void processNotStarted(final String executorIdLocal, @NotNull final ExecutionEnvironment environmentLocal) {
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
targetDone.up();
}
}
public void processStarted(final String executorIdLocal,
@NotNull final ExecutionEnvironment environmentLocal,
@NotNull final ProcessHandler handler) {
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
handler.addProcessListener(new ProcessAdapter() {
public void processTerminated(ProcessEvent event) {
result.set(event.getExitCode() == 0);
targetDone.up();
environmentLocal.getContentToReuse();
}
});
}
}
});
try {
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
try {
runner.execute(environment);
}
catch (ExecutionException e) {
targetDone.up();
LOG.error(e);
}
}
}, ModalityState.NON_MODAL);
}
catch (Exception e) {
LOG.error(e);
Disposer.dispose(disposable);
return false;
}
targetDone.waitFor();
Disposer.dispose(disposable);
return result.get();
}
@Override
public String getDescription(ExternalSystemBeforeRunTask task) {
final String externalProjectPath = task.getTaskExecutionSettings().getExternalProjectPath();
if (task.getTaskExecutionSettings().getTaskNames().isEmpty()) {
return ExternalSystemBundle.message("tasks.before.run.empty", mySystemId.getReadableName());
}
String desc = StringUtil.join(task.getTaskExecutionSettings().getTaskNames(), " ");
for (Module module : ModuleManager.getInstance(myProject).getModules()) {
if (!mySystemId.toString().equals(module.getOptionValue(ExternalSystemConstants.EXTERNAL_SYSTEM_ID_KEY))) continue;
if (StringUtil.equals(externalProjectPath, module.getOptionValue(ExternalSystemConstants.LINKED_PROJECT_PATH_KEY))) {
desc = module.getName() + ": " + desc;
break;
}
}
return ExternalSystemBundle.message("tasks.before.run", mySystemId.getReadableName(), desc);
}
}
/*
* Copyright 2000-2014 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.openapi.externalSystem.service.execution;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.externalSystem.util.PaintAwarePanel;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
public class ExternalSystemEditTaskDialog extends DialogWrapper {
@NotNull private final ExternalSystemTaskExecutionSettings myTaskExecutionSettings;
@NotNull private final ExternalSystemTaskSettingsControl myControl;
@Nullable private JComponent contentPane;
public ExternalSystemEditTaskDialog(@NotNull Project project,
@NotNull ExternalSystemTaskExecutionSettings taskExecutionSettings,
@NotNull ProjectSystemId externalSystemId) {
super(project, true);
myTaskExecutionSettings = taskExecutionSettings;
setTitle(ExternalSystemBundle.message("tasks.edit.task.title", externalSystemId.getReadableName()));
myControl = new ExternalSystemTaskSettingsControl(project, externalSystemId);
myControl.setOriginalSettings(taskExecutionSettings);
setModal(true);
init();
}
protected JComponent createCenterPanel() {
if (contentPane == null) {
contentPane = new PaintAwarePanel(new GridBagLayout());
myControl.fillUi((PaintAwarePanel)contentPane, 0);
myControl.reset();
}
return contentPane;
}
public JComponent getPreferredFocusedComponent() {
return null;
}
@Override
protected void dispose() {
super.dispose();
myControl.disposeUIResources();
}
@Override
protected void doOKAction() {
myControl.apply(myTaskExecutionSettings);
super.doOKAction();
}
}
......@@ -67,6 +67,7 @@ import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
......@@ -537,40 +538,50 @@ public class ExternalSystemUtil {
public static void runTask(@NotNull ExternalSystemTaskExecutionSettings taskSettings,
@NotNull String executorId,
@NotNull Project project,
@NotNull ProjectSystemId externalSystemId)
{
Executor executor = ExecutorRegistry.getInstance().getExecutorById(executorId);
if (executor == null) {
return;
@NotNull ProjectSystemId externalSystemId) {
runTask(taskSettings, executorId, project, externalSystemId, null);
}
public static void runTask(@NotNull ExternalSystemTaskExecutionSettings taskSettings,
@NotNull String executorId,
@NotNull Project project,
@NotNull ProjectSystemId externalSystemId,
@Nullable ProgramRunner.Callback callback) {
final Pair<ProgramRunner, ExecutionEnvironment> pair = createRunner(taskSettings, executorId, project, externalSystemId);
if (pair == null) return;
try {
pair.first.execute(pair.second, callback);
}
String runnerId = getRunnerId(executorId);
if (runnerId == null) {
return;
catch (ExecutionException e) {
LOG.warn("Can't execute task " + taskSettings, e);
}
}
@Nullable
public static Pair<ProgramRunner, ExecutionEnvironment> createRunner(@NotNull ExternalSystemTaskExecutionSettings taskSettings,
@NotNull String executorId,
@NotNull Project project,
@NotNull ProjectSystemId externalSystemId) {
Executor executor = ExecutorRegistry.getInstance().getExecutorById(executorId);
if (executor == null) return null;
String runnerId = getRunnerId(executorId);
if (runnerId == null) return null;
ProgramRunner runner = RunnerRegistry.getInstance().findRunnerById(runnerId);
if (runner == null) {
return;
}
if (runner == null) return null;
AbstractExternalSystemTaskConfigurationType configurationType = findConfigurationType(externalSystemId);
if (configurationType == null) {
return;
}
if (configurationType == null) return null;
String name = AbstractExternalSystemTaskConfigurationType.generateName(project, taskSettings);
RunnerAndConfigurationSettings settings = RunManager.getInstance(project).createRunConfiguration(name, configurationType.getFactory());
ExternalSystemRunConfiguration runConfiguration = (ExternalSystemRunConfiguration)settings.getConfiguration();
runConfiguration.getSettings().setExternalProjectPath(taskSettings.getExternalProjectPath());
runConfiguration.getSettings().setTaskNames(taskSettings.getTaskNames());
ExecutionEnvironment env = new ExecutionEnvironment(executor, runner, settings, project);
try {
runner.execute(env, null);
}
catch (ExecutionException e) {
LOG.warn("Can't execute task " + taskSettings, e);
}
return Pair.create(runner, new ExecutionEnvironment(executor, runner, settings, project));
}
@Nullable
......
......@@ -106,6 +106,7 @@
<projectService serviceImplementation="org.jetbrains.plugins.gradle.service.project.GradleNotification"/>
<projectService serviceImplementation="org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager"/>
<stepsBeforeRunProvider implementation="org.jetbrains.plugins.gradle.execution.GradleBeforeRunTaskProvider" />
<configurationProducer implementation="org.jetbrains.plugins.gradle.service.execution.GradleRuntimeConfigurationProducer"/>
<toolWindow id="Gradle" anchor="right" icon="GradleIcons.ToolWindowGradle"
......
/*
* Copyright 2000-2014 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 org.jetbrains.plugins.gradle.execution;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemBeforeRunTask;
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemBeforeRunTaskProvider;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import icons.GradleIcons;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import javax.swing.*;
/**
* @author Vladislav.Soroka
* @since 5/30/2014
*/
public class GradleBeforeRunTaskProvider extends ExternalSystemBeforeRunTaskProvider {
public static final Key<ExternalSystemBeforeRunTask> ID = Key.create("Gradle.BeforeRunTask");
public GradleBeforeRunTaskProvider(Project project) {
super(GradleConstants.SYSTEM_ID, project, ID);
}
@Override
public Icon getIcon() {
return GradleIcons.Gradle;
}
@Nullable
@Override
public Icon getTaskIcon(ExternalSystemBeforeRunTask task) {
return GradleIcons.Gradle;
}
@Nullable
@Override
public ExternalSystemBeforeRunTask createTask(RunConfiguration runConfiguration) {
return new ExternalSystemBeforeRunTask(ID, GradleConstants.SYSTEM_ID);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment