IDEA-84112 (check for available terminal emulators; deprecate isKDE/isGNOME as unreliable)

This commit is contained in:
Roman Shevchenko
2012-04-05 19:04:49 +02:00
parent 6e6e6a1677
commit 7c97044b3d
6 changed files with 127 additions and 48 deletions
@@ -19,6 +19,7 @@ import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.process.CapturingProcessHandler;
import com.intellij.execution.process.ProcessOutput;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.NotNull;
@@ -30,6 +31,46 @@ import java.util.List;
import java.util.Map;
public class ExecUtil {
private static final NotNullLazyValue<Boolean> hasGkSudo = new NotNullLazyValue<Boolean>() {
@NotNull
@Override
protected Boolean compute() {
return new File("/usr/bin/gksudo").canExecute();
}
};
private static final NotNullLazyValue<Boolean> hasKdeSudo = new NotNullLazyValue<Boolean>() {
@NotNull
@Override
protected Boolean compute() {
return new File("/usr/bin/kdesudo").canExecute();
}
};
private static final NotNullLazyValue<Boolean> hasGnomeTerminal = new NotNullLazyValue<Boolean>() {
@NotNull
@Override
protected Boolean compute() {
return new File("/usr/bin/gnome-terminal").canExecute();
}
};
private static final NotNullLazyValue<Boolean> hasKdeTerminal = new NotNullLazyValue<Boolean>() {
@NotNull
@Override
protected Boolean compute() {
return new File("/usr/bin/konsole").canExecute();
}
};
private static final NotNullLazyValue<Boolean> hasXTerm = new NotNullLazyValue<Boolean>() {
@NotNull
@Override
protected Boolean compute() {
return new File("/usr/bin/xterm").canExecute();
}
};
private ExecUtil() { }
public static int execAndGetResult(final String... command) throws ExecutionException, InterruptedException {
@@ -87,8 +128,9 @@ public class ExecUtil {
return "/usr/bin/open";
}
public static ProcessOutput execAndGetOutput(@NotNull final List<String> command, @Nullable final String workDir) throws ExecutionException {
assert command.size() > 0 : command;
public static ProcessOutput execAndGetOutput(@NotNull final List<String> command,
@Nullable final String workDir) throws ExecutionException {
assert command.size() > 0;
final GeneralCommandLine commandLine = new GeneralCommandLine(command);
commandLine.setWorkDirectory(workDir);
final Process process = commandLine.createProcess();
@@ -124,13 +166,13 @@ public class ExecUtil {
final String script = "do shell script \"" + scriptPath + "\" with administrator privileges";
return execAndGetOutput(Arrays.asList(getOsascriptPath(), "-e", script), workDir);
}
else if (SystemInfo.isKDE) {
else if (hasKdeSudo.getValue()) {
return execAndGetOutput(Arrays.asList("kdesudo", "--comment", prompt, scriptPath), workDir);
}
else if (SystemInfo.isGnome) {
else if (hasGkSudo.getValue()) {
return execAndGetOutput(Arrays.asList("gksudo", "--message", prompt, scriptPath), workDir);
}
else if (SystemInfo.isUnix) {
else if (SystemInfo.isUnix && hasTerminalApp()) {
final File sudo = createTempExecutableScript("sudo", ".sh",
"#!/bin/sh\n" +
"echo \"" + prompt + "\"\n" +
@@ -140,15 +182,54 @@ public class ExecUtil {
"echo\n" +
"read -p \"Press Enter to close this window...\" TEMP\n" +
"exit $STATUS\n");
return execAndGetOutput(Arrays.asList("xterm", "-T", "Install", "-e", sudo.getAbsolutePath()), workDir);
}
else {
throw new UnsupportedOperationException("Unsupported OS/desktop: " + SystemInfo.OS_NAME + '/' + SystemInfo.SUN_DESKTOP);
return execAndGetOutput(getTerminalCommand("Install", sudo.getAbsolutePath()), workDir);
}
throw new UnsupportedSystemException();
}
public static int sudoAndGetResult(@NotNull final String scriptPath,
@NotNull final String prompt) throws IOException, ExecutionException {
return sudoAndGetOutput(scriptPath, prompt).getExitCode();
}
public static boolean hasTerminalApp() {
return SystemInfo.isWindows || SystemInfo.isMac || hasKdeTerminal.getValue() || hasGnomeTerminal.getValue() || hasXTerm.getValue();
}
public static List<String> getTerminalCommand(@Nullable final String title, @NotNull final String command) {
if (SystemInfo.isWindows) {
return Arrays.asList("cmd.exe", "/c", "start", '"' + (title != null ? title : "") + '"', command);
}
else if (SystemInfo.isMac) {
return Arrays.asList(getOpenCommandPath(), "-a", "Terminal", command); // todo: title?
}
else if (hasKdeTerminal.getValue()) {
return Arrays.asList("/usr/bin/konsole", "-e", command); // todo: title?
}
else if (hasGnomeTerminal.getValue()) {
if (title != null) {
return Arrays.asList("/usr/bin/gnome-terminal", "-t", title, "-x", command);
}
else {
return Arrays.asList("/usr/bin/gnome-terminal", "-x", command);
}
}
else if (hasXTerm.getValue()) {
if (title != null) {
return Arrays.asList("/usr/bin/xterm", "-T", title, "-e", command);
}
else {
return Arrays.asList("/usr/bin/xterm", "-e", command);
}
}
throw new UnsupportedSystemException();
}
public static class UnsupportedSystemException extends UnsupportedOperationException {
public UnsupportedSystemException() {
super("Unsupported OS/desktop: " + SystemInfo.OS_NAME + '/' + SystemInfo.SUN_DESKTOP);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -15,15 +15,14 @@
*/
package com.intellij.openapi.fileTypes;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -31,11 +30,12 @@ import java.util.List;
* @author yole
*/
public class NativeFileType implements INativeFileType {
private static final Icon ICON = IconLoader.getIcon("/fileTypes/custom.png");
private NativeFileType() { }
public static final NativeFileType INSTANCE = new NativeFileType();
private static final Icon ICON = IconLoader.getIcon("/fileTypes/custom.png");
private NativeFileType() { }
@NotNull
public String getName() {
return "Native";
@@ -68,7 +68,7 @@ public class NativeFileType implements INativeFileType {
}
@Override
public boolean openFileInAssociatedApplication(Project project, VirtualFile file) {
public boolean openFileInAssociatedApplication(final Project project, @NotNull final VirtualFile file) {
return openAssociatedApplication(file);
}
@@ -77,8 +77,8 @@ public class NativeFileType implements INativeFileType {
return true;
}
public static boolean openAssociatedApplication(VirtualFile file) {
List<String> commands = new ArrayList<String>();
public static boolean openAssociatedApplication(@NotNull final VirtualFile file) {
final List<String> commands = new ArrayList<String>();
if (SystemInfo.isWindows) {
commands.add("rundll32.exe");
commands.add("url.dll,FileProtocolHandler");
@@ -86,23 +86,20 @@ public class NativeFileType implements INativeFileType {
else if (SystemInfo.isMac) {
commands.add("/usr/bin/open");
}
else if (SystemInfo.isKDE) {
commands.add("kfmclient");
commands.add("exec");
}
else if (SystemInfo.isGnome) {
commands.add("gnome-open");
else if (SystemInfo.hasXdgOpen()) {
commands.add("xdg-open");
}
else {
return false;
}
commands.add(file.getPath());
try {
Runtime.getRuntime().exec(ArrayUtil.toStringArray(commands));
new GeneralCommandLine(commands).createProcess();
return true;
}
catch (IOException e) {
catch (Exception e) {
return false;
}
return true;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -54,7 +54,7 @@ public class CreateDesktopEntryAction extends DumbAwareAction {
private static final int MIN_ICON_SIZE = 32;
public static boolean isAvailable() {
return SystemInfo.isLinux || SystemInfo.isGnome || SystemInfo.isKDE; // KDE patched for FreeBSD, sure
return SystemInfo.hasXdgOpen();
}
@Override
@@ -47,9 +47,10 @@ public class SystemInfo extends SystemInfoRt {
public static final boolean isSolaris = _OS_NAME.startsWith("sunos");
public static final boolean isUnix = SystemInfoRt.isUnix;
private static final String _SUN_DESKTOP = SUN_DESKTOP.toLowerCase();
public static final boolean isKDE = _SUN_DESKTOP.contains("kde");
public static final boolean isGnome = _SUN_DESKTOP.contains("gnome");
/** @deprecated inaccurate (to remove in IDEA 13) */
public static final boolean isKDE = SUN_DESKTOP.toLowerCase().contains("kde");
/** @deprecated inaccurate (to remove in IDEA 13) */
public static final boolean isGnome = SUN_DESKTOP.toLowerCase().contains("gnome");
public static final boolean isMacSystemMenu = isMac && "true".equals(System.getProperty("apple.laf.useScreenMenuBar"));
@@ -63,7 +64,7 @@ public class SystemInfo extends SystemInfoRt {
public static final boolean isMacIntel64 = isMac && "x86_64".equals(OS_ARCH);
/** @deprecated use {@linkplain #hasXdgOpen()} (to remove in IDEA 13) */
public static final boolean hasXdgOpen = false;
public static final boolean hasXdgOpen = isLinux;
private static final NotNullLazyValue<Boolean> ourHasXdgOpen = new AtomicNotNullLazyValue<Boolean>() {
@NotNull
@Override
@@ -1,17 +1,17 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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
* 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
* 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.
* 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.groovy.mvc;
@@ -115,7 +115,7 @@ public abstract class MvcFramework {
}
}
public boolean isInteractiveConsoleSupport(@NotNull Module module) {
public boolean isInteractiveConsoleSupported(@NotNull Module module) {
return false;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -73,7 +73,7 @@ public class MvcRunTargetDialog extends DialogWrapper {
boolean hasOneSupportedModule = false;
for (Module module : ModuleManager.getInstance(myModule.getProject()).getModules()) {
if (module == myModule || myFramework.hasSupport(module)) {
if (myFramework.isInteractiveConsoleSupport(module)) {
if (myFramework.isInteractiveConsoleSupported(module)) {
hasOneSupportedModule = true;
break;
}
@@ -89,7 +89,7 @@ public class MvcRunTargetDialog extends DialogWrapper {
}
};
myInteractiveRunAction.setEnabled(myFramework.isInteractiveConsoleSupport(myModule));
myInteractiveRunAction.setEnabled(myFramework.isInteractiveConsoleSupported(myModule));
return new Action[]{myInteractiveRunAction};
}
@@ -120,7 +120,7 @@ public class MvcRunTargetDialog extends DialogWrapper {
public void actionPerformed(ActionEvent e) {
myModule = (Module)myModuleBox.getSelectedItem();
if (myInteractiveRunAction != null) {
myInteractiveRunAction.setEnabled(myFramework.isInteractiveConsoleSupport(myModule));
myInteractiveRunAction.setEnabled(myFramework.isInteractiveConsoleSupported(myModule));
}
}
});