Search

Dark theme | Light theme
Showing posts with label GradleGoodness:Commandline. Show all posts
Showing posts with label GradleGoodness:Commandline. Show all posts

February 4, 2019

Gradle Goodness: Only Show All Tasks In A Group

To get an overview of all Gradle tasks in our project we need to run the tasks task. Since Gradle 5.1 we can use the --group option followed by a group name. Gradle will then show all tasks belonging to the group and not the other tasks in the project.

Suppose we have a Gradle Java project and want to show the tasks that belong to the build group:

$ gradle tasks --group build
> Task :tasks

------------------------------------------------------------
Tasks runnable from root project - Sample
------------------------------------------------------------

Build tasks
-----------
assemble - Assembles the outputs of this project.
bootBuildInfo - Generates a META-INF/build-info.properties file.
bootJar - Assembles an executable jar archive containing the main classes and their dependencies.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles main classes.
clean - Deletes the build directory.
generateGitProperties - Generate a git.properties file.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles test classes.

To see all tasks and more detail, run gradle tasks --all

To see more detail about a task, run gradle help --task <task>

Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.1.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

Written with Gradle 5.1.1.

June 5, 2018

Gradle Goodness: Enable Task Based On Offline Command Line Argument

One of the command line options of Gradle is --offline. With this option we run Gradle in offline mode to indicate we are not connected to network resources like the internet. This could be useful for example if we have defined dependencies in our build script that come from a remote repository, but we cannot access the remote repository, and we still want to run the build. Gradle will use the locally cached dependencies, without checking the remote repository. New dependencies, not already cached, cannot be downloaded of course, so in that scenario we still need a network connection.

We can check in our build script if the --offline command line argument is used. We can use this to disable tasks that depend on network resources so the build will not fail. To see if we invoked our build with the --offline option we can access the property gradle.startParameter.offline. The value is true if the command line argument --offline is used and false if the command line argument is not used.

In the following example build file we use the task type VfsCopy from the VFS Gradle Plugin to define a new task download. The task will download the file index.html from the site http://www.mrhaki.com. We enable the task if the --offline command line argument is not used. If the argument is used the task is disabled.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'org.ysb33r.gradle:vfs-gradle-plugin:1.0'
        classpath 'commons-httpclient:commons-httpclient:3.1'
    }
}

task download(type: org.ysb33r.gradle.vfs.tasks.VfsCopy) {
    description = 'Downloads index.html from http://www.mrhaki.com'
    group = 'Remote'

    // Only enable task when we don't use
    // the --offline command line argument.
    enabled = !gradle.startParameter.offline

    from 'http://www.mrhaki.com/index.html'
    into project.file("${buildDir}/downloads")
}

Let's run the download task with and without the --offline option:

$ gradle download --offline --console=plain
> Task :download SKIPPED

BUILD SUCCESSFUL in 0s
$ gradle download --console=plain
> Task :download

BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

Written with Gradle 4.8.

December 20, 2016

Gradle Goodness: Run Task Ignoring Up-to-date Checks

Gradle builds are fast because Gradle supports incremental tasks. This means Gradle can determine if input or output of task has changed, before running the task. If nothing has changed a task is marked a up-to-date and the task is not executed, otherwise the task is executed. If we want execute a task even if it is up-to-date we must use the command line option --rerun-tasks.

In the following example we run the assemble task for a simple Java project, and we see all tasks are executed. When we invoke the assemble task again we see the tasks are all up-to-date:

$ gradle assemble

:compileJava
:processResources
:classes
:jar
:assemble

BUILD SUCCESSFUL

Total time: 1.765 secs
$ gradle assemble

:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:assemble UP-TO-DATE

BUILD SUCCESSFUL

Total time: 0.715 secs
$

To run all tasks without an up-to-date check we use the option --rerun-tasks:

$ gradle --rerun-tasks assemble
:compileJava
:processResources
:classes
:jar
:assemble

BUILD SUCCESSFUL

Total time: 1.037 secs
$

Written with Gradle 3.2.1.

September 19, 2016

Gradle Goodness: Specify Wrapper Version and Distribution Type From Command Line

Gradle has the built-in task wrapper to create a Gradle wrapper. The Gradle wrapper can be part of our project so other people can build our project with Gradle, without the need for them to install Gradle. Also if we specify the Gradle wrapper we can make sure the correct Gradle version is used. To specify the version we must use the option --gradle-version. This version can be different than the Gradle version we use to create the Gradle wrapper. Since Gradle 3.1 we can also specify the distribution type of the Gradle wrapper. We choose between a binary distribution or the all distribution, which contains documentation and source code. Especially IDEs like to have the all distribution type, so they can provide better help in their editors.

