// Copyright (C) 2023 Gradle, Inc.
//
// Licensed under the Creative Commons Attribution-Noncommercial-ShareAlike 4.0 International License.;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://creativecommons.org/licenses/by-nc-sa/4.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.

[[dependency_management_in_gradle]]
= Dependency Management

Software projects rarely work in isolation.
Projects often rely on reusable functionality from libraries.
Some projects organize unrelated functionality into separate parts of a modular system.

Dependency management is an automated technique for declaring, resolving, and using functionality required by a project.

TIP: For an overview of dependency management terms, see <<glossary.adoc#dependency_management_terminology,Dependency Management Terminology>>.

[[sec:dependency-mgmt-in-gradle]]
== Dependency Management in Gradle

.Dependencies management at a glance
image::dependency-management-resolution.png[]

Gradle has built-in support for dependency management.

Let's explore the main concepts with the help of a theoretical but common project:

* This project builds Java source code.
* Some Java source files import classes from the link:https://github.com/google/guava[Google Guava] library.
* This project uses link:http://junit.org/junit5/[JUnit] for testing.

The Gradle build file might look as follows:

.Gradle build file with dependencies
====
include::sample[dir="snippets/dependencyManagement/introductionCoreDependencies/kotlin",files="build.gradle.kts"]
include::sample[dir="snippets/dependencyManagement/introductionCoreDependencies/groovy",files="build.gradle"]
====

<1> *Here we define repositories for the project.*

<2> *Here we declare remote and local repositories for dependency locations.*
+
You can <<declaring_repositories.adoc#declaring-basic-repositories,declare _repositories_>> to tell Gradle where to fetch local or remote _dependencies_. +
In this example, Gradle fetches _dependencies_ from the link:https://repo1.maven.org/maven2/[Maven Central] and link:https://maven.google.com/[Google] _repositories_. +
During a build, Gradle locates and downloads the dependencies, a process called <<dependency_resolution.adoc#sec:how-gradle-downloads-deps,_dependency resolution_>>.
Gradle then <<dependency_resolution.adoc#sec:dependency_cache,stores resolved dependencies in a local cache>> called the _dependency cache_.
Subsequent builds use this cache to avoid unnecessary network calls and speed up the build process.

<3> *Here we define dependencies used by the project.*

<4> *Here we declare the specific dependency name and version within a scope.*
+
You can add code to your Java project from an external library such as `com.google.common.base` (a Guava package) which becomes a _dependency_. +
In this example, the theoretical project uses Guava version 32.1.2-jre and JUnit 4.13.2 as _dependencies_. +
A build engineer can <<declaring_dependencies.adoc#declaring-basic-dependencies,declare dependencies>> for different scopes. For example, you can declare dependencies that are only used at compile time.
Gradle calls the <<dependency_configurations.adoc#sec:what-are-dependency-configurations,scope of a dependency>> a _configuration_.

Repositories offer dependencies in multiple formats.
For information about the formats supported by Gradle, see <<declaring_dependencies.adoc#sec:dependency-types,dependency types>>.

Metadata describes dependencies.
Some examples of metadata include:

* coordinates for finding the dependency in a repository
* information about the project that created the dependency
* the authors of the dependency
* other dependencies required for a dependency to work properly, known as _transitive dependencies_

You can <<dependency_constraints.adoc#dependency-constraints,customize Gradle's handling of transitive dependencies>> based on the requirements of a project.

Projects with hundreds of declared dependencies can be difficult to debug.
Gradle provides tools to visualize and analyze a project's dependency graph (i.e. dependency tree).
You can use a link:https://scans.gradle.com/get-started[Build Scan(TM)] or <<viewing_debugging_dependencies.adoc#sec:debugging-build-scans,built-in tasks>>.

.Build scan dependencies report
image::gradle-core-test-build-scan-dependencies.png[]
