IDEA-129961 Make scratch files executable: Groovy

This commit is contained in:
Gregory.Shrago
2015-01-15 18:21:17 +03:00
parent 864a293f9e
commit 47859e192e
5 changed files with 134 additions and 12 deletions
@@ -24,6 +24,10 @@ public class CantRunException extends ExecutionException {
super(message);
}
public CantRunException(String s, Throwable cause) {
super(s, cause);
}
public static CantRunException noModuleConfigured(final String moduleName) {
if (moduleName.trim().length() == 0) {
return new CantRunException(ExecutionBundle.message("no.module.defined.error.message"));
@@ -0,0 +1,111 @@
package com.intellij.execution.util;
import com.intellij.execution.CantRunException;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.PathUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
public class ScriptFileUtil {
private static final Logger LOG = Logger.getInstance(ScriptFileUtil.class);
private static final String SCHEME = "mem://";
private static final Map<String, VirtualFile> ourFilesMap = ContainerUtil.createConcurrentWeakValueMap();
private static final AtomicLong ourFileCounter = new AtomicLong();
private ScriptFileUtil() {}
public static boolean isMemoryScriptPath(@Nullable String url) {
return url != null && url.startsWith(SCHEME);
}
public static String getScriptFilePath(@NotNull VirtualFile file) {
if (file.isInLocalFileSystem()) return file.getPath();
long id = ourFileCounter.incrementAndGet();
String url = SCHEME + id + "/" + file.getName();
ourFilesMap.put(url, file);
return url;
}
@Nullable
public static VirtualFile findScriptFileByPath(@Nullable String path) {
if (StringUtil.isEmpty(path)) return null;
if (!path.startsWith(SCHEME)) {
return LocalFileSystem.getInstance().findFileByPath(path);
}
return ourFilesMap.get(path);
}
@NotNull
public static String getLocalFilePath(@NotNull String scriptPath) throws CantRunException {
if (isMemoryScriptPath(scriptPath)) {
File tmpFile = copyToTempFile(scriptPath);
return tmpFile.getAbsolutePath();
}
if (SystemInfo.isWindows) {
return PathUtil.driveLetterToLowerCase(scriptPath);
}
return scriptPath;
}
@NotNull
public static File copyToTempFile(@NotNull String path) throws CantRunException {
VirtualFile virtualFile = findScriptFileByPath(path);
if (virtualFile == null) {
throw new CantRunException("File not found: " + path);
}
File ioFile;
try {
ioFile = FileUtil.createTempFile(virtualFile.getName(), "", true);
}
catch (IOException e) {
throw new CantRunException("Cannot create temporary file " + virtualFile.getName(), e);
}
try {
copyFile(virtualFile, ioFile);
return ioFile;
}
catch (IOException e) {
throw new CantRunException("Cannot write temp file " + virtualFile.getPath() + " to " + ioFile.getAbsolutePath(), e);
}
}
private static void copyFile(@NotNull VirtualFile srcFile, @NotNull File destFile) throws IOException {
LOG.info("Copying to " + destFile.getPath());
CharSequence content = getContent(srcFile);
CharBuffer cb = CharBuffer.wrap(content);
ByteBuffer bb = CharsetToolkit.UTF8_CHARSET.encode(cb);
byte[] result = new byte[bb.remaining()];
bb.get(result);
FileUtil.writeToFile(destFile, result, false);
}
@NotNull
private static CharSequence getContent(@NotNull VirtualFile file) {
Document document = FileDocumentManager.getInstance().getCachedDocument(file);
if (document != null) {
return document.getText();
}
return LoadTextUtil.loadText(file);
}
}
@@ -22,12 +22,14 @@ import com.intellij.execution.Executor;
import com.intellij.execution.configurations.JavaParameters;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.runners.ExecutionUtil;
import com.intellij.execution.util.ScriptFileUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.ClasspathEditor;
import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.encoding.EncodingManager;
@@ -77,7 +79,8 @@ public class DefaultGroovyScriptRunner extends GroovyScriptRunner {
params.getProgramParametersList().add("--debug");
}
params.getProgramParametersList().add(FileUtil.toSystemDependentName(configuration.getScriptPath()));
String path = ScriptFileUtil.getLocalFilePath(StringUtil.notNullize(configuration.getScriptPath()));
params.getProgramParametersList().add(FileUtil.toSystemDependentName(path));
params.getProgramParametersList().addParametersString(configuration.getScriptParameters());
}
@@ -22,6 +22,7 @@ import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.util.ProgramParametersUtil;
import com.intellij.execution.util.ScriptFileUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PathMacroManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -37,8 +38,6 @@ import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizer;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.PsiClass;
@@ -47,8 +46,10 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.refactoring.listeners.RefactoringElementAdapter;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.util.ObjectUtils;
import com.intellij.util.PathUtil;
import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.hash.LinkedHashMap;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
@@ -175,7 +176,7 @@ public class GroovyScriptRunConfiguration extends ModuleBasedConfiguration<RunCo
throw new CantRunException("Unknown script type " + scriptPath);
}
final Module module = getModule();
final Module module = ObjectUtils.chooseNotNull(getModule(), ContainerUtil.getFirstItem(getValidModules()));
if (!scriptRunner.ensureRunnerConfigured(module, this, executor, getProject())) {
return null;
}
@@ -231,7 +232,7 @@ public class GroovyScriptRunConfiguration extends ModuleBasedConfiguration<RunCo
protected void elementRenamedOrMoved(@NotNull PsiElement newElement) {
if (newElement instanceof GroovyFile) {
GroovyFile file = (GroovyFile)newElement;
setScriptPath(file.getVirtualFile().getPath());
setScriptPath(ScriptFileUtil.getScriptFilePath(file.getVirtualFile()));
}
}
@@ -284,8 +285,7 @@ public class GroovyScriptRunConfiguration extends ModuleBasedConfiguration<RunCo
@Nullable
private VirtualFile getScriptFile() {
if (scriptPath == null) return null;
return LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(scriptPath));
return ScriptFileUtil.findScriptFileByPath(scriptPath);
}
@Nullable
@@ -25,8 +25,10 @@ import com.intellij.execution.application.ApplicationConfigurationProducer;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.configurations.RunConfigurationModule;
import com.intellij.execution.junit.RuntimeConfigurationProducer;
import com.intellij.execution.util.ScriptFileUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
@@ -100,7 +102,7 @@ public class GroovyScriptRunConfigurationProducer extends RuntimeConfigurationPr
final PsiFile file = location.getPsiElement().getContainingFile();
if (file instanceof GroovyFile) {
final VirtualFile vfile = file.getVirtualFile();
if (vfile != null && FileUtil.toSystemIndependentName(path).equals(vfile.getPath())) {
if (vfile != null && FileUtil.toSystemIndependentName(path).equals(ScriptFileUtil.getScriptFilePath(vfile))) {
if (!((GroovyFile)file).isScript() ||
GroovyScriptUtil.getScriptType((GroovyFile)file).isConfigurationByLocation(existing, location)) {
return existingConfiguration;
@@ -127,15 +129,17 @@ public class GroovyScriptRunConfigurationProducer extends RuntimeConfigurationPr
final GroovyScriptRunConfiguration configuration = (GroovyScriptRunConfiguration)settings.getConfiguration();
final PsiFile file = aClass.getContainingFile().getOriginalFile();
final PsiDirectory dir = file.getContainingDirectory();
if (dir == null) return null;
configuration.setWorkDir(dir.getVirtualFile().getPath());
if (dir != null) {
configuration.setWorkDir(dir.getVirtualFile().getPath());
}
final VirtualFile vFile = file.getVirtualFile();
if (vFile == null) return null;
configuration.setScriptPath(vFile.getPath());
String path = ScriptFileUtil.getScriptFilePath(vFile);
configuration.setScriptPath(path);
RunConfigurationModule module = configuration.getConfigurationModule();
String name = GroovyRunnerUtil.getConfigurationName(aClass, module);
configuration.setName(name);
configuration.setName(StringUtil.isEmpty(name) ? vFile.getName() : name);
configuration.setModule(JavaExecutionUtil.findModule(aClass));
return settings;
}