Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add sourcesJar task to custom Gradle plugin

My company recently wrote gradle plugin for vanilla configuration (repositories, common dependencies across projects, etc). Overall, this has greatly simplified our build process and uncovered a few inconsistencies across projects. We recently tried to add a sourcesJar task to the plugin and it's not working.

Here's the broken plugin:

package com.mycompany.plugins

import org.gradle.api.Project
import org.gradle.api.Plugin
import org.gradle.api.tasks.bundling.Jar

class OurJavaPlugin implements Plugin<Project> {

    void apply(Project project) {

        def date = com.mycompany.util.UtilityFunctions.getDate()

        project.configure(project) {
            println('Applying Java properties to: ' + project.name)

            apply plugin: 'java'
            apply plugin: 'maven'
            apply plugin: 'idea'
            apply plugin: 'eclipse'

            version = date

            // Use the local repos
            repositories {
                maven {
                    url "$externalDependenciesRepo"
                }
                maven {
                    url "$internalDependenciesRepo"
                }
            }

            uploadArchives {
                repositories {
                    mavenDeployer {
                        // Deploy to internal repo
                        repository(url: "$internalDependenciesRepo")
                    }
                }
            }

            // Common dependencies
            dependencies {
                compile group: 'log4j', name: 'log4j', version:'1.2.17'
                compile group: 'org.slf4j', name: 'slf4j-log4j12', version:'1.6.6'
                compile group: 'org.slf4j', name: 'slf4j-api', version:'1.6.6'
                testCompile "junit:junit:$junit_version"
            }

            eclipse.project {
              natures 'org.springsource.ide.eclipse.gradle.core.nature'
            }

            task sourcesJar(type: Jar, dependsOn: classes) {
                classifier = 'sources'
                from sourceSets.main.allSource
            }

            artifacts {
                archives sourcesJar
            }
        }
    }
}

This plugin works great, except for the sourcesJar. When I add that into the mix (and compile/deploy to our local repo) I get this error when I try to build a project that uses the plugin:

$ gradle :myProject:clean -x Test
Applying Java properties to: myProject

FAILURE: Build failed with an exception.

* Where:
Build file 'C:\Users\me\Documents\code\root\myProject\build.gradle' line: 1

* What went wrong:
A problem occurred evaluating project ':myProject'.
> Failed to apply plugin [id 'customjava']
   > Could not find method sourcesJar() for arguments [{type=class org.gradle.api.tasks.bundling.Jar, dependsOn=task ':analytics-isr:classes'}, com.mycompany.plugins.OurJavaPlugin $_apply_closure1$_closure6@4c1d59cd] on project ':myProject'.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 3.352 secs
like image 511
fbl Avatar asked Jun 16 '16 22:06

fbl


1 Answers

When you define a task in build.gradle script one (out of 4) of task method is called - you can see the first one here. As you can also see none of these methods matches the DSL - with which - you define a task in build.gradle. Why? Because before execution every build.gradle is evaluated to translate the DSL to appropriate methods invocations. For further details please have a look at this question.

The mentioned mechanism does not work in a custom plugin - here the code is interpreted as is without translating it. As you can see here there's no sourcesJar method defined on Project class. To create a task inside a plugin you need to invoke on of the mentioned task methods, e.g.:

task('sourcesJar', type: Jar, dependsOn: classes) {
   classifier = 'sources'
   from sourceSets.main.allSource
}

which invokes exactly this method (I know the arguments order is different but this is how groovy works - trust me).

Also you don't need project.configure(project) {...}, project.with {...} will be enough.

like image 107
Opal Avatar answered Sep 23 '22 01:09

Opal