Gradle的settings.gradle.kts你真的理解吗?

news2024/10/6 20:26:38

你还在用.gradle文件吗?例如build.gradle、settings.gradle,那么你就out了。现在我们有必要了解一下kts脚本了。在Android项目中,默认有3个文件可以替换成kts脚本,即project的build.gradle、app模块的build.gradle和project的settings.gradle,它们更名后分别为build.gradle.kts、build.gradle.kts和settings.gradle.kts。

settings.gradle简介

我们的gradle脚本本质上是执行一个个gradle plugin,即apply plugin,可以执行外部导入的,也可以执行项目编写的编译脚本代码。所以settings.gradle.kts也是编译过程中一个gradle plugin。在
org.gradle.initialization.DefaultSettings中有个getSettings方法,调用这个方法拿到我们配置的settings gradle plugin。settings.gradle.kts中可以配置的内容我们参考Settings这个类。在settings.gradle.kts这个文件中,主要配置一些项目全局的设置。

Settings全局设置解析

package org.gradle.api.initialization;

import org.gradle.StartParameter;
import org.gradle.api.Action;
import org.gradle.api.Incubating;
import org.gradle.api.UnknownProjectException;
import org.gradle.api.initialization.dsl.ScriptHandler;
import org.gradle.api.initialization.resolve.DependencyResolutionManagement;
import org.gradle.api.invocation.Gradle;
import org.gradle.api.plugins.ExtensionAware;
import org.gradle.api.plugins.PluginAware;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.ProviderFactory;
import org.gradle.api.toolchain.management.ToolchainManagement;
import org.gradle.api.cache.CacheConfigurations;
import org.gradle.caching.configuration.BuildCacheConfiguration;
import org.gradle.internal.HasInternalProtocol;
import org.gradle.plugin.management.PluginManagementSpec;
import org.gradle.vcs.SourceControl;

import javax.annotation.Nullable;
import java.io.File;
import java.util.Arrays;

/**
 * <p>Declares the configuration required to instantiate and configure the hierarchy of {@link
 * org.gradle.api.Project} instances which are to participate in a build.</p>
 *
 * <p>There is a one-to-one correspondence between a <code>Settings</code> instance and a <code>{@value
 * #DEFAULT_SETTINGS_FILE}</code> settings file. Before Gradle assembles the projects for a build, it creates a
 * <code>Settings</code> instance and executes the settings file against it.</p>
 *
 * <h3>Assembling a Multi-Project Build</h3>
 *
 * <p>One of the purposes of the <code>Settings</code> object is to allow you to declare the projects which are to be
 * included in the build. You add projects to the build using the {@link #include(String...)} method.  There is always a
 * root project included in a build.  It is added automatically when the <code>Settings</code> object is created.  The
 * root project's name defaults to the name of the directory containing the settings file. The root project's project
 * directory defaults to the directory containing the settings file.</p>
 *
 * <p>When a project is included in the build, a {@link ProjectDescriptor} is created. You can use this descriptor to
 * change the default values for several properties of the project.</p>
 *
 * <h3>Using Settings in a Settings File</h3>
 *
 * <h4>Dynamic Properties</h4>
 *
 * <p>In addition to the properties of this interface, the {@code Settings} object makes some additional read-only
 * properties available to the settings script. This includes properties from the following sources:</p>
 *
 * <ul>
 *
 * <li>Defined in the {@value org.gradle.api.Project#GRADLE_PROPERTIES} file located in the settings directory of the
 * build.</li>
 *
 * <li>Defined the {@value org.gradle.api.Project#GRADLE_PROPERTIES} file located in the user's {@code .gradle}
 * directory.</li>
 *
 * <li>Provided on the command-line using the -P option.</li>
 *
 * </ul>
 */
@HasInternalProtocol
public interface Settings extends PluginAware, ExtensionAware {
    /**
     * <p>The default name for the settings file.</p>
     */
    String DEFAULT_SETTINGS_FILE = "settings.gradle";

    /**
     * <p>Adds the given projects to the build. Each path in the supplied list is treated as the path of a project to
     * add to the build. Note that these path are not file paths, but instead specify the location of the new project in
     * the project hierarchy. As such, the supplied paths must use the ':' character as separator (and NOT '/').</p>
     *
     * <p>The last element of the supplied path is used as the project name. The supplied path is converted to a project
     * directory relative to the root project directory. The project directory can be altered by changing the 'projectDir'
     * property after the project has been included (see {@link ProjectDescriptor#setProjectDir(File)})</p>
     *
     * <p>As an example, the path {@code a:b} adds a project with path {@code :a:b}, name {@code b} and project
     * directory {@code $rootDir/a/b}. It also adds the a project with path {@code :a}, name {@code a} and project
     * directory {@code $rootDir/a}, if it does not exist already.</p>
     *
     * <p>Some common examples of using the project path are:</p>
     *
     * <pre class='autoTestedSettings'>
     *   // include two projects, 'foo' and 'foo:bar'
     *   // directories are inferred by replacing ':' with '/'
     *   include 'foo:bar'
     *
     *   // include one project whose project dir does not match the logical project path
     *   include 'baz'
     *   project(':baz').projectDir = file('foo/baz')
     *
     *   // include many projects whose project dirs do not match the logical project paths
     *   file('subprojects').eachDir { dir -&gt;
     *     include dir.name
     *     project(":${dir.name}").projectDir = dir
     *   }
     * </pre>
     *
     * @param projectPaths the projects to add.
     */
    default void include(String... projectPaths) {
        include(Arrays.asList(projectPaths));
    }

