All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-Beta1
Show newest version
/*
 * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * 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.tasks

import org.gradle.api.DefaultTask
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson
import org.jetbrains.kotlin.gradle.targets.js.npm.fakePackageJsonValue
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.MayBeUpToDatePackageJsonTasksRegistry
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinCompilationNpmResolver
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.PACKAGE_JSON_UMBRELLA_TASK_NAME
import org.jetbrains.kotlin.gradle.tasks.dependsOn
import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.getValue
import java.io.File

abstract class KotlinPackageJsonTask : DefaultTask() {

    init {
        onlyIf {
            npmResolutionManager.isConfiguringState()
        }
        outputs.upToDateWhen {
            // this way we will ensure that we need to resolve dependencies for the compilation in case of UP-TO-DATE task
            // used in KotlinCompilationNpmResolver#getResolutionOrResolveIfForced
            mayBeUpToDateTasksRegistry.get().markForNpmDependenciesResolve(it as KotlinPackageJsonTask)
            true
        }
    }

    @Transient
    private lateinit var nodeJs: NodeJsRootExtension

    private val npmResolutionManager by project.provider { nodeJs.npmResolutionManager }

    @Transient
    private lateinit var compilation: KotlinJsCompilation

    @get:Internal
    internal abstract val mayBeUpToDateTasksRegistry: Property

    private val compilationDisambiguatedName by lazy {
        compilation.disambiguatedName
    }

    @Input
    val projectPath = project.path

    private val compilationResolver
        get() = npmResolutionManager.resolver[projectPath][compilationDisambiguatedName]

    private val producer: KotlinCompilationNpmResolver.PackageJsonProducer
        get() = compilationResolver.packageJsonProducer

    @get:Input
    val packageJsonCustomFields: Map by lazy {
        PackageJson(fakePackageJsonValue, fakePackageJsonValue)
            .apply {
                compilation.packageJsonHandlers.forEach { it() }
            }.customFields
    }

    private fun findDependentTasks(): Collection =
        producer.internalDependencies.map { dependency ->
            npmResolutionManager.resolver[dependency.projectPath][dependency.compilationName].npmProject.packageJsonTaskPath
        } + producer.internalCompositeDependencies.map { dependency ->
            dependency.includedBuild?.task(":$PACKAGE_JSON_UMBRELLA_TASK_NAME") ?: error("includedBuild instance is not available")
            dependency.includedBuild.task(":${RootPackageJsonTask.NAME}")
        }

    @get:Input
    internal val toolsNpmDependencies: List by lazy {
        nodeJs.taskRequirements
            .getCompilationNpmRequirements(projectPath, compilationDisambiguatedName)
            .map { it.toString() }
            .sorted()
    }

    @get:Nested
    internal val producerInputs: KotlinCompilationNpmResolver.PackageJsonProducerInputs by lazy {
        producer.inputs
    }

    @get:OutputFile
    val packageJson: File by lazy {
        compilationResolver.npmProject.packageJsonFile
    }

    @TaskAction
    fun resolve() {
        compilationResolver.resolve()
    }

    companion object {
        fun create(compilation: KotlinJsCompilation): TaskProvider {
            val target = compilation.target
            val project = target.project
            val npmProject = compilation.npmProject
            val nodeJs = NodeJsRootPlugin.apply(project.rootProject)

            val rootClean = project.rootProject.tasks.named(BasePlugin.CLEAN_TASK_NAME)
            val npmInstallTask = nodeJs.npmInstallTaskProvider
            val npmCachesSetupTask = nodeJs.npmCachesSetupTaskProvider
            val packageJsonTaskName = npmProject.packageJsonTaskName
            val packageJsonUmbrella = nodeJs.packageJsonUmbrellaTaskProvider
            val packageJsonTask = project.registerTask(packageJsonTaskName) { task ->
                task.nodeJs = nodeJs
                task.compilation = compilation
                task.description = "Create package.json file for $compilation"
                task.group = NodeJsRootPlugin.TASKS_GROUP_NAME
                task.mayBeUpToDateTasksRegistry.apply {
                    set(MayBeUpToDatePackageJsonTasksRegistry.registerIfAbsent(project))
                    disallowChanges()
                }

                task.dependsOn(target.project.provider { task.findDependentTasks() })
                task.dependsOn(npmCachesSetupTask)
                task.mustRunAfter(rootClean)
            }
            packageJsonUmbrella.configure { task ->
                task.inputs.file(packageJsonTask.map { it.packageJson })
            }

            nodeJs.rootPackageJsonTaskProvider!!.configure { it.mustRunAfter(packageJsonTask) }

            compilation.compileKotlinTaskProvider.dependsOn(npmInstallTask!!)
            compilation.compileKotlinTaskProvider.dependsOn(packageJsonTask)

            return packageJsonTask
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy