English 中文(简体)
How can I import one Gradle script into another?
原标题:

I have a complex Gradle script that wraps up a load of functionality around building and deploying a number of NetBeans projects to a number of environments.

The script works very well, but in essence it is all configured through half a dozen maps holding project and environment information.

I want to abstract the tasks away into another file, so that I can simply define my maps in a simple build file, and import the tasks from the other file. In this way, I can use the same core tasks for a number of projects and configure those projects with a simple set of maps.

Can anyone tell me how I can import one Gradle file into another, in a similar manner to Ant s task? I ve trawled Gradle s docs to no avail so far.

Additional Info

After Tom s response below, I thought I d try and clarify exactly what I mean.

Basically I have a Gradle script which runs a number of subprojects. However, the subprojects are all NetBeans projects, and come with their own ant build scripts, so I have tasks in Gradle to call each of these.

My problem is that I have some configuration at the top of the file, such as:

projects = [
    [name:"MySubproject1", shortname: "sub1", env:"mainEnv", cvs_module="mod1"],
    [name:"MySubproject2", shortname: "sub2", env:"altEnv", cvs_module="mod2"]
]

I then generate tasks such as:

projects.each({
    task "checkout_$it.shortname" << {
         // Code to for example check module out from cvs using config from  it .
    }
})

I have many of these sort of task generation snippets, and all of them are generic - they entirely depend on the config in the projects list.

So what I want is a way to put this in a separate script and import it in the following sort of way:

projects = [
    [name:"MySubproject1", shortname: "sub1", env:"mainEnv", cvs_module="mod1"],
    [name:"MySubproject2", shortname: "sub2", env:"altEnv", cvs_module="mod2"]
]

import("tasks.gradle") // This will import and run the script so that all tasks are generated for the projects given above.

So, in this example, tasks.gradle will have all the generic task generation code in, and will get run for the projects defined in the main build.gradle file. In this way, tasks.gradle is a file that can be used by all large projects that consist of a number of sub-projects with NetBeans ant build files.

最佳回答

The answer to the question turned out to be in the Plugins system, where you can add the desired functionality in a set of plugins which can be groovy files located in the directory buildSrc/src/main/groovy. Plugins can also be bundled as a Jar though I haven t tried this.

Details here: Custom Plugins

问题回答

There is a new feature in 0.9. You can use apply from: other.gradle command.

Read my question about same thing at: Is there a way to split/factor out common parts of Gradle build

Well, it is hard to tell what serves you best without actually seeing your build file.

I could assume that stetting up your environment as multi-project build should provide you the abstraction you are looking for.

In your project root build.gradle you define all your domain specific stuff as well as the things that apply to all your subprojects:

repositories {
    add(new org.apache.ivy.plugins.resolver.FileSystemResolver()) {
        name =  destRepo 
        addIvyPattern( file( project.properties[ repo.dest.dir ]).absolutePath +  /[organisation]/[module]/ivys/ivy(-[revision]).xml )
        addArtifactPattern( file( project.properties[ repo.dest.dir ]).absolutePath +  /[organisation]/[module]/[type]s/[artifact](-[revision]).[ext] )
        descriptor =  optional 
        checkmodified = true
    }
    ...
}
...
subprojects {
    sourceCompatibility = 1.5
    targetCompatibility = 1.5
    group =  my.group 
    version =  1.0 
    uploadArchives {
        uploadDescriptor = true
        repositories {
            add rootProject.repositories.destRepo
        }
    }
    apply{ type my.group.gradle.api.plugins.MyPlugin }
    ...
}

dependsOnChildren()

The project root directory might also contain a gradle.properties file where you define properties used by your projects:

buildDirName=staging
repo.dest.dir=/var/repo
...

Then in an additional file from your project root named settings.gradle you actually point to your subprojects:

include  my-first-component ,
         my-second-component 
...
project( :my-first-component ).projectDir = new File(rootDir,  path/to/first/component )
project( :my-second-component ).projectDir = new File(rootDir,  path/to/second/component )
...

Each sub-project directory contains a build.gradle file containing the sub-project specific stuff only.

No matter if you invoke gradle from your project root or sub-project directory, gradle will automatically consider all your definitions done in the various files.

Also note that no compile task will be executed for your project root as long as you don t load any plugin beyond the default plugin at the root level.

This is an example for Kotlin DSL (build.gradle.kts).

apply(from = "scripts/my-script.gradle.kts")

scripts/my-script.gradle.kts:

println(
    """
    I am defined at the top level of the script and
    executed at the configuration phase of build process
    """
)

tasks.create("MyTask") {
    println(
        """
        I am defined in a task and
        run at the configration phase of build process"""
    )
    doLast {
        // ...
    }
}

See this answer and this answer for how to import a function from another script in Kotlin DSL.

Based off this similar question/answer, the easiest solution I ve found after searching for days is using buildscript.sourceFile. It correctly gives the file being run rather than the pwd/cwd/parent-file of said process. I feel like this would solve your issue.





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签