With the following wrapper command we create a wrapper for Gradle 3.1 and the all distribution type. For a binary distribution we either use the value bin or we don't specify the option, so Gradle falls back to the default value bin.

$ gradle wrapper --gradle-version 3.1 --distribution-type all
:wrapper

BUILD SUCCESSFUL

Total time: 1.012 secs

$

We can check the file gradle/wrapper/gradle-wrapper.properties and look for the key distributionUrl. We see the value points to the correct Gradle version and distribution type:

$ more gradle/wrapper/gradle-wrapper.properties
#Mon Sep 19 15:26:27 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-all.zip
$

Written with Gradle 3.1

September 14, 2016

Gradle Goodness: Check The Gradle Daemon Status

Since Gradle 3 the Gradle daemon is automatically used to run Gradle. This means Gradle will startup up faster after a first run. Gradle tries to re-use a daemon if it is available. We can check the status of the Gradle daemon processes with the new command-line option --status. We get the status results for the Gradle daemons with the same Gradle version that is used to view the status. So when we use Gradle 3.0 with the --status option we only see the 3.0 Gradle daemons.

The following example shows the sample output of running gradle with the --status option:

$ gradle --status
No Gradle daemons are running.
   PID STATUS   INFO
 28914 IDLE     3.0
 26854 STOPPED  (after being idle for 22 minutes and to reclaim system memory)

Only Daemons for the current Gradle version are displayed. See https://docs.gradle.org/3.0/userguide/gradle_daemon.html#sec:status

Written with Gradle 3.0.

September 21, 2015

Gradle Goodness: Pass Java System Properties To Java Tasks

Gradle is of course a great build tool for Java related projects. If we have tasks in our projects that need to execute a Java application we can use the JavaExec task. When we need to pass Java system properties to the Java application we can set the systemProperties property of the JavaExec task. We can assign a value to the systemProperties property or use the method systemProperties that will add the properties to the existing properties already assigned. Now if we want to define the system properties from the command-line when we run Gradle we must pass along the properties to the task. Therefore we must reconfigure a JavaExec task and assign System.properties to the systemProperties property.

In the following build script we reconfigure all JavaExec tasks in the project. We use the systemProperties method and use the value System.properties. This means any system properties from the command-line are passed on to the JavaExec task.

apply plugin: 'groovy'
apply plugin: 'application'

mainClassName = 'com.mrhaki.sample.Application'

repositories.jcenter()

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.4.4'
}

// The run task added by the application plugin
// is also of type JavaExec.
tasks.withType(JavaExec) {
    // Assign all Java system properties from 
    // the command line to the JavaExec task.
    systemProperties System.properties
}

We write a simple Groovy application that uses a Java system property app.greeting to print a message to the console:

// File: src/main/groovy/com/mrhaki/sample/Application.groovy
package com.mrhaki.sample

println "Hello ${System.properties['app.greeting']}"

Now when we execute the run task (of type JavaExec) and define the Java system property app.greeting in our command it is used by the application:

$ gradle -Dapp.greeting=Gradle! -q run
Hello Gradle!

Written with Gradle 2.7.

Gradle Goodness: Getting More Help For a Task

To see which tasks are available for a Gradle project we can invoke the tasks task. With this task all tasks are printed to the console with their description. To get more information about a specific task we can use the Gradle help task with the command-line option --task followed by the task name. Gradle prints out the path, type, description, group and optional options for the task.

Let's run the help task for the wrapper task:

$ gradle help --task wrapper                   
:help
Detailed task information for wrapper

Path
     :wrapper

Type
     Wrapper (org.gradle.api.tasks.wrapper.Wrapper)

Options
     --gradle-distribution-url     The URL to download the gradle distribution from.

     --gradle-version     The version of the Gradle distribution required by the wrapper.

Description
     Generates Gradle wrapper files. [incubating]

Group
     Build Setup

BUILD SUCCESSFUL

Total time: 0.568 secs

Or use the help task to get more information about the help task:

$ gradle -q help --task help
Detailed task information for help

Path
     :help

Type
     Help (org.gradle.configuration.Help)

Options
     --task     The task to show help for.

Description
     Displays a help message.

Group
     help

Written with Gradle 2.7.

August 24, 2015

Gradle Goodness: Using Continuous Build Feature

Gradle introduced the continuous build feature in version 2.5. The feature is still incubating, but we can already use it in our daily development. The continuous build feature means Gradle will not shut down after a task is finished, but keeps running and looks for changes to files to re-run tasks automatically. It applies perfectly for a scenario where we want to re-run the test task while we write our code. With the continuous build feature we start Gradle once with the test task and Gradle will automatically recompile source files and run tests if a source file changes.

