2017年7月8日 星期六

[ Gradle IA ] Ch2 - Next-generation builds with Gradle (Part2)

Installing Gradle 
As a prerequisite, make sure you’ve already installed the JDK with a version of 1.5 or higher. Even though some operating systems provide you with an out-of-the-box Java installation, make sure you have a valid version installed on your system. To check the JDK version, run java –version. Then you can refer to How to Install Gradle on CentOS 7 or leverage below script: 
- installGradle.sh 
  1. #!/bin/bash  
  2. cd /root  
  3. gradle_package=`curl -s https://services.gradle.org/distributions/ --list-only | sed -n 's/.*\(gradle-.*.all.zip\).*/\1/p' | egrep -v "milestone|rc" | head -1`  
  4. gradle_version=`echo ${gradle_package} | cut -d "-" -f 1,2`  
  5. mkdir /opt/gradle  
  6. curl -L -Of http://services.gradle.org/distributions/${gradle_package}  
  7. unzip -oq ./${gradle_package} -d /opt/gradle  
  8. ln -sfnv ${gradle_version} /opt/gradle/latest  
  9. printf "export GRADLE_HOME=/opt/gradle/latest\nexport PATH=\$PATH:\$GRADLE_HOME/bin" > /etc/profile.d/gradle.sh  
  10. . /etc/profile.d/gradle.sh  
  11. hash -r ; sync  
  12. # check installation  
  13. gradle -v  
You’ll verify that Gradle has been installed correctly and is ready to go. To check the version of the installed runtime, issue the command gradle –v in your shell: 
# gradle -v
------------------------------------------------------------
Gradle 3.5.1
------------------------------------------------------------

Build time: 2017-06-16 14:36:27 UTC
Revision: d4c3bb4eac74bd0a3c70a0d213709e484193e251

Groovy: 2.4.10
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_121 (Oracle Corporation 25.121-b13)

OS: Linux 3.10.0-327.el7.x86_64 amd64

Setting Gradle’s JVM options 
Like every other Java application, Gradle shares the same JVM options set by the environment variable JAVA_OPTS. If you want to pass arguments specifically to the Gradle runtime, use the environment variable GRADLE_OPTS. Let’s say you want to increase the default maximum heap size to 1 GB. You could set it like this:
  1. GRADLE_OPTS="-Xmx1024m"  
The preferred way to do that is to add the variable to the Gradle startup script under $GRADLE_HOME/bin.

Now that you’re all set, you’ll implement a simple build script with Gradle. Even though most of the popular IDEs provide a Gradle plugin, all you need now is your favorite editor. Chapter 10 will discuss Gradle plugin support for IDEs like IntelliJ, Eclipse, and NetBeans. 

Getting started with Gradle 
Every Gradle build starts with a script. The default naming convention for a Gradle build script is build.gradle. When executing the command gradle in a shell, Gradle looks for a file with that exact name. If it can’t be located, the runtime will display a help message. 

Let’s set the lofty goal of creating the typical “Hello world!” example in Gradle. First you’ll create a file called build.gradle. Within that script, define a single atomic piece of work. In Gradle’s vocabulary, this is called a task. In this example, the task is called helloWorld. To print the message “Hello world!” make use of Gradle’s lingua franca, Groovy, by adding the println command to the task’s action doLast. The method println is Groovy’s shorter equivalent to Java’s System.out.println
  1. task helloWorld {  
  2.     doLast {  
  3.         println "Hello World!"  
  4.     }  
  5. }  
Give it a spin: 
// -q, --quiet: Log errors only.
# gradle -q helloWorld
Hello World!

As expected, you see the output “Hello world!” when running the script. By defining the optional command-line option quiet with –q, you tell Gradle to only output the task’s output. 

Without knowing it, you already used Gradle’s DSL. Tasks and actions are important elements of the language. An action named doLast is almost self-expressive. It’s the last action that’s executed for a task. Gradle allows for specifying the same logic in a more concise way. The left shift operator << is a shortcut for the action doLast. The following snippet shows a modified version of the first example: 
  1. task helloWorld << {  
  2.     println 'Hello world!'  
  3. }  
