/
GradleNodeModuleBuilder.kt
107 lines (87 loc) · 3.13 KB
/
GradleNodeModuleBuilder.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.targets.js.npm
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import org.gradle.api.Project
import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.api.artifacts.ResolvedDependency
import java.io.File
/**
* Creates fake NodeJS module directory from given gradle [dependency].
*/
internal class GradleNodeModuleBuilder(
val project: Project,
val dependency: ResolvedDependency,
val artifacts: Collection<ResolvedArtifact>,
val cache: GradleNodeModulesCache
) {
var srcPackageJsonFile: File? = null
val files = mutableListOf<File>()
fun visitArtifacts() {
artifacts.forEach { artifact ->
val srcFile = artifact.file
when {
isKotlinJsRuntimeFile(srcFile) -> files.add(srcFile)
srcFile.isZip -> project.zipTree(srcFile).forEach { innerFile ->
when {
innerFile.name == NpmProject.PACKAGE_JSON -> srcPackageJsonFile = innerFile
isKotlinJsRuntimeFile(innerFile) -> files.add(innerFile)
}
}
}
}
}
fun rebuild(): File? {
if (files.isEmpty()) return null
val packageJson = srcPackageJsonFile?.reader()?.use {
Gson().fromJson(it, PackageJson::class.java)
} ?: PackageJson(dependency.moduleName, dependency.moduleVersion)
val jsFiles = files.filter { it.name.endsWith(".js") }
if (jsFiles.size == 1) {
val jsFile = jsFiles.single()
packageJson.name = jsFile.nameWithoutExtension
packageJson.main = jsFile.name
}
// yarn requires semver
packageJson.version = fixSemver(packageJson.version)
return makeNodeModule(cache.dir, packageJson) { nodeModule ->
project.copy { copy ->
copy.from(files)
copy.into(nodeModule)
}
}
}
}
private val File.isZip
get() = isFile && (name.endsWith(".jar") || name.endsWith(".zip"))
private fun isKotlinJsRuntimeFile(file: File): Boolean {
if (!file.isFile) return false
val name = file.name
return (name.endsWith(".js") && !name.endsWith(".meta.js"))
|| name.endsWith(".js.map")
}
fun makeNodeModule(
container: File,
packageJson: PackageJson,
files: (File) -> Unit
): File {
val dir = importedPackageDir(container, packageJson.name, packageJson.version)
if (dir.exists()) dir.deleteRecursively()
check(dir.mkdirs()) {
"Cannot create directory: $dir"
}
val gson = GsonBuilder()
.setPrettyPrinting()
.create()
files(dir)
dir.resolve("package.json").writer().use {
gson.toJson(packageJson, it)
}
return dir
}
fun importedPackageDir(container: File, name: String, version: String): File =
container.resolve(name).resolve(version)
fun GradleNodeModule(dir: File) = GradleNodeModule(dir.parentFile.name, dir.name, dir)