This issue will be an initiative to revamp the Ballerina Gradle Plugin. Following areas are to be considered with this effort.
Identified Issues
Use Proper Gradle Tasks Instead of Passing Arguments
Currently, most of the Ballerina-specific arguments are passed as command-line parameters. Consider the following scenarios:
Publishing to local central
./gradlew build -P publishToLocalCentral=true
Publishing to Ballerina central
./gradlew build -P publishToCentral=true
Test with GraalVM
./gradlew build -P balGraalVMTest
All these cases are handled by passing custom CLI parameters, which is incorrect. Ideally, the publish tasks should be part of the Gradle publish task, and the GraalVM test should be a part of the Gradle test task. These scenarios should be included as separate Gradle tasks instead of using the build command for everything.
Handle All Possible Scenarios within the Plugin
Currently, the Ballerina Gradle Plugin only handles the ballerina submodule build within a Ballerina Library project. While this was useful for the time being, the ideal solution would be to handle a complete Ballerina library project. This should include:
Ballerina Native Build
This is the native Java code that packs with a Ballerina library package. There are many Ballerina libraries that have a native submodule. This was the reason behind using Gradle for Ballerina library projects. But the current Ballerina plugin does not build this directory, instead, the Java Gradle plugin is used to build this submodule. But ideally, the Ballerina Gradle plugin should check the existence of the native submodule and build it within the Ballerina plugin since this is a part of the Ballerina Library Gradle project. We can use the Ballerina Java plugin internally to build the Java project.
Ballerina Tests Build
This is a separate Gradle submodule used for writing tests for a Ballerina package, in addition to the unit tests. Ballerina packages like HTTP, GraphQL, and Log, uses this approach to test the packages. This submodule is also a Ballerina project. Ideally, the Ballerina Gradle plugin should handle this submodule, if exists.
Ballerina Compiler Plugin Build
Some Ballerina libraries include a compiler plugin, written in Java. This should also be handled by the Ballerina plugin, if the compiler plugin exists.
Ballerina Compiler Plugin Tests Build
This is for testing the compiler plugin. This is also a Gradle submodule and is handled using the Java plugin currently. But this too should be handled within the Ballerina plugin.
Examples
Ballerina Libraries include a set of examples that reside within the repository. These examples are also a part of the Ballerina build since the examples should be up-to-date with the package changes, and any discrepancies should be identified at the build phase. The examples directory includes a set of directories per example, and the Ballerina Gradle plugin should handle each of the examples.
Handle Ballerina Connector Builds
The Ballerina connectors have some differences from the usual Ballerina packages. There are hand-written connectors and generated connectors. These different connector types should be considered and handled within the plugin.
Handle Test Groups
The Ballerina test groups are also handled by a CLI parameter. Ideally, we should handle this as a parameter for the test task.
Handle Debugging within the Plugin
The debugging of the project is currently handled by a separate parameter. We should research more on this subject and come up with the best possible solution, which IMO, isn't a custom CLI parameter.
Handle Inputs and Outputs of a Ballerina Project
Gradle uses inputs and outputs to determine whether a particular task should be re-run or not in subsequent builds. Currently, the Ballerina Gradle plugin does not define any inputs or outputs, resulting in the Ballerina package being compiled for each build even though there are no code changes. This amounts to a lot of developer time and the introduction of this will drastically reduce the time spent for subsequent builds.
Fix OS-Related Issues
There are some known limitations and issues, especially related to Windows build. We need proper testing and identifying these issues to properly address them.
Publish the Ballerina Gradle Plugin to Gradle Plugin Portal
Refer to ballerina-platform/ballerina-library#7288
Design Considerations
For most of the above-mentioned issues, we need to scan the project directory and identify the type of the project. We can start this by identifying the potential project types. Then we can decide how to cater to these different types of projects.
After this effort, the Ballerina Gradle plugin should be applied to the root Gradle project.
We should minimize the number of CLI arguments needed to run the Ballerina project. It is okay to have more tasks defined than to have more parameters for the same task.
Gradle plugins were written using Groovy in the past, but now the default option is to write plugins using Kotlin. We can explore the possibility of writing the plugin using Kotlin with this effort, although this is not a necessity.
Summary
The above-mentioned issues/improvements are not blocking currently, but implementing these would be a great help and will reduce the time spent creating a new Ballerina package, and also time spent when building a Ballerina library package.
This is also a good internship project as well, where we can spend time researching more on the topic, and identify the areas where we can improve the performance as well.
Introduction
This issue will be an initiative to revamp the Ballerina Gradle Plugin. Following areas are to be considered with this effort.
Identified Issues
Use Proper Gradle Tasks Instead of Passing Arguments
Currently, most of the Ballerina-specific arguments are passed as command-line parameters. Consider the following scenarios:
All these cases are handled by passing custom CLI parameters, which is incorrect. Ideally, the publish tasks should be part of the Gradle publish task, and the GraalVM test should be a part of the Gradle test task. These scenarios should be included as separate Gradle tasks instead of using the build command for everything.
Handle All Possible Scenarios within the Plugin
Currently, the Ballerina Gradle Plugin only handles the
ballerina
submodule build within a Ballerina Library project. While this was useful for the time being, the ideal solution would be to handle a complete Ballerina library project. This should include:Ballerina Native Build
This is the native Java code that packs with a Ballerina library package. There are many Ballerina libraries that have a native submodule. This was the reason behind using Gradle for Ballerina library projects. But the current Ballerina plugin does not build this directory, instead, the Java Gradle plugin is used to build this submodule. But ideally, the Ballerina Gradle plugin should check the existence of the
native
submodule and build it within the Ballerina plugin since this is a part of the Ballerina Library Gradle project. We can use the Ballerina Java plugin internally to build the Java project.Ballerina Tests Build
This is a separate Gradle submodule used for writing tests for a Ballerina package, in addition to the unit tests. Ballerina packages like HTTP, GraphQL, and Log, uses this approach to test the packages. This submodule is also a Ballerina project. Ideally, the Ballerina Gradle plugin should handle this submodule, if exists.
Ballerina Compiler Plugin Build
Some Ballerina libraries include a compiler plugin, written in Java. This should also be handled by the Ballerina plugin, if the compiler plugin exists.
Ballerina Compiler Plugin Tests Build
This is for testing the compiler plugin. This is also a Gradle submodule and is handled using the Java plugin currently. But this too should be handled within the Ballerina plugin.
Examples
Ballerina Libraries include a set of examples that reside within the repository. These examples are also a part of the Ballerina build since the examples should be up-to-date with the package changes, and any discrepancies should be identified at the build phase. The examples directory includes a set of directories per example, and the Ballerina Gradle plugin should handle each of the examples.
Handle Ballerina Connector Builds
The Ballerina connectors have some differences from the usual Ballerina packages. There are hand-written connectors and generated connectors. These different connector types should be considered and handled within the plugin.
Handle Test Groups
The Ballerina test groups are also handled by a CLI parameter. Ideally, we should handle this as a parameter for the test task.
Handle Debugging within the Plugin
The debugging of the project is currently handled by a separate parameter. We should research more on this subject and come up with the best possible solution, which IMO, isn't a custom CLI parameter.
Handle Inputs and Outputs of a Ballerina Project
Gradle uses inputs and outputs to determine whether a particular task should be re-run or not in subsequent builds. Currently, the Ballerina Gradle plugin does not define any inputs or outputs, resulting in the Ballerina package being compiled for each build even though there are no code changes. This amounts to a lot of developer time and the introduction of this will drastically reduce the time spent for subsequent builds.
Fix OS-Related Issues
There are some known limitations and issues, especially related to Windows build. We need proper testing and identifying these issues to properly address them.
Publish the Ballerina Gradle Plugin to Gradle Plugin Portal
Refer to ballerina-platform/ballerina-library#7288
Design Considerations
Summary
The above-mentioned issues/improvements are not blocking currently, but implementing these would be a great help and will reduce the time spent creating a new Ballerina package, and also time spent when building a Ballerina library package.
This is also a good internship project as well, where we can spend time researching more on the topic, and identify the areas where we can improve the performance as well.