Printing “Hello world!” only goes so far. I’ll give you a taste of more advanced features in the example build script shown in the following listing. Let’s strengthen our belief in Gradle by exercising a little group therapy session. Repeat after me: Gradle rocks! 
- Listing 2.1 Dynamic task definition and task chaining 
  1. task startSession << {  
  2.     chant()  
  3. }  
  4.   
  5. def chant(){  
  6.     ant.echo(message: 'Repeat after me...')  // (1)  Implicit Ant task usage  
  7. }  
  8.   
  9. 3.times {  
  10.     task "yayGradle$it" << {   // (2) Dynamic task definition  
  11.         println "Gradle rocks-$it"  
  12.     }  
  13. }  
  14.   
  15. // (3) Task dependencies  
  16. yayGradle0.dependsOn startSession  
  17. yayGradle2.dependsOn yayGradle1, yayGradle0  
  18. task groupTherapy(dependsOn: yayGradle2)  
You may not notice it at first, but there’s a lot going on in this listing. You introduced the keyword dependsOn to indicate dependencies between tasks (3). Gradle makes sure that the depended-on task will always be executed before the task that defines the dependency. Under the hood, dependsOn is actually a method of a taskChapter 4 will cover the internals of tasks, so we won’t dive into too much detail here. 

A feature we’ve talked about before is Gradle’s tight integration with Ant (2). Because you have full access to Groovy’s language features, you can also print your message in a method named chant(). This method can easily be called from your task. Every script is equipped with a property called ant that grants direct access to Ant tasks. In this example, you print out the message “Repeat after me” using the Ant task echo to start the therapy session. 

A nifty feature Gradle provides is the definition of dynamic tasks, which specify their name at runtime. Your script creates three new tasks within a loop (2) using Groovy’s times method extension on java.lang.Number. Groovy automatically exposes an implicit variable named it to indicate the loop iteration index. You’re using this counter to build the task name. For the first iteration, the task would be called yayGradle0

Now running gradle groupTherapy results in the following output: 
# gradle groupTherapy
:startSession
[ant:echo] Repeat after me...
:yayGradle0
Gradle rocks-task ':yayGradle0'
:yayGradle1
Gradle rocks-task ':yayGradle1'
:yayGradle2
Gradle rocks-task ':yayGradle2'
:groupTherapy

BUILD SUCCESSFUL

Total time: 0.838 secs

As shown in figure 2.10 Gradle executed the tasks in the correct order. You may have noticed that the example omitted the quiet command-line option, which gives more information on the tasks run. 

Thanks to your group therapy, you got rid of your deepest fears that Gradle will be just another build tool that can’t deliver. In the next chapter, you’ll stand up a full-fledged Java application covering a broad range of Gradle’s core concepts. For now, let’s get more accustomed to Gradle’s command line. 

Using the Command line 
In the previous sections, you executed the tasks helloWorld and groupTherapy on the command line, which is going to be your tool of choice for running most examples throughout this book. Even though using an IDE may seem more convenient to newcomers, a deep understanding of Gradle’s command-line options and helper tasks will make you more efficient and productive in the long run. 

Listing available tasks of a project 
In the last section I showed you how to run a specific task using the gradle command. Running a task requires you to know the exact name. Wouldn’t it be great if Gradle could tell you which tasks are available without you having to look at the source code? Gradle provides a helper task named tasks to introspect your build script and display each available task, including a descriptive message of its purpose. Running gradle tasks in quiet mode produces the following output: 

There are some things to note about the output. Gradle provides the concept of a task group, which can be seen as a cluster of tasks assigned to that group. Out of the box, each build script exposes the task group Help tasks(1) without any additional work from the developer. If a task doesn’t belong to a task group, it’s displayed under Other tasks (2). This is where you find the task groupTherapy (3). We’ll look at how to add a task to a task group in Chapter 4