    /**
     * <p>Adds the given projects to the build. Each path in the supplied list is treated as the path of a project to
     * add to the build. Note that these path are not file paths, but instead specify the location of the new project in
     * the project hierarchy. As such, the supplied paths must use the ':' character as separator (and NOT '/').</p>
     *
     * <p>The last element of the supplied path is used as the project name. The supplied path is converted to a project
     * directory relative to the root project directory. The project directory can be altered by changing the 'projectDir'
     * property after the project has been included (see {@link ProjectDescriptor#setProjectDir(File)})</p>
     *
     * <p>As an example, the path {@code a:b} adds a project with path {@code :a:b}, name {@code b} and project
     * directory {@code $rootDir/a/b}. It also adds the a project with path {@code :a}, name {@code a} and project
     * directory {@code $rootDir/a}, if it does not exist already.</p>
     *
     * <p>Some common examples of using the project path are:</p>
     *
     * <pre class='autoTestedSettings'>
     *   // include two projects, 'foo' and 'foo:bar'
     *   // directories are inferred by replacing ':' with '/'
     *   include(['foo:bar'])
     *
     *   // include one project whose project dir does not match the logical project path
     *   include(['baz'])
     *   project(':baz').projectDir = file('foo/baz')
     *
     *   // include many projects whose project dirs do not match the logical project paths
     *   file('subprojects').eachDir { dir -&gt;
     *     include([dir.name])
     *     project(":${dir.name}").projectDir = dir
     *   }
     * </pre>
     *
     * @param projectPaths the projects to add.
     *
     * @since 7.4
     */
    void include(Iterable<String> projectPaths);

    /**
     * <p>Adds the given projects to the build. Each name in the supplied list is treated as the name of a project to
     * add to the build.</p>
     *
     * <p>The supplied name is converted to a project directory relative to the <em>parent</em> directory of the root
     * project directory.</p>
     *
     * <p>As an example, the name {@code a} add a project with path {@code :a}, name {@code a} and project directory
     * {@code $rootDir/../a}.</p>
     *
     * @param projectNames the projects to add.
     */
    default void includeFlat(String... projectNames) {
        includeFlat(Arrays.asList(projectNames));
    }

    /**
     * <p>Adds the given projects to the build. Each name in the supplied list is treated as the name of a project to
     * add to the build.</p>
     *
     * <p>The supplied name is converted to a project directory relative to the <em>parent</em> directory of the root
     * project directory.</p>
     *
     * <p>As an example, the name {@code a} add a project with path {@code :a}, name {@code a} and project directory
     * {@code $rootDir/../a}.</p>
     *
     * @param projectNames the projects to add.
     *
     * @since 7.4
     */
    void includeFlat(Iterable<String> projectNames);

    /**
     * <p>Returns this settings object.</p>
     *
     * @return This settings object. Never returns null.
     */
    Settings getSettings();

    /**
     * Returns the build script handler for settings. You can use this handler to query details about the build
     * script for settings, and manage the classpath used to compile and execute the settings script.
     *
     * @return the classpath handler. Never returns null.
     *
     * @since 4.4
     */
    ScriptHandler getBuildscript();

    /**
     * <p>Returns the settings directory of the build. The settings directory is the directory containing the settings
     * file.</p>
     *
     * @return The settings directory. Never returns null.
     */
    File getSettingsDir();

    /**
     * <p>Returns the root directory of the build. The root directory is the project directory of the root project.</p>
     *
     * @return The root directory. Never returns null.
     */
    File getRootDir();

    /**
     * <p>Returns the root project of the build.</p>
     *
     * @return The root project. Never returns null.
     */
    ProjectDescriptor getRootProject();

    /**
     * <p>Returns the project with the given path.</p>
     *
     * @param path The path.
     * @return The project with the given path. Never returns null.
     * @throws UnknownProjectException If no project with the given path exists.
     */
    ProjectDescriptor project(String path) throws UnknownProjectException;

    /**
     * <p>Returns the project with the given path.</p>
     *
     * @param path The path
     * @return The project with the given path. Returns null if no such project exists.
     */
    @Nullable
    ProjectDescriptor findProject(String path);

    /**
     * <p>Returns the project with the given project directory.</p>
     *
     * @param projectDir The project directory.
     * @return The project with the given project directory. Never returns null.
     * @throws UnknownProjectException If no project with the given path exists.
     */
    ProjectDescriptor project(File projectDir) throws UnknownProjectException;

    /**
     * <p>Returns the project with the given project directory.</p>
     *
     * @param projectDir The project directory.
     * @return The project with the given project directory. Returns null if no such project exists.
     */
    @Nullable
    ProjectDescriptor findProject(File projectDir);

