mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Startup scripts: cleanup
This commit is contained in:
@@ -152,11 +152,12 @@ public class ExtensionsRootType extends RootType {
|
||||
private File findExtensionsDirectoryImpl(@NotNull PluginId pluginId, @NotNull String path, boolean createIfMissing) throws IOException {
|
||||
String fullPath = getPath(pluginId, path);
|
||||
File dir = new File(FileUtil.toSystemDependentName(fullPath));
|
||||
if (createIfMissing && !dir.exists()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
dir.mkdirs();
|
||||
if (createIfMissing && !dir.exists() && !dir.mkdirs()) {
|
||||
throw new IOException("Failed to create directory: " + dir.getPath());
|
||||
}
|
||||
return dir.exists() && dir.isDirectory()? dir : null;
|
||||
if (!dir.exists()) return null;
|
||||
if (!dir.isDirectory()) throw new IOException("Not a directory: " + dir.getPath());
|
||||
return dir;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.PluginId;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.project.ProjectManagerAdapter;
|
||||
@@ -30,7 +31,6 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -41,157 +41,128 @@ import org.jetbrains.ide.script.IdeScriptEngineManager;
|
||||
import org.jetbrains.ide.script.IdeScriptException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
class IdeStartupScripts extends ApplicationComponent.Adapter {
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private static String SCRIPT_DIR_NAME = "startup";
|
||||
|
||||
private static Logger LOG = Logger.getInstance(IdeStartupScripts.class);
|
||||
private static final Logger LOG = Logger.getInstance(IdeStartupScripts.class);
|
||||
private static final String SCRIPT_DIR_NAME = "startup";
|
||||
|
||||
@Override
|
||||
public void initComponent() {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
return;
|
||||
}
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) return;
|
||||
|
||||
List<VirtualFile> scripts = getScripts();
|
||||
if (scripts.isEmpty()) {
|
||||
LOG.debug("No startup scripts detected");
|
||||
}
|
||||
else {
|
||||
scheduleStartupScriptsExecution(scripts);
|
||||
}
|
||||
scheduleStartupScriptsExecution();
|
||||
}
|
||||
|
||||
private static void scheduleStartupScriptsExecution(@NotNull List<VirtualFile> scripts) {
|
||||
private static void scheduleStartupScriptsExecution() {
|
||||
List<VirtualFile> scripts = getScripts();
|
||||
LOG.info(scripts.size() + " startup script(s) found");
|
||||
if (scripts.isEmpty()) return;
|
||||
|
||||
final Future<List<Pair<VirtualFile, IdeScriptEngine>>> scriptsAndEnginesFuture = prepareScriptEnginesAsync(scripts);
|
||||
ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerAdapter() {
|
||||
private final AtomicBoolean myScriptsExecutionStarted = new AtomicBoolean();
|
||||
final AtomicBoolean myScriptsExecutionStarted = new AtomicBoolean();
|
||||
|
||||
@Override
|
||||
public void projectOpened(final Project project) {
|
||||
StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myScriptsExecutionStarted.compareAndSet(false, true)) {
|
||||
executeScriptsAndDispose(project);
|
||||
}
|
||||
}
|
||||
StartupManager.getInstance(project).runWhenProjectIsInitialized(() -> {
|
||||
if (project.isDisposed()) return;
|
||||
if (!myScriptsExecutionStarted.compareAndSet(false, true)) return;
|
||||
ProjectManager.getInstance().removeProjectManagerListener(this);
|
||||
runAllScriptsImpl(project);
|
||||
});
|
||||
}
|
||||
|
||||
private void executeScriptsAndDispose(@NotNull Project project) {
|
||||
for (Pair<VirtualFile, IdeScriptEngine> scriptAndEngine : getScriptsAndEngines()) {
|
||||
executeScript(project.isDisposed() ? null : project, scriptAndEngine.first, scriptAndEngine.second);
|
||||
}
|
||||
ProjectManager.getInstance().removeProjectManagerListener(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<Pair<VirtualFile, IdeScriptEngine>> getScriptsAndEngines() {
|
||||
private void runAllScriptsImpl(@NotNull Project project) {
|
||||
try {
|
||||
return scriptsAndEnginesFuture.get();
|
||||
for (Pair<VirtualFile, IdeScriptEngine> pair : scriptsAndEnginesFuture.get()) {
|
||||
try {
|
||||
if (pair.second == null) {
|
||||
LOG.warn(pair.first.getPath() + " not supported (no script engine)");
|
||||
}
|
||||
else {
|
||||
runImpl(project, pair.first, pair.second);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
LOG.warn("... cancelled");
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
LOG.info("Script engines initialization cancelled");
|
||||
LOG.warn("... interrupted");
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
LOG.error("Failed to initialize script engines", e);
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
return ContainerUtil.emptyList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Future<List<Pair<VirtualFile, IdeScriptEngine>>> prepareScriptEnginesAsync(@NotNull final List<VirtualFile> scripts) {
|
||||
return PooledThreadExecutor.INSTANCE.submit(new Callable<List<Pair<VirtualFile, IdeScriptEngine>>>() {
|
||||
@Override
|
||||
public List<Pair<VirtualFile, IdeScriptEngine>> call() throws Exception {
|
||||
return prepareScriptEngines(scripts);
|
||||
}
|
||||
});
|
||||
return PooledThreadExecutor.INSTANCE.submit(() -> prepareScriptEngines(scripts));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<Pair<VirtualFile, IdeScriptEngine>> prepareScriptEngines(@NotNull final List<VirtualFile> scripts) {
|
||||
final IdeScriptEngineManager scriptEngineManager = IdeScriptEngineManager.getInstance();
|
||||
return ContainerUtil.map(scripts, new Function<VirtualFile, Pair<VirtualFile, IdeScriptEngine>>() {
|
||||
@Override
|
||||
public Pair<VirtualFile, IdeScriptEngine> fun(VirtualFile script) {
|
||||
String extension = script.getExtension();
|
||||
return Pair.create(script, extension != null ? scriptEngineManager.getEngineForFileExtension(extension, null) : null);
|
||||
}
|
||||
});
|
||||
private static List<Pair<VirtualFile, IdeScriptEngine>> prepareScriptEngines(@NotNull List<VirtualFile> scripts) {
|
||||
IdeScriptEngineManager scriptEngineManager = IdeScriptEngineManager.getInstance();
|
||||
List<Pair<VirtualFile, IdeScriptEngine>> result = ContainerUtil.newArrayList();
|
||||
for (VirtualFile script : scripts) {
|
||||
String extension = script.getExtension();
|
||||
IdeScriptEngine engine = extension != null ? scriptEngineManager.getEngineForFileExtension(extension, null) : null;
|
||||
result.add(Pair.create(script, engine));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void executeScript(@Nullable Project project, @NotNull VirtualFile script, @Nullable IdeScriptEngine scriptEngine) {
|
||||
if (scriptEngine == null) {
|
||||
LOG.warn("No script engine found for script: " + script.getPath());
|
||||
return;
|
||||
}
|
||||
|
||||
String scriptText;
|
||||
try {
|
||||
scriptText = VfsUtilCore.loadText(script);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.warn("Cannot load script: " + script.getPath(), e);
|
||||
return;
|
||||
}
|
||||
|
||||
IdeScriptBindings.ensureIdeIsBound(project, scriptEngine);
|
||||
private static void runImpl(@NotNull Project project,
|
||||
@NotNull VirtualFile script,
|
||||
@NotNull IdeScriptEngine engine) throws ExecutionException, IOException, IdeScriptException {
|
||||
String scriptText = VfsUtilCore.loadText(script);
|
||||
IdeScriptBindings.ensureIdeIsBound(project, engine);
|
||||
|
||||
LOG.info(script.getPath());
|
||||
long start = System.currentTimeMillis();
|
||||
try {
|
||||
LOG.info("Running script: " + script.getPath());
|
||||
scriptEngine.eval(scriptText);
|
||||
}
|
||||
catch (IdeScriptException e) {
|
||||
LOG.error("Error in script: " + script.getPath(), e);
|
||||
engine.eval(scriptText);
|
||||
}
|
||||
finally {
|
||||
long end = System.currentTimeMillis();
|
||||
LOG.info(script.getPath() + " completed in " + (end - start) + " ms");
|
||||
LOG.info("... completed in " + StringUtil.formatDuration(System.currentTimeMillis() - start));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<VirtualFile> getScripts() {
|
||||
VirtualFile root = getScriptsRootDirectory();
|
||||
VirtualFile root = null;
|
||||
try {
|
||||
root = getScriptsRootDirectory();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.warn(e);
|
||||
}
|
||||
if (root == null) return ContainerUtil.emptyList();
|
||||
|
||||
VfsUtil.markDirtyAndRefresh(false, true, true, root);
|
||||
List<VirtualFile> scripts = VfsUtil.collectChildrenRecursively(root);
|
||||
scripts = ContainerUtil.filter(scripts, ExtensionsRootType.regularFileFilter());
|
||||
ContainerUtil.sort(scripts, new FileNameComparator());
|
||||
ContainerUtil.sort(scripts, (f1, f2) -> {
|
||||
String f1Name = f1 != null ? f1.getName() : null;
|
||||
String f2Name = f2 != null ? f2.getName() : null;
|
||||
return StringUtil.compare(f1Name, f2Name, false);
|
||||
});
|
||||
return scripts;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static VirtualFile getScriptsRootDirectory() {
|
||||
try {
|
||||
PluginId corePlugin = ObjectUtils.assertNotNull(PluginId.findId(PluginManagerCore.CORE_PLUGIN_ID));
|
||||
return ExtensionsRootType.getInstance().findResourceDirectory(corePlugin, SCRIPT_DIR_NAME, false);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.warn("Failed to open/create startup scripts directory", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class FileNameComparator implements Comparator<VirtualFile> {
|
||||
@Override
|
||||
public int compare(VirtualFile f1, VirtualFile f2) {
|
||||
String f1Name = f1 != null ? f1.getName() : null;
|
||||
String f2Name = f2 != null ? f2.getName() : null;
|
||||
return StringUtil.compare(f1Name, f2Name, false);
|
||||
}
|
||||
private static VirtualFile getScriptsRootDirectory() throws IOException {
|
||||
PluginId corePlugin = ObjectUtils.assertNotNull(PluginId.findId(PluginManagerCore.CORE_PLUGIN_ID));
|
||||
return ExtensionsRootType.getInstance().findResourceDirectory(corePlugin, SCRIPT_DIR_NAME, false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user