Skip to content

Commit

Permalink
refactor(stack): Remove code reduncancies in scope creation
Browse files Browse the repository at this point in the history
Signed-off-by: Frank Viernau <frank_viernau@epam.com>
  • Loading branch information
fviernau committed Jul 3, 2024
1 parent 5a9700f commit f8fc96c
Showing 1 changed file with 37 additions and 29 deletions.
66 changes: 37 additions & 29 deletions plugins/package-managers/stack/src/main/kotlin/Stack.kt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import org.semver4j.RangesListFactory
private const val EXTERNAL_SCOPE_NAME = "external"
private const val TEST_SCOPE_NAME = "test"
private const val BENCH_SCOPE_NAME = "bench"
private val SCOPE_NAMES = setOf(EXTERNAL_SCOPE_NAME, TEST_SCOPE_NAME, BENCH_SCOPE_NAME)

private const val HACKAGE_PACKAGE_TYPE = "hackage"
private const val PROJECT_PACKAGE_TYPE = "project package"
Expand Down Expand Up @@ -90,35 +91,19 @@ class Stack(
override fun resolveDependencies(definitionFile: File, labels: Map<String, String>): List<ProjectAnalyzerResult> {
val workingDir = definitionFile.parentFile

val externalDependencies = listDependencies(workingDir, EXTERNAL_SCOPE_NAME)
val testDependencies = listDependencies(workingDir, TEST_SCOPE_NAME)
val benchDependencies = listDependencies(workingDir, BENCH_SCOPE_NAME)
val dependenciesForScopeName = SCOPE_NAMES.associateWith { listDependencies(workingDir, it) }

val dependencyPackageMap = (externalDependencies + testDependencies + benchDependencies).filterNot {
// Do not add the project as a package.
it.isProject()
}.associateWith { it.toPackage() }
val packageForName = dependenciesForScopeName.values.flatten()
.distinctBy { it.name }
.filterNot { it.isProject() } // Do not add the project as a package.
.associate { it.name to it.toPackage() }

fun List<String>.toPackageReferences(): Set<PackageReference> =
mapNotNullTo(mutableSetOf()) { name ->
// TODO: Stack identifies dependencies only by name. Find out how dependencies with the same name but in
// different namespaces should be handled.
dependencyPackageMap.entries.find { (dependency, _) -> dependency.name == name }?.let { entry ->
val pkg = entry.value
val dependencies = entry.key.dependencies.toPackageReferences()

pkg.toReference().copy(dependencies = dependencies)
}
}

val scopes = setOf(
Scope(EXTERNAL_SCOPE_NAME, externalDependencies.getProjectDependencies().toPackageReferences()),
Scope(TEST_SCOPE_NAME, testDependencies.getProjectDependencies().toPackageReferences()),
Scope(BENCH_SCOPE_NAME, benchDependencies.getProjectDependencies().toPackageReferences())
)
val scopes = dependenciesForScopeName.mapTo(mutableSetOf()) { (name, dependencies) ->
dependencies.toScope(name, packageForName)
}

val referencedPackageIds = scopes.flatMapTo(mutableSetOf()) { it.collectDependencies() }
val packages = dependencyPackageMap.values.filterTo(mutableSetOf()) { it.id in referencedPackageIds }
val referencedPackages = scopes.flatMapTo(mutableSetOf()) { it.collectDependencies() }
val packages = packageForName.values.filterTo(mutableSetOf()) { it.id in referencedPackages }
val project = getProject(definitionFile, scopes)

return listOf(ProjectAnalyzerResult(project, packages))
Expand Down Expand Up @@ -329,7 +314,30 @@ class Stack(
}
}

private fun List<Dependency>.getProjectDependencies(): List<String> =
single { it.location?.type == PROJECT_PACKAGE_TYPE }.dependencies

private fun Dependency.isProject(): Boolean = location?.type == PROJECT_PACKAGE_TYPE

private fun Collection<Dependency>.toScope(scopeName: String, packageForName: Map<String, Package>): Scope {
// TODO: Stack identifies dependencies only by name. Find out how dependencies with the same name but in
// different namespaces should be handled.
val dependencyForName = associateBy { it.name }

return Scope(
name = scopeName,
dependencies = single {
it.location?.type == PROJECT_PACKAGE_TYPE
}.dependencies.mapTo(mutableSetOf()) { name ->
dependencyForName.getValue(name).toPackageReference(dependencyForName, packageForName)
}
)
}

private fun Dependency.toPackageReference(
dependencyForName: Map<String, Dependency>,
packageForName: Map<String, Package>
): PackageReference =
PackageReference(
id = packageForName.getValue(name).id,
dependencies = dependencies.mapTo(mutableSetOf()) { name ->
dependencyForName.getValue(name).toPackageReference(dependencyForName, packageForName)
}
)

0 comments on commit f8fc96c

Please sign in to comment.