<!--
  ~ Copyright 2010 the original author or authors.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->
<chapter id='gradle_wrapper'>
    <title>The Gradle Wrapper</title>
    <para>Most tools require installation on your computer before you can use them. If the installation is easy, you
        may think that’s fine. But it can be an unnecessary burden on the users of the build. Equally importantly,
        will the user install the right version of the tool for the build? What if they’re building an old version
        of the software?</para>

    <para>The Gradle Wrapper (henceforth referred to as the “Wrapper”) solves both these problems and is the preferred
        way of starting a Gradle build.</para>

    <section id='using_wrapper_scripts'>
        <title>Executing a build with the Wrapper</title>
        <para>If a Gradle project has set up the Wrapper (and we recommend all projects do so), you can execute
            the build using one of the following commands from the root of the project:
            <itemizedlist>
                <listitem><para><userinput>./gradlew &lt;task&gt;</userinput>  (on Unix-like platforms such as Linux
                    and Mac OS X)</para></listitem>
                <listitem><para><userinput>gradlew &lt;task&gt;</userinput>  (on Windows using the gradlew.bat
                    batch file)</para></listitem>
            </itemizedlist>
            Each Wrapper is tied to a specific version of Gradle, so when you first run one of the commands above
            for a given Gradle version, it will download the corresponding Gradle distribution and use it to execute
            the build.
        </para>

        <tip>
            <title>IDEs</title>
            <para>When importing a Gradle project via its wrapper, your IDE may ask to use the Gradle 'all'
                distribution. This is perfectly fine and helps the IDE provide code completion for the build files.
            </para>
        </tip>

        <para>Not only does this mean that you don’t have to manually install Gradle yourself, but you are also sure
            to use the version of Gradle that the build is designed for. This makes your historical builds more
            reliable. Just use the appropriate syntax from above whenever you see a command line starting with
            <userinput>gradle ...</userinput> in the user guide, on Stack Overflow, in articles or wherever.
        </para>

        <para>For completeness sake, and to ensure you don’t delete any important files, here are the files and
            directories in a Gradle project that make up the Wrapper:
            <itemizedlist>
                <listitem><para><filename>gradlew</filename>  (Unix Shell script)</para></listitem>
                <listitem><para><filename>gradlew.bat</filename>  (Windows batch file)</para></listitem>
                <listitem><para><filename>gradle/wrapper/gradle-wrapper.jar</filename>  (Wrapper JAR)</para></listitem>
                <listitem><para><filename>gradle/wrapper/gradle-wrapper.properties</filename>  (Wrapper properties)</para></listitem>
            </itemizedlist>
        </para>

        <para>If you’re wondering where the Gradle distributions are stored, you’ll find them in your user home
            directory under <filename>$USER_HOME/.gradle/wrapper/dists</filename>.
        </para>

    </section>

    <section id="sec:wrapper_generation">
        <title>Adding the Wrapper to a project</title>
        <para>
            The Wrapper is something you <emphasis>should</emphasis> check into version control. By distributing the Wrapper with your project,
            anyone can work with it without needing to install Gradle beforehand. Even better, users of the build are guaranteed to use the
            version of Gradle that the build was designed to work with. Of course, this is also great for
            <ulink url="http://en.wikipedia.org/wiki/Continuous_integration">continuous integration</ulink> servers (i.e. servers that regularly
            build your project) as it requires no configuration on the server.
        </para>
        <para>
            You install the Wrapper into your project by running the <literal>wrapper</literal> task. (This task is always available, even if
            you don't add it to your build). To specify a Gradle version use <literal>--gradle-version</literal> on the command-line.
            You can also set the URL to download Gradle from directly via <literal>--gradle-distribution-url</literal>. If no version or distribution
            URL is specified, the Wrapper will be configured to use the gradle version the <literal>wrapper</literal> task is executed with.
            So if you run the <literal>wrapper</literal> task with Gradle 2.4, then the Wrapper configuration will default to version 2.4.
        </para>
        <sample id="wrapperCommandLine" dir="userguide/wrapper/simple" title="Running the Wrapper task">
            <output args="wrapper --gradle-version 2.0"/>
        </sample>
        <para>
            The Wrapper can be further customized by adding and configuring a <apilink class="org.gradle.api.tasks.wrapper.Wrapper"/>
            task in your build script, and then executing it.
        </para>
        <sample id="wrapperSimple" dir="userguide/wrapper/simple" title="Wrapper task">
            <sourcefile file="build.gradle"/>
        </sample>
        <para>
            After such an execution you find the following new or updated files in your project directory
            (in case the default configuration of the Wrapper task is used).
        </para>
        <sample id="wrapperSimple" dir="userguide/wrapper/simple" title="Wrapper generated files">
            <layout after="wrapper">
                gradlew
                gradlew.bat
                gradle/wrapper/gradle-wrapper.jar
                gradle/wrapper/gradle-wrapper.properties
            </layout>
        </sample>
        <para>
            All of these files <emphasis>should</emphasis> be submitted to your version control system. This only needs to be done once. After
            these files have been added to the project, the project should then be built with the added <command>gradlew</command> command.
            The <command>gradlew</command> command can be used <emphasis>exactly</emphasis> the same way as the <command>gradle</command> command.
        </para>
        <para>If you want to switch to a new version of Gradle you don't need to rerun the <literal>wrapper</literal> task. It is good enough
            to change the respective entry in the <literal>gradle-wrapper.properties</literal> file, but if you want to take
            advantage of new functionality in the Gradle wrapper, then you would need to regenerate the wrapper files.
        </para>
    </section>

    <section id='sec:configuration'>
        <title>Configuration</title>
        <para>If you run Gradle with <command>gradlew</command>, the Wrapper checks if a Gradle distribution for the Wrapper
            is available. If so, it delegates to the <command>gradle</command>
            command of this distribution with all the arguments passed originally to the <command>gradlew</command>
            command.  If it didn't find a Gradle distribution, it will download it first.
        </para>
        <para>
            When you configure the <literal>Wrapper</literal> task, you can specify the Gradle version you wish to use. The <command>gradlew</command>
            command will download the appropriate distribution from the Gradle repository.
            Alternatively, you can specify the download URL of the Gradle distribution. The <command>gradlew</command> command will use this URL to download
            the distribution.
            If you specified neither a Gradle version nor download URL, the <command>gradlew</command> command will download whichever version
            of Gradle was used to generate the Wrapper files.
        </para>
        <para>For the details on how to configure the Wrapper, see the <apilink class="org.gradle.api.tasks.wrapper.Wrapper"/> class in the API documentation.
        </para>
        <para>If you don't want any download to happen when your project is built via <command>gradlew</command>, simply add the Gradle
            distribution zip to your version control at the location specified by your Wrapper configuration.
            A relative URL is supported - you can specify a distribution file relative to the location of <literal>gradle-wrapper.properties</literal> file.
        </para>
        <para>If you build via the Wrapper, any existing Gradle distribution installed on the machine is ignored.
        </para>
    </section>
    <section id='sec:verification'>
        <title>Verification of downloaded Gradle distributions</title>
        <para>The Gradle Wrapper allows for verification of the downloaded Gradle distribution via SHA-256 hash sum comparison.
            This increases security against targeted attacks by preventing a man-in-the-middle attacker from tampering with the downloaded Gradle distribution.
        </para>
        <para>
            To enable this feature you'll want to first calculate the SHA-256 hash of a known Gradle distribution. You can generate a SHA-256 hash from Linux and
            OSX or Windows (via <ulink url="https://www.cygwin.com/">Cygwin</ulink>) with the <command>shasum</command> command.
        </para>
        <example>
            <title>Generating a SHA-256 hash</title>
            <programlisting><![CDATA[
> shasum -a 256 gradle-2.4-all.zip
371cb9fbebbe9880d147f59bab36d61eee122854ef8c9ee1ecf12b82368bcf10  gradle-2.4-all.zip
]]></programlisting>
        </example>
        <para>
            Add the returned hash sum to the <literal>gradle-wrapper.properties</literal> using the <literal>distributionSha256Sum</literal> property.
        </para>
        <example>
            <title>Configuring SHA-256 checksum verification</title>
            <para><filename>gradle-wrapper.properties</filename></para>
            <programlisting><![CDATA[
distributionSha256Sum=371cb9fbebbe9880d147f59bab36d61eee122854ef8c9ee1ecf12b82368bcf10
]]></programlisting>
        </example>
    </section>
    <section id='sec:unix_file_permissions'>
        <title>Unix file permissions</title>
        <para>The Wrapper task adds appropriate file permissions to allow the execution of the <literal>gradlew</literal> *NIX command.
            Subversion preserves this file permission. We are not sure how other version control systems deal with this.
            What should always work is to execute “<literal>sh gradlew</literal>”.
        </para>
    </section>
</chapter>