    /**
     * <p>Returns the set of parameters used to invoke this instance of Gradle.</p>
     *
     * @return The parameters. Never returns null.
     */
    StartParameter getStartParameter();

    /**
     * Provides access to methods to create various kinds of {@link Provider} instances.
     *
     * @since 6.8
     */
    ProviderFactory getProviders();

    /**
     * Returns the {@link Gradle} instance for the current build.
     *
     * @return The Gradle instance. Never returns null.
     */
    Gradle getGradle();

    /**
     * Includes a build at the specified path to the composite build.
     * @param rootProject The path to the root project directory for the build.
     *
     * @since 3.1
     */
    void includeBuild(Object rootProject);

    /**
     * Includes a build at the specified path to the composite build, with the supplied configuration.
     * @param rootProject The path to the root project directory for the build.
     * @param configuration An action to configure the included build.
     *
     * @since 3.1
     */
    void includeBuild(Object rootProject, Action<ConfigurableIncludedBuild> configuration);

    /**
     * Returns the build cache configuration.
     *
     * @since 3.5
     */
    BuildCacheConfiguration getBuildCache();

    /**
     * Configures build cache.
     *
     * @since 3.5
     */
    void buildCache(Action<? super BuildCacheConfiguration> action);

    /**
     * Configures plugin management.
     *
     * @since 3.5
     */
    void pluginManagement(Action<? super PluginManagementSpec> pluginManagementSpec);

    /**
     * Returns the plugin management configuration.
     *
     * @since 3.5
     */
    PluginManagementSpec getPluginManagement();

    /**
     * Configures source control.
     *
     * @since 4.4
     */
    void sourceControl(Action<? super SourceControl> configuration);

    /**
     * Returns the source control configuration.
     *
     * @since 4.4
     */
    SourceControl getSourceControl();

    /**
     * Enables a feature preview by name.
     *
     * @param name the name of the feature to enable
     *
     * @since 4.6
     */
    void enableFeaturePreview(String name);

    /**
     * Configures the cross-project dependency resolution aspects
     * @param dependencyResolutionConfiguration the configuration
     *
     * @since 6.8
     */
    void dependencyResolutionManagement(Action<? super DependencyResolutionManagement> dependencyResolutionConfiguration);

    /**
     * Returns the dependency resolution management handler.
     *
     * @since 6.8
     */
    DependencyResolutionManagement getDependencyResolutionManagement();

    /**
     * Configures toolchain management.
     *
     * @since 7.6
     */
    @Incubating
    void toolchainManagement(Action<? super ToolchainManagement> toolchainManagementConfiguration);

    /**
     * Returns the toolchain management configuration.
     *
     * @since 7.6
     */
    @Incubating
    ToolchainManagement getToolchainManagement();

    /**
     * Returns the configuration for caches stored in the user home directory.
     *
     * @since 8.0
     */
    @Incubating
    CacheConfigurations getCaches();

    /**
     * Configures the settings for caches stored in the user home directory.
     *
     * @param cachesConfiguration the configuration
     *
     * @since 8.0
     */
    @Incubating
    void caches(Action<? super CacheConfigurations> cachesConfiguration);
}

比如要索引哪些模块。

include(":app")

以及项目的编译期间的名称。

rootProject.name = "DoraMusic"

PluginManagementSpec插件管理规格

我们可以看到,在这里我们还可以配置pluginManagement函数,pluginManagement传入的是一个PluginManagementSpec。

package org.gradle.plugin.management;

import org.gradle.api.Action;
import org.gradle.api.artifacts.dsl.RepositoryHandler;
import org.gradle.api.initialization.ConfigurableIncludedPluginBuild;
import org.gradle.internal.HasInternalProtocol;
import org.gradle.plugin.use.PluginDependenciesSpec;

/**
 * Configures how plugins are resolved.
 *
 * @since 3.5
 */
@HasInternalProtocol
public interface PluginManagementSpec {

    /**
     * Defines the plugin repositories to use.
     */
    void repositories(Action<? super RepositoryHandler> repositoriesAction);

    /**
     * The plugin repositories to use.
     */
    RepositoryHandler getRepositories();

    /**
     * Configure the plugin resolution strategy.
     */
    void resolutionStrategy(Action<? super PluginResolutionStrategy> action);

    /**
     * The plugin resolution strategy.
     */
    PluginResolutionStrategy getResolutionStrategy();

    /**
     * Configure the default plugin versions.
     * @since 5.6
     */
    void plugins(Action<? super PluginDependenciesSpec> action);

    /**
     * The Plugin dependencies, permitting default plugin versions to be configured.
     * @since 5.6
     */
    PluginDependenciesSpec getPlugins();

    /**
     * Includes a plugin build at the specified path to the composite build.
     * Included plugin builds can contribute settings and project plugins.
     * @param rootProject The path to the root project directory for the build.
     *
     * @since 7.0
     */
    void includeBuild(String rootProject);

    /**
     * Includes a plugin build at the specified path to the composite build, with the supplied configuration.
     * Included plugin builds can contribute settings and project plugins.
     * @param rootProject The path to the root project directory for the build.
     * @param configuration An action to configure the included build.
     *
     * @since 7.0
     */
    void includeBuild(String rootProject, Action<ConfigurableIncludedPluginBuild> configuration);

}

