import org.gradle.api.DefaultTask import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.tasks.* import org.gradle.api.tasks.bundling.Jar import org.gradle.kotlin.dsl.* import java.io.File import java.util.concurrent.Callable class ScriptCraftPlugin : Plugin { open class Config(rootDir: File) { var root: File = File(rootDir, "src/main/ts") } open class NPMTask : DefaultTask() { @get:Input lateinit var taskName: String @get:Optional @get:Input var outputDir: String? = null @TaskAction fun exec() { project.delete { delete(getOutput()) } project.exec { workingDir(getInput()) executable("npm") args("run", taskName) } } @InputDirectory fun getInput(): Callable { return Callable { project.the().root } } @Optional @OutputDirectory fun getOutput(): Callable? { val dir = outputDir return if (dir != null) { Callable { if (File(dir).isAbsolute) { File(dir) } else { File(project.the().root, dir) } } } else { null } } } open class NPMInstallTask : DefaultTask() { @TaskAction fun exec() { project.delete { delete(getOutput()) } project.exec { workingDir(Callable { project.the().root }) executable("npm") args("install") } } @InputFile fun getInput(): Callable { return Callable { File(project.the().root, "package.json") } } @OutputDirectory fun getOutput(): Callable { return Callable { File(project.the().root, "node_modules") } } } override fun apply(project: Project): Unit = project.run { val extension = project.extensions.create("scriptcraft", projectDir) val typescript = configurations.create("typescript") { isTransitive = false } val npmInstallTask = tasks.register("npmInstall") { group = "scriptcraft" } val extractTypescriptDependenciesTask = tasks.register("extractTypescriptDependencies") { group = "scriptcraft" dependsOn(typescript) from(Callable { typescript.map { zipTree(it).matching { exclude("META-INF", "META-INF/**") } } }) into(File(extension.root, "build/dependencies")) } project.afterEvaluate { tasks.forEach { if (it is NPMTask) { it.dependsOn(npmInstallTask) it.dependsOn(extractTypescriptDependenciesTask) } } } val typescriptTask = tasks.register("typescript") { group = "scriptcraft" taskName = "build" outputDir = "build/ts" } val apiJarTask = tasks.register("apiJar") { group = "scriptcraft" into("/types") { from(Callable { File(extension.root, "types") }) } into("/src") { from(Callable { File(extension.root, "build/dts") }) } archiveClassifier.set("api") dependsOn(typescriptTask) } artifacts { add("archives", apiJarTask) } tasks.named("processResources") { dependsOn(typescriptTask) into("scriptcraft") { from(Callable { File(extension.root, "build/ts") }) } } } }