// Copyright (C) 2024 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.

[[two-dependency-configurations]]
= 2. Dependency Configurations

Every dependency declared for a Gradle project applies to a specific scope.

For example, some dependencies should be used for compiling source code whereas others only need to be available at runtime:

====
[.multi-language-sample]
=====
[source, kotlin]
.build.gradle.kts
----
dependencies {
    implementation("com.google.guava:guava:30.0-jre")   // Needed to compile and run the app
    runtimeOnly("org.slf4j:slf4j-simple:2.0.13")        // Only needed at runtime
}
----
=====
[.multi-language-sample]
=====
[source, groovy]
.build.gradle
----
dependencies {
    implementation("com.google.guava:guava:30.0-jre")   // Needed to compile and run the app
    runtimeOnly("org.slf4j:slf4j-simple:2.0.13")        // Only needed at runtime
}
----
=====
====

Dependency configurations are a way to define different sets of dependencies for different purposes within a project.
They determine how and when dependencies are used in various stages of the build process.

Configurations are a fundamental part of dependency resolution in Gradle.

[[sub:what-are-dependency-configurations]]
== Understanding dependency configurations

Gradle represents the scope of a dependency with the help of a link:{groovyDslPath}/org.gradle.api.artifacts.Configuration.html[Configuration].
Every configuration can be identified by a unique name.

Many Gradle plugins add pre-defined configurations to your project.

The Java Library plugin is used to define a project that produces a Java library.
The plugin adds many dependency configurations.
These configurations represent the various classpaths needed for source code compilation, executing tests, and more.
The configurations below are used to declare dependencies for different purposes:

[cols="~,~"]
|===
|Configuration Name |Description

|`api`
|Dependencies required for both compilation and runtime, and included in the published API.

|`implementation`
|Dependencies required for both compilation and runtime.

|`compileOnly`
|Dependencies needed only for compilation, not included in runtime or publication.

|`compileOnlyApi`
|Dependencies needed only for compilation, but included in the published API.

|`runtimeOnly`
|Dependencies needed only at runtime, not included in the compile classpath.

|`testImplementation`
|Dependencies required for compiling and running tests.

|`testCompileOnly`
|Dependencies needed only for test compilation.

|`testRuntimeOnly`
|Dependencies needed only for running tests.

|===

[[sub:dependency-declaration-configurations]]
=== Dependency declaration Configurations

The *dependency declaration configurations* (`compileOnly`, `implementation`, `runtimeOnly`) focus on declaring and managing dependencies based on their usage (compile time, runtime, API exposure):

====
[.multi-language-sample]
=====
[source, kotlin]
----
dependencies {
    implementation("com.google.guava:guava:30.1.1-jre")     // Implementation dependency
    compileOnly("org.projectlombok:lombok:1.18.20")         // Compile-only dependency
    runtimeOnly("mysql:mysql-connector-java:8.0.23")        // Runtime-only dependency
}
----
=====
[.multi-language-sample]
=====
[source,groovy]
----
dependencies {
    implementation("com.google.guava:guava:30.1.1-jre")     // Implementation dependency
    compileOnly("org.projectlombok:lombok:1.18.20")         // Compile-only dependency
    runtimeOnly("mysql:mysql-connector-java:8.0.23")        // Runtime-only dependency
}
----
=====
====

[[sub:other-configurations]]
=== Other Configurations

There are other types of configurations (such as `runtimeClasspath`, `compileClasspath`, `apiElements`, `runtimeElements`), but they are not used to declare dependencies.
They are used internally by Gradle to assemble the classpaths for application or to configure dependencies between projects.

It is also possible to create custom configurations.
A custom configuration allows you to define a distinct group of dependencies that can be used for specific purposes, such as toolchains or code generation, separate from the standard configurations (e.g., `implementation`, `testImplementation`):

====
[.multi-language-sample]
=====
[source, kotlin]
.build.gradle.kts
----
val customConfig = configurations.create("customConfig")

dependencies {
    customConfig("org.example:example-lib:1.0")
}
----
=====
[.multi-language-sample]
=====
[source, groovy]
.build.gradle
----
configurations {
    customConfig
}

dependencies {
    customConfig("org.example:example-lib:1.0")
}
----
=====
====

Creating a custom configuration helps manage and isolate dependencies, ensuring they are only included in the relevant classpaths and build processes.

[[sub:view-configurations]]
== Viewing configurations

The `dependencies` task provides an overview of the dependencies of your project.
To focus on the information about one dependency configuration, provide the optional parameter `--configuration`.

The following example show dependencies in the `implementation` dependency configuration of a Java project:

[source,bash]
----
$ ./gradlew -q app:dependencies --configuration implementation
----
[source,text]
----
------------------------------------------------------------
Project ':app'
------------------------------------------------------------

implementation - Implementation only dependencies for source set 'main'.
\--- com.google.guava:guava:30.0-jre
----

[.text-right]
**Next Step:** <<declaring_repositories.adoc#three-declaring-repositories,Learn about Declaring Repositories>> >>