在PluginManagementSpec的源码中,我们可以得知,这个高阶函数传入的block可以配置repositories、resolutionStrategy、plugins、includeBuild这几个函数。我们用的比较多的是前面三个。我们再细看repositories,需要传入的是Action<? super RepositoryHandler>,那么问题来了,我明明是要传入的Action,怎么编译器提示的是Action里面的泛型类。
比如:

pluginManagement {
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
        maven { setUrl("xxx")
    }
}

截屏2023-08-27 21.11.10.png

不信你就看,this指代的是RepositoryHandler。我们观摩一下Action类。

package org.gradle.api;

/**
 * Performs some action against objects of type T.
 *
 * @param <T> The type of object which this action accepts.
 */
@HasImplicitReceiver
public interface Action<T> {
    /**
     * Performs this action against the given object.
     *
     * @param t The object to perform the action on.
     */
    void execute(T t);
}

如果你理解T.() -> Unit,那么就会很好理解这个概念了。这里其实是kotlin的一个高级的用法,SAM接口。Kotlin中的SAM接口是指"Single Abstract Method"接口,它也被称为函数式接口。在Kotlin中,可以使用lambda表达式来代替这些只有一个抽象方法的接口。通过使用lambda表达式,可以更简洁地表示函数或方法。

Kotlin的SAM转换是指将lambda表达式转换为这些SAM接口的实例,从而可以像使用普通函数一样使用它们。这在使用Java的库或与Java代码交互时特别有用,因为在Java中,通常需要使用匿名内部类来实现SAM接口,而在Kotlin中可以直接使用lambda表达式。

例如,如果有一个只有一个抽象方法的Java接口OnClickListener,在Kotlin中可以这样使用lambda表达式来代替:

button.setOnClickListener { view ->
    // 点击事件的处理逻辑
}

这样我们就好理解为什么这么配置RepositoryHandler了。

/*
 * 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.
 */
package org.gradle.api.artifacts.dsl;

import groovy.lang.Closure;
import groovy.lang.DelegatesTo;
import org.gradle.api.Action;
import org.gradle.api.artifacts.ArtifactRepositoryContainer;
import org.gradle.api.artifacts.repositories.ArtifactRepository;
import org.gradle.api.artifacts.repositories.ExclusiveContentRepository;
import org.gradle.api.artifacts.repositories.FlatDirectoryArtifactRepository;
import org.gradle.api.artifacts.repositories.IvyArtifactRepository;
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
import org.gradle.internal.HasInternalProtocol;

import java.util.Map;

/**
 * A {@code RepositoryHandler} manages a set of repositories, allowing repositories to be defined and queried.
 */
@HasInternalProtocol
public interface RepositoryHandler extends ArtifactRepositoryContainer {

    /**
     * Adds a resolver that looks into a number of directories for artifacts. The artifacts are expected to be located in the
     * root of the specified directories. The resolver ignores any group/organization information specified in the
     * dependency section of your build script. If you only use this kind of resolver you might specify your
     * dependencies like <code>":junit:4.4"</code> instead of <code>"junit:junit:4.4"</code>.
     *
     * The following parameter are accepted as keys for the map:
     *
     * <table summary="Shows property keys and associated values">
     * <tr><th>Key</th>
     *     <th>Description of Associated Value</th></tr>
     * <tr><td><code>name</code></td>
     *     <td><em>(optional)</em> The name of the repository.
     * The default is a Hash value of the rootdir paths. The name is used in the console output,
     * to point to information related to a particular repository. A name must be unique amongst a repository group.</td></tr>
     * <tr><td><code>dirs</code></td>
     *     <td>Specifies a list of rootDirs where to look for dependencies. These are evaluated as per {@link org.gradle.api.Project#files(Object...)}</td></tr>
     * </table>
     *
     * <p>Examples:</p>
     * <pre class='autoTested'>
     * repositories {
     *     flatDir name: 'libs', dirs: "$projectDir/libs"
     *     flatDir dirs: ["$projectDir/libs1", "$projectDir/libs2"]
     * }
     * </pre>
     *
     * @param args The arguments used to configure the repository.
     * @return the added resolver
     * @throws org.gradle.api.InvalidUserDataException In the case neither rootDir nor rootDirs is specified of if both
     * are specified.
     */
    FlatDirectoryArtifactRepository flatDir(Map<String, ?> args);

    /**
     * Adds and configures a repository which will look for dependencies in a number of local directories.
     *
     * @param configureClosure The closure to execute to configure the repository.
     * @return The repository.
     */
    FlatDirectoryArtifactRepository flatDir(@DelegatesTo(FlatDirectoryArtifactRepository.class) Closure configureClosure);

    /**
     * Adds and configures a repository which will look for dependencies in a number of local directories.
     *
     * @param action The action to execute to configure the repository.
     * @return The repository.
     */
    FlatDirectoryArtifactRepository flatDir(Action<? super FlatDirectoryArtifactRepository> action);

    /**
     * Adds a repository which looks in Gradle Central Plugin Repository for dependencies.
     *
     * @return The Gradle Central Plugin Repository
     * @since 4.4
     */
    ArtifactRepository gradlePluginPortal();

