Gradle 开放了一个 API,用于声明存储库可能或不可能包含的内容。它有不同的用例

  • 性能:当您知道某个依赖项永远不会在特定存储库中找到时

  • 安全性:通过避免泄露私有项目中使用的依赖项

  • 可靠性:当某些存储库包含无效或不正确的元数据或工件时

考虑到声明的存储库顺序很重要,这一点就更加重要了。

声明存储库过滤器

build.gradle.kts
repositories {
    maven {
        url = uri("https://repo.mycompany.com/maven2")
        content {
            // this repository *only* contains artifacts with group "my.company"
            includeGroup("my.company")
        }
    }
    mavenCentral {
        content {
            // this repository contains everything BUT artifacts with group starting with "my.company"
            excludeGroupByRegex("my\\.company.*")
        }
    }
}
build.gradle
repositories {
    maven {
        url = "https://repo.mycompany.com/maven2"
        content {
            // this repository *only* contains artifacts with group "my.company"
            includeGroup "my.company"
        }
    }
    mavenCentral {
        content {
            // this repository contains everything BUT artifacts with group starting with "my.company"
            excludeGroupByRegex "my\\.company.*"
        }
    }
}

默认情况下,存储库包含所有内容,不排除任何内容

  • 如果您声明了一个包含项,那么它将排除除包含项之外的所有内容。

  • 如果您声明了一个排除项,那么它将包含除排除项之外的所有内容。

  • 如果您同时声明包含项和排除项,那么它将只包含明确包含且未排除的内容。

可以通过显式模块版本进行过滤,可以是严格匹配,也可以使用正则表达式。当使用严格版本时,可以使用版本范围,采用 Gradle 支持的格式。此外,还有按解析上下文(配置名称甚至配置属性)进行过滤的选项。有关详细信息,请参阅RepositoryContentDescriptor

声明仅在一个存储库中找到的内容

使用存储库级别内容过滤器声明的过滤器不是排他性的。这意味着声明某个存储库包含一个工件并不意味着其他存储库不能拥有它:您必须声明每个存储库包含的扩展内容。

或者,Gradle 提供了一个 API,允许您声明某个存储库独占性地包含一个工件。如果您这样做

  • 在某个存储库中声明的工件不能在任何其他存储库中找到

  • 独占存储库内容必须在扩展中声明(就像存储库级别内容一样)

build.gradle.kts
repositories {
    // This repository will _not_ be searched for artifacts in my.company
    // despite being declared first
    mavenCentral()
    exclusiveContent {
        forRepository {
            maven {
                url = uri("https://repo.mycompany.com/maven2")
            }
        }
        filter {
            // this repository *only* contains artifacts with group "my.company"
            includeGroup("my.company")
        }
    }
}
build.gradle
repositories {
    // This repository will _not_ be searched for artifacts in my.company
    // despite being declared first
    mavenCentral()
    exclusiveContent {
        forRepository {
            maven {
                url = "https://repo.mycompany.com/maven2"
            }
        }
        filter {
            // this repository *only* contains artifacts with group "my.company"
            includeGroup "my.company"
        }
    }
}

可以通过显式模块版本进行过滤,可以是严格匹配,也可以使用正则表达式。有关详细信息,请参阅InclusiveRepositoryContentDescriptor

如果您在settings.gradle(.kts)pluginManagement 部分利用了独占内容过滤,那么通过项目 buildscript.repositories 添加更多存储库将是非法的。在这种情况下,构建配置将失败。

您的选择是:要么在设置中声明所有存储库,要么使用非独占内容过滤。

Maven 存储库过滤

对于Maven 存储库,通常一个存储库会包含发布版或快照版。Gradle 允许您使用此 DSL 声明存储库中包含的工件类型

build.gradle.kts
repositories {
    maven {
        url = uri("https://repo.mycompany.com/releases")
        mavenContent {
            releasesOnly()
        }
    }
    maven {
        url = uri("https://repo.mycompany.com/snapshots")
        mavenContent {
            snapshotsOnly()
        }
    }
}
build.gradle
repositories {
    maven {
        url = "https://repo.mycompany.com/releases"
        mavenContent {
            releasesOnly()
        }
    }
    maven {
        url = "https://repo.mycompany.com/snapshots"
        mavenContent {
            snapshotsOnly()
        }
    }
}

启用 Ivy 动态解析模式

通常,在 Ivy 存储库中,依赖项通过 ivy.xml 中的 rev(修订版)属性指定。但是,动态解析模式允许 Gradle 优先使用 revConstraint 属性而不是 rev

  • 如果 ivy.xml 中存在 revConstraint,Gradle 将使用它而不是 rev

  • 如果 revConstraint 存在,Gradle 会退回到 rev

这为依赖解析提供了更大的灵活性,尤其是在使用定义了可接受版本约束的 Ivy 存储库时。

在声明 Ivy 存储库时,您需要明确启用动态解析模式

build.gradle.kts
// Can enable dynamic resolve mode when you define the repository
repositories {
    ivy {
        url = uri("http://repo.mycompany.com/repo")
        resolve.isDynamicMode = true
    }
}

// Can use a rule instead to enable (or disable) dynamic resolve mode for all repositories
repositories.withType<IvyArtifactRepository> {
    resolve.isDynamicMode = true
}
build.gradle
// Can enable dynamic resolve mode when you define the repository
repositories {
    ivy {
        url = "http://repo.mycompany.com/repo"
        resolve.dynamicMode = true
    }
}

// Can use a rule instead to enable (or disable) dynamic resolve mode for all repositories
repositories.withType(IvyArtifactRepository) {
    resolve.dynamicMode = true
}
动态解析模式仅适用于 Gradle 的 Ivy 存储库。它不适用于 Maven 存储库或自定义 Ivy DependencyResolver 实现。