Skip to content

Commit

Permalink
parse aptos command line json output
Browse files Browse the repository at this point in the history
  • Loading branch information
mkurnikov committed Nov 10, 2024
1 parent f60ec3d commit 4218965
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 56 deletions.
43 changes: 31 additions & 12 deletions src/main/kotlin/org/move/cli/MoveProjectsSyncTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.concurrency.annotations.RequiresReadLock
import org.move.cli.MoveProject.UpdateStatus
import org.move.cli.manifest.MoveToml
import org.move.cli.runConfigurations.aptos.AptosExitStatus
import org.move.cli.settings.getAptosCli
import org.move.cli.settings.moveSettings
import org.move.lang.toNioPathOrNull
Expand Down Expand Up @@ -182,7 +183,6 @@ class MoveProjectsSyncTask(
}

private fun fetchDependencyPackages(childContext: SyncContext, projectRoot: Path): TaskResult<Unit> {
val taskResult: TaskResult<Unit>? = null
val syncListener =
SyncProcessListener(childContext) { event ->
childContext.syncProgress.output(event.text, true)
Expand All @@ -192,17 +192,36 @@ class MoveProjectsSyncTask(
return when {
aptos == null -> TaskResult.Err("Invalid Aptos CLI configuration")
else -> {
aptos.fetchPackageDependencies(
projectRoot,
skipLatest,
processListener = syncListener
).unwrapOrElse {
return TaskResult.Err(
"Failed to fetch / update dependencies",
it.message
)
val aptosProcessOutput =
aptos.fetchPackageDependencies(
projectRoot,
skipLatest,
processListener = syncListener
).unwrapOrElse {
return TaskResult.Err(
"Failed to fetch / update dependencies",
it.message
)
}
when (val exitStatus = aptosProcessOutput.exitStatus) {
is AptosExitStatus.Result -> TaskResult.Ok(Unit)
is AptosExitStatus.Error -> {
if (exitStatus.message.contains("Unable to resolve packages for package")) {
return TaskResult.Err(
"Unable to resolve packages",
exitStatus.message.split(": ").joinToString(": \n")
)
}
if (!exitStatus.message.contains("Compilation error")) {
return TaskResult.Err(
"Error occurred",
exitStatus.message.split(": ").joinToString(": \n")
)
}
TaskResult.Ok(Unit)
}
is AptosExitStatus.Malformed -> TaskResult.Ok(Unit)
}
TaskResult.Ok(Unit)
}
}
}
Expand Down Expand Up @@ -310,7 +329,7 @@ class MoveProjectsSyncTask(
val depRoot = dep.rootDirectory()
.unwrapOrElse {
syncContext.syncProgress.message(
"Failed to load ${dep.name}.",
"Failed to load ${dep.name}",
"Error when resolving dependency root, \n${it.message}",
MessageEvent.Kind.ERROR,
null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ data class AptosCommandLine(
.withParameters(this.arguments)
.withWorkingDirectory(this.workingDirectory)
.withCharset(Charsets.UTF_8)
// disables default coloring for stderr
.withRedirectErrorStream(true)
this.environmentVariables.configureCommandLine(generalCommandLine, true)
return generalCommandLine
}
Expand Down
76 changes: 35 additions & 41 deletions src/main/kotlin/org/move/cli/runConfigurations/aptos/Aptos.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.execution.ParametersListUtil
import org.move.cli.MvConstants
import org.move.cli.MoveProject
import org.move.cli.externalLinter.ExternalLinter
import org.move.cli.externalLinter.externalLinterSettings
import org.move.cli.MvConstants
import org.move.cli.runConfigurations.AptosCommandLine
import org.move.cli.settings.moveSettings
import org.move.openapiext.*
import org.move.openapiext.common.isUnitTestMode
import org.move.stdext.RsResult
Expand Down Expand Up @@ -56,17 +53,17 @@ data class Aptos(val cliLocation: Path, val parentDisposable: Disposable?): Disp
executeCommandLine(commandLine).unwrapOrElse { return Err(it) }

fullyRefreshDirectory(rootDirectory)

val manifest =
checkNotNull(rootDirectory.findChild(MvConstants.MANIFEST_FILE)) { "Can't find the manifest file" }

return Ok(manifest)
}

fun fetchPackageDependencies(
projectDir: Path,
skipLatest: Boolean,
processListener: ProcessListener
): RsProcessResult<Unit> {
): AptosProcessResult<Unit> {
val commandLine =
AptosCommandLine(
subCommand = "move compile",
Expand All @@ -75,10 +72,9 @@ data class Aptos(val cliLocation: Path, val parentDisposable: Disposable?): Disp
),
workingDirectory = projectDir
)
commandLine
.toColoredCommandLine(this.cliLocation)
.execute(innerDisposable, listener = processListener)
return Ok(Unit)
val aptosProcessOutput =
executeAptosCommandLine(commandLine, colored = true, listener = processListener)
return aptosProcessOutput
}

fun checkProject(args: AptosCompileArgs): RsResult<ProcessOutput, RsProcessExecutionException.Start> {
Expand Down Expand Up @@ -179,44 +175,42 @@ data class Aptos(val cliLocation: Path, val parentDisposable: Disposable?): Disp

private fun executeCommandLine(
commandLine: AptosCommandLine,
colored: Boolean = false,
listener: ProcessListener? = null,
runner: CapturingProcessHandler.() -> ProcessOutput = { runProcessWithGlobalProgress() }
): RsProcessResult<ProcessOutput> {
return commandLine
.toGeneralCommandLine(this.cliLocation)
.execute(innerDisposable, listener = listener, runner = runner)
val generalCommandLine = if (colored) {
commandLine.toColoredCommandLine(this.cliLocation)
} else {
commandLine.toGeneralCommandLine(this.cliLocation)
}
return generalCommandLine.execute(innerDisposable, runner, listener)
}

override fun dispose() {}
}
private fun executeAptosCommandLine(
commandLine: AptosCommandLine,
colored: Boolean = false,
listener: ProcessListener? = null,
runner: CapturingProcessHandler.() -> ProcessOutput = { runProcessWithGlobalProgress() }
): AptosProcessResult<Unit> {
val processOutput = executeCommandLine(commandLine, colored, listener, runner)
.unwrapOrElse {
if (it !is RsProcessExecutionException.FailedWithNonZeroExitCode) {
return Err(it)
}
it.output
}

data class AptosCompileArgs(
val linter: ExternalLinter,
val moveProjectDirectory: Path,
val extraArguments: String,
val envs: Map<String, String>,
val enableMove2: Boolean,
val skipLatestGitDeps: Boolean,
) {
companion object {
fun forMoveProject(moveProject: MoveProject): AptosCompileArgs {
val linterSettings = moveProject.project.externalLinterSettings
val moveSettings = moveProject.project.moveSettings

val additionalArguments = linterSettings.additionalArguments
val enviroment = linterSettings.envs
val workingDirectory = moveProject.workingDirectory

return AptosCompileArgs(
linterSettings.tool,
workingDirectory,
additionalArguments,
enviroment,
enableMove2 = moveSettings.enableMove2,
skipLatestGitDeps = moveSettings.skipFetchLatestGitDeps
)
}
val json = processOutput.stdout
.lines().dropWhile { l -> !l.startsWith("{") }.joinToString("\n").trim()
val exitStatus = AptosExitStatus.fromJson(json)
val aptosProcessOutput = AptosProcessOutput(Unit, processOutput, exitStatus)

return Ok(aptosProcessOutput)
}

override fun dispose() {}
}


val MoveProject.workingDirectory: Path get() = this.currentPackage.contentRoot.pathAsPath
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.move.cli.runConfigurations.aptos

import org.move.cli.MoveProject
import org.move.cli.externalLinter.ExternalLinter
import org.move.cli.externalLinter.externalLinterSettings
import org.move.cli.settings.moveSettings
import java.nio.file.Path

data class AptosCompileArgs(
val linter: ExternalLinter,
val moveProjectDirectory: Path,
val extraArguments: String,
val envs: Map<String, String>,
val enableMove2: Boolean,
val skipLatestGitDeps: Boolean,
) {
companion object {
fun forMoveProject(moveProject: MoveProject): AptosCompileArgs {
val linterSettings = moveProject.project.externalLinterSettings
val moveSettings = moveProject.project.moveSettings

val additionalArguments = linterSettings.additionalArguments
val enviroment = linterSettings.envs
val workingDirectory = moveProject.workingDirectory

return AptosCompileArgs(
linterSettings.tool,
workingDirectory,
additionalArguments,
enviroment,
enableMove2 = moveSettings.enableMove2,
skipLatestGitDeps = moveSettings.skipFetchLatestGitDeps
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.move.cli.runConfigurations.aptos

import com.intellij.execution.process.ProcessOutput
import org.move.openapiext.RsProcessExecutionException
import org.move.stdext.RsResult

typealias AptosProcessResult<T> = RsResult<AptosProcessOutput<T>, RsProcessExecutionException>

data class AptosProcessOutput<T>(
val item: T,
val output: ProcessOutput,
val exitStatus: AptosExitStatus,
) {
fun <T, U> replaceItem(newItem: U): AptosProcessOutput<U> = AptosProcessOutput(newItem, output, exitStatus)
}
2 changes: 1 addition & 1 deletion src/main/kotlin/org/move/openapiext/CommandLineExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ fun GeneralCommandLine.execute(
output.isCancelled -> RsResult.Err(RsProcessExecutionException.Canceled(commandLineString, output))
output.isTimeout -> RsResult.Err(RsProcessExecutionException.Timeout(commandLineString, output))
output.exitCode != 0 -> RsResult.Err(
RsProcessExecutionException.ProcessAborted(
RsProcessExecutionException.FailedWithNonZeroExitCode(
commandLineString,
output
)
Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/org/move/openapiext/MvProcessResult.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ sealed class RsProcessExecutionException : RsProcessExecutionOrDeserializationEx
) : RsProcessExecutionException(errorMessage(commandLineString, output))

/** The process exited with non-zero exit code */
class ProcessAborted(
class FailedWithNonZeroExitCode(
override val commandLineString: String,
val output: ProcessOutput,
) : RsProcessExecutionException(errorMessage(commandLineString, output))
Expand All @@ -65,6 +65,6 @@ fun RsProcessResult<ProcessOutput>.ignoreExitCode(): RsResult<ProcessOutput, RsP
is RsProcessExecutionException.Start -> RsResult.Err(err)
is RsProcessExecutionException.Canceled -> RsResult.Ok(err.output)
is RsProcessExecutionException.Timeout -> RsResult.Ok(err.output)
is RsProcessExecutionException.ProcessAborted -> RsResult.Ok(err.output)
is RsProcessExecutionException.FailedWithNonZeroExitCode -> RsResult.Ok(err.output)
}
}

0 comments on commit 4218965

Please sign in to comment.