Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix broken wsl support #194

Merged
merged 6 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/193.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix broken wsl support
12 changes: 7 additions & 5 deletions modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,7 @@ class MirrordApi(private val service: MirrordProjectService) {
throw MirrordError.fromStdErr(processStdError)
}

val parser = SafeParser()
val bufferedReader = process.inputStream.reader().buffered()

val warningHandler = MirrordWarningHandler(project.service<MirrordProjectService>())
return bufferedReader.readText()
}
}
Expand All @@ -208,9 +205,13 @@ class MirrordApi(private val service: MirrordProjectService) {
*/
fun verifyConfig(
cli: String,
configFilePath: String
configFilePath: String,
wslDistribution: WSLDistribution?
): String {
return MirrordVerifyConfigTask(cli, configFilePath).run(service.project)
val verifyConfigTask = MirrordVerifyConfigTask(cli, configFilePath).apply {
this.wslDistribution = wslDistribution
}
return verifyConfigTask.run(service.project)
}

/**
Expand Down Expand Up @@ -303,6 +304,7 @@ private abstract class MirrordCliTask<T>(private val cli: String, private val co
wslDistribution?.let {
val wslOptions = WSLCommandLineOptions().apply {
isLaunchWithWslExe = true
isExecuteCommandInShell = false
}
it.patchCommandLine(this, project, wslOptions)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class MirrordBinaryManager {
val local = if (checkInPath) {
manager.getLocalBinary(version, wslDistribution)
} else {
manager.findBinaryInStorage(version)
manager.findBinaryInStorage(version, wslDistribution)
}

if (local != null) {
Expand Down Expand Up @@ -241,19 +241,24 @@ class MirrordBinaryManager {
Files.move(tmpDestination, destination, StandardCopyOption.REPLACE_EXISTING)
}

private class MirrordBinary(val command: String) {
private class MirrordBinary(val command: String, wslDistribution: WSLDistribution?) {
val version: String

init {
val child = Runtime.getRuntime().exec(arrayOf(command, "--version"))
version = if (wslDistribution != null) {
val command = wslDistribution.getWslPath(command)
val output = wslDistribution.executeOnWsl(1000, command, "--version")
output.stdout.split(' ')[1].trim()
} else {
val child = Runtime.getRuntime().exec(arrayOf(command, "--version"))
val result = child.waitFor()
if (result != 0) {
MirrordLogger.logger.debug("`mirrord --version` failed with code $result")
throw RuntimeException("failed to get mirrord version")
}

val result = child.waitFor()
if (result != 0) {
MirrordLogger.logger.debug("`mirrord --version` failed with code $result")
throw RuntimeException("failed to get mirrord version")
child.inputReader().readLine().split(' ')[1].trim()
}

version = child.inputReader().readLine().split(' ')[1].trim()
}
}

Expand All @@ -277,7 +282,7 @@ class MirrordBinaryManager {
output.stdoutLines.first().trim()
}

val binary = MirrordBinary(output)
val binary = MirrordBinary(output, wslDistribution)
if (requiredVersion == null || requiredVersion == binary.version) {
return binary
}
Expand All @@ -291,10 +296,10 @@ class MirrordBinaryManager {
/**
* @return executable found in plugin storage
*/
private fun findBinaryInStorage(requiredVersion: String?): MirrordBinary? {
private fun findBinaryInStorage(requiredVersion: String?, wslDistribution: WSLDistribution?): MirrordBinary? {
try {
MirrordPathManager.getBinary(CLI_BINARY, true)?.let {
val binary = MirrordBinary(it)
val binary = MirrordBinary(it, wslDistribution)
if (requiredVersion == null || requiredVersion == binary.version) {
return binary
}
Expand All @@ -310,7 +315,7 @@ class MirrordBinaryManager {
* @return the local installation of mirrord, either in `PATH` or in plugin storage
*/
private fun getLocalBinary(requiredVersion: String?, wslDistribution: WSLDistribution?): MirrordBinary? {
return findBinaryInPath(requiredVersion, wslDistribution) ?: findBinaryInStorage(requiredVersion)
return findBinaryInPath(requiredVersion, wslDistribution) ?: findBinaryInStorage(requiredVersion, wslDistribution)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,45 +109,43 @@ class MirrordExecManager(private val service: MirrordProjectService) {
service.versionCheck.checkVersion() // TODO makes an HTTP request, move to background

val cli = cliPath(wslDistribution, product)
val config = service.configApi.getConfigPath(mirrordConfigFromEnv)

// Find the mirrord config path, then call `mirrord verify-config {path}` so we can display warnings/errors
// from the config without relying on mirrord-layer.
val configPath = service.configApi.getConfigPath(mirrordConfigFromEnv)
var verifiedConfig: MirrordVerifiedConfig? = null
if (configPath != null) {
val verifiedConfigOutput = service.mirrordApi.verifyConfig(cli, configPath)
val verified = MirrordVerifiedConfig(verifiedConfigOutput, service.notifier).also { verifiedConfig = it }
if (verified.isError()) {
throw InvalidConfigException(configPath, "validation failed for config")

val verifiedConfig = configPath?.let {
val verifiedConfigOutput =
service.mirrordApi.verifyConfig(cli, wslDistribution?.getWslPath(it) ?: it, wslDistribution)
MirrordVerifiedConfig(verifiedConfigOutput, service.notifier).apply {
if (isError()) {
throw InvalidConfigException(it, "Validation failed for config")
}
}
}

MirrordLogger.logger.debug("target selection")
MirrordLogger.logger.debug("Verified Config: $verifiedConfig, Target selection.")

var target: String? = null
val isTargetSet = (config != null && isTargetSet(verifiedConfig?.config))
MirrordLogger.logger.debug("$verifiedConfig")

if (!isTargetSet) {
val target = if (configPath != null && !isTargetSet(verifiedConfig?.config)) {
MirrordLogger.logger.debug("target not selected, showing dialog")
target = chooseTarget(cli, wslDistribution, config)
if (target == MirrordExecDialog.targetlessTargetName) {
MirrordLogger.logger.info("No target specified - running targetless")
service.notifier.notification(
"No target specified, mirrord running targetless.",
NotificationType.INFORMATION
)
.withDontShowAgain(MirrordSettingsState.NotificationId.RUNNING_TARGETLESS)
.fire()
target = null
chooseTarget(cli, wslDistribution, configPath).also {
if (it == MirrordExecDialog.targetlessTargetName) {
MirrordLogger.logger.info("No target specified - running targetless")
service.notifier.notification(
"No target specified, mirrord running targetless.",
NotificationType.INFORMATION
)
.withDontShowAgain(MirrordSettingsState.NotificationId.RUNNING_TARGETLESS)
.fire()
}
}
} else {
null
}

val executionInfo = service.mirrordApi.exec(
cli,
target,
config,
configPath,
executable,
wslDistribution
)
Expand Down