You may wonder what happened to the other tasks that you defined in your build script. On the bottom of the output, you’ll find a note that you can get even more details about your project’s tasks by using the --all option. Run it to get more information on them: 

The --all option is a great way to determine the execution order of a task graph before actually executing it. To reduce the noise, Gradle is smart enough to hide tasks that act as dependencies to a root task (1). For better readability, dependent tasks are displayed indented and ordered underneath the root task. 

Task execution 
In the previous examples, you told Gradle to execute one specific task by adding it as an argument to the command gradle. Gradle’s command-line implementation will in turn make sure that the task and all its dependencies are executed. You can also execute multiple tasks in a single build run by defining them as command-line parameters. Running gradle yayGradle0 groupTherapy would execute the task yayGradle0 first and the task groupTherapy second. 

Tasks are always executed just once, no matter whether they’re specified on the command line or act as a dependency for another task. Let’s see what the output looks like: 
# gradle yayGradle0 groupTherapy
...
:startSession
[ant:echo] Repeat after me...
:yayGradle0
Gradle rocks-task ':yayGradle0'
:yayGradle1
Gradle rocks-task ':yayGradle1'
:yayGradle2
Gradle rocks-task ':yayGradle2'
:groupTherapy
...

No surprises here. You see the same output as if you’d just run gradle groupTherapy. The correct order was preserved and each of the tasks was only executed once. 

TASK NAME ABBREVIATION 
One of Gradle’s productivity tools is the ability to abbreviate camel-cased task names on the command line. If you wanted to run the previous example in the abbreviated form, you’d just have to type gradle yG0 gT. This is especially useful if you’re dealing with very long task names or multiple task arguments. Keep in mind that the task name abbreviation has to be unique to enable Gradle to identify the corresponding task

EXCLUDING A TASK FROM EXECUTION 
Sometimes you want to exclude a specific task from your build run. Gradle provides the command-line option –x to achieve that. Let’s say you want to exclude the task yayGradle0
# gradle gT -x yG0
:yayGradle1
Gradle rocks-task ':yayGradle1'
:yayGradle2
Gradle rocks-task ':yayGradle2'
:groupTherapy

Gradle excluded the task yayGradle0 and its dependent task startSession, a concept Gradle calls smart exclusion. Now that you’re becoming familiar with the command line, let’s explore some more helpful functions. 

Command-line options 
In this section, we explore the most important general-purpose options, flags to control your build script’s logging level, and ways to provide properties to your project. The gradle command allows you to define one or more options at the same time. Let’s say you want to change the log level to INFO using the –i option and print out any stack trace if an error occurs during execution with the option -s. To do so, execute the task groupTherapy command like this: gradle groupTherapy –is or gradle groupTherapy –i –s. As you can see, it’s very easy to combine multiple options. To discover the full set, run your build with the –h argument. I won’t go over all the available options, but the most important ones are as follows: 
* -?, -h, --help: 
Prints out all available command-line options including a descriptive message.

* -b, --build-file: 
The default naming convention for Gradle build script is build.gradle. Use this option to execute a build script with a different name (for example, gradle –b test.gradle).

* --offline: 
Often your build declares dependencies on libraries only available in repositories outside of your network. If these dependencies were not stored in your local cache yet, running a build without a network connection to these repositories would result in a failed build. Use this option to run your build in offline mode and only check the local dependency cache for dependencies.

PROPERTY OPTIONS 
* -D, --system-prop: 
Gradle runs as a JVM process. As with all Java processes, you can provide a system property like this: –Dmyprop=myvalue.

* -P, --project-prop: 
Project properties are variables available in your build script. You can use this option to pass a property to the build script directly from the command line (for example, -Pmyprop=myvalue).

LOGGING OPTIONS 
* -i, --info: 
In the default settings, a Gradle build doesn’t output a lot of information. Use this option to get more informative messages by changing Gradle’s logger to INFO log level. This is helpful if you want to get more information on what’s happening under the hood.

