override suspend fun run()

in sources/amper-cli/src/org/jetbrains/amper/tasks/ResolveExternalDependenciesTask.kt [121:277]


    override suspend fun run(
        dependenciesResult: List<TaskResult>,
        executionContext: TaskGraphExecutionContext,
    ): TaskResult {
        val repositories = module.mavenRepositories
            .filter { it.resolve }
            .map { it.url }
            .distinct()

        // order in compileDependencies is important (classpath is generally (and unfortunately!) order-dependent),
        // but the current implementation requires a full review of it

        val resolvedPlatform = platform.toResolutionPlatform()
        if (resolvedPlatform == null) {
            logger.error("${module.userReadableName}: Non-leaf platform $platform is not supported for resolving external dependencies")
            return onParametersErrorResult
        } else if (resolvedPlatform != ResolutionPlatform.JVM
            && resolvedPlatform != ResolutionPlatform.ANDROID
            && resolvedPlatform.nativeTarget == null
            && resolvedPlatform != ResolutionPlatform.JS
            && resolvedPlatform.wasmTarget == null
        ) {
            logger.error("${module.userReadableName}: $platform is not yet supported for resolving external dependencies")
            return onParametersErrorResult
        }

        // We capture these nodes bypassing the incremental result because we can
        // rely on the plain paths list of the dependencies to act as an indicator
        // for incrementality.
        // Also, `DependencyNode` generally is not serializable.
        val compileDependencyCoordinates = fragmentsCompileModuleDependencies.getExternalDependencies()
        val runtimeDependencyCoordinates = fragmentsRuntimeModuleDependencies?.getExternalDependencies()
        return spanBuilder("resolve-dependencies")
            .setAmperModule(module)
            .setFragments(fragments)
            .setListAttribute("dependencies", compileDependencyCoordinates.map { it.toString() })
            .setListAttribute("runtimeDependencies", runtimeDependencyCoordinates?.map { it.toString() } ?: emptyList())
            .setAttribute("isTest", isTest)
            .setAttribute("platform", resolvedPlatform.type.value)
            .also {
                resolvedPlatform.nativeTarget?.let { target ->
                    it.setAttribute("native-target", target)
                }
                resolvedPlatform.wasmTarget?.let { target ->
                    it.setAttribute("wasm-target", target)
                }
            }
            .setAttribute("native-target", resolvedPlatform.type.value)
            .setAttribute("user-cache-root", userCacheRoot.path.pathString)
            .use {
                logger.debug(
                    "resolve dependencies ${module.userReadableName} -- " +
                            "${fragments.userReadableList()} -- " +
                            "${compileDependencyCoordinates.joinToString(" ")} -- " +
                            "resolvePlatform=${resolvedPlatform.type.value} " +
                            "nativeTarget=${resolvedPlatform.nativeTarget} " +
                            "wasmTarget=${resolvedPlatform.wasmTarget}"
                )

                val result = try {
                    incrementalCache.execute(
                        key = taskName.name,
                        inputValues = mapOf(
                            "userCacheRoot" to userCacheRoot.path.pathString,
                            "compileDependencies" to compileDependencyCoordinates.joinToString("|"),
                            "runtimeDependencies" to (runtimeDependencyCoordinates?.joinToString("|") ?: ""),
                            "repositories" to repositories.joinToString("|"),
                            "resolvePlatform" to resolvedPlatform.type.value,
                            "resolveNativeTarget" to (resolvedPlatform.nativeTarget ?: ""),
                            "resolveWasmTarget" to (resolvedPlatform.wasmTarget ?: ""),
                        ),
                        inputFiles = emptyList()
                    ) {
                        val (compileDependenciesRootNode, runtimeDependenciesRootNode, expirationTime) =
                            mavenResolver.doResolveExternalDependencies(
                                module = module,
                                platform = platform,
                                isTest = isTest,
                                compileModuleDependencies = fragmentsCompileModuleDependencies,
                                runtimeModuleDependencies = fragmentsRuntimeModuleDependencies,
                            )

                        val compileClasspath = compileDependenciesRootNode.dependencyPaths()
                        val runtimeClasspath = runtimeDependenciesRootNode?.dependencyPaths() ?: emptyList()

                        val publicationCoordsOverrides = getPublicationCoordinatesOverrides(
                            compileDependenciesRootNode = compileDependenciesRootNode,
                            runtimeDependenciesRootNode = runtimeDependenciesRootNode,
                        )

                        return@execute IncrementalCache.ExecutionResult(
                            outputFiles = (compileClasspath + runtimeClasspath).toSet().sorted(),
                            outputValues = mapOf(
                                "compile" to compileClasspath.joinToString(File.pathSeparator),
                                "runtime" to runtimeClasspath.joinToString(File.pathSeparator),
                                "publicationCoordsOverrides" to Json.encodeToString(publicationCoordsOverrides),
                            ),
                            expirationTime = expirationTime,
                        )
                    }
                } catch (t: CancellationException) {
                    throw t
                } catch (t: Throwable) {
                    DoNotLogToTerminalCookie.use {
                        logger.error(
                            "resolve dependencies of module '${module.userReadableName}' failed\n" +
                                    "fragments: ${fragments.userReadableList()}\n" +
                                    "repositories:\n${repositories.joinToString("\n").prependIndent("  ")}\n" +
                                    "direct dependencies:\n${
                                        fragmentsCompileModuleDependencies.getExternalDependencies(true)
                                            .joinToString("\n")
                                            .prependIndent("  ")
                                    }\n" +
                                    "all dependencies:\n${
                                        compileDependencyCoordinates.joinToString("\n").prependIndent("  ")
                                    }\n" +
                                    "platform: $resolvedPlatform" +
                                    (resolvedPlatform.nativeTarget?.let { "\nnativeTarget: $it" } ?: "") +
                                    (resolvedPlatform.wasmTarget?.let { "\nwasmTarget: $it" } ?: ""), t)
                    }

                    throw t
                }

                val compileClasspath =
                    result.outputValues["compile"]!!.split(File.pathSeparator).filter { it.isNotEmpty() }
                        .map { Path(it) }
                val runtimeClasspath =
                    result.outputValues["runtime"]!!.split(File.pathSeparator).filter { it.isNotEmpty() }
                        .map { Path(it) }
                val publicationCoordsOverrides =
                    Json.decodeFromString<PublicationCoordinatesOverrides>(result.outputValues["publicationCoordsOverrides"]!!)

                logger.debug(
                    "resolve dependencies ${module.userReadableName} -- " +
                            "${fragments.userReadableList()} -- " +
                            "${compileDependencyCoordinates.joinToString(" ")} -- " +
                            "resolvePlatform=$resolvedPlatform " +
                            "nativeTarget=${resolvedPlatform.nativeTarget}\n" +
                            "wasmTarget=${resolvedPlatform.wasmTarget}\n" +
                            "${repositories.joinToString(" ")} resolved to:\n${
                                compileClasspath.joinToString("\n") {
                                    "  " + it.relativeToOrSelf(
                                        userCacheRoot.path
                                    ).pathString
                                }
                            }"
                )

                // todo (AB) : output should contain placeholder for every module (in a correct place in the list!!!
                // todo (AB) : It might be replaced with the path to compiled module later in order to form complete correctly ordered classpath)
                Result(
                    compileClasspath = compileClasspath,
                    runtimeClasspath = runtimeClasspath,
                    coordinateOverridesForPublishing = publicationCoordsOverrides,
                )
            }