处理 Gradle 样板文件的最佳方式?

Best way to handle Gradle boilerplate?

我使用的是双启动机器。大多数情况下,我会在 Linux(Linux Mint 18.3)中编码,但偶尔会在 W10 分区中编码。

对于给定的 Gradle 项目,我总是希望使用 "installDist" 的可执行文件输出到相同的位置。因此,我在 build.gradle:

中包含了以下几行
def currentOS = org.gradle.internal.os.OperatingSystem.current()
def platform
if (currentOS.isWindows()) {
    platform = 'win'
} else if (currentOS.isLinux()) {
    platform = 'linux'
} else if (currentOS.isMacOsX()) {
    // platform = 'mac'
    throw new Exception( "not configured for Mac OS: $currentOS" )
}
else {
    throw new Exception( "attempt to run on unknown platform: $currentOS" )
}
println "OS/platform |$platform|"
String operativeDir
def homePath = System.properties['user.home']
// in W10 homePath is apparently "D:\My Documents"
// in linux homePath is "/home/mike"
// no doubt I could use java.nio.file.Path for a more elegant solution:
String pathSeparator = platform == 'linux'? '/' : '\'
// would be better to get the My Documents path from an Env Var in Linux:
String myDoxPath = platform == 'linux'? '/media/mike/W10 D drive/My Documents' : homePath 
operativeDir = "$myDoxPath${pathSeparator}software projects${pathSeparator}operative${pathSeparator}${name}"
// get version number: must be a version.properties file at the path indicated
ConfigObject conf = new ConfigSlurper().parse( file("src/main/resources/version.properties").toURI().toURL())
version = conf.versionNumber
println "version is $version"

installDist{
    destinationDir = file( "$operativeDir/$version" )
}

... 问题是,所有这些都是样板文件:我想将它包含在我开发的每个项目中。目前它正在弄乱我的 build.gradle。 standard/best 将此样板作为 Gradle 的某种模块的 standard/best 方法是什么?

正如评论中 usr-local-ΕΨΗΕΛΩΝ 指出的那样,如果您发现自己在许多项目中重复构建逻辑,自定义 Gradle 插件是解决方案。

您可以使用Build Init Plugin to generate a skeleton Gradle plugin. You'll want to install Gradle globally in order to invoke gradle anywhere. See the directions here安装Gradle。

例如,要定义 platform 属性,您的插件可以执行以下操作:

import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.Plugin;
import org.gradle.internal.os.OperatingSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ExamplePlugin implements Plugin<Project> {

    private static final Logger log = LoggerFactory.getLogger(ExamplePlugin.class);

    public void apply(Project project) {
        String platform = inferPlatform(project);
        project.getExtensions().getExtraProperties().set("platform", platform);
        log.info("OS/platform |{}|", platform);
    }

    private String inferPlatform(Project project) {
        // OperatingSystem is an INTERNAL package.
        // It is strongly recommended you not use internal Gradle APIs.
        OperatingSystem currentOS = OperatingSystem.current();
        if (currentOS.isWindows()) {
            return "win";
        } else if (currentOS.isLinux()) {
            return "linux";
        } else {
            throw new GradleException("unsupported OS: " + currentOS.toString());
        }
    }
}

我给出了一个 Java 示例,但您也可以用 Groovy 或 Kotlin 编写插件。

获得插件后,只需将其发布到本地或 Gradle 插件门户即可。