    /**
     * Adds a repository which looks in Gradle Central Plugin Repository for dependencies.
     *
     * @param action a configuration action
     * @return the added resolver
     * @since 5.4
     */
    ArtifactRepository gradlePluginPortal(Action<? super ArtifactRepository> action);

    /**
     * Adds a repository which looks in Bintray's JCenter repository for dependencies.
     * <p>
     * The URL used to access this repository is {@literal "https://jcenter.bintray.com/"}.
     * The behavior of this repository is otherwise the same as those added by {@link #maven(org.gradle.api.Action)}.
     * <p>
     * Examples:
     * <pre class='autoTestedWithDeprecations'>
     * repositories {
     *   jcenter {
     *     artifactUrls = ["http://www.mycompany.com/artifacts1", "http://www.mycompany.com/artifacts2"]
     *   }
     *   jcenter {
     *     name = "nonDefaultName"
     *     artifactUrls = ["http://www.mycompany.com/artifacts1"]
     *   }
     * }
     * </pre>
     *
     * @param action a configuration action
     * @return the added repository
     * @deprecated JFrog announced JCenter's <a href="https://blog.gradle.org/jcenter-shutdown">sunset</a> in February 2021. Use {@link #mavenCentral()} instead.
     */
    @Deprecated
    MavenArtifactRepository jcenter(Action<? super MavenArtifactRepository> action);

    /**
     * Adds a repository which looks in Bintray's JCenter repository for dependencies.
     * <p>
     * The URL used to access this repository is {@literal "https://jcenter.bintray.com/"}.
     * The behavior of this repository is otherwise the same as those added by {@link #maven(org.gradle.api.Action)}.
     * <p>
     * Examples:
     * <pre class='autoTestedWithDeprecations'>
     * repositories {
     *     jcenter()
     * }
     * </pre>
     *
     * @return the added resolver
     * @see #jcenter(Action)
     * @deprecated JFrog announced JCenter's <a href="https://blog.gradle.org/jcenter-shutdown">sunset</a> in February 2021. Use {@link #mavenCentral()} instead.
     */
    @Deprecated
    MavenArtifactRepository jcenter();

    /**
     * Adds a repository which looks in the Maven central repository for dependencies. The URL used to access this repository is
     * {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#MAVEN_CENTRAL_URL}.
     *
     * <p>The following parameter are accepted as keys for the map:
     *
     * <table summary="Shows property keys and associated values">
     * <tr><th>Key</th>
     *     <th>Description of Associated Value</th></tr>
     * <tr><td><code>name</code></td>
     *     <td><em>(optional)</em> The name of the repository. The default is
     * {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#DEFAULT_MAVEN_CENTRAL_REPO_NAME} is used as the name. A name
     * must be unique amongst a repository group.
     * </td></tr>
     * <tr><td><code>artifactUrls</code></td>
     *     <td>A single jar repository or a collection of jar repositories containing additional artifacts not found in the Maven central repository.
     * But be aware that the POM must exist in Maven central.
     * The provided values are evaluated as per {@link org.gradle.api.Project#uri(Object)}.</td></tr>
     * </table>
     *
     * <p>Examples:</p>
     * <pre class='autoTested'>
     * repositories {
     *     mavenCentral artifactUrls: ["http://www.mycompany.com/artifacts1", "http://www.mycompany.com/artifacts2"]
     *     mavenCentral name: "nonDefaultName", artifactUrls: ["http://www.mycompany.com/artifacts1"]
     * }
     * </pre>
     *
     * @param args A list of urls of repositories to look for artifacts only.
     * @return the added repository
     */
    MavenArtifactRepository mavenCentral(Map<String, ?> args);

    /**
     * Adds a repository which looks in the Maven central repository for dependencies. The URL used to access this repository is
     * {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#MAVEN_CENTRAL_URL}. The name of the repository is
     * {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#DEFAULT_MAVEN_CENTRAL_REPO_NAME}.
     *
     * <p>Examples:</p>
     * <pre class='autoTested'>
     * repositories {
     *     mavenCentral()
     * }
     * </pre>
     *
     * @return the added resolver
     * @see #mavenCentral(java.util.Map)
     */
    MavenArtifactRepository mavenCentral();

    /**
     * Adds a repository which looks in the Maven central repository for dependencies. The URL used to access this repository is
     * {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#MAVEN_CENTRAL_URL}. The name of the repository is
     * {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#DEFAULT_MAVEN_CENTRAL_REPO_NAME}.
     *
     * <p>Examples:</p>
     * <pre class='autoTested'>
     * repositories {
     *     mavenCentral()
     * }
     * </pre>
     *
     * @param action a configuration action
     * @return the added resolver
     * @since 5.3
     */
    MavenArtifactRepository mavenCentral(Action<? super MavenArtifactRepository> action);