* -s, --stacktrace: 
If you run into errors in your build, you’ll want to know where they stem from. The option –s prints out an abbreviated stack trace if an exception is thrown, making it perfect for debugging broken builds.

* -q, --quiet: 
Reduces the log messages of a build run to error messages only.

HELP TASKS 
* tasks: 
Displays all runnable tasks of your project including their descriptions. Plugins applied to your project may provide additional tasks.

* properties: 
Emits a list of all available properties in your project. Some of these properties are provided by Gradle’s project object, the build’s internal representation. Other properties are user-defined properties originating from a property file or property command-line option, or directly declared in your build script.

Gradle daemon 
When using Gradle on a day-to-day basis, you’ll find yourself having to run your build repetitively. This is especially true if you’re working on a web application. You change a class, rebuild the web application archive, bring up the server, and reload the URL in the browser to see your changes being reflected. Many developers prefer test-driven development to implement their application. For continuous feedback on their code quality, they run their unit tests over and over again to find code defects early on. In both cases, you’ll notice a significant productivity hit. Each time you initiate a build, the JVM has to be started, Gradle’s dependencies have to be loaded into the class loader, and the project object model has to be constructed. This procedure usually takes a couple of seconds. Gradle daemon to the rescue! 

The daemon runs Gradle as a background process. Once started, the gradle command will reuse the forked daemon process for subsequent builds, avoiding the startup costs altogether. Let’s come back to the previous build script example. On my machine, it takes about three seconds to successfully complete running the task groupTherapy. Hopefully, we can improve the startup and execution time. It’s easy to start the Gradle daemon on the command line: simply add the option --daemon to your gradle command. You may notice that we add a little extra time for starting up the daemon as well. 

Subsequent invocations of the gradle command will now reuse the daemon process. Give it a shot and try running gradle groupTherapy --daemon. Wow, you got your startup and execution time down to about one second! Keep in mind that a daemon process will only be forked once even though you add the command-line option --daemonThe daemon process will automatically expire after a three-hour idle time. At any time you can choose to execute your build without using the daemon by adding the command-line option --no-daemon. To stop the daemon process, manually run gradle --stop. That’s the Gradle daemon in a nutshell. For a deep dive into all configuration options and intricacies, please refer to the Gradle online documentation at https://docs.gradle.org/current/userguide/gradle_daemon.html . 
# gradle gT --daemon | grep 'Total time' // First time execution without gradle daemon will take 4 seconds
Total time: 4.042 secs
# gradle gT --daemon | grep 'Total time' // Second time execution will take less than 3 seconds!
Total time: 2.53 secs
# ps aux | grep gradle | grep -v 'grep' | wc -l // Check the process of gradle daemon
1
# gradle gT --no-daemon | grep 'Total time' // Launch execution without help of daemon will take 3 seconds
Total time: 3.49 secs
# gradle --stop // Stop the gradle daemon
Stopping Daemon(s)
1 Daemon stopped

# ps aux | grep gradle | grep -v 'grep' | wc -l // Make sure the gradle daemon is gone
0


Summary 
Existing tools can’t meet the build needs of today’s industry. Improving on the best ideas of its competitors, Gradle provides a build-by-convention approach, reliable dependency management, and support for multiproject builds without having to sacrifice the flexibility and descriptiveness of your build. 

In Chapter 3, I’ll show how to build a full-fledged, web-enabled application with Gradle. Starting out with a simple, standalone Java application, you’ll extend the code base by adding a web component and use Gradle’s in-container web development support to efficiently implement the solution. We won’t stop there. I’m going to show how to enhance your web archive to make it enterprise-ready and make the build transferable across machines without having to install the Gradle runtime. 

Supplement 
認識 Gradle - (3)Gradle 起手式

沒有留言:

張貼留言

[ Py DS ] Ch5 - Machine Learning (Part2)

Source From  Here   Introducing Scikit-Learn   There are several Python libraries that provide solid implementations of a range of machin...