【问题标题】:Gradle: Access build informationGradle:访问构建信息
【发布时间】:2014-05-19 23:53:46
【问题描述】:

我希望从我的 java 项目中访问构建信息,该项目使用 gradle 来构建项目。我需要访问的信息是由 teamcity 生成的内部版本号、构建 vcs 号等。这些可以通过 maven 轻松访问,并使用 maven-replacer-plugin 可以在属性文件中替换。首先,在 gradle 中是否有替代方案来实现相同的目标?然后,怎么做呢? :)

我尝试了共享 here 的方法,但我总是得到 null 作为内部版本号。

在 Maven 中,我在项目中放置了一个属性文件 (project.properties) 来保存键值对,键是那些项目信息,如

project.groupId、project.artifactId、project.version、 maven.build.timestamp

我希望使用 gradle 访问相同的构建信息。 . pom 如下所示:

                    <!-- Write project version number to file -->
                <plugin>
                    <groupId>com.google.code.maven-replacer-plugin</groupId>
                    <artifactId>maven-replacer-plugin</artifactId>
                    <version>1.3.8</version>
                    <executions>
                        <execution>
                            <phase>prepare-package</phase>
                            <goals>
                                <goal>replace</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <includes>
                            <!-- replace the token in this file -->
                            <include>target/classes/project.properties</include>
                        </includes>
                        <replacements>
                            <replacement>
                                <token>PROJECT_GROUP</token>
                                <value>${project.groupId}</value>
                            </replacement>
                            <replacement>
                                <token>PROJECT_ARTIFACT</token>
                                <value>${project.artifactId}</value>
                            </replacement>
                            <replacement>
                                <token>PROJECT_VERSION</token>
                                <value>${project.version}</value>
                            </replacement>
                            <replacement>
                                <token>PROJECT_BUILD_DATE</token>
                                <value>${maven.build.timestamp}</value>
                            </replacement>
                            <replacement>
                                <token>BUILD_NUMBER</token>
                                <value>${build.number}</value>
                            </replacement>
                        </replacements>
                    </configuration>
                </plugin>

maven replacer 插件所做的是替换属性对象中的值,可以在 java 应用程序中使用。

我需要使用 gradle 访问相同的属性。

pom 中的 Team City 配置如下:

<ciManagement>
    <system>Team City</system>
    <url>http://teamcity.mycompany.com/teamcity/project.html?projectId=bt007
    </url>
</ciManagement>

build.gradle 文件中,我有一个任务定义如下:

task getProjectGroup << {
    ext.projectGroup = System.getProperty("project.group")
    println "Project Group: $projectGroup"
  }

执行此任务时我得到以下输出:

:service:getProjectGroup
Project Group: null

BUILD SUCCESSFUL

【问题讨论】:

  • 如果你得到null,你的 TeamCity 构建没有设置这个系统属性,你也不能从 Maven 访问它。在属性文件中替换占位符是配置processResources 任务的问题(参见Gradle Build Language Reference 中的Copy)。
  • 我在上面的 Maven POM 中找不到任何 TeamCity 属性。
  • 以上更新。还添加了团队城市配置,让问题更完整。
  • 除了build.number,你不能直接从Gradle 中获取所有这些值吗?例如。 project.groupproject.archivesBaseNameproject.version(以及构建日期的 new Date())都可以在 Gradle 脚本中直接访问。
  • 我得到了构建日期的new Date() 对象。除此以外的都是空的。我更新了原始问题中的 gradle 任务。

标签: java gradle teamcity build.gradle


【解决方案1】:

我在我的项目中做了非常相似的事情——将构建信息打包到一个属性文件中,该文件可以从你的 Java 应用程序的类路径中读取。

以下是我在 Gradle 脚本中的实现方式:

tasks.withType(Jar).all { Jar jar ->
    jar.doFirst {
        String jarType = jar.extension
        if(jar.classifier) jarType = jar.classifier
        String fileName = "project.properties"
        ant.propertyfile(file: "${jar.temporaryDir}/${fileName}") {
            entry(key: "PROJECT_GROUP", value: project.group)
            entry(key: "PROJECT_ARTIFACT", value: project.archivesBaseName)
            entry(key: "PROJECT_VERSION", value: project.version)
            entry(key: "PROJECT_BUILD_DATE", value: new Date())
            entry(key: "BUILD_NUMBER", value: hasProperty("teamcity") ? teamcity["build.number"] : "local")
        }
        String intoPath = "your/package/name/here/${project.name}/${jarType}"
        jar.from(jar.temporaryDir) {
            include fileName
            if(jar instanceof War) intoPath = "WEB-INF/classes/${intoPath}"
            into(intoPath)
        }
        println "\tCreated ${intoPath}/${fileName}"
    }
}

在这里,我为每个Jar 任务(包括War)添加功能,为该存档创建一个属性文件并将其包含在your/package/name/here/${project.name}/${jarType}/project.properties 下的类路径中。

这就是 Gradle 的美妙之处。它使这样的自定义非常简单 - 不需要插件。

然后,为了读取我的应用程序中的属性,我注入或硬编码文件的预期路径并像这样加载属性:

public Properties lookupClassPathResource(String pathToResource) {
    Properties p = null;
    org.springframework.core.io.Resource r = new org.springframework.core.io.ClassPathResource(pathToResource);
    if(r.exists()) {
        try {
            p = org.springframework.core.io.support.PropertiesLoaderUtils.loadProperties(r);
        } catch (IOException e) {
            //log or wrap/rethrow exception
        }
    }
    return p;
}

所有人都度过了愉快的时光!

编辑: 显然,OP 中链接的问题/答案(关于访问build.number)有点过时了。您可以使用 TeamCity 通过 Gradle 初始化脚本隐式添加到项目中的 teamcity 属性,而不是执行 System.getProperty("build.number")。上面的代码已被修改以反映这一点。另请参阅this question 了解其他示例。

【讨论】:

  • 这是一个好方法。我会继续努力并随时通知您。谢谢。
  • 在该任务完成后,即在执行build 之后,我仍然在属性文件中获得null 的值。
  • 这没有意义 - 即使您没有明确设置内置项目属性,它们也将具有非空默认值。您是否仍在尝试提取系统属性而不是使用project?尝试将此行添加到您的 build.gradle 文件中,然后从命令行运行 gradlew x 并发布您的结果:task x &lt;&lt; {println "$project.group $project.version"}。至少它应该打印&lt;root_project_name&gt; unspecified
  • 是的。对于某些属性,我确实看到了unspecifiedproject.versionunspecifiedbuild.vcs.number & build.number 为“空”。
  • 1: 对于 build.number,不要使用 System.getProperty,而是尝试使用 project.teamcity["build.number"]。假设您在构建步骤中使用“Gradle”运行程序(它应用 TeamCity 定义的初始化脚本),这可以工作,但请注意,它在本地构建中不可用 - see this answer for more on that2:project.versionunspecified 的唯一原因是您没有在 Gradle 脚本中定义它。您应该设置此值,就像在 POM 中设置项目 version 字符串一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-16
  • 1970-01-01
  • 2016-04-21
  • 2018-04-27
  • 2017-04-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多