From 1b27c36128397470ff84e913dc1b42fd76b0d7d1 Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Sat, 9 Nov 2024 23:36:09 +0100 Subject: [PATCH] refactor notifications (#235) --- .../org/move/bytecode/AptosDecompiler.kt | 10 +- .../CommandConfigurationBase.kt | 4 +- .../cli/settings/MvProjectSettingsService.kt | 21 ++-- .../cli/settings/aptos/ChooseAptosCliPanel.kt | 2 +- .../ide/newProject/MoveProjectGenerator.kt | 2 +- .../newProject/MoveProjectGeneratorPeer.kt | 2 +- ...validAptosCliConfigurationNotification.kt} | 29 +++--- .../MvEditorNotificationProvider.kt | 48 --------- .../notifications/MvNotificationProvider.kt | 99 +++++++++++++++++++ ... => NoAptosProjectDetectedNotification.kt} | 36 ++----- .../org/move/openapiext/common/utils.kt | 4 +- src/main/resources/META-INF/plugin.xml | 6 +- .../move/utils/tests/AptosCliTestFixture.kt | 4 +- 13 files changed, 146 insertions(+), 121 deletions(-) rename src/main/kotlin/org/move/ide/notifications/{InvalidBlockchainCliConfiguration.kt => InvalidAptosCliConfigurationNotification.kt} (58%) delete mode 100644 src/main/kotlin/org/move/ide/notifications/MvEditorNotificationProvider.kt create mode 100644 src/main/kotlin/org/move/ide/notifications/MvNotificationProvider.kt rename src/main/kotlin/org/move/ide/notifications/{NoMoveProjectDetectedNotificationProvider.kt => NoAptosProjectDetectedNotification.kt} (59%) diff --git a/src/main/kotlin/org/move/bytecode/AptosDecompiler.kt b/src/main/kotlin/org/move/bytecode/AptosDecompiler.kt index b906d220a..7daf6bfa5 100644 --- a/src/main/kotlin/org/move/bytecode/AptosDecompiler.kt +++ b/src/main/kotlin/org/move/bytecode/AptosDecompiler.kt @@ -80,7 +80,7 @@ class AptosBytecodeDecompiler: BinaryFileDecompiler { } fun getDecompilerTargetFileDirOnTemp(project: Project, file: VirtualFile): Path? { - val rootDecompilerDir = getArtifactsDir() + val rootDecompilerDir = decompiledArtifactsFolder() val projectDecompilerDir = rootDecompilerDir.resolve(project.name) val root = project.rootPath ?: return null val relativeFilePath = file.parent.pathAsPath.relativeTo(root) @@ -88,10 +88,6 @@ class AptosBytecodeDecompiler: BinaryFileDecompiler { return targetFileDir } - fun getArtifactsDir(): File { - return File(FileUtil.getTempDirectory(), "intellij-move-decompiled-artifacts") - } - fun sourceFileName(file: VirtualFile): String { val fileName = file.name return "$fileName.move" @@ -101,6 +97,10 @@ class AptosBytecodeDecompiler: BinaryFileDecompiler { val fileName = file.name return "$fileName#decompiled.move" } + + companion object { + fun decompiledArtifactsFolder() = File(FileUtil.getTempDirectory(), "intellij-move-decompiled-artifacts") + } } fun Project.createDisposableOnFileChange(file: VirtualFile): Disposable { diff --git a/src/main/kotlin/org/move/cli/runConfigurations/CommandConfigurationBase.kt b/src/main/kotlin/org/move/cli/runConfigurations/CommandConfigurationBase.kt index 6d6dd5c78..80651660e 100644 --- a/src/main/kotlin/org/move/cli/runConfigurations/CommandConfigurationBase.kt +++ b/src/main/kotlin/org/move/cli/runConfigurations/CommandConfigurationBase.kt @@ -14,7 +14,7 @@ import org.move.cli.readString import org.move.cli.runConfigurations.CommandConfigurationBase.CleanConfiguration.Companion.configurationError import org.move.cli.runConfigurations.test.AptosTestConsoleProperties.Companion.TEST_TOOL_WINDOW_SETTING_KEY import org.move.cli.runConfigurations.test.AptosTestRunState -import org.move.cli.settings.aptosExecPath +import org.move.cli.settings.aptosCliPath import org.move.cli.writePath import org.move.cli.writeString import org.move.stdext.exists @@ -68,7 +68,7 @@ abstract class CommandConfigurationBase( val workingDirectory = workingDirectory ?: return configurationError("No working directory specified") - val aptosPath = project.aptosExecPath ?: return configurationError("No Aptos CLI specified") + val aptosPath = project.aptosCliPath ?: return configurationError("No Aptos CLI specified") if (!aptosPath.exists()) { return configurationError("Invalid Aptos CLI location: $aptosPath") } diff --git a/src/main/kotlin/org/move/cli/settings/MvProjectSettingsService.kt b/src/main/kotlin/org/move/cli/settings/MvProjectSettingsService.kt index 56f4bb0d8..34a9c0298 100644 --- a/src/main/kotlin/org/move/cli/settings/MvProjectSettingsService.kt +++ b/src/main/kotlin/org/move/cli/settings/MvProjectSettingsService.kt @@ -89,15 +89,16 @@ class MvProjectSettingsService( val Project.moveSettings: MvProjectSettingsService get() = service() -fun Project.getAptosCli(parentDisposable: Disposable? = null): Aptos? { - val aptosExecPath = - AptosExecType.aptosExecPath( - this.moveSettings.aptosExecType, - this.moveSettings.localAptosPath - ) - val aptos = aptosExecPath?.let { Aptos(it, parentDisposable) } - return aptos -} +val Project.aptosCliPath: Path? + get() { + val settings = this.moveSettings + return AptosExecType.aptosCliPath(settings.aptosExecType, settings.localAptosPath) + } + +fun Project.getAptosCli( + parentDisposable: Disposable? = null +): Aptos? = + this.aptosCliPath?.let { Aptos(it, parentDisposable) } val Project.isAptosConfigured: Boolean get() = this.getAptosCli() != null @@ -106,8 +107,6 @@ fun Project.getAptosCliDisposedOnFileChange(file: VirtualFile): Aptos? { return this.getAptosCli(anyChangeDisposable) } -val Project.aptosExecPath: Path? get() = this.getAptosCli()?.cliLocation - fun Path?.isValidExecutable(): Boolean { return this != null && this.toString().isNotBlank() diff --git a/src/main/kotlin/org/move/cli/settings/aptos/ChooseAptosCliPanel.kt b/src/main/kotlin/org/move/cli/settings/aptos/ChooseAptosCliPanel.kt index 93752f7c9..6fe954ca7 100644 --- a/src/main/kotlin/org/move/cli/settings/aptos/ChooseAptosCliPanel.kt +++ b/src/main/kotlin/org/move/cli/settings/aptos/ChooseAptosCliPanel.kt @@ -49,7 +49,7 @@ enum class AptosExecType { val bundledAptosCLIPath: Path? get() = BundledAptosManager.getBundledAptosPath() - fun aptosExecPath(execType: AptosExecType, localAptosPath: String?): Path? { + fun aptosCliPath(execType: AptosExecType, localAptosPath: String?): Path? { val pathCandidate = when (execType) { BUNDLED -> bundledAptosCLIPath diff --git a/src/main/kotlin/org/move/ide/newProject/MoveProjectGenerator.kt b/src/main/kotlin/org/move/ide/newProject/MoveProjectGenerator.kt index 5b5700f83..4d6b5f10f 100644 --- a/src/main/kotlin/org/move/ide/newProject/MoveProjectGenerator.kt +++ b/src/main/kotlin/org/move/ide/newProject/MoveProjectGenerator.kt @@ -43,7 +43,7 @@ class MoveProjectGenerator: DirectoryProjectGeneratorBase(), ) { val packageName = project.name val aptosPath = - AptosExecType.aptosExecPath(projectConfig.aptosExecType, projectConfig.localAptosPath) + AptosExecType.aptosCliPath(projectConfig.aptosExecType, projectConfig.localAptosPath) ?: error("validated before") val aptos = Aptos(aptosPath, disposable) val moveTomlFile = diff --git a/src/main/kotlin/org/move/ide/newProject/MoveProjectGeneratorPeer.kt b/src/main/kotlin/org/move/ide/newProject/MoveProjectGeneratorPeer.kt index 6be91ee6c..08bcbc0d3 100644 --- a/src/main/kotlin/org/move/ide/newProject/MoveProjectGeneratorPeer.kt +++ b/src/main/kotlin/org/move/ide/newProject/MoveProjectGeneratorPeer.kt @@ -58,7 +58,7 @@ class MoveProjectGeneratorPeer(val parentDisposable: Disposable): GeneratorPeerI override fun validate(): ValidationInfo? { val panelData = this.chooseAptosCliPanel.data val aptosExecPath = - AptosExecType.aptosExecPath(panelData.aptosExecType, panelData.localAptosPath) + AptosExecType.aptosCliPath(panelData.aptosExecType, panelData.localAptosPath) if (aptosExecPath == null) { return ValidationInfo("Invalid path to Aptos executable") } diff --git a/src/main/kotlin/org/move/ide/notifications/InvalidBlockchainCliConfiguration.kt b/src/main/kotlin/org/move/ide/notifications/InvalidAptosCliConfigurationNotification.kt similarity index 58% rename from src/main/kotlin/org/move/ide/notifications/InvalidBlockchainCliConfiguration.kt rename to src/main/kotlin/org/move/ide/notifications/InvalidAptosCliConfigurationNotification.kt index 234d94e66..1c127ccb5 100644 --- a/src/main/kotlin/org/move/ide/notifications/InvalidBlockchainCliConfiguration.kt +++ b/src/main/kotlin/org/move/ide/notifications/InvalidAptosCliConfigurationNotification.kt @@ -1,38 +1,30 @@ package org.move.ide.notifications -import com.intellij.ide.impl.isTrusted import com.intellij.openapi.project.DumbAware import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile import com.intellij.ui.EditorNotificationPanel import org.move.cli.settings.PerProjectAptosConfigurable import org.move.cli.settings.aptos.AptosExecType.LOCAL -import org.move.cli.settings.aptosExecPath +import org.move.cli.settings.aptosCliPath import org.move.cli.settings.isValidExecutable import org.move.cli.settings.moveSettings -import org.move.lang.isMoveFile -import org.move.lang.isMoveTomlManifestFile -import org.move.openapiext.common.isUnitTestMode import org.move.openapiext.showSettingsDialog import org.move.stdext.getCliFromPATH -class InvalidBlockchainCliConfiguration(project: Project): MvEditorNotificationProvider(project), - DumbAware { +class InvalidAptosCliConfigurationNotification(project: Project): MvAptosEditorNotificationProvider(project), + DumbAware { - override val VirtualFile.disablingKey: String get() = NOTIFICATION_STATUS_KEY + path + override val notificationProviderId: String get() = NOTIFICATION_STATUS_KEY - override fun createNotificationPanel(file: VirtualFile, project: Project): EditorNotificationPanel? { - if (isUnitTestMode) return null - if (!(file.isMoveFile || file.isMoveTomlManifestFile)) return null - @Suppress("UnstableApiUsage") - if (!project.isTrusted()) return null - if (isNotificationDisabled(file)) return null + override fun createAptosNotificationPanel(file: VirtualFile, project: Project): EditorNotificationPanel? { - if (project.aptosExecPath.isValidExecutable()) return null + if (project.aptosCliPath.isValidExecutable()) return null - val aptosCliFromPATH = getCliFromPATH("aptos")?.toString() return EditorNotificationPanel().apply { text = "Aptos CLI path is not provided or invalid" + + val aptosCliFromPATH = getCliFromPATH("aptos")?.toString() if (aptosCliFromPATH != null) { createActionLabel("Set to \"$aptosCliFromPATH\"") { project.moveSettings.modify { @@ -41,6 +33,7 @@ class InvalidBlockchainCliConfiguration(project: Project): MvEditorNotificationP } } } + createActionLabel("Configure") { project.showSettingsDialog() } @@ -51,6 +44,10 @@ class InvalidBlockchainCliConfiguration(project: Project): MvEditorNotificationP } } + override val enableForScratchFiles: Boolean get() = true + + override val enableForDecompiledFiles: Boolean get() = true + companion object { private const val NOTIFICATION_STATUS_KEY = "org.move.hideMoveNotifications" } diff --git a/src/main/kotlin/org/move/ide/notifications/MvEditorNotificationProvider.kt b/src/main/kotlin/org/move/ide/notifications/MvEditorNotificationProvider.kt deleted file mode 100644 index cd204a08d..000000000 --- a/src/main/kotlin/org/move/ide/notifications/MvEditorNotificationProvider.kt +++ /dev/null @@ -1,48 +0,0 @@ -package org.move.ide.notifications - -import com.intellij.ide.util.PropertiesComponent -import com.intellij.openapi.fileEditor.FileEditor -import com.intellij.openapi.project.Project -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.ui.EditorNotificationPanel -import com.intellij.ui.EditorNotificationProvider -import com.intellij.ui.EditorNotifications -import org.move.cli.settings.MvProjectSettingsServiceBase.* -import java.util.function.Function -import javax.swing.JComponent - -fun updateAllNotifications(project: Project) { - EditorNotifications.getInstance(project).updateAllNotifications() -} - -class UpdateNotificationsOnSettingsChangeListener(val project: Project): MoveSettingsListener { - - override fun > settingsChanged(e: SettingsChangedEventBase) { - updateAllNotifications(project) - } -} - -abstract class MvEditorNotificationProvider(protected val project: Project): EditorNotificationProvider { - - protected abstract val VirtualFile.disablingKey: String - - override fun collectNotificationData( - project: Project, - file: VirtualFile - ): Function { - return Function { createNotificationPanel(file, project) } - } - - abstract fun createNotificationPanel(file: VirtualFile, project: Project): EditorNotificationPanel? - - protected fun disableNotification(file: VirtualFile) { - PropertiesComponent.getInstance(project).setValue(file.disablingKey, true) - } - - protected fun isNotificationDisabled(file: VirtualFile): Boolean = - PropertiesComponent.getInstance(project).getBoolean(file.disablingKey) - - protected fun updateAllNotifications() { - EditorNotifications.getInstance(project).updateAllNotifications() - } -} \ No newline at end of file diff --git a/src/main/kotlin/org/move/ide/notifications/MvNotificationProvider.kt b/src/main/kotlin/org/move/ide/notifications/MvNotificationProvider.kt new file mode 100644 index 000000000..be45fcc96 --- /dev/null +++ b/src/main/kotlin/org/move/ide/notifications/MvNotificationProvider.kt @@ -0,0 +1,99 @@ +package org.move.ide.notifications + +import com.intellij.ide.impl.isTrusted +import com.intellij.ide.scratch.ScratchUtil +import com.intellij.ide.util.PropertiesComponent +import com.intellij.openapi.fileEditor.FileEditor +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.ui.EditorNotificationPanel +import com.intellij.ui.EditorNotificationProvider +import com.intellij.ui.EditorNotifications +import org.move.bytecode.AptosBytecodeDecompiler +import org.move.cli.settings.MvProjectSettingsServiceBase.* +import org.move.lang.isMoveFile +import org.move.lang.isMoveTomlManifestFile +import org.move.lang.toNioPathOrNull +import org.move.openapiext.common.isUnitTestMode +import java.util.function.Function +import javax.swing.JComponent +import kotlin.io.relativeToOrNull + +fun updateAllNotifications(project: Project) { + EditorNotifications.getInstance(project).updateAllNotifications() +} + +class UpdateNotificationsOnSettingsChangeListener(val project: Project): MoveSettingsListener { + + override fun > settingsChanged(e: SettingsChangedEventBase) { + updateAllNotifications(project) + } +} + +abstract class MvNotificationProvider(protected val project: Project): EditorNotificationProvider { + + protected abstract val VirtualFile.disablingKey: String + + override fun collectNotificationData( + project: Project, + file: VirtualFile + ): Function { + return Function { + createNotificationPanel(file, project) + } + } + + abstract fun createNotificationPanel(file: VirtualFile, project: Project): EditorNotificationPanel? + + protected fun disableNotification(file: VirtualFile) { + PropertiesComponent.getInstance(project).setValue(file.disablingKey, true) + } + + protected fun isNotificationDisabled(file: VirtualFile): Boolean = + PropertiesComponent.getInstance(project).getBoolean(file.disablingKey) + + protected fun updateAllNotifications() { + EditorNotifications.getInstance(project).updateAllNotifications() + } +} + +abstract class MvAptosEditorNotificationProvider(project: Project): MvNotificationProvider(project) { + + abstract val notificationProviderId: String + + abstract fun createAptosNotificationPanel(file: VirtualFile, project: Project): EditorNotificationPanel? + + open val enableForScratchFiles: Boolean = false + open val enableForDecompiledFiles: Boolean = false + + override val VirtualFile.disablingKey: String get() = notificationProviderId + path + + override fun createNotificationPanel(file: VirtualFile, project: Project): EditorNotificationPanel? { + // disable in unit tests + if (isUnitTestMode) return null + + if (!enableForScratchFiles && ScratchUtil.isScratch(file)) return null + @Suppress("UnstableApiUsage") + if (!project.isTrusted()) return null + + // only run for .move or Move.toml files + if (!file.isMoveFile && !file.isMoveTomlManifestFile) return null + + val nioFile = file.toNioPathOrNull()?.toFile() + // skip non-physical file + if (nioFile == null) return null + + if (!enableForDecompiledFiles) { + // check whether file is a decompiler artifact + val decompiledArtifactsFolder = AptosBytecodeDecompiler.decompiledArtifactsFolder() + // belongs to the decompiled artifacts directory + if (nioFile.relativeToOrNull(decompiledArtifactsFolder) != null) return null + } + + // explicitly disabled in file + if (isNotificationDisabled(file)) return null + + return createAptosNotificationPanel(file, project) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/org/move/ide/notifications/NoMoveProjectDetectedNotificationProvider.kt b/src/main/kotlin/org/move/ide/notifications/NoAptosProjectDetectedNotification.kt similarity index 59% rename from src/main/kotlin/org/move/ide/notifications/NoMoveProjectDetectedNotificationProvider.kt rename to src/main/kotlin/org/move/ide/notifications/NoAptosProjectDetectedNotification.kt index 8b03e4f21..bbf20e503 100644 --- a/src/main/kotlin/org/move/ide/notifications/NoMoveProjectDetectedNotificationProvider.kt +++ b/src/main/kotlin/org/move/ide/notifications/NoAptosProjectDetectedNotification.kt @@ -1,27 +1,17 @@ package org.move.ide.notifications -import com.intellij.ide.impl.isTrusted -import com.intellij.ide.scratch.ScratchUtil import com.intellij.openapi.project.DumbAware import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile import com.intellij.ui.EditorNotificationPanel -import org.move.bytecode.AptosBytecodeDecompiler import org.move.cli.MoveProjectsService import org.move.cli.MoveProjectsService.Companion.MOVE_PROJECTS_TOPIC import org.move.cli.moveProjectsService import org.move.cli.settings.MvProjectSettingsServiceBase.* import org.move.cli.settings.MvProjectSettingsServiceBase.Companion.MOVE_SETTINGS_TOPIC -import org.move.lang.isMoveFile -import org.move.lang.isMoveTomlManifestFile -import org.move.lang.toNioPathOrNull -import org.move.openapiext.common.isDispatchThread -import org.move.openapiext.common.isUnitTestMode -class NoMoveProjectDetectedNotificationProvider(project: Project): MvEditorNotificationProvider(project), - DumbAware { - - override val VirtualFile.disablingKey: String get() = NOTIFICATION_STATUS_KEY + path +class NoAptosProjectDetectedNotification(project: Project): MvAptosEditorNotificationProvider(project), + DumbAware { init { project.messageBus.connect().apply { @@ -37,30 +27,21 @@ class NoMoveProjectDetectedNotificationProvider(project: Project): MvEditorNotif } } - override fun createNotificationPanel(file: VirtualFile, project: Project): EditorNotificationPanel? { - if (isUnitTestMode && !isDispatchThread) return null - if (!(file.isMoveFile || file.isMoveTomlManifestFile)) return null - if (ScratchUtil.isScratch(file)) return null - @Suppress("UnstableApiUsage") - if (!project.isTrusted()) return null + override val notificationProviderId: String get() = NOTIFICATION_STATUS_KEY - // check whether file is a decompiler artifact - val decompiledArtifactsDir = AptosBytecodeDecompiler().getArtifactsDir() - val asNioFile = file.toNioPathOrNull()?.toFile() - if (asNioFile == null || asNioFile.relativeToOrNull(decompiledArtifactsDir) != null) return null + override fun createAptosNotificationPanel( + file: VirtualFile, + project: Project + ): EditorNotificationPanel? { val moveProjectsService = project.moveProjectsService // HACK: Reloads projects once on an opening of any Move file, if not yet reloaded. // It should be invoked somewhere else where it's more appropriate, // not in the notification handler. if (!moveProjectsService.initialized) { -// moveProjectsService.scheduleProjectsRefresh( -// reason = "called from notification on uninitialized projects service" -// ) // exit notification handler here, it's going to be entered again after the refresh return null } - if (isNotificationDisabled(file)) return null if (moveProjectsService.allProjects.isEmpty()) { // no move projects available @@ -88,8 +69,5 @@ class NoMoveProjectDetectedNotificationProvider(project: Project): MvEditorNotif companion object { private const val NOTIFICATION_STATUS_KEY = "org.move.hideNoMoveProjectNotifications" - - const val NO_MOVE_PROJECTS = "NoMoveProjects" - const val FILE_NOT_IN_MOVE_PROJECT = "FileNotInMoveProject" } } \ No newline at end of file diff --git a/src/main/kotlin/org/move/openapiext/common/utils.kt b/src/main/kotlin/org/move/openapiext/common/utils.kt index 3d0d31ad9..98110340f 100644 --- a/src/main/kotlin/org/move/openapiext/common/utils.kt +++ b/src/main/kotlin/org/move/openapiext/common/utils.kt @@ -3,7 +3,6 @@ package org.move.openapiext.common import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.ex.temp.TempFileSystemMarker -import org.move.cli.MvConstants val isUnitTestMode: Boolean get() = ApplicationManager.getApplication().isUnitTestMode @@ -20,6 +19,7 @@ fun checkUnitTestMode() = check(isUnitTestMode) { "UnitTestMode needed" } val isHeadlessEnvironment: Boolean get() = ApplicationManager.getApplication().isHeadlessEnvironment -val isDispatchThread: Boolean get() = ApplicationManager.getApplication().isDispatchThread +val isEventDispatchThread: Boolean get() = ApplicationManager.getApplication().isDispatchThread +val isEDT: Boolean get() = isEventDispatchThread val isInternal: Boolean get() = ApplicationManager.getApplication().isInternal diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 35dadb4c8..5bd40247c 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -169,7 +169,7 @@ implementationClass="org.move.ide.hints.StructLitFieldsInfoHandler" /> - + + implementation="org.move.ide.notifications.InvalidAptosCliConfigurationNotification" /> + implementation="org.move.ide.notifications.NoAptosProjectDetectedNotification" /> Move diff --git a/src/test/kotlin/org/move/utils/tests/AptosCliTestFixture.kt b/src/test/kotlin/org/move/utils/tests/AptosCliTestFixture.kt index cb892075a..3721aa4c3 100644 --- a/src/test/kotlin/org/move/utils/tests/AptosCliTestFixture.kt +++ b/src/test/kotlin/org/move/utils/tests/AptosCliTestFixture.kt @@ -4,7 +4,7 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess import com.intellij.testFramework.fixtures.impl.BaseFixture import org.move.cli.settings.aptos.AptosExecType.LOCAL -import org.move.cli.settings.aptosExecPath +import org.move.cli.settings.aptosCliPath import org.move.cli.settings.moveSettings import org.move.stdext.getCliFromPATH import java.nio.file.Path @@ -20,7 +20,7 @@ class AptosCliTestFixture( override fun setUp() { super.setUp() - var aptosSdkPath = project.aptosExecPath + var aptosSdkPath = project.aptosCliPath if (aptosSdkPath == null) { aptosSdkPath = getCliFromPATH("aptos") project.moveSettings.modifyTemporary(testRootDisposable) {