mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-08 06:39:38 +07:00
WEB-38925 support file watchers and external tools in WSL
We evaluate an executable path first and if it is in WSL, evaluate all subsequent macro with a converter transforming windows paths into wsl paths and run the command in wsl instead of windows. (cherry picked from commit 4ffaa5443a8ac8509537d771eb97c37d43bb2272) IJ-CR-15447 GitOrigin-RevId: e6b492dcd4ffad54bb572ddab49a94562a724592
This commit is contained in:
committed by
intellij-monorepo-bot
parent
30d0fd71ad
commit
46d7d180f1
@@ -0,0 +1,43 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.execution.wsl;
|
||||
|
||||
import com.intellij.ide.macro.MacroPathConverter;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.util.text.Strings;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public class WslMacroPathConverter implements MacroPathConverter {
|
||||
private static final Logger LOG = Logger.getInstance(WslMacroPathConverter.class);
|
||||
|
||||
private final WSLDistribution myWsl;
|
||||
|
||||
public WslMacroPathConverter(@NotNull WSLDistribution wsl) {
|
||||
myWsl = wsl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String convertPath(@NotNull String path) {
|
||||
try {
|
||||
String converted = myWsl.getWslPath(path);
|
||||
return converted != null ? converted : path;
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
LOG.warn("Failed to convert to path: " + path, e);
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String convertPathList(@NotNull String pathList) {
|
||||
List<String> paths = StringUtil.split(pathList, File.pathSeparator);
|
||||
return Strings.join(ContainerUtil.map(paths, p -> convertPath(p)), ":");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,11 +12,17 @@ import com.intellij.execution.runners.ExecutionEnvironmentBuilder;
|
||||
import com.intellij.execution.runners.ProgramRunner;
|
||||
import com.intellij.execution.ui.RunContentDescriptor;
|
||||
import com.intellij.execution.util.ExecutionErrorDialog;
|
||||
import com.intellij.execution.wsl.WSLCommandLineOptions;
|
||||
import com.intellij.execution.wsl.WSLDistribution;
|
||||
import com.intellij.execution.wsl.WslMacroPathConverter;
|
||||
import com.intellij.execution.wsl.WslPath;
|
||||
import com.intellij.ide.macro.Macro;
|
||||
import com.intellij.ide.macro.MacroManager;
|
||||
import com.intellij.ide.macro.MacroPathConverter;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.options.SchemeElement;
|
||||
@@ -25,15 +31,14 @@ import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.execution.ParametersListUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
|
||||
public class Tool implements SchemeElement {
|
||||
private static final Logger LOG = Logger.getInstance(Tool.class);
|
||||
@@ -334,9 +339,19 @@ public class Tool implements SchemeElement {
|
||||
? new PtyCommandLine().withConsoleMode(true)
|
||||
: new GeneralCommandLine();
|
||||
try {
|
||||
String exePath = MacroManager.getInstance().expandMacrosInString(getProgram(), true, dataContext);
|
||||
exePath = MacroManager.getInstance().expandMacrosInString(exePath, false, dataContext);
|
||||
if (exePath == null) return null;
|
||||
|
||||
WSLDistribution wsl = WslPath.getDistributionByWindowsUncPath(exePath);
|
||||
MacroPathConverter pathConverter = null;
|
||||
if (wsl != null) {
|
||||
pathConverter = new WslMacroPathConverter(wsl);
|
||||
dataContext = SimpleDataContext.getSimpleContext(MacroManager.PATH_CONVERTER_KEY, pathConverter, dataContext);
|
||||
}
|
||||
|
||||
String paramString = MacroManager.getInstance().expandMacrosInString(getParameters(), true, dataContext);
|
||||
String workingDir = MacroManager.getInstance().expandMacrosInString(getWorkingDirectory(), true, dataContext);
|
||||
String exePath = MacroManager.getInstance().expandMacrosInString(getProgram(), true, dataContext);
|
||||
|
||||
commandLine.getParametersList().addParametersString(
|
||||
MacroManager.getInstance().expandMacrosInString(paramString, false, dataContext));
|
||||
@@ -344,14 +359,21 @@ public class Tool implements SchemeElement {
|
||||
if (!StringUtil.isEmpty(workDirExpanded)) {
|
||||
commandLine.setWorkDirectory(workDirExpanded);
|
||||
}
|
||||
exePath = MacroManager.getInstance().expandMacrosInString(exePath, false, dataContext);
|
||||
if (exePath == null) return null;
|
||||
|
||||
File exeFile = new File(exePath);
|
||||
if (exeFile.isDirectory() && exeFile.getName().endsWith(".app")) {
|
||||
commandLine.setExePath("open");
|
||||
commandLine.getParametersList().prependAll("-a", exePath);
|
||||
}
|
||||
else if (wsl != null) {
|
||||
try {
|
||||
commandLine = createWslCommandLine(CommonDataKeys.PROJECT.getData(dataContext), wsl, commandLine, workDirExpanded,
|
||||
pathConverter.convertPath(exePath));
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
LOG.error("Failed to create wsl command line", e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
commandLine.setExePath(exePath);
|
||||
}
|
||||
@@ -388,4 +410,22 @@ public class Tool implements SchemeElement {
|
||||
public String getActionIdPrefix() {
|
||||
return ACTION_ID_PREFIX;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static GeneralCommandLine createWslCommandLine(@Nullable Project project,
|
||||
@NotNull WSLDistribution wsl,
|
||||
@NotNull GeneralCommandLine cmd,
|
||||
@Nullable String linuxWorkingDir,
|
||||
@NotNull String windowsExePath) throws ExecutionException {
|
||||
cmd.setExePath(windowsExePath);
|
||||
WSLCommandLineOptions wslOptions = new WSLCommandLineOptions();
|
||||
if (StringUtil.isNotEmpty(linuxWorkingDir)) {
|
||||
wslOptions.setRemoteWorkingDirectory(linuxWorkingDir);
|
||||
}
|
||||
// Working directory as well as all parameters were computed with MacroPathConverter, so they are
|
||||
// paths in linux. Reset working directory in command line, because linux directory is not valid
|
||||
// in windows, and we will fail to start process with it.
|
||||
cmd.setWorkDirectory((String)null);
|
||||
return wsl.patchCommandLine(cmd, project, wslOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.macro.Macro.ExecutionCancelledException;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.DataKey;
|
||||
import com.intellij.openapi.actionSystem.PlatformCoreDataKeys;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
@@ -27,6 +28,8 @@ public final class MacroManager {
|
||||
|
||||
private static final Pattern MACRO_PATTERN = Pattern.compile("\\$.+\\$");
|
||||
|
||||
public static final DataKey<MacroPathConverter> PATH_CONVERTER_KEY = DataKey.create("MacroPathConverter");
|
||||
|
||||
public static MacroManager getInstance() {
|
||||
return ApplicationManager.getApplication().getService(MacroManager.class);
|
||||
}
|
||||
@@ -180,6 +183,7 @@ public final class MacroManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
MacroPathConverter converter = dataContext.getData(PATH_CONVERTER_KEY);
|
||||
while (macros.hasNext()) {
|
||||
Macro macro = macros.next();
|
||||
if (macro instanceof SecondQueueExpandMacro && firstQueueExpand) continue;
|
||||
@@ -199,6 +203,7 @@ public final class MacroManager {
|
||||
if (expanded == null) {
|
||||
return null;
|
||||
}
|
||||
expanded = convertPathIfNeeded(converter, macro, expanded);
|
||||
str = str.substring(0, index) + expanded + str.substring(index + name.length());
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
index += expanded.length();
|
||||
@@ -220,6 +225,7 @@ public final class MacroManager {
|
||||
if (expanded == null) {
|
||||
return null;
|
||||
}
|
||||
expanded = convertPathIfNeeded(converter, macro, expanded);
|
||||
toReplace.put(macroNameWithParamStart + param + macroNameWithParamEnd, expanded);
|
||||
i = j + macroNameWithParamEnd.length();
|
||||
}
|
||||
@@ -236,4 +242,17 @@ public final class MacroManager {
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
private static String convertPathIfNeeded(@Nullable MacroPathConverter converter, @NotNull Macro macro, @NotNull String expandedValue) {
|
||||
if (converter == null) {
|
||||
return expandedValue;
|
||||
}
|
||||
if (macro instanceof PathMacro) {
|
||||
return converter.convertPath(expandedValue);
|
||||
}
|
||||
if (macro instanceof PathListMacro) {
|
||||
return converter.convertPathList(expandedValue);
|
||||
}
|
||||
return expandedValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ide.macro;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Converts paths and path lists produced by macros.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public interface MacroPathConverter {
|
||||
@NotNull
|
||||
String convertPath(@NotNull String path);
|
||||
|
||||
@NotNull
|
||||
String convertPathList(@NotNull String pathList);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ide.macro;
|
||||
|
||||
/**
|
||||
* Marker interface for {@link Macro} returning a list of paths concatenated with {@link java.io.File#pathSeparator}
|
||||
*/
|
||||
public interface PathListMacro {
|
||||
}
|
||||
8
platform/macro/src/com/intellij/ide/macro/PathMacro.java
Normal file
8
platform/macro/src/com/intellij/ide/macro/PathMacro.java
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ide.macro;
|
||||
|
||||
/**
|
||||
* Marker interface for {@link Macro} returning a file path
|
||||
*/
|
||||
public interface PathMacro {
|
||||
}
|
||||
Reference in New Issue
Block a user