To use the continuous build feature we must use the command line option --continuous or the shorter version -t. With this option Gradle will start up in continuous mode. To stop Gradle we must use the Ctrl+D key combination.

In the following output we see how to start Gradle in continuous mode and run the test tasks. The first time our test code fails, we change the source file and without restarting Gradle the file is compiled and the test task is run again. Notice that Gradle will honour the task dependencies to see if files have changed:

$ gradle -t test
Continuous build is an incubating feature.
:compileJava UP-TO-DATE
:compileGroovy
:processResources UP-TO-DATE
:classes
:compileTestJava UP-TO-DATE
:compileTestGroovy
:processTestResources UP-TO-DATE
:testClasses
:test

com.mrhaki.SampleSpec > get message FAILED
    org.spockframework.runtime.SpockComparisonFailure at SampleSpec.groovy:7

1 test completed, 1 failed
:test FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':test'.
> There were failing tests. See the report at: file:///Users/mrhaki/.../build/reports/tests/index.html

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 4.464 secs

Waiting for changes to input files of tasks... (ctrl-d to exit)
Change detected, executing build...

:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava UP-TO-DATE
:compileTestGroovy
:processTestResources UP-TO-DATE
:testClasses
:test

BUILD SUCCESSFUL

Total time: 1.792 secs

Waiting for changes to input files of tasks... (ctrl-d to exit)

Written with Gradle 2.6.

March 4, 2015

Gradle Goodness: Define System Properties in gradle.properties File

To define system properties for our Gradle build we can use the command line option --system-prop or -D. But we can also add the values for system properties in the gradle.properties file of our project. This file contains project properties we want to externalized, but if we prefix the property name with systemProp. the property is turned into a system property. For a multi-module build only system properties defined in the gradle.properties file in the root of the project structure are used, others are ignored.

In the following build script we have the task showSystemProperty. Inside the task we assert the value of the system property sample and the project property sample:

// Simple task to show 
// some properties.
task showSystemProperty << {

    // System property 'sample' is set 
    // in gradle.properties file.
    assert System.properties.sample == 'Gradle is gr8'

    // Regular project property set
    // in gradle.properties file.
    assert project.sample == 'Gradle is great'

}

We can run the following command line command to make sure the assertions are true: $ gradle --system-prop "sample=Gradle is gr8" --project-prop "sample=Gradle is great" showSystemProperty.

Or we could create the following gradle.properties file in our project directory:

systemProp.sample = Gradle is gr8
sample = Gradle is great

Now we can run $ gradle showSystemProperty and the assertions are true.

Written with Gradle 2.3.

December 9, 2014

Gradle Goodness: Continue Build Even with Failed Tasks

If we run a Gradle build and one of the tasks fails, the whole build stops immediately. So we have fast feedback of our build status. If we don't want to this and want Gradle to execute all tasks, even though some might have failed, we use the command line option --continue. When we use the --continue command line option Gradle will execute every task where the dependent tasks are not failing. This is also useful in a multi-module project where we might want to build all projects even though some may have failing tests, so we get a complete overview of failed tests for all modules.

In the following Gradle build file we have two tasks. The task failTask throws a TaskExecutionException to purposely fail the task. The successTask will not fail:

task failTask << { task ->
    println "Running ${task.name}"

    throw new TaskExecutionException(
            task, 
            new Exception('Fail task on purpose')) 
}

task successTask << {
    println "Running ${it.name}"
}

Let's run both tasks from the command line and see the output:

$ gradle failTask successTask
:failTask
Running failTask
:failTask FAILED

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/mrhaki/samples/gradle/continue/build.gradle' line: 4

* What went wrong:
Execution failed for task ':failTask'.
> Fail task on purpose

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 4.148 secs
$

We see the build has failed and only the task failTask is executed. Now we run the same two tasks, but we use the command line option --continue:

$ gradle --continue failTask successTask
:failTask
Running failTask
:failTask FAILED
:successTask
Running successTask

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/mrhaki/samples/gradle/continue/build.gradle' line: 4

* What went wrong:
Execution failed for task ':failTask'.
> Fail task on purpose

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 6.918 secs
$

This time the successTask is executed even though the failTask has failed again. Gradle will keep track of all tasks that have failed and displays a summary with all the tasks that have failed.

Written with Gradle 2.2.1

December 5, 2014

Gradle Goodness: Skip Building Project Dependencies

If we use Gradle in a multi-module project we can define project dependencies between modules. Gradle uses the information from the project dependencies to determine which tasks need to be run. For example if module B depends on module A and we want to build module B, Gradle will also build module A for us, because module B depends on it. But if we know for sure that module A is up to date and has not changed, we can also instruct Gradle to skip building module A, when we build module B.

