Refactoring AbstractWslDistribution: Use Path instead of String for Windows path.

Local paths should always be represented as VFS or nio `Path`, since `String` doesn't have any semantic: is it local or remote path? Is it trimmed or might contain spaces etc

GitOrigin-RevId: 5dc0e003b9cd9b68be656557ba1bde6727b5fd0f
This commit is contained in:
Ilya.Kazakevich
2023-11-01 22:34:17 +01:00
committed by intellij-monorepo-bot
parent ff01580815
commit ac05f290c3
19 changed files with 49 additions and 32 deletions

View File

@@ -104,7 +104,7 @@ final class WslBuildCommandLineBuilder implements BuildCommandLineBuilder {
myProgressIndicator.setText(JavaCompilerBundle.message("progress.preparing.wsl.build.environment"));
myReportedProgress = true;
}
builder.append(myDistribution.getWslPath(targetPath.toString()));
builder.append(myDistribution.getWslPath(targetPath));
}
}
for (String s : classpathInTarget) {

View File

@@ -10,7 +10,7 @@ import kotlin.io.path.pathString
* Win drives -> /mnt
*/
val WSLDistribution.rootMappings: List<PathMappingSettings.PathMapping>
get() = listWindowsLocalDriveRoots().map { PathMappingSettings.PathMapping(it.pathString, getWslPath(it.pathString)) } + listOf(
get() = listWindowsLocalDriveRoots().map { PathMappingSettings.PathMapping(it.pathString, getWslPath(it)) } + listOf(
PathMappingSettings.PathMapping(getWindowsPath("/"), "/")
)

View File

@@ -39,7 +39,7 @@ class WslTargetEnvironmentConfiguration() : TargetConfigurationWithId(WslTargetT
override fun getTargetPathIfLocalPathIsOnTarget(probablyPathOnTarget: Path): FullPathOnTarget? {
if (probablyPathOnTarget.root in listWindowsLocalDriveRoots()) return null
if (!probablyPathOnTarget.pathString.startsWith("\\\\wsl")) return null
return distribution!!.getWslPath(probablyPathOnTarget.pathString)
return distribution!!.getWslPath(probablyPathOnTarget)
}
override fun getState() = MyState().also {

View File

@@ -16,7 +16,7 @@ interface AbstractWslDistribution {
* @return Linux path for a file pointed by `windowsPath` or null if unavailable, like \\MACHINE\path
*/
@NlsSafe
fun getWslPath(windowsPath: String): String?
fun getWslPath(windowsPath: Path): String?
/**
* Patches passed command line to make it runnable in WSL context, e.g changes `date` to `ubuntu run "date"`.

View File

@@ -94,7 +94,7 @@ class JdkInstaller : JdkInstallerBase() {
private fun wrap(d: WSLDistribution) = WSLDistributionForJdkInstallerImpl(d)
private class WSLDistributionForJdkInstallerImpl(val d: WSLDistribution) : WSLDistributionForJdkInstaller {
override fun getWslPath(path: Path): String = d.getWslPath(path.toString()) ?: error("Failed to map $path to WSL")
override fun getWslPath(path: Path): String = d.getWslPath(path) ?: error("Failed to map $path to WSL")
override fun executeOnWsl(command: List<String>, dir: String, timeout: Int): ProcessOutput {
return d.executeOnWsl(command, WSLCommandLineOptions().setRemoteWorkingDirectory(dir), timeout, null)

View File

@@ -530,9 +530,17 @@ public class WSLDistribution implements AbstractWslDistribution {
return false;
}
/**
* @deprecated Use {@link #getWslPath(Path)}
*/
@Deprecated
public final @Nullable String getWslPath(@NotNull @NlsSafe String windowsPath) {
return getWslPath(Path.of(windowsPath));
}
@Override
public @Nullable @NlsSafe String getWslPath(@NotNull String windowsPath) {
WslPath wslPath = WslPath.parseWindowsUncPath(windowsPath);
public @Nullable @NlsSafe String getWslPath(@NotNull Path windowsPath) {
WslPath wslPath = WslPath.parseWindowsUncPath(windowsPath.toString());
if (wslPath != null) {
if (wslPath.getDistributionId().equalsIgnoreCase(myDescriptor.getMsId())) {
return wslPath.getLinuxPath();
@@ -542,8 +550,8 @@ public class WSLDistribution implements AbstractWslDistribution {
", but context distribution is " + myDescriptor.getMsId());
}
if (OSAgnosticPathUtil.isAbsoluteDosPath(windowsPath)) { // absolute windows path => /mnt/disk_letter/path
return getMntRoot() + convertWindowsPath(windowsPath);
if (OSAgnosticPathUtil.isAbsoluteDosPath(windowsPath.toString())) { // absolute windows path => /mnt/disk_letter/path
return getMntRoot() + convertWindowsPath(windowsPath.toString());
}
return null;
}
@@ -731,7 +739,8 @@ public class WSLDistribution implements AbstractWslDistribution {
WSLCommandLineOptions options = new WSLCommandLineOptions()
.setExecuteCommandInInteractiveShell(true)
.setExecuteCommandInLoginShell(true);
return WslExecution.executeInShellAndGetCommandOnlyStdout(this, new GeneralCommandLine("printenv", name), options.setLaunchWithWslExe(true), DEFAULT_TIMEOUT,
return WslExecution.executeInShellAndGetCommandOnlyStdout(this, new GeneralCommandLine("printenv", name),
options.setLaunchWithWslExe(true), DEFAULT_TIMEOUT,
true);
}

View File

@@ -58,14 +58,14 @@ public final class WSLDistributionLegacy extends WSLDistribution {
}
@Override
public @Nullable String getWslPath(@NotNull String windowsPath) {
public @Nullable String getWslPath(@NotNull Path windowsPath) {
String wslRootInHost = WSL_ROOT_IN_WINDOWS_PROVIDER.getValue();
if (wslRootInHost == null) {
return null;
}
if (FileUtil.isAncestor(wslRootInHost, windowsPath, true)) { // this is some internal WSL file
return FileUtil.toSystemIndependentName(windowsPath.substring(wslRootInHost.length()));
if (FileUtil.isAncestor(wslRootInHost, windowsPath.toString(), true)) { // this is some internal WSL file
return FileUtil.toSystemIndependentName(windowsPath.toString().substring(wslRootInHost.length()));
}
return super.getWslPath(windowsPath);

View File

@@ -63,7 +63,7 @@ class WslIjentManager private constructor(private val scope: CoroutineScope) {
args = *command.toList().drop(1).toTypedArray(),
env = processBuilder.environment(),
pty = pty,
workingDirectory = processBuilder.directory()?.let { wslDistribution.getWslPath(it.path) }
workingDirectory = processBuilder.directory()?.let { wslDistribution.getWslPath(it.toPath()) }
)) {
is IjentApi.ExecuteProcessResult.Success -> processResult.process.toProcess(pty != null)
is IjentApi.ExecuteProcessResult.Failure -> throw IOException(processResult.message)
@@ -145,7 +145,7 @@ suspend fun deployAndLaunchIjentGettingPath(
val targetPlatform = IjentExecFileProvider.SupportedPlatform.X86_64__LINUX
val ijentBinary = IjentExecFileProvider.getIjentBinary(targetPlatform)
val wslIjentBinary = wslDistribution.getWslPath(ijentBinary.absolutePathString())!!
val wslIjentBinary = wslDistribution.getWslPath(ijentBinary.toAbsolutePath())!!
val commandLine = GeneralCommandLine(
// It's supposed that WslDistribution always converts commands into SHELL.

View File

@@ -36,6 +36,6 @@ fun browseWslPath(linuxPathField: TextAccessor,
}
val dialog = FileChooserDialogImpl(descriptor, parent)
val files = if (windowsPath != null) dialog.choose(null, windowsPath) else dialog.choose(null)
val linuxPath = files.firstOrNull()?.let { distro.getWslPath(it.path) } ?: return
val linuxPath = files.firstOrNull()?.let { distro.getWslPath(it.toNioPath()) } ?: return
linuxPathField.text = linuxPath
}

View File

@@ -209,7 +209,7 @@ public final class WSLCommandEscapingTest {
}
private void assertPwdOutputInDirectory(String directoryName) throws ExecutionException {
String path = wslRule.getWsl().getWslPath(myTempDirectory.newDirectory(directoryName).getPath());
String path = wslRule.getWsl().getWslPath(myTempDirectory.newDirectory(directoryName).toPath());
assertWslCommandOutput(path + "\n", path, Collections.emptyMap(), List.of("pwd"));
}
@@ -249,7 +249,7 @@ public final class WSLCommandEscapingTest {
private String createEchoScriptAndGetLinuxPath(String executableName) {
File file = myTempDirectory.newFile(executableName + ".sh", "#!/bin/sh\necho \"$@\"".getBytes(StandardCharsets.UTF_8));
String wslPath = wslRule.getWsl().getWslPath(file.getPath());
String wslPath = wslRule.getWsl().getWslPath(file.toPath());
assertNotNull("local path: " + file, wslPath);
return wslPath;
}

View File

@@ -5,17 +5,25 @@ import com.intellij.execution.processTools.ProcessExistedNotZeroException
import com.intellij.openapi.application.PathManager
import java.nio.file.Path
internal fun AbstractWslDistribution.getWslPath(path: Path): String = getWslPath(path.toString())
?: throw Exception("Can't access from Linux: $path")
/**
* throws exception instead of null
*/
internal fun AbstractWslDistribution.getWslPathSafe(path: Path): String = getWslPath(path)
?: throw Exception("Can't access from Linux: $path")
/**
* How Linux can access tool from IJ "bin" folder
*/
internal fun AbstractWslDistribution.getToolLinuxPath(toolName: String): String =
getWslPathSafe(PathManager.findBinFileWithException(toolName))
internal fun AbstractWslDistribution.getTool(toolName: String, vararg arguments: String): GeneralCommandLine {
val toolOnWindows = PathManager.findBinFileWithException(toolName)
val toolOnLinux = getWslPath(toolOnWindows)
val toolOnLinux = getToolLinuxPath(toolName)
try {
runCommand("test", "-x", toolOnLinux)
}
catch (e: ProcessExistedNotZeroException) {
throw Exception("File is not executable: $toolOnLinux ($toolOnWindows)", e)
throw Exception("File is not executable: $toolOnLinux", e)
}
return createWslCommandLine(toolOnLinux, *arguments)
}

View File

@@ -114,7 +114,7 @@ class LinuxFileStorage(dir: LinuxFilePath, distro: AbstractWslDistribution)
listFile.first.delete()
LOGGER.info("Copying tar")
distro.runCommand("cp", linuxTarFile, distro.getWslPath(destTar))
distro.runCommand("cp", linuxTarFile, distro.getWslPathSafe(destTar))
distro.runCommand("rm", linuxTarFile)
}

View File

@@ -2,7 +2,7 @@
package com.intellij.execution.wsl.sync
import com.intellij.execution.wsl.AbstractWslDistribution
import com.intellij.execution.wsl.getWslPath
import com.intellij.execution.wsl.getWslPathSafe
import io.ktor.util.toLowerCasePreservingASCIIRules
import java.nio.file.Files
import java.nio.file.Path
@@ -46,5 +46,5 @@ internal const val AVG_NUM_FILES = 10_000
internal fun createTmpWinFile(distro: AbstractWslDistribution): Pair<WindowsFilePath, LinuxFilePath> {
val file = Files.createTempFile("intellij", "tmp")
return Pair(file, distro.getWslPath(file))
return Pair(file, distro.getWslPathSafe(file))
}

View File

@@ -105,7 +105,7 @@ sealed class GitExecutable {
val path = file.absolutePath
// 'C:\Users\file.txt' -> '/mnt/c/Users/file.txt'
val wslPath = distribution.getWslPath(path)
val wslPath = distribution.getWslPath(file.toPath().toAbsolutePath())
return wslPath ?: path
}

View File

@@ -165,7 +165,7 @@ public class GradlePositionManager extends ScriptPositionManagerHelper {
private static TextResource getWslUriResource(@NotNull File scriptFile) {
WSLDistribution wslDistribution = WslPath.getDistributionByWindowsUncPath(scriptFile.getPath());
if (wslDistribution == null) return null;
String wslPath = wslDistribution.getWslPath(scriptFile.getPath());
String wslPath = wslDistribution.getWslPath(scriptFile.toPath());
if (wslPath == null) return null;
return new UriTextResource("script", pathToUri(wslPath), new IdentityFileResolver());
}

View File

@@ -441,7 +441,7 @@ public class MavenRunConfiguration extends LocatableConfigurationBase implements
MavenDistribution mavenDistribution =
MavenDistributionsCache.getInstance(myConfiguration.getProject()).getMavenDistribution(myConfiguration.getRunnerParameters()
.getWorkingDirPath());
String mavenHome = StringUtil.notNullize(config.getDistribution().getWslPath(mavenDistribution.getMavenHome().toString()));
String mavenHome = StringUtil.notNullize(config.getDistribution().getWslPath(mavenDistribution.getMavenHome()));
String mavenVersion = StringUtil.notNullize(mavenDistribution.getVersion());
MavenRuntimeTargetConfiguration mavenConfig = new MavenRuntimeTargetConfiguration();

View File

@@ -68,7 +68,7 @@ class MavenWslTargetConfigurator : MavenImporter("", ""),
val mavenPath = wslDistribution.collectWslMavenDirectories()
.firstOrNull()?.let { MavenUtil.getMavenHomeFile(it) }
dataHolder.putUserData(MAVEN_HOME_DIR, mavenPath)
val targetMavenPath = mavenPath?.let { wslDistribution.getWslPath(it.path) }
val targetMavenPath = mavenPath?.let { wslDistribution.getWslPath(it.toPath()) }
dataHolder.putUserData(MAVEN_TARGET_PATH, targetMavenPath)
val mavenVersion = MavenUtil.getMavenVersion(mavenPath)
dataHolder.putUserData(MAVEN_HOME_VERSION, mavenVersion)

View File

@@ -30,7 +30,7 @@ class WslMavenRemoteProcessSupportFactory : MavenRemoteProcessSupportFactory {
private fun toWslMavenDistribution(mavenDistribution: MavenDistribution, wslDistribution: WSLDistribution): WslMavenDistribution {
if (mavenDistribution is WslMavenDistribution) return mavenDistribution
if (mavenDistribution is LocalMavenDistribution) {
return wslDistribution.getWslPath(mavenDistribution.mavenHome.absolutePathString())?.let {
return wslDistribution.getWslPath(mavenDistribution.mavenHome.toAbsolutePath())?.let {
WslMavenDistribution(wslDistribution, it, it)
} ?: throw IllegalArgumentException("Cannot use mavenDistribution ${mavenDistribution}")
}

View File

@@ -849,7 +849,7 @@ public class MavenUtil {
private static String getMavenLibVersion(final File file) {
WSLDistribution distribution = WslPath.getDistributionByWindowsUncPath(file.getPath());
File fileToRead = Optional.ofNullable(distribution)
.map(it -> distribution.getWslPath(file.getPath()))
.map(it -> distribution.getWslPath(file.toPath()))
.map(it -> distribution.resolveSymlink(it))
.map(it -> distribution.getWindowsPath(it))
.map(it -> new File(it))