<chapter id="artifact_dependencies_tutorial">
    <title>Dependency Management Basics</title>
    <para>
        This chapter introduces some of the basics of dependency management in Gradle.
    </para>

    <section>
        <title>What is dependency management?</title>
        <para>
            Very roughly, dependency management is made up of two pieces. Firstly, Gradle needs to
            know about the things that your project needs to build or run, in order to find them. We call these incoming
            files the <firstterm>dependencies</firstterm> of the project.
            Secondly, Gradle needs to build and upload the things that your project produces. We call these outgoing files
            the <firstterm>publications</firstterm> of the project. Let's look at these two pieces in more detail:
        </para>
        <para>Most projects are not completely self-contained. They need files built by other projects in order to
            be compiled or tested and so on. For example, in order to use Hibernate in my project, I need to include some
            Hibernate jars in the classpath when I compile my source. To run my tests, I might also need to include some
            additional jars in the test classpath, such as a particular JDBC driver or the Ehcache jars.
        </para>
        <para>
            These incoming files form the dependencies of the project.
            Gradle allows you to tell it what the dependencies of your project are, so that it can take care of
            finding these dependencies, and making them available in your build.
            The dependencies might need to be downloaded from a remote Maven or Ivy repository, or located in a local directory, or
            may need to be built by another project in the same multi-project build.
            We call this process <firstterm>dependency resolution</firstterm>.
        </para>
        <para>
            Often, the dependencies of a project will themselves have dependencies. For example, Hibernate core requires
            several other libraries to be present on the classpath with it runs. So, when Gradle runs the tests for your
            project, it also needs to find these dependencies and make them available. We call these <firstterm>transitive dependencies</firstterm>.
        </para>
        <para>
            The main purpose of most projects is to build some files that are to be used outside the project.
            For example, if your project produces a java library, you need to build a jar, and maybe a source jar and
            some documentation, and publish them somewhere.
        </para>
        <para>These outgoing files form the publications of the project. Gradle also takes care of this important work for you. You declare the
            publications of your project, and Gradle take care of building them and publishing them somewhere.
            Exactly what "publishing" means depends on what you want to do. You might want to copy the files to a local directory,
            or upload them to a remote Maven or Ivy repository. Or you might use the files in another project in the same
            multi-project build.
            We call this process <firstterm>publication</firstterm>.
        </para>
    </section>

    <section>
        <title>Declaring your dependencies</title>
        <para>
            Let's look at some dependency declarations. Here's a basic build script:
        </para>
        <sample id="basicDependencyDeclarations" dir="userguide/artifacts/dependencyBasics" title="Declaring dependencies">
            <sourcefile file="build.gradle"/>
        </sample>
        <para>What's going on here? This build script says a few things about the project.
            Firstly, it states that Hibernate core 3.6.7.Final is required
            to compile the project's production source. By implication, Hibernate core and its dependencies are also required
            at runtime.
            The build script also states that any junit >= 4.0 is required to compile the project's tests.
            It also tells Gradle to look in the Maven central repository for any dependencies that are required.
            The following sections go into the details.
        </para>
    </section>

    <section>
        <title>Dependency configurations</title>
        <para>Dependencies are grouped into <firstterm>configurations</firstterm>. A configuration is simply a set of dependencies
            with a name. You can use them to declare the external dependencies of your project. As we will see later, they are also
            used to declare the publications of your project.</para>
        <para>
            The Java plugin defines a number of standard configurations. These configurations represent the classpaths that the
            Java plugin uses. Some are listed below, and you can find more details in <xref linkend="tab:configurations"/>.
        </para>
        <variablelist>
            <varlistentry>
                <term>compile</term>
                <listitem>
                    <para>Defines the dependencies required to compile the production source of the project.</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>runtime</term>
                <listitem>
                    <para>
                        Defines the dependencies required by the production classes at runtime. By default, also includes the
                        compile time dependencies.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>testCompile</term>
                <listitem>
                    <para>
                        Defines the dependencies required to compile the test source of the project. By default, also includes
                        the compiled production classes and the compile time dependencies.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>testRuntime</term>
                <listitem>
                    <para>
                        The dependencies required to run the tests. By default, also includes the compile, runtime and test compile
                        dependencies.
                    </para>
                </listitem>
            </varlistentry>
        </variablelist>

        <para>
            Various plugins add further standard configurations. You can also define your own custom configurations to use in your
            build. Please see <xref linkend="sub:configurations"/> for the details of defining and customizing dependency configurations.
        </para>
    </section>

    <section>
        <title>External dependencies</title>
        <para>There are various types of dependencies that you can declare. One such type is an <firstterm>external dependency</firstterm>.
            This a dependency on some files built outside the current build, and stored in a repository of some kind, such as Maven central, or
            a corporate Maven or Ivy repository, or a directory in the local file system.
        </para>
        <para>
            To define an external dependency, you add it to a dependency configuration:
        </para>
        <sample id="externalDependencies" dir="userguide/artifacts/externalDependencies" title="Definition of an external dependency">
            <sourcefile file="build.gradle" snippet="define-dependency"/>
        </sample>
        <para>
            An external dependency is identified using <literal>group</literal>, <literal>name</literal> and <literal>version</literal> attributes.
            Depending on which kind of repository you are using, <literal>group</literal> and <literal>version</literal> may be optional.
        </para>
        <para>There is a shortcut form for declaring external dependencies, which uses a string of the form <literal>"<replaceable>group</replaceable>:<replaceable>name</replaceable>:<replaceable>version</replaceable>"</literal>.
        </para>
        <sample id="externalDependencies" dir="userguide/artifacts/externalDependencies" title="Shortcut definition of an external dependency">
            <sourcefile file="build.gradle" snippet="define-dependency-shortcut"/>
        </sample>
        <para>To find out more about defining and working with dependencies, have a look at <xref linkend="sec:how_to_declare_your_dependencies"/>.</para>
    </section>

    <section>
        <title>Repositories</title>
        <para>
            How does Gradle find the files for external dependencies? Gradle looks for them in a <firstterm>repository</firstterm>.
            A repository is really just a collection of files, organized by <literal>group</literal>, <literal>name</literal> and
            <literal>version</literal>. Gradle understands several different repository formats, such as Maven and Ivy, and several
            different ways of accessing the repository, such as using the local file system or HTTP.
        </para>
        <para>By default, Gradle does not define any repositories. You need to define at least one before you can use external dependencies.
            One option is use the Maven central repository:</para>
        <sample id="defineMavenCentral" dir="userguide/artifacts/defineRepository" title="Usage of Maven central repository">
            <sourcefile file="build.gradle" snippet="maven-central"/>
        </sample>
        <para>Or a remote Maven repository:</para>
        <sample id="defineRemoteMavenRepo" dir="userguide/artifacts/defineRepository" title="Usage of a remote Maven repository">
            <sourcefile file="build.gradle" snippet="maven-like-repo"/>
        </sample>
        <para>Or a remote Ivy repository:</para>
        <sample id="defineRemoteIvyRepo" dir="userguide/artifacts/defineRepository" title="Usage of a remote Ivy directory">
            <sourcefile file="build.gradle" snippet="ivy-repo"/>
        </sample>
        <para>You can also have repositories on the local file system. This works for both Maven and Ivy repositories.</para>
        <sample id="defineRemoteIvyRepo" dir="userguide/artifacts/defineRepository" title="Usage of a local Ivy directory">
            <sourcefile file="build.gradle" snippet="local-ivy-repo"/>
        </sample>
        <para>A project can have multiple repositories. Gradle will look for a dependency in each repository in the order they are specified, stopping
            at the first repository that contains the requested module.
        </para>
        <para>To find out more about defining and working with repositories, have a look at <xref linkend="sec:repositories"/>.</para>
    </section>

    <section>
        <title>Publishing artifacts</title>
        <para>
            Dependency configurations are also used to publish files.<footnote><para>We think this is confusing, and we are gradually teasing apart the two concepts in the Gradle DSL.</para></footnote>
            We call these files <firstterm>publication artifacts</firstterm>, or usually just <firstterm>artifacts</firstterm>.
        </para>
        <para>
            The plugins do a pretty good job of defining the artifacts of a project, so you usually don't need to do anything special to tell Gradle
            what needs to be published. However, you do need to tell Gradle where to publish the artifacts. You do this by attaching repositories
            to the <literal>uploadArchives</literal> task. Here's an example of publishing to a remote Ivy repository:
        </para>
        <sample id="publishIvyRepository" dir="userguide/artifacts/uploading" title="Publishing to an Ivy repository">
            <sourcefile file="build.gradle" snippet="publish-repository"/>
        </sample>
        <para>
            Now, when you run <userinput>gradle uploadArchives</userinput>, Gradle will build and upload your Jar.
            Gradle will also generate and upload an <filename>ivy.xml</filename> as well.
        </para>
        <para>
            You can also publish to Maven repositories. The syntax is slightly different.<footnote>
                <para>We are working to make the syntax consistent for resolving from and publishing to Maven repositories.</para>
            </footnote>
            Note that you also need to apply the Maven plugin in order to publish to a Maven repository. In this instance, Gradle
            will generate and upload a <filename>pom.xml</filename>.
        </para>
        <sample id="publishMavenRepository" dir="userguide/artifacts/maven" title="Publishing to a Maven repository">
            <sourcefile file="build.gradle" snippet="upload-file"/>
        </sample>
        <para>To find out more about publication, have a look at <xref linkend="artifact_management"/>.</para>
    </section>

    <section>
        <title>Where to next?</title>
        <para>
            For all the details of dependency resolution, see <xref linkend="dependency_management"/>, and for artifact publication see <xref linkend="artifact_management"/>.
        </para>
        <para>
            If you are interested in the DSL elements mentioned here, have a look at <apilink class="org.gradle.api.Project" method="configurations"/>,
            <apilink class="org.gradle.api.Project" method="repositories"/> and <apilink class="org.gradle.api.Project" method="dependencies"/>.
        </para>
        <para>Otherwise, continue on to some of the other <link linkend="tutorials">tutorials</link>.</para>
    </section>
</chapter>
