Commit 3e14f002 authored by Dmitry Jemerov's avatar Dmitry Jemerov
Browse files

launcher script in Python

parent 8b0dbd68
Branches unavailable Tags unavailable
No related merge requests found
Showing with 118 additions and 36 deletions
+118 -36
......@@ -15,6 +15,7 @@
*/
package com.intellij.ide.actions;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
......@@ -31,9 +32,12 @@ import com.intellij.openapi.vfs.CharsetToolkit;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* @author yole
......@@ -59,35 +63,9 @@ public class CreateLauncherScriptAction extends AnAction {
public static void createLauncherScript(Project project, String name, String path) {
try {
final File scriptFile = createLauncherScriptFile();
final String mvCommand = "mv -f " + scriptFile + " " + path + "/" + name;
if (SystemInfo.isMac) {
final ScriptEngine engine = new ScriptEngineManager(null).getEngineByName("AppleScript");
if (engine == null) {
throw new IOException("Could not find AppleScript engine");
}
engine.eval("do shell script \"" + mvCommand + "\" with administrator privileges");
}
else if (SystemInfo.isUnix) {
GeneralCommandLine cmdLine = new GeneralCommandLine();
if (SystemInfo.isGnome) {
cmdLine.setExePath("gksudo");
cmdLine.addParameters("--message",
"In order to create a launcher script in " +
path +
", please enter your administrator password:");
}
else if (SystemInfo.isKDE) {
cmdLine.setExePath("kdesudo");
}
else {
Messages.showMessageDialog("Unsupported graphical environment. Please execute the following command from the shell:\n" + mvCommand,
"Create Launcher Script",
Messages.getInformationIcon());
return;
}
cmdLine.addParameter(mvCommand);
cmdLine.createProcess();
if (!scriptFile.renameTo(new File(path, name))) {
final String mvCommand = "mv -f " + scriptFile + " " + path + "/" + name;
sudo(mvCommand, "In order to create a launcher script in " + path + ", please enter your administrator password:");
}
}
catch (Exception e) {
......@@ -96,21 +74,51 @@ public class CreateLauncherScriptAction extends AnAction {
}
}
private static boolean sudo(String mvCommand, final String prompt) throws IOException, ScriptException, ExecutionException {
if (SystemInfo.isMac) {
final ScriptEngine engine = new ScriptEngineManager(null).getEngineByName("AppleScript");
if (engine == null) {
throw new IOException("Could not find AppleScript engine");
}
engine.eval("do shell script \"" + mvCommand + "\" with administrator privileges");
}
else if (SystemInfo.isUnix) {
GeneralCommandLine cmdLine = new GeneralCommandLine();
if (SystemInfo.isGnome) {
cmdLine.setExePath("gksudo");
cmdLine.addParameters("--message", prompt);
}
else if (SystemInfo.isKDE) {
cmdLine.setExePath("kdesudo");
}
else {
Messages.showMessageDialog("Unsupported graphical environment. Please execute the following command from the shell:\n" + mvCommand,
"Create Launcher Script",
Messages.getInformationIcon());
return true;
}
cmdLine.addParameter(mvCommand);
cmdLine.createProcess();
}
return false;
}
private static File createLauncherScriptFile() throws IOException {
final File tempFile = FileUtil.createTempFile("launcher", "");
StringBuilder textBuilder = new StringBuilder("#!/bin/bash\n");
final InputStream stream = CreateLauncherScriptAction.class.getClassLoader().getResourceAsStream("launcher.py");
String launcherContents = FileUtil.loadTextAndClose(new InputStreamReader(stream));
launcherContents = launcherContents.replace("$CONFIG_PATH$", PathManager.getConfigPath());
String homePath = PathManager.getHomePath().replace(" ", "\\ ");
String productName = ApplicationNamesInfo.getInstance().getProductName().toLowerCase();
if (SystemInfo.isMac) {
textBuilder.append("cd ").append(homePath).append("/Contents/MacOS/\n");
textBuilder.append("./").append(productName);
launcherContents = launcherContents.replace("$RUN_PATH$", homePath + "/Contents/MacOS/" + productName);
}
else {
textBuilder.append("cd ").append(homePath).append("/bin\n");
textBuilder.append("./").append(productName).append(".sh");
launcherContents = launcherContents.replace("$RUN_PATH$", homePath + "/bin/" + productName + ".sh");
}
textBuilder.append(" $@\n");
FileUtil.writeToFile(tempFile, textBuilder.toString().getBytes(CharsetToolkit.UTF8_CHARSET));
FileUtil.writeToFile(tempFile, launcherContents.getBytes(CharsetToolkit.UTF8_CHARSET));
if (!tempFile.setExecutable(true)) {
throw new IOException("Failed to mark the launcher script as executable");
}
......
#!/usr/bin/python
import socket
import struct
import sys
import os
import os.path
import time
# see com.intelij.idea.SocketLock for the server side of this interface
RUN_PATH = '$RUN_PATH$'
CONFIG_PATH = '$CONFIG_PATH$'
args = []
skip_next = False
for arg in sys.argv[1:]:
if arg == '-l' or arg == '--line':
args.append(arg)
skip_next = True
elif skip_next:
args.append(arg)
skip_next = False
else:
args.append(os.path.abspath(arg))
def launch_with_port(port):
found = False
s = socket.socket()
s.settimeout(0.3)
try:
s.connect(('127.0.0.1', port))
except:
return False
while True:
try:
path_len = struct.unpack(">h", s.recv(2))[0]
path = s.recv(path_len)
path = os.path.abspath(path)
if os.path.abspath(path) == os.path.abspath(CONFIG_PATH):
found = True
break
except:
break
if found:
if args:
cmd = "activate " + "\0".join(args)
encoded = struct.pack(">h", len(cmd)) + cmd
s.send(encoded)
time.sleep(0.5) # don't close socket immediately
return True
return False
port = -1
try:
f = open(os.path.join(CONFIG_PATH, 'port'))
port = int(f.read())
except Exception, e:
print e
port = -1
if port == -1:
# SocketLock actually allows up to 50 ports, but the checking takes too long
for port in range(6942, 6942+10):
if launch_with_port(port): exit()
else:
if launch_with_port(port): exit()
bin_dir, bin_file = os.path.split(RUN_PATH)
os.chdir(bin_dir)
os.execv(bin_file, args)
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