    /**
     * Adds a repository which looks in the local Maven cache for dependencies. The name of the repository is
     * {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#DEFAULT_MAVEN_LOCAL_REPO_NAME}.
     *
     * <p>Examples:</p>
     * <pre class='autoTested'>
     * repositories {
     *     mavenLocal()
     * }
     * </pre>
     * <p>
     * The location for the repository is determined as follows (in order of precedence):
     * </p>
     * <ol>
     * <li>The value of system property 'maven.repo.local' if set;</li>
     * <li>The value of element &lt;localRepository&gt; of <code>~/.m2/settings.xml</code> if this file exists and element is set;</li>
     * <li>The value of element &lt;localRepository&gt; of <code>$M2_HOME/conf/settings.xml</code> (where <code>$M2_HOME</code> is the value of the environment variable with that name) if this file exists and element is set;</li>
     * <li>The path <code>~/.m2/repository</code>.</li>
     * </ol>
     *
     * @return the added resolver
     */
    MavenArtifactRepository mavenLocal();

    /**
     * Adds a repository which looks in the local Maven cache for dependencies. The name of the repository is
     * {@value org.gradle.api.artifacts.ArtifactRepositoryContainer#DEFAULT_MAVEN_LOCAL_REPO_NAME}.
     *
     * <p>Examples:</p>
     * <pre class='autoTested'>
     * repositories {
     *     mavenLocal()
     * }
     * </pre>
     * <p>
     * The location for the repository is determined as follows (in order of precedence):
     * </p>
     * <ol>
     * <li>The value of system property 'maven.repo.local' if set;</li>
     * <li>The value of element &lt;localRepository&gt; of <code>~/.m2/settings.xml</code> if this file exists and element is set;</li>
     * <li>The value of element &lt;localRepository&gt; of <code>$M2_HOME/conf/settings.xml</code> (where <code>$M2_HOME</code> is the value of the environment variable with that name) if this file exists and element is set;</li>
     * <li>The path <code>~/.m2/repository</code>.</li>
     * </ol>
     *
     * @param action a configuration action
     * @return the added resolver
     * @since 5.3
     */
    MavenArtifactRepository mavenLocal(Action<? super MavenArtifactRepository> action);

    /**
     * Adds a repository which looks in Google's Maven repository for dependencies.
     * <p>
     * The URL used to access this repository is {@literal "https://dl.google.com/dl/android/maven2/"}.
     * <p>
     * Examples:
     * <pre class='autoTested'>
     * repositories {
     *     google()
     * }
     * </pre>
     *
     * @return the added resolver
     * @since 4.0
     */
    MavenArtifactRepository google();

    /**
     * Adds a repository which looks in Google's Maven repository for dependencies.
     * <p>
     * The URL used to access this repository is {@literal "https://dl.google.com/dl/android/maven2/"}.
     * <p>
     * Examples:
     * <pre class='autoTested'>
     * repositories {
     *     google()
     * }
     * </pre>
     *
     * @param action a configuration action
     * @return the added resolver
     * @since 5.3
     */
    MavenArtifactRepository google(Action<? super MavenArtifactRepository> action);

    /**
     * Adds and configures a Maven repository. Newly created instance of {@code MavenArtifactRepository} is passed as an argument to the closure.
     *
     * @param closure The closure to use to configure the repository.
     * @return The added repository.
     */
    MavenArtifactRepository maven(@DelegatesTo(MavenArtifactRepository.class) Closure closure);

    /**
     * Adds and configures a Maven repository.
     *
     * @param action The action to use to configure the repository.
     * @return The added repository.
     */
    MavenArtifactRepository maven(Action<? super MavenArtifactRepository> action);

    /**
     * Adds and configures an Ivy repository. Newly created instance of {@code IvyArtifactRepository} is passed as an argument to the closure.
     *
     * @param closure The closure to use to configure the repository.
     * @return The added repository.
     */
    IvyArtifactRepository ivy(@DelegatesTo(IvyArtifactRepository.class) Closure closure);

    /**
     * Adds and configures an Ivy repository.
     *
     * @param action The action to use to configure the repository.
     * @return The added repository.
     */
    IvyArtifactRepository ivy(Action<? super IvyArtifactRepository> action);

    /**
     * Declares exclusive content repositories. Exclusive content repositories are
     * repositories for which you can declare an inclusive content filter. Artifacts
     * matching the filter will then only be searched in the repositories which
     * exclusively match it.
     *
     * @param action the configuration of the repositories
     *
     * @since 6.2
     */
    void exclusiveContent(Action<? super ExclusiveContentRepository> action);
}

PluginResolutionStrategy插件解决策略

接下来我们看resolutionStrategy,它传入的是一个PluginResolutionStrategy。Kotlin DSL中有大量Action的用法。

pluginManagement {
    resolutionStrategy {
        eachPlugin {
            if (requested.id.namespace == "com.android.tools.build") {
                useModule("com.android.tools.build:gradle:7.1.2")
            }
            if (requested.id.namespace == "com.google.firebase") {
                useModule("com.google.firebase:firebase-crashlytics-gradle:2.9.2")
            }
        }
    }
}
package org.gradle.plugin.management;

import org.gradle.api.Action;
import org.gradle.internal.HasInternalProtocol;

/**
 * Allows modification of {@link PluginRequest}s before they are resolved.
 *
 * @since 3.5
 */
@HasInternalProtocol
public interface PluginResolutionStrategy {

