// 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.

[[repository-content-filtering]]
= Filtering Repository Content

Gradle exposes an API to declare what a repository may or may not contain.
There are different use cases for it:

- **Performance** when you know a dependency will never be found in a specific repository
- **Security** by avoiding leaking what dependencies are used in a private project
- **Reliability** when some repositories contain invalid or incorrect metadata or artifacts

It's even more important when considering that the declared order of repositories matter.

[[sec:declaring-repository-filter]]
== Declaring a repository filter

====
include::sample[dir="snippets//dependencyManagement/declaringRepositories-filtering/kotlin",files="build.gradle.kts[tags=repository-filter]"]
include::sample[dir="snippets/dependencyManagement/declaringRepositories-filtering/groovy",files="build.gradle[tags=repository-filter]"]
====

By default, repositories include everything and exclude nothing:

* If you declare an include, then it excludes everything _but_ what is included.
* If you declare an exclude, then it includes everything _but_ what is excluded.
* If you declare both includes and excludes, then it includes only what is explicitly included and not excluded.

It is possible to filter either by explicit _group_, _module_ or _version_, either strictly or using regular expressions.
When using a strict version, it is possible to use a version range, using <<dependency_versions.adoc#sec:single-version-declarations,the format supported>> by Gradle.
In addition, there are filtering options by resolution context: configuration name or even configuration attributes.
See link:{javadocPath}/org/gradle/api/artifacts/repositories/RepositoryContentDescriptor.html[RepositoryContentDescriptor] for details.

[[sec:declaring-content-repositories]]
== Declaring content exclusively found in one repository

Filters declared using the <<#sec:declaring-repository-filter,repository-level content filter>> are not exclusive.
This means that declaring that a repository _includes_ an artifact doesn't mean that the other repositories can't have it either: you must declare what every repository contains in extension.

Alternatively, Gradle provides an API which lets you declare that a repository _exclusively includes_ an artifact.
If you do so:

- an artifact declared in a repository _can't_ be found in any other
- exclusive repository content must be declared in extension (just like for <<#sec:declaring-repository-filter, repository-level content>>)

====
include::sample[dir="snippets/dependencyManagement/declaringRepositories-filtering/kotlin",files="build.gradle.kts[tags=exclusive-repository-filter]"]
include::sample[dir="snippets/dependencyManagement/declaringRepositories-filtering/groovy",files="build.gradle[tags=exclusive-repository-filter]"]
====

It is possible to filter either by explicit _group_, _module_ or _version_, either strictly or using regular expressions.
See link:{javadocPath}/org/gradle/api/artifacts/repositories/InclusiveRepositoryContentDescriptor.html[InclusiveRepositoryContentDescriptor] for details.

[NOTE]
====
If you leverage exclusive content filtering in the <<plugins.adoc#sec:custom_plugin_repositories,`pluginManagement` section of the `settings.gradle(.kts)`>>, it becomes illegal to add more repositories through the project `buildscript.repositories`.
In that case, the build configuration will fail.

Your options are either to declare all repositories in settings or to use non-exclusive content filtering.
====

=== Maven repository filtering

For <<supported_repository_types.adoc#sec:maven-repo,Maven repositories>>, it's often the case that a repository would either contain releases or snapshots.
Gradle lets you declare what kind of artifacts are found in a repository using this DSL:

====
include::sample[dir="snippets/dependencyManagement/declaringRepositories-filtering/kotlin",files="build.gradle.kts[tags=repository-snapshots]"]
include::sample[dir="snippets/dependencyManagement/declaringRepositories-filtering/groovy",files="build.gradle[tags=repository-snapshots]"]
====
