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,
)
}