/*
* 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.before;
import com.goide.GoIcons;
import com.goide.runconfig.GoRunConfigurationBase;
import com.goide.sdk.GoSdkService;
import com.goide.util.GoExecutor;
import com.intellij.execution.BeforeRunTaskProvider;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public class GoBeforeRunTaskProvider extends BeforeRunTaskProvider<GoCommandBeforeRunTask> {
public static final Key<GoCommandBeforeRunTask> ID = Key.create("GoBeforeRunTask");
@Override
public Key<GoCommandBeforeRunTask> getId() {
return ID;
}
@Override
public String getName() {
return "Go Command";
}
@Override
public String getDescription(GoCommandBeforeRunTask task) {
return "Run `" + task + "`";
}
@Nullable
@Override
public Icon getIcon() {
return GoIcons.APPLICATION_RUN;
}
@Override
public boolean isConfigurable() {
return true;
}
@Nullable
@Override
public Icon getTaskIcon(GoCommandBeforeRunTask task) {
return getIcon();
}
@Nullable
@Override
public GoCommandBeforeRunTask createTask(RunConfiguration runConfiguration) {
return runConfiguration instanceof GoRunConfigurationBase ? new GoCommandBeforeRunTask() : null;
}
@Override
public boolean configureTask(RunConfiguration configuration, GoCommandBeforeRunTask task) {
Project project = configuration.getProject();
if (!(configuration instanceof GoRunConfigurationBase)) {
showAddingTaskErrorMessage(project, "Go Command task supports only Go Run Configurations");
return false;
}
Module module = ((GoRunConfigurationBase)configuration).getConfigurationModule().getModule();
if (!GoSdkService.getInstance(project).isGoModule(module)) {
showAddingTaskErrorMessage(project, "Go Command task supports only Go Modules");
return false;
}
GoCommandConfigureDialog dialog = new GoCommandConfigureDialog(project);
if (dialog.showAndGet()) {
task.setCommand(dialog.getCommand());
return true;
}
return false;
}
@Override
public boolean canExecuteTask(RunConfiguration configuration, GoCommandBeforeRunTask task) {
if (configuration instanceof GoRunConfigurationBase) {
Module module = ((GoRunConfigurationBase)configuration).getConfigurationModule().getModule();
GoSdkService sdkService = GoSdkService.getInstance(configuration.getProject());
if (sdkService.isGoModule(module)) {
return StringUtil.isNotEmpty(sdkService.getSdkHomePath(module)) && StringUtil.isNotEmpty(task.getCommand());
}
}
return false;
}
@Override
public boolean executeTask(DataContext context,
RunConfiguration configuration,
ExecutionEnvironment env,
GoCommandBeforeRunTask task) {
Semaphore done = new Semaphore();
Ref<Boolean> result = Ref.create(false);
GoRunConfigurationBase goRunConfiguration = (GoRunConfigurationBase)configuration;
Module module = goRunConfiguration.getConfigurationModule().getModule();
Project project = configuration.getProject();
String workingDirectory = goRunConfiguration.getWorkingDirectory();
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
if (StringUtil.isEmpty(task.getCommand())) return;
if (project == null || project.isDisposed()) return;
GoSdkService sdkService = GoSdkService.getInstance(project);
if (!sdkService.isGoModule(module)) return;
done.down();
GoExecutor.in(module).withParameterString(task.getCommand())
.withWorkDirectory(workingDirectory)
.showOutputOnError()
.showNotifications(false, true)
.withPresentableName("Executing `" + task + "`")
.withProcessListener(new ProcessAdapter() {
@Override
public void processTerminated(ProcessEvent event) {
done.up();
result.set(event.getExitCode() == 0);
}
})
.executeWithProgress(false, result1 -> VirtualFileManager.getInstance().asyncRefresh(null));
}
});
done.waitFor();
return result.get();
}
private static void showAddingTaskErrorMessage(Project project, String message) {
Messages.showErrorDialog(project, message, "Go Command Task");
}
}