Call tasks from within an applied plugin in an external build.gradle file

Hello all,

As stated in the title, I would like to be able to call a task (from a custom plugin I wrote) in an external build.gradle file. If possible, I would also like to be able to pass arguments (that can be interpreted as command line arguments by the plugin) to the task.

How can I do this? I’ve searched the web for hours and hours, with no result.

The main point is that the custom plugin shouldn’t be altered anymore, as it’s use isn’t pinned to this project only - meaning it should be possible to use it for other projects too, therefore it should be as abstract as possible.

I hope someone understands me, as I’m not very good at explaining ^^

Any help or answer is appreciated!

~ Joe

I’m not sure if I understand the question, but build scripts and plugins don’t call tasks. They declare tasks, and add dependencies between them (all in the configuration phase). In the execution phase, the tasks requested by the user are executed, along with any depended-on tasks.

If you explained your use case, I might be able to say more.

First of all thank you for the swift reply.

I’ll explain the use case:

I’m trying to create an installation proces, consisting of multiple steps. I wrote 2 custom plugins that take care of specific tasks (backing up a given file and code insertion into a given file) which I would like to be able to re-use along these different steps.

The thing is that I need to be able to call these two plugins at about every step, and supply them with different command line arguments for each step (the command line arguments are located in a gradle.properties file).

I think it’s obvious the custom plugins are 2 standalone projects, they don’t “know” anything about the multi-step installation.

This wouldn’t be a problem if this was all one big project, but it’s crucial for the custom plugins to be as abstract as possible so they can be re-used later on for other purposes.

I hope this clarifies the situation a bit more.

~ Joe

In that case, the plugins would just supply the task types. Someone else (build script, another plugin) would then create the necessary tasks and task dependencies. This could be done directly, or you could come up with some “step” abstraction that creates tasks under the hood.

Keep in mind that Gradle’s execution model is declarative rather than imperative. Build scripts and plugins don’t call tasks, they declare them (along with their dependencies). Each task is executed at most once, but you can have multiple tasks of the same type, and can configure them in one go.

Could you clarify your answer a little bit more? I don’t really understand what you mean.

If this helps: The plugins are just pieces of code. These just need to be separated from the installation process, wether as plugins or in any other way. So if there’s another approach that works - not using plugins - to be able to entirely separate this code from the installation process, I’d be happy to try that out.

~ Joe

It’s difficult for me to provide advice because I don’t really understand what your question is. To make external code available to build scripts (if that’s the question), you have to declare it as a build script dependency. See External dependencies for build scripts in the Gradle User Guide.

Thank you for the answers so far.

my build.gradle file looks like this at the moment:

apply plugin: 'insertCodePlugin'
apply plugin: 'backupPlugin'
  buildscript {
    repositories {
        maven {
            url uri('../repo')
        }
    }
      dependencies {
        classpath group: 'com.me', name: 'insertCodePlugin', version: '1.1-SNAPSHOT'
        classpath group: 'com.me', name: 'backupPlugin', version: '1.1-SNAPSHOT'
    }
  }
  task moduleInstallation << {
    ...
      insertCodePlugin.'import-code'(file: "", code: "", closure: "", parentTags: "")
          ...
}

As you can see, the goal is to be able to call a method/task from the insertCodePlugin that’s declared as a dependency.

The plugin I call is structured as follows:

class InsertCodePlugin implements Plugin<Project> {
      def void apply(Project project) {
        project.task('import-code') << {
  ...
    importCode(project)
     ...
             }
    }
      void importCode(Project project) {
 ...
          testCase(...)
   ...
    }
      void testCase(..) {
 ...
 saveFile(...)
    }
      private static void saveXmlFile(...) {
 ...
        }
}

I hope this helps. I just need to be able to call the task in the apply method, and add some (command line) arguments to that call.

Appreciate your help so far!

~ Joe

Again, plugins don’t call tasks, and also tasks don’t call other tasks. Before you start writing your own plugins, I recommend to study the first few chapters of the Gradle User Guide, and also the Writing Custom Plugins chapter. It may also help to check out some of the plugins in the Gradle codebase (e.g. one of the code-quality plugins).

The lack of me being able to explain the situation and my needs is killing me ^^

I just have the plugin (which is basically a class with methods) and a build script. The script should be able to access the class methods, that’s all. For what it’s worth, the code to be called doesn’t have to be a task. It can be a method, or any other possible type of code block. I don’t care how it’s done, the code just needs to be kept separated.

I have declared the plugins as dependencies - as you said Peter - but that doesn’t help me further. The only thing that does is add the tasks in that plugin to the list of tasks (as seen by typing “gradle tasks” in the terminal).

I don’t know how to explain it otherwise… So if you really don’t think you understand it or you think you can’t help me, so be it. I’ve received quite a few answers from you already, for which I am very gratefull.

~ Joe

Another thing:

I’ve read the parts I need from the user guide a couple of times already. In chapter 56.5.1 (Using your standalone plugin in another project), it’s described how to add the plugin as a dependency.

But how can you use it then? Can you just call it like “plugin.methodName()”?

I’m really puzzled.

~ Joe