All those who've worked on automating the builds must have worked on ANT. ANT was a simple tool but extremely effective in making the builds automated. It had a simple XML based structure, allowed you to break building pieces into tasks and easily use external JARS. You could also create your own tasks.
However, I think Ant has not evolved as we would have wanted. The XML syntax, despite being easy to use is tedious. Time to analyze the other players on the block.
A few popular ones out today are:
The biggest endorsement for Gradle comes from Google itself who've based their new Android IDE, Android studio completely on Gradle, need I say more? The flexibility that Gradle provides is amazing, you can use Gradle to:
To understand the examples better, you can read basics about gradle here:
Gradle Homepage
Gradle JS Plugin
Download Gradle at: Gradle 2.1
Let's get started! First create an empty text file and name it "build.gradle". Second thing we will do is define the plugins we are going to use for this
Create a new text file "gradle.properties" and add a variable as follows:
message=Hello World
And this is how we use it in the script:
println "Just want to say ${message}";
Simple, ain't it! That's not all. Gradle also provides a powerful mechanism of creating custom properties files and using both the default one and the custom one. This is particularly useful when you want to customize build according to themes but don't want to specify the common properties repeatedly. We will see it in action in the tutorial that follows:
In this tutorial, I will create a Task, which will first combine a list of JS files, combine them and then Obfuscate the same using Google Closure compiler.
First thing we will do is load a properties file
Here, we loaded a custom properties file based on the theme parameter. Now, I will create the tasks to Combine the JS files. We will create 2 tasks, just to demonstrate use of custom properties.
So, here, we created 2 tasks, both of type CombineJsTask. The idea here is to fetch a list of JS files from properties and combine them. In the first task, the list of JS files was picked from the default properties and in the second one, it was picked from the custom properties. In the second one, we also used a condition to check whether we are making a build for mobile flavor or not. Here flavor is just another variable which can be anything but when working with Android studio, flavor is special but will talk about that later. Variables can also be provided as input parameters, to a gradle script, but that for later.
By now, we have written code to combine all JS files into 2 files common.js and custom.js. Now, we'd create tasks to minify these using Google Closure Compiler.
So, now we have all the tasks ready but we need to define the dependencies so that they execute in the correct order. For that we'd add a few more lines to the gradle script:
We have defined dependencies in a way that when we call minifyCommonJS task, it will execute all other tasks due to the defined dependencies. That's it, we have the script ready. Before we execute, let us see how to define JS files in the properties file.
gradle.properties:
defaulttheme.properties:
customtheme.properties:
Here, we have created 3 properties files, one default one and 2 for the themes. Take special care that there is no space between the file names and no trailing spaces. Now let us see how to execute this gradle script.
Assuming you've added gradle to the Path. Open command line, locate to the folder containing the build.gradle file and type:
Here we have instructed gradle to run the task minifyCommonJS and provide 2 properties as input, theme and flavor. The properties need to be defined using the -P syntax. Note there is no space after -P.
When this task runs, the defaulttheme.properties file will be loaded and from the scripts, mobile_common_scripts will be compiled in the combineCommonJS task. We can change the input properties to change the behavior as follows:
Once the task executes, we will have the minimized and obfuscated output for the JS files. That's it! We have successfully created and executed a gradle build.
This concludes the tutorial but we have just about touched Gradle. The possibilities are endless. Gradle for Android brings an interesting concept of flavor. With the help of flavor, you can maintain different assets per flavor and at the time of compilation, it will only copy the chosen flavor. Makes life easier. To explore the full powers of Gradle on Android, use Android Studio.
Gradle for XCODE is something I am yet to touch but you can read about it here: Gradle XCode Plugin
I hope this post helps you in getting familiar with Gradle. For any queries, feel free to email me
However, I think Ant has not evolved as we would have wanted. The XML syntax, despite being easy to use is tedious. Time to analyze the other players on the block.
A few popular ones out today are:
- Maven
- Gulp
- Grunt
- NodeJS
- Gradle
- Ant Tasks
- RequireJS
- Google Closure Compiler
- GZipJs
- ...and many more
The biggest endorsement for Gradle comes from Google itself who've based their new Android IDE, Android studio completely on Gradle, need I say more? The flexibility that Gradle provides is amazing, you can use Gradle to:
- Build JS Projects
- Build Android projects
- .. And also build XCode Projects
To understand the examples better, you can read basics about gradle here:
Gradle Homepage
Gradle JS Plugin
Download Gradle at: Gradle 2.1
Let's get started! First create an empty text file and name it "build.gradle". Second thing we will do is define the plugins we are going to use for this
buildscript {That's all we need, Gradle will itself download and install all plugins defined when build script is run. As we move ahead, some of the things will seem strikingly similar to Ant. Gradle leverages on ANT and the terminology it uses is also quite close. The methods are called tasks and variables are accessed using $(var). Just like Ant, Gradle allows defining configurations in a properties file. The name of the default properties file is gradle.properties. Any property defined in the properties file can be used using the varName syntax. Let's see an example:
repositories {
jcenter()
}
dependencies {
classpath "com.eriwen:gradle-js-plugin:1.12.1"
}
}
Create a new text file "gradle.properties" and add a variable as follows:
message=Hello World
And this is how we use it in the script:
println "Just want to say ${message}";
Simple, ain't it! That's not all. Gradle also provides a powerful mechanism of creating custom properties files and using both the default one and the custom one. This is particularly useful when you want to customize build according to themes but don't want to specify the common properties repeatedly. We will see it in action in the tutorial that follows:
In this tutorial, I will create a Task, which will first combine a list of JS files, combine them and then Obfuscate the same using Google Closure compiler.
First thing we will do is load a properties file
Properties props = new Properties() props.load(new FileInputStream("${theme}.properties"));
Here, we loaded a custom properties file based on the theme parameter. Now, I will create the tasks to Combine the JS files. We will create 2 tasks, just to demonstrate use of custom properties.
task combineCommonJS(type: com.eriwen.gradle.js.tasks.CombineJsTask) {
Listlist = new ArrayList ();
if(flavor == "mobile")
{
mobile_common_scripts.split(",").each{String f -> list.add(f)}
}
else
{
common_scripts.split(",").each{String f -> list.add(f)}
}
source = list;
dest = file("${buildDir}/common.js")
}
task combineCustomJS(type: com.eriwen.gradle.js.tasks.CombineJsTask) {
Listlist = new ArrayList ();
if(flavor == "mobile")
{
props.mobile_custom_scripts.split(",").each{String f -> list.add(f)}
}
else
{
props.custom_scripts.split(",").each{String f -> list.add(f)}
}
source = list;
dest = file("${buildDir}/custom.js")
}
So, here, we created 2 tasks, both of type CombineJsTask. The idea here is to fetch a list of JS files from properties and combine them. In the first task, the list of JS files was picked from the default properties and in the second one, it was picked from the custom properties. In the second one, we also used a condition to check whether we are making a build for mobile flavor or not. Here flavor is just another variable which can be anything but when working with Android studio, flavor is special but will talk about that later. Variables can also be provided as input parameters, to a gradle script, but that for later.
By now, we have written code to combine all JS files into 2 files common.js and custom.js. Now, we'd create tasks to minify these using Google Closure Compiler.
task minifyCommonJS(type: com.eriwen.gradle.js.tasks.MinifyJsTask) {
source = file("${buildDir}/common.js")
dest = file("${buildDir}/common.min.js")
closure {
warningLevel = 'QUIET'
}
}
task minifyCustomJS(type: com.eriwen.gradle.js.tasks.MinifyJsTask) {
source = file("${buildDir}/custom.js")
dest = file("${buildDir}/custom.min.js")
closure {
warningLevel = 'QUIET'
}
}
So, now we have all the tasks ready but we need to define the dependencies so that they execute in the correct order. For that we'd add a few more lines to the gradle script:
minifyCommonJS.dependsOn combineCommonJS minifyCustomJS.dependsOn combineCustomJS combineCommonJS.dependsOn minifyReaderJS
We have defined dependencies in a way that when we call minifyCommonJS task, it will execute all other tasks due to the defined dependencies. That's it, we have the script ready. Before we execute, let us see how to define JS files in the properties file.
gradle.properties:
common_scripts=lib/a.js,lib/b.js,lib/c.js
mobile_common_scripts=lib/a.js,lib/b.js,lib/mobile.js
defaulttheme.properties:
custom_scripts=defaulttheme/1.js,defaulttheme/2.js
customtheme.properties:
custom_scripts=customtheme/1.js,custom=theme/2.js
Here, we have created 3 properties files, one default one and 2 for the themes. Take special care that there is no space between the file names and no trailing spaces. Now let us see how to execute this gradle script.
Assuming you've added gradle to the Path. Open command line, locate to the folder containing the build.gradle file and type:
gradle minifyCommonJS -Ptheme=defaulttheme -Pflavor=mobile
Here we have instructed gradle to run the task minifyCommonJS and provide 2 properties as input, theme and flavor. The properties need to be defined using the -P syntax. Note there is no space after -P.
When this task runs, the defaulttheme.properties file will be loaded and from the scripts, mobile_common_scripts will be compiled in the combineCommonJS task. We can change the input properties to change the behavior as follows:
gradle minifyCommonJS -Ptheme=customtheme -Pflavor=web
Once the task executes, we will have the minimized and obfuscated output for the JS files. That's it! We have successfully created and executed a gradle build.
This concludes the tutorial but we have just about touched Gradle. The possibilities are endless. Gradle for Android brings an interesting concept of flavor. With the help of flavor, you can maintain different assets per flavor and at the time of compilation, it will only copy the chosen flavor. Makes life easier. To explore the full powers of Gradle on Android, use Android Studio.
Gradle for XCODE is something I am yet to touch but you can read about it here: Gradle XCode Plugin
I hope this post helps you in getting familiar with Gradle. For any queries, feel free to email me