0

Do we have any option to read the contents of the build.gradle file in a java program. I was able to do something similar in maven using the below code. Now, I'm looking at options to do the same in gradle. I tried using Gradle-tooling-api as explained below, but getting some errors (not sure if I'm following the right approach).

reading pom.xml using MavenXpp3Reader

    ```FileReader fileReader;
    try {
        fileReader = new FileReader(destPath);
    } catch (FileNotFoundException fileNotFoundException) {
        fileNotFoundException.printStackTrace();
    }
    MavenXpp3Reader reader = new MavenXpp3Reader();
    Model pomModel = reader.read(fileReader);

    //close the file reader
    fileReader.close();
    ```

Tried to leverage gradle-tooling-api as below, but got the below error.

public class ToolingApiCustomModelPlugin implements Plugin<Project> {
    private final ToolingModelBuilderRegistry registry;

    @Inject
    public ToolingApiCustomModelPlugin(ToolingModelBuilderRegistry registry) {
        this.registry = registry;
    }

    @Override
    public void apply(Project project) {
        registry.register(new CustomToolingModelBuilder());
    }

    private static class CustomToolingModelBuilder implements ToolingModelBuilder {
        @Override
        public boolean canBuild(String modelName) {
            return modelName.equals(CustomModel.class.getName());
        }

        @Override
        public Object buildAll(String modelName, Project project) {
            List<String> pluginClassNames = new ArrayList<String>();

            for(Plugin plugin : project.getPlugins()) {
                pluginClassNames.add(plugin.getClass().getName());
            }

            return new DefaultModel(pluginClassNames);
        }
    }
}

public static void main(String[] args) {
        GradleConnector connector = GradleConnector.newConnector();
        connector.forProjectDirectory(new File("./sample"));
        ProjectConnection connection = null;

        try {
            connection = connector.connect();
            ModelBuilder<CustomModel> customModelBuilder = connection.model(CustomModel.class);
            //customModelBuilder.withArguments("--init-script", "init.gradle");
            CustomModel model = customModelBuilder.get();    
}   

Exception in thread "main" org.gradle.tooling.UnknownModelException: No model of type 'CustomModel' is available in this build.

Caused by: org.gradle.tooling.provider.model.UnknownModelException: No builders are available to build a model of type 'org.gradle.sample.toolingapi.CustomModel'.

Marco R.
  • 2,667
  • 15
  • 33
Prasanth Mohan
  • 285
  • 1
  • 2
  • 12

1 Answers1

1

The entire build.gradle file is translated into a project object during the build's initialization phase:

There is a one-to-one relationship between a Project and a "build.gradle" file. During build initialisation, Gradle assembles a Project object for each project which is to participate in the build

So you can access any configuration (implicit or explicit) from your build.gradle by accessing the programatic project object model after the build.gradle file has been translated, during execution phase

You can do this in a customized gradle plugin or in a simple gradle type right inside your build.gradle (seems recursive; but that's why you have phases to delimit reading the file and accessing the project object).

Paste the following task in your build.gradle and execute it in the command line (gradle diagnostics) to output all plugins, configurations and the names of the tasks present in the build.gradle file:

task diagnostics {
    doLast {
        println project.plugins
        println project.tasks*.name
        println project.configurations
    }
}

These links will help you check how to navigate to the different properties inside the gradle project object:

For properties and methods exposed by other plugins you have to reach the plugin first and then refer to their respective documentation to follow from there. Finally plugins may register what are know as extensions right into the project object, so you can reach them as direct properties of the project.

Hope this helps.

Marco R.
  • 2,667
  • 15
  • 33
  • 1
    Thanks Marco. Quick clarification, I'm trying to get the project model details from outside the build.gradle file inside a java program. What I have as input is the build.gradle file and what I need as output is a populated Project object. Is there any way to do that ? – Prasanth Mohan May 21 '19 at 09:42
  • 1
    In that case you can use the gradle tooling API. This is a great tutorial with working examples: https://dzone.com/articles/gradle-tooling-api-introduction – Marco R. May 21 '19 at 10:07
  • 1
    Thanks Marco. I did see this article. GradleProject model had limited fields and I couldnt find ways to get the plugins and project details. So, wasn't sure if I was going in the correct direction. Anyways, I have decided to write my own model builder using groovy ast parser, as I had to update the build.gradle file post processing and overwrite the original build.gradle. – Prasanth Mohan May 21 '19 at 14:00