0

I'm using Gradle 6.2.2 with this plugin: com.gorylenko.gradle-git-properties (version 2.2.2). I'm trying to "translate" the following snippet into Kotlin DSL:

gitProperties {
  extProperty = "gitProps" // git properties will be put in a map at project.ext.gitProps
}

shadowJar {
  manifest {
    attributes(
      "Build-Revision": "${ -> project.ext.gitProps["git.commit.id"]}"  // Uses GString lazy evaluation to delay until git properties are populated
    )
  }
}

...but this what I've come up with so far:

gitProperties {
  extProperty = "gitProps"
  keys = listOf("git.branch", "git.build.host", "git.build.version", "git.commit.id", "git.commit.id.abbrev",
      "git.commit.time", "git.remote.origin.url", "git.tags", "git.total.commit.count")
}

tasks {
  withType<ShadowJar> {
    manifest.attributes.apply {
      put("Build-Revision", "${project.ext.properties["git.commit.id"]}")
    }
  }
}

I can't figure out to make the "GString lazy evaluation" part working in Kotlin DSL, nor how the gitProps map fits on here; eventually that approach (which I know it's partially wrong) is returning null. Any ideas?

x80486
  • 6,627
  • 5
  • 52
  • 111
  • There is a feature request https://github.com/gradle/gradle/issues/8531. When it is implemented then you can use Gradle built-in syntax (provider). But not yet – Basil Peace Nov 04 '21 at 09:12

2 Answers2

2

The below Kotlin syntax worked for me:

put("Build-Revision", object {
  override fun toString():String = (project.extra["gitProps"] as Map<String, String>)["git.commit.id"]!!
})
Thai
  • 56
  • 1
  • 4
1

I think you have some confusion over where and how the data is being stored, and in particular when it's available.

I just got hold of this plugin and had a look at it: it supplies a project extension, which you're configuring to specify why extras property to populate, and a task: "generateGitProperties". This task is added as a dependency for the "classes" task, so it's already run once you get to "shadowJar"

The issue is that figuring out the git properties and populating the extra properties only happens when that task is executed, so they're not available when the build is configured, hence the need for the lazy GString shenanigans to pass a lazy value down into the shadowJar configuration that will only be evaluated once shadowJar executes.

You can get hold of the extra properties like this:

tasks.register("example") {
    dependsOn("generateGitProperties")
    doFirst {
        val gitProps: Map<String, String> by project.ext
        for ((name, value) in gitProps) {
            println("GIT: $name -> $value")
        }
    }
}

That works because it's in a "doFirst" block, so it's happening at task execution time, not configuration time. So essentially, you could emulate the "lazy GString" stuff. Something like this:

withType<Jar>().configureEach {
    val lazyCommitId = object {
        override fun toString(): String {
            val gitProps: Map<String, String> by project.ext
            return gitProps["git.commit.id"] ?: ""
        }
    }

    manifest {
        attributes["Git-Commit-Id"] = lazyCommitId
    }
}

I did this just for "jar", but "shadowJar" is just a subtype of a Jar task anyway.

araqnid
  • 127,052
  • 24
  • 157
  • 134