gradlegradle-plugingradle-kotlin-dslgradle-task

A gradle project compiles successfully, how to replicate this success if it is included in another project?


The project I intend to include is the latest version of splain:

https://github.com/tek/splain

Which is built with gradle, and has the following extra task definition (in gradle kts):

    // invoke 
    task("dependencyTree") {

        dependsOn("dependencies")
    }

If I include it (in another gradle project):

include("splain")

I will encounter 2 problems:

  1. any build plugin used by splain that works only in root project (e.g. the "io.github.gradle-nexus.publish-plugin") will throw an error, because apparently splain is no longer a root project in this case (it is not a submodule either, so not sure how it is classified)

  2. if the new project also define the task "dependencyTree" it will cause a naming conflict:


org.gradle.api.internal.tasks.DefaultTaskContainer$DuplicateTaskException: Cannot add task 'dependencyTree' as a task with that name already exists.
    at org.gradle.api.internal.tasks.DefaultTaskContainer.failOnDuplicateTask(DefaultTaskContainer.java:257)
    at org.gradle.api.internal.tasks.DefaultTaskContainer.addTask(DefaultTaskContainer.java:250)
    at org.gradle.api.internal.tasks.DefaultTaskContainer.access$400(DefaultTaskContainer.java:76)
    at org.gradle.api.internal.tasks.DefaultTaskContainer$2.call(DefaultTaskContainer.java:298)
    at org.gradle.api.internal.tasks.DefaultTaskContainer$2.call(DefaultTaskContainer.java:292)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
    at org.gradle.api.internal.tasks.DefaultTaskContainer.doCreate(DefaultTaskContainer.java:292)
    at org.gradle.api.internal.tasks.DefaultTaskContainer.create(DefaultTaskContainer.java:334)
    at org.gradle.api.internal.tasks.DefaultTaskContainer.create(DefaultTaskContainer.java:75)
    at org.gradle.api.internal.project.DefaultProject.task(DefaultProject.java:1270)

Apparently gradle task names have to be unique per each run, there is no design of scope or namespace for names.

I need the gradle to be able to declare any other gradle project that compiles successfully on its own as "included", instead of adding a lot of extra constraint that no one used to worry about. Is it possible? If not, what can be possibly done to mitigate the above 2 problems?


Solution

  • You can use composite builds to include a completely independent Gradle build.

    // settings.gradle.kts
    
    rootProject.name = "my-project"
    
    includeBuild("../tek-splain")
    

    You can use included builds to substitute dependencies.

    // settings.gradle.kts
    
    rootProject.name = "my-project"
    
    includeBuild("../anonymous-library") {
        dependencySubstitution {
            substitute(module("org.sample:number-utils")).using(project(":"))
        }
    }
    

    The full documentation is here: https://docs.gradle.org/7.4.2/userguide/composite_builds.html#settings_defined_composite

    Source dependencies

    You can also declare a dependency on a public Git repository. Gradle will automatically checkout the remote repo, so you don't have to manage it.

    Be warned, it is experimental and can be unstable!

    https://blog.gradle.org/introducing-source-dependencies

    // settings.gradle
    
    sourceControl {
        gitRepository("https://github.com/gradle/native-samples-cpp-library.git") {
            producesModule("org.gradle.cpp-samples:utilities")
        }
    }