Gradle, js, npm: store imported packages as yarn workspaces

#KT-30530
This commit is contained in:
Sergey Rostov
2019-05-17 11:02:05 +03:00
parent 64f997daa4
commit fab879bf33
9 changed files with 40 additions and 28 deletions
@@ -28,15 +28,15 @@ open class NodeJsRootExtension(project: Project) : NodeJsExtension(project) {
val npmResolveTask: NpmResolveTask
get() = project.tasks.getByName(NpmResolveTask.NAME) as NpmResolveTask
val nodeModulesGradleCacheDir: File
get() = project.buildDir.resolve("node_modules_gradle")
val rootPackageDir: File
get() = project.buildDir.resolve("js")
val projectPackagesDir: File
get() = rootPackageDir.resolve("packages")
val nodeModulesGradleCacheDir: File
get() = rootPackageDir.resolve("packages_imported")
internal val environment: NodeJsEnv
get() {
val platform = NodeJsPlatform.name
@@ -10,4 +10,4 @@ import java.io.File
/**
* Fake NodeJS module directory created from Gradle external module
*/
class GradleNodeModule(val name: String, val path: File)
class GradleNodeModule(val name: String, val version: String, val path: File)
@@ -39,7 +39,7 @@ internal class GradleNodeModuleBuilder(
}
}
fun rebuild(): File? {
fun rebuild(): PackageJson? {
if (files.isEmpty()) return null
val packageJson = srcPackageJsonFile?.reader()?.use {
@@ -100,7 +100,7 @@ fun makeNodeModule(
container: File,
packageJson: PackageJson,
files: (File) -> Unit
): File {
): PackageJson {
val dir = container.resolve(packageJson.name)
if (dir.exists()) dir.deleteRecursively()
@@ -119,5 +119,5 @@ fun makeNodeModule(
gson.toJson(packageJson, it)
}
return dir
return packageJson
}
@@ -22,10 +22,10 @@ internal class GradleNodeModulesCache(val project: Project) : AutoCloseable {
}
internal val dir = project.nodeJs.root.nodeModulesGradleCacheDir
private val cache = ProcessedFilesCache(project, dir, STATE_FILE_NAME, "5")
private val cache = ProcessedFilesCache(project, dir, STATE_FILE_NAME, "6")
private val visited = mutableSetOf<ResolvedDependency>()
fun collectDependenciesFromConfiguration(configuration: Configuration, result: NpmProjectGradleDeps) {
fun collectDependenciesFromConfiguration(configuration: Configuration, result: NpmGradleDependencies) {
if (configuration.isCanBeResolved) {
configuration.resolvedConfiguration.firstLevelModuleDependencies.forEach {
visitDependency(it, result)
@@ -33,7 +33,7 @@ internal class GradleNodeModulesCache(val project: Project) : AutoCloseable {
}
}
private fun visitDependency(dependency: ResolvedDependency, result: NpmProjectGradleDeps) {
private fun visitDependency(dependency: ResolvedDependency, result: NpmGradleDependencies) {
if (!visited.add(dependency)) return
visitArtifacts(dependency, dependency.moduleArtifacts, result)
@@ -46,14 +46,8 @@ internal class GradleNodeModulesCache(val project: Project) : AutoCloseable {
private fun visitArtifacts(
dependency: ResolvedDependency,
artifacts: MutableSet<ResolvedArtifact>,
result: NpmProjectGradleDeps
result: NpmGradleDependencies
) {
val lazyDirName: String? by lazy {
val module = GradleNodeModuleBuilder(project, dependency, artifacts, this)
module.visitArtifacts()
module.rebuild()?.canonicalFile?.relativeTo(dir)?.path
}
artifacts.forEach { artifact ->
val componentIdentifier = artifact.id.componentIdentifier
if (componentIdentifier is ProjectComponentIdentifier) {
@@ -63,11 +57,16 @@ internal class GradleNodeModulesCache(val project: Project) : AutoCloseable {
result.internalModules.add(dependentProject)
} else {
val key = cache.getOrCompute(artifact.file) {
lazyDirName
val module = GradleNodeModuleBuilder(project, dependency, artifacts, this)
module.visitArtifacts()
module.rebuild()?.let {
it.name + ":" + it.version
}
}
if (key != null) {
result.externalModules.add(GradleNodeModule(key, dir.resolve(key)))
val (name, version) = key.split(":")
result.externalModules.add(GradleNodeModule(name, version, dir.resolve(name)))
}
}
}
@@ -10,7 +10,12 @@ import org.gradle.api.Project
/**
* Gradle dependencies for [NpmProject].
*/
class NpmProjectGradleDeps {
class NpmGradleDependencies {
val internalModules = mutableSetOf<Project>()
val externalModules = mutableSetOf<GradleNodeModule>()
fun addAll(other: NpmGradleDependencies) {
internalModules.addAll(other.internalModules)
externalModules.addAll(other.externalModules)
}
}
@@ -14,5 +14,6 @@ class NpmProjectPackage(
val project: Project,
val npmProject: NpmProject,
val npmDependencies: Collection<NpmDependency>,
val gradleDependencies: NpmGradleDependencies,
val packageJson: PackageJson
)
@@ -99,7 +99,7 @@ internal class NpmProjectVisitor(val resolver: NpmResolver, val project: Project
project.version.toString()
)
val npmDependencies = mutableSetOf<NpmDependency>()
val gradleDeps = NpmProjectGradleDeps()
val gradleDeps = NpmGradleDependencies()
compilation.allKotlinSourceSets.forEach { sourceSet ->
sourceSet.relatedConfigurationNames.forEach { configurationName ->
@@ -125,8 +125,7 @@ internal class NpmProjectVisitor(val resolver: NpmResolver, val project: Project
}
gradleDeps.externalModules.forEach {
val relativePath = it.path.relativeTo(npmProject.dir)
packageJson.dependencies[it.name] = "file:$relativePath"
packageJson.dependencies[it.name] = it.version
}
gradleDeps.internalModules.forEach { target ->
@@ -140,7 +139,7 @@ internal class NpmProjectVisitor(val resolver: NpmResolver, val project: Project
it(packageJson)
}
val npmPackage = NpmProjectPackage(project, npmProject, npmDependencies, packageJson)
val npmPackage = NpmProjectPackage(project, npmProject, npmDependencies, gradleDeps, packageJson)
npmPackage.packageJson.saveTo(npmProject.packageJsonFile)
resolver.packageManager.resolveProject(npmPackage)
@@ -151,9 +150,9 @@ internal class NpmProjectVisitor(val resolver: NpmResolver, val project: Project
private fun visitConfiguration(
configuration: Configuration,
npmDependencies: MutableSet<NpmDependency>,
gradleDeps: NpmProjectGradleDeps
gradleDependencies: NpmGradleDependencies
) {
resolver.gradleNodeModules.collectDependenciesFromConfiguration(configuration, gradleDeps)
resolver.gradleNodeModules.collectDependenciesFromConfiguration(configuration, gradleDependencies)
configuration.allDependencies.forEach { dependency ->
when (dependency) {
@@ -124,6 +124,7 @@ internal class NpmResolver private constructor(val rootProject: Project) : AutoC
val visited = NpmProjectVisitor(this, project).visitProject()
data.visit = visited
allNpmPackages.addAll(visited.npmProjects)
return visited
@@ -125,8 +125,15 @@ object Yarn : NpmApi {
) {
val rootPackageJson = PackageJson(rootProject.name, rootProject.version.toString())
rootPackageJson.private = true
rootPackageJson.workspaces = npmProjects
.map { it.npmProject.dir.relativeTo(nodeJsWorldDir).path }
val npmProjectWorkspaces = npmProjects.map { it.npmProject.dir.relativeTo(nodeJsWorldDir).path }
val importedProjectWorkspaces = npmProjects.flatMapTo(mutableSetOf()) {
it.gradleDependencies.externalModules.map { importedProject ->
importedProject.path.relativeTo(nodeJsWorldDir).path
}
}
rootPackageJson.workspaces = npmProjectWorkspaces + importedProjectWorkspaces
rootProject.nodeJs.packageJsonHandlers.forEach {
it(rootPackageJson)