Let's start with the following module structure, where each module depends on the module above it. So module services depends on common and module web depends on services:

.
├── common
├── services
└── web

When we want to build the service module we go to the services directory and execute the build task and we get the following output:

$ gradle build
:common:compileJava 
:common:processResources 
:common:classes 
:common:jar 
:services:compileJava 
:services:processResources 
:services:classes 
:services:jar 
:services:assemble 
:services:compileTestJava 
:services:processTestResources 
:services:testClasses 
:services:test 
:services:check 
:services:build 

BUILD SUCCESSFUL

Total time: 8.013 secs

We see in the output that first the common module is build, because the services module depends on it. But if we work on this project and we know for sure the common module is up to date and has not changed since the last build (for example we didn't checkout new sources from version control or changed sources in the common module ourselves), then we can skip building the common module. We use the command line option -a or --no-rebuild to tell Gradle to skip project dependencies.

When we run the build task from the services directory using the command line option -a we get the following output:

$ gradle -a build
:services:compileJava 
:services:processResources 
:services:classes 
:services:jar 
:services:assemble 
:services:compileTestJava 
:services:processTestResources 
:services:testClasses 
:services:test 
:services:check 
:services:build 

BUILD SUCCESSFUL

Total time: 5.626 secs

This time only the services module is build, which also speeds up the build proces. Still this should only be used if we know ourselves the project dependencies are up to date.

Written with Gradle 2.2.1.

November 17, 2014

Gradle Goodness: Check Task Dependencies With a Dry Run

We can run a Gradle build without any of the task actions being executed. This is a so-called dry run of our build. We can use the dry run of a build to see if the task dependencies we have defined or are defined in a plugin are defined properly. Because all tasks and task dependencies are resolved if we use the dry run mode we can see in the output which tasks are executed.

We define a simple build file with three tasks and some task dependencies:

def printTaskNameAction = {
    println "Running ${it.name}"
}

task first << printTaskNameAction

task second(dependsOn: first) << printTaskNameAction

task third(dependsOn: [first, second]) << printTaskNameAction

To run a Gradle build as a dry run we can use the command line option -m or --dry-run. So let's execute the task third with the dry run command line option:

$ gradle -m third
:first SKIPPED
:second SKIPPED
:third SKIPPED

BUILD SUCCESSFUL

Total time: 2.242 secs
$ 

And we see in the output none of the tasks are really executed, because SKIPPED is shown, but we do see the task names of the tasks that are resolved.

Written with Gradle 2.2.

October 21, 2014

Gradle Goodness: Changing Name of Default Build File

Gradle uses the name build.gradle as the default name for a build file. If we write our build code in a file build.gradle then we don't have to specify the build filename when we run tasks. We can create build files with a different name other than build.gradle. For example we can define our build logic in a file sample.gradle. To run the tasks from this build file we can use the command line option -b or --build-file followed by the file name. But we can also change the project settings and set a new default build file name for our project. With the changed project settings we do not have to use the command line options -b or --build-file.

Suppose we have the following build file with the name sample.gradle:

// File: sample.gradle
task sample(description: 'Sample task') << {
    println 'Sample task'
}

defaultTasks 'sample'

To run the sample task from the command line we can use the command line options -b or --build-file:

$ gradle -b sample.gradle
:sample
Sample task

BUILD SUCCESSFUL

Total time: 3.168 secs
$ gradle --build-file sample.gradle 
:sample
Sample task

BUILD SUCCESSFUL

Total time: 2.148 secs
$

To change the default build file name for our project we create a file settings.gradle in our project. Inside the settings.gradle file we can change the property buildFileName for rootProject:

// File: settings.gradle
// Change default build file name for this project.
rootProject.buildFileName = 'sample.gradle'

Now we execute the tasks from sample.gradle without the options -b or --build-file:

$ gradle
:sample
Sample task

BUILD SUCCESSFUL

Total time: 3.312 secs
$

Code written with Gradle 2.1.

August 15, 2014

Gradle Goodness: Suppress Progress Logging

Gradle has some sophisticated progress logging on the console. For example we can see how much percentage of the building process is done. The percentage value is updated on the same console line. The following snippet is a sample of such output > Building 0% > :dependencies > Resolving dependencies ':compile'. The information is updated on the same line, which is really nice. But sometimes we might need to run Gradle builds on a system that doesn't support this mechanism on the console or terminal, possibly an continuous integration server. To disable the progress logging we can set the environment variable TERM to the value dumb.

Written with Gradle 2.0.