    /**
     * Adds an action that is executed for each plugin that is resolved.
     * The {@link PluginResolveDetails} parameter contains information about
     * the plugin that was requested and allows the rule to modify which plugin
     * will actually be resolved.
     */
    void eachPlugin(Action<? super PluginResolveDetails> rule);

}
package org.gradle.plugin.management;

import javax.annotation.Nullable;

/**
 * Allows plugin resolution rules to inspect a requested plugin and modify which
 * target plugin will be used.
 *
 * @since 3.5
 */
public interface PluginResolveDetails {

    /**
     * Get the plugin that was requested.
     */
    PluginRequest getRequested();

    /**
     * Sets the implementation module to use for this plugin.
     *
     * @param notation the module to use, supports the same notations as {@link org.gradle.api.artifacts.dsl.DependencyHandler}
     */
    void useModule(Object notation);

    /**
     * Sets the version of the plugin to use.
     *
     * @param version version to use
     */
    void useVersion(@Nullable String version);

    /**
     * The target plugin request to use.
     */
    PluginRequest getTarget();

}

PluginResolveDetails这个类用来允许插件解析规则检查请求的插件并修改将使用目标插件。

DependencyResolutionManagement依赖解决管理

我们再来看看dependencyResolutionManagement和要传入DependencyResolutionManagement。这个类字面意思就告诉我们用来指定依赖解决管理,简单来说,就是我们项目中的那些implementation依赖的库等,从哪些库里面找。

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven {  setUrl("https://jitpack.io") }
    }
}

这里简单讲解下RepositoriesMode。

package org.gradle.api.initialization.resolve;

import org.gradle.api.Incubating;

/**
 * The repository mode configures how repositories are setup in the build.
 *
 * @since 6.8
 */
@Incubating
public enum RepositoriesMode {
    /**
     * If this mode is set, any repository declared on a project will cause
     * the project to use the repositories declared by the project, ignoring
     * those declared in settings.
     *
     * This is the default behavior.
     */
    PREFER_PROJECT,

    /**
     * If this mode is set, any repository declared directly in a project,
     * either directly or via a plugin, will be ignored.
     */
    PREFER_SETTINGS,

    /**
     * If this mode is set, any repository declared directly in a project,
     * either directly or via a plugin, will trigger a build error.
     */
    FAIL_ON_PROJECT_REPOS;
}

PREFER_PROJECT表示,如果设置此模式,项目上声明的任何存储库都会导致项目使用项目声明的存储库,忽略在设置中声明的,简单来说就是项目中的存储库优先使用。这也是默认的模式。如果PREFER_SETTINGS,则正好相反。FAIL_ON_PROJECT_REPOS则表示,强制使用设置中的存储库。建议修改模式为FAIL_ON_PROJECT_REPOS强制全局都使用设置中的存储库,方便管理。无论你使用何种模式,你在dependencyResolutionManagement中配置下就能确保可以使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1695367.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于在子线程中获取不到HttpServletRequest对象的问题

这篇文章主要分享一下项目里遇到的获取request对象为null的问题&#xff0c;具体是在登录的时候触发的邮箱提醒&#xff0c;获取客户端ip地址&#xff0c;然后通过ip地址定位获取定位信息&#xff0c;从而提示账号在哪里登录。 但是登录却发现获取request对象的时候报错了。 具…

数据插值之朗格朗日插值(一)

目录 一、引言 二、代码实现 2.1 Lagrange插值求插值多项式&#xff1a; 代码解析&#xff1a; 1.vpa解释 2.ploy&#xff08;x&#xff09;解释: 3.conv&#xff08;&#xff09;解释 4.poly2sym()解释 2.2 Lagrange插值求新样本值和误差估计&#xff1a; 代码解析&…

鲁教版七年级数学上册-笔记

文章目录 第一章 三角形1 认识三角形2 图形的全等3 探索三角形全等的条件4 三角形的尺规作图5 利用三角形全等测距离 第二章 轴对称1 轴对称现象2 探索轴对称的性质4 利用轴对称进行设计 第三章 勾股定理1 探索勾股定理2 一定是直角三角形吗3 勾股定理的应用举例 第四章 实数1 …

C++技能进阶指南——多态语法剖析

前言&#xff1a;多态是面向对象的三大特性之一。顾名思义&#xff0c; 多态就是多种状态。 那么是什么的多种状态呢&#xff1f; 这里的可能有很多。比如我们去买火车票&#xff0c; 有普通票&#xff0c; 学生票&#xff1b; 又比如我们去旅游&#xff0c; 有儿童票&#xff…

心链2---前端开发(整合路由,搜索页面,用户信息页开发)

心链——伙伴匹配系统 接口调试 说书人&#x1f4d6;&#xff1a;上回书说到用了两种方法查询标签1.SQL查询&#xff0c;2.内存查询&#xff1b;两种查询效率是部分上下&#xff0c;打的是难解难分&#xff0c;是时大地皴裂&#xff0c;天色聚变&#xff0c;老祖斟酌再三最后决…

数据库-SQL性能分析

SQL执行频率 慢查询日志 慢查询日志记录了所有执行时间超过指定参数&#xff08;long_query_time&#xff0c;单位&#xff1a;秒&#xff0c;默认10秒&#xff09;的所有 SQL语句的日志。 MySQL的慢查询日志默认没有开启&#xff0c;我们可以查看一下系统变量 slow_query_l…

leetcode328. 奇偶链表,附详细解析和代码注释

leetcode328. 奇偶链表 给定单链表的头节点 head &#xff0c;将所有索引为奇数的节点和索引为偶数的节点分别组合在一起&#xff0c;然后返回重新排序的列表。 第一个节点的索引被认为是 奇数 &#xff0c; 第二个节点的索引为 偶数 &#xff0c;以此类推。 请注意&#xff0…

初出茅庐的小李博客之用MQTT.fx软件进行消息发布与订阅【 基于EMQX Cloud】

MQTT.fx软件使用简单介绍 MQTT.fx 的软件界面如下图所示&#xff0c;最上方为 MQTT Broker 连接地址栏&#xff0c;及其连接配置。其下方功能 Tabs 含有 Publish 发布栏、Subscribe 订阅栏、Scripts 脚本栏、Broker Status 状态消息栏、Log 日志信息控制栏。 连接之前要明确几…

Distributed Transactions Mit 6.824

Topic1&#xff1a;distributed transactions concurrency control atomic commit 传统计划&#xff1a;事务 程序员标记代码序列的开始/结束作为事务。 事务示例 x 和 y 是银行余额——数据库表中的记录。x 和 y 位于不同的服务器上&#xff08;可能在不同的银行&#x…

NDIS小端口驱动(九)

PCIe设备难免会遇到一些重置设备的请求&#xff0c;例如重置总线的时候&#xff0c;但是由于NIC网卡的多样性&#xff0c;重置设备确实也有许多要注意的地方&#xff0c;另外还有一些包含WDM的NDIS驱动 微型端口驱动程序硬件重置 微型端口驱动程序必须向 NdisMRegisterMinipo…

10款免费黑科技软件,强烈推荐!

1.AI视频生成——巨日禄 网页版https://aitools.jurilu.com/ "巨日禄 "是一款功能强大的文本视频生成器&#xff0c;可以快速将文本内容转换成极具吸引力的视频。操作简单&#xff0c;用户只需输入文字&#xff0c;选择喜欢的样式和模板&#xff0c; “巨日禄”就会…

qemu+gdb调试linux内核

打开CONFIG_DEBUG_INFO,编译内核 通过图形菜单配置该宏,执行make menuconfig。 kernel hacking —> compile-time checks and compiler options —> compile the kernel with debug info 验证是否打开成功,grep -nr “CONFIG_DEBUG_INFO” .config。 打开成功,然后…

初识Spring Boot

初识Spring Boot SpringBoot是建立在Spring框架之上的一个项目,它的目标是简化Spring应用程序的初始搭建以及开发过程。 对比Spring Spring Boot作为Spring框架的一个模块&#xff0c;旨在简化Spring应用程序的初始搭建和开发过程&#xff0c;以下是Spring Boot相对于传统Spri…

【通义千问—Qwen-Agent系列2】案例分析(图像理解图文生成Agent||多模态助手|| 基于ReAct范式的数据分析Agent)

目录 前言一、快速开始1-1、介绍1-2、安装1-3、开发你自己的Agent 二、基于Qwen-Agent的案例分析2-0、环境安装2-1、图像理解&文本生成Agent2-2、 基于ReAct范式的数据分析Agent2-3、 多模态助手 附录1、agent源码2、router源码 总结 前言 Qwen-Agent是一个开发框架。开发…

iZotope RX 11 for Mac:音频修复的终极利器

在音频处理的世界里&#xff0c;纯净与清晰是每一个创作者追求的目标。iZotope RX 11 for Mac&#xff0c;这款专为Mac用户打造的音频修复软件&#xff0c;凭借其卓越的音频修复能力和丰富的功能&#xff0c;已经成为众多音频工程师和音乐制作人的首选工具。 iZotope RX 11 for…

线程生命周期

创建线程的两种方法 1.继承Thread类 2.实现Runnable接口 线程从创建到消亡分为新建、就绪、运行、阻塞、死亡5种状态。 新建状态 创建一个线程就处于新建状态。此时线程对象已经被分配了内存空间&#xff0c;并且私有数据也被初始化&#xff0c;但是该线程还不能运行。 就…

nodeJs学习(第一周)

文章目录 学习总结nodejs基础知识核心模块&#xff08;内置模块&#xff09;fs&#xff08;file-system&#xff09;文件系统fs增删查改urlQuery String httprequest根据不同的请求路径发送不同的响应结果requireip地址和端口号Content-Type 第三方模块 express登录接口逻辑分析…

【LeetCode:2769. 找出最大的可达成数字 + 模拟】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

MySQL--执行计划

一、执行计划 1.介绍 执行计划是sql在执行时&#xff0c;优化器优化后&#xff0c;选择的cost最低的方案 通过desc、explain可以查看sql的执行计划 2.如何查看执行计划 table语句操作的表&#xff0c;在多表时才有意义type查找类型possible_keys可能会用到的索引key最终选择的…