Looking for an example on how a custom plugin invokes another plugin/task

plugins

(dirk koehler) #1

Hi there,

I’m relatively new when it comes down to writing custom plugins. I’m wondering whether there examples out there which demonstrate how a plugin/task can invoke another task. Specifically I’d like to make use of the Zip task to archive a set of files and upload the artifact into artifactory via the com.jfrog.artifactory plugin. Any pointers to some sample code are or some code doing similar things highly appreciated.

Thx!


(Francois Ritaly) #2

I have an example which looks like this.

buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.4.0'
  }
}

apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.artifactory'

defaultTasks 'clean', 'artifactoryPublish'

group='com.company.gradle.samples'
version='1.0.0-SNAPSHOT'

// Package the sources files into a zip file and publish the file with a 'sources' classifier
task packageSources(type: Zip) {
  from sourceSets.main.allSource
  classifier = 'sources'
}

publishing {
  publications {
    mavenJava(MavenPublication) {
      from components.java

      // Also publish the source zip file
      artifact packageSources
    }
  }
}

artifactory {
  publish {
    contextUrl = 'https://artifactory/'

    repository {
      repoKey = "repository-name"
      username = artifactory_user
      password = artifactory_password
    }

    defaults {
      // Define the publications to publish
      publications('mavenJava')
    }
  }
}

(Steve Cohen) #3

Here’s an example of such a thing. Our organization has a practice of deploying artifacts to a legacy “software depot”, which is simply an NFS-directory. We have created a task that pulls the artifact just deployed to the local Maven repo and sends it via sftp to the “software depots”. This requires the org.hidetake.ssh plugin to work, and this plugin applies the ssh plugin.

import org.gradle.api.Plugin
import org.gradle.api.Project

import com.whatever.gradle.plugins.tasks.SoftwareDepotDeployer;
import static org.gradle.api.publish.maven.plugins.MavenPublishPlugin.PUBLISH_LOCAL_LIFECYCLE_TASK_NAME;

class SoftwareDepotDeployerPlugin implements Plugin<Project> {
    private SoftwareDepotDeployer swDepotTask
    
    @Override
    public void apply(Project project) {
        project.plugins.apply('org.hidetake.ssh')
        project.ext.swdepot = SoftwareDepotDeployer.class
        swDepotTask = createSwDeployerTask(project)
    }
    
    protected SoftwareDepotDeployer createSwDeployerTask(Project project) {
        SoftwareDepotDeployer task = project.tasks.create("deployToSWDepot", SoftwareDepotDeployer.class)
        task.dependsOn(project.tasks.findByName(PUBLISH_LOCAL_LIFECYCLE_TASK_NAME))
        task.init();
        return task;
    }


}

(dirk koehler) #4

Thanks for your replies, @sc1478 & @Francois_Ritaly. Unfortunately it’s not exactly what I was looking for. I’m interesting in writing a custom plugin which directly invokes another task implementation (along with providing [extension] configuration) rather then just declaring a dependency on it. Is this possible via some DSL or is that just not good practice?


(Steve Cohen) #5

I think what you want is to create a task in your plugin (as in my example). That task could invoke the other task you want to run, perhaps in a doLast() block.


(Francois Ritaly) #6

Directly invoking task methods isn’t how tasks are supposed to be used. The Gradle script is supposed to create dependencies between tasks, let Gradle resolve the build sequence and execute the tasks.

See this comment and this other comment


(Steve Cohen) #7

is doLast() frowned upon? I didn’t know that.

In any case, the PLUGIN wouldn’t invoke the task. The plugin would create a task that would somehow, via dependencies or maybe doLast, cause the other task to be invoked.


(Francois Ritaly) #8

Calling aTask.doLast() is perfectly fine because doLast() is part of the task public API.

I was referring to invoking a task’s internal method (a method which is not part of the task public API) because you know that’s the method which contains the logic you want to reuse. For instance aTask.execute() or aTask.zipMyFilesPlease().