3

I'm totally stuck here. I am writing a java class that is supposed to manipulate gradle builds.

I've managed to instantiate gradle tooling API (Connector, GradleProject), but neither of these would let me get the plain simple list of all the tasks available for BuildLauncher (hint: some of the tasks might be in plugins). However, I've managed to run ":tasks" task, and then parse its output, but it sounds terrible.

One of the ideas was to somehow obtain a org.gradle.api.Project reference, but I couldn't make it either.

Am I missing something big, or is it just that tooling API was never meant to provide access to the gradle API?

Opal
  • 81,889
  • 28
  • 189
  • 210
tishma
  • 1,855
  • 1
  • 21
  • 43

3 Answers3

2

It seems that the following piece of code may help you:

GradleConnector connector = GradleConnector.newConnector();
connector.forProjectDirectory(new File(".")); // project dir

ProjectConnection connection = connector.connect();
try {
   // Load the model for the project
   GradleProject project = connection.getModel(GradleProject.class);
   System.out.println("Project: " + project.getName());
   System.out.println("Tasks:");
   for (Task task : project.getTasks()) {
       System.out.println("    " + task.getName());
    }
 } finally {
    // Clean up
    connection.close();
 }

Basically you need to obtain the model. Please also have a look at the samples under $GRADLE_HOME/sample/toolingApi.

Opal
  • 81,889
  • 28
  • 189
  • 210
  • 1
    Thanks @Opal. Actually, that's about the same code I was able to find myself, and that I'm complaining about. I'd expect the output of this to be equivalent to the output of ':tasks' task (titled: All tasks runnable from root project). I have more or less 'Hello world' Android Studio gradle project, and there are sections: Android tasks, Build tasks, Build setup tasks, ... total of 20something tasks, but running this code gives me only 10 tasks. – tishma Jun 19 '15 at 19:37
  • Could you please provide an example that reproduces the problem? – Opal Jun 20 '15 at 05:44
  • I don't think I'd be able to provide all that's relevant. It's a result of default New Project plus selecting a single activity in Android Studio AI-141.2006197. I know it refers android gradle plugin, but no android tasks (from the plugin) are found using project.getTasks(). – tishma Jun 20 '15 at 11:16
1

If you run gradle :tasks, it will list tasks for all projects.

If you do the following, it will only list tasks for the root project:

GradleProject project = connection.getModel(GradleProject.class);
for (Task task : project.getTasks()) {
    System.out.println("    " + task.getName());
}

This might explain why you're only seeing 10 tasks when you expect 20+ tasks.

To list all tasks, you need to iterate through all projects.

As the project hierarchy is a tree, you will probably need to use recursion to walk through the tree structure.

You can use project.getChildren() to list child project nodes and walk/traverse the tree. At each project node, you can use project.getTasks() to get the tasks.

badsyntax
  • 9,394
  • 3
  • 49
  • 67
0

I hate to answer my own question, and I've already mentioned that I'm not happy with this solution, but here it is in case someone needs it. I won't accept it.

It consists of running ":tasks" task that happens to print all available tasks to it's stdout. Unfortunately, not all lines of the stdout contain task names, but I did not have to deal with that.

    OutputStream outputStream = new OutputStream() {
        private StringBuilder string = new StringBuilder();
        @Override
        public void write(int b) throws IOException {
            this.string.append((char) b);
        }
        public String toString() {
            return this.string.toString();
        }
    };

    ProjectConnection connection = GradleConnector.newConnector()
            .forProjectDirectory(getProjectDirectoryFile())
            .connect();

    BuildLauncher buildLauncher = connection.newBuild();
    buildLauncher.forTasks(":tasks");

    buildLauncher.setStandardOutput(outputStream);
    buildLauncher.run();

    for (String line : outputStream.toString().split("\\r?\\n")) {
        if(containsTaskName(line)) {
            String taskName = line.split(" ")[0];
            System.out.println(taskName);
        }
    }
tishma
  • 1,855
  • 1
  • 21
  • 43