<!--
  ~ Copyright 2009 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="artifact_management">
    <title>Publishing artifacts</title>
    <note>
        <para>
            This chapter describes the <emphasis>original</emphasis> publishing mechanism available in Gradle 1.0: in Gradle 1.3 a new mechanism for publishing was introduced.
            While this new mechanism is <emphasis>incubating</emphasis> and not yet complete, it introduces some new concepts and features that do (and will) make Gradle publishing even more powerful.
        </para>
        <para>
            You can read about the new publishing plugins in <xref linkend="publishing_ivy"/> and <xref linkend="publishing_maven"/>. Please try them out and give us feedback.
        </para>
    </note>
    <section>
        <title>Introduction</title>
        <para>This chapter is about how you declare the outgoing artifacts of your project, and how to work with
            them (e.g. upload them). We define the artifacts of the projects as the files the project provides to the
            outside world. This might be a library or a ZIP distribution or any other file. A project can publish as many artifacts as it wants.
        </para>
    </section>
    <section id="artifacts_and_configurations">
        <title>Artifacts and configurations</title>
        <para>Like dependencies, artifacts are grouped by configurations. In fact, a configuration can contain
            both artifacts and dependencies at the same time.
        </para>
        <para>For each configuration in your project, Gradle provides the tasks <literal>upload<replaceable>ConfigurationName</replaceable></literal> and
        <literal>build<replaceable>ConfigurationName</replaceable></literal>.
        <footnote><para>To be exact, the Base plugin provides those tasks. This plugin is automatically applied if you use
        the Java plugin.</para></footnote>
        Execution of these tasks will build or upload the artifacts belonging to the respective configuration.
        </para>
        <para>Table <xref linkend="tab:configurations"/> shows the configurations added by the Java plugin. Two of the
        configurations are relevant for the usage with artifacts. The <code>archives</code> configuration is the standard
        configuration to assign your artifacts to. The Java plugin automatically assigns the default jar to this
        configuration. We will talk more about the <code>runtime</code> configuration in <xref linkend="project_libraries"/>.
        As with dependencies, you can declare as many custom configurations as you like and assign artifacts to them.
        </para>
    </section>

    <section>
        <title>Declaring artifacts</title>
        <section>
            <title>Archive task artifacts</title>
            <para>You can use an archive task to define an artifact:</para>
            <sample id="archiveTaskArtifact" dir="userguide/artifacts/uploading" title="Defining an artifact using an archive task">
                <sourcefile file="build.gradle" snippet="archive-artifact"/>
            </sample>
            <para>It is important to note that the custom archives you are creating as part of your build are not
            automatically assigned to any configuration. You have to explicitly do this assignment.</para>
        </section>
        <section>
            <title>File artifacts</title>
            <para>You can also use a file to define an artifact:</para>
            <sample id="fileArtifact" dir="userguide/artifacts/uploading" title="Defining an artifact using a file">
                <sourcefile file="build.gradle" snippet="file-artifact"/>
            </sample>
            <para>Gradle will figure out the properties of the artifact based on the name of the file. You can customize these properties:</para>
            <sample id="fileArtifact" dir="userguide/artifacts/uploading" title="Customizing an artifact">
                <sourcefile file="build.gradle" snippet="customised-file-artifact"/>
            </sample>
            <para>There is a map-based syntax for defining an artifact using a file. The map must include a <literal>file</literal> entry that
                defines the file. The map may include other artifact properties:
            </para>
            <sample id="fileArtifact" dir="userguide/artifacts/uploading" title="Map syntax for defining an artifact using a file">
                <sourcefile file="build.gradle" snippet="map-file-artifact"/>
            </sample>
        </section>
    </section>

    <section>
        <title>Publishing artifacts</title>
        <para>We have said that there is a specific upload task for each configuration. But before you can do an upload,
            you have to configure the upload task and define where to publish the artifacts to. The repositories you have defined (as described
            in <xref linkend="sec:repositories"/>) are not automatically used for uploading. In fact, some of those repositories allow only for artifact downloading.
            Here is an example how you can configure the upload task of a configuration:
        </para>
        <sample id="uploading" dir="userguide/artifacts/uploading" title="Configuration of the upload task">
            <sourcefile file="build.gradle" snippet="uploading"/>
        </sample>
        <para>As you can see, you can either use a reference to an existing repository or create a new repository.
        As described in <xref linkend="sub:more_about_ivy_resolvers"/>, you can use all the Ivy resolvers suitable
        for the purpose of uploading.
        </para>
        <para>If an upload repository is defined with multiple patterns, Gradle must choose a pattern to use for uploading each file.
            By default, Gradle will upload to the pattern defined by the <literal>url</literal> parameter, combined with the optional <literal>layout</literal> parameter.
            If no <literal>url</literal> parameter is supplied, then Gradle will use the first defined <literal>artifactPattern</literal> for uploading,
            or the first defined <literal>ivyPattern</literal> for uploading Ivy files, if this is set.
        </para>
        <para>Uploading to a Maven repository is described in <xref linkend="uploading_to_maven_repositories"/>.</para>
    </section>
    <section id="project_libraries">
        <title>More about project libraries</title>
        <para>If your project is supposed to be used as a library, you need to define what are the artifacts of this library
            and what are the dependencies of these artifacts. The Java plugin adds a <code>runtime</code> configuration for
            this purpose, with the implicit assumption that the <code>runtime</code> dependencies are the dependencies of
            the artifact you want to publish. Of course this is fully customizable. You can add your own custom configuration or let the
            existing configurations extend from other configurations. You might have different group of artifacts which have
            a different set of dependencies. This mechanism is very powerful and flexible.
            </para>
        <para>If someone wants to use your project as a library, she simply needs to declare on which configuration of
            the dependency to depend on.
            A Gradle dependency offers the <code>configuration</code> property to declare this. If this
            is not specified, the <code>default</code> configuration is used (see <xref linkend="sec:dependency_configurations"/>).
            Using your project as a library
            can either happen from within a multi-project build or by retrieving your project from a repository. In
            the latter case, an <filename>ivy.xml</filename> descriptor in the repository is supposed to contain all the necessary information. If you
            work with Maven repositories you don't have the flexibility as described above. For how to publish to a Maven
            repository, see the section <xref linkend="uploading_to_maven_repositories"/>.
        </para>
    </section>
</chapter>
