2

I'm trying to publish the git commit hash to prometheus and for this I need to get the output of the following command and save to file.

git rev-parse HEAD

I'd like to save to gitReleaseVersion.txt

I found some similar post for android here but I'm not able to translate it to kotlin gradle.

Here's what I have but it's not creating any file.

task<Exec>("getVersionInfo"){
    doLast {
        exec {
            commandLine("git rev-parse HEAD > gitReleaseVersion.txt")
        }
    }
}

Output: no error, no file

and also tried

task<Exec>("getVersionInfo"){
    val logFile = file("src/main/resources/gitReleaseVersion.txt")
    exec {
        commandLine("git rev-parse HEAD").standardOutput.to(logFile)
    }
}

Output:

Cannot run program "git rev-parse HEAD" (in directory "/Users/kaigo/code/core/module/base/function-base"): error=2, No such file or directory

The file does exist and if I print the file path, the link resolves to the file.

Kaigo
  • 1,267
  • 2
  • 14
  • 33
  • Are you able to see the output printed to console? Most likely, you’ll have to assign a file writer to `standardOutput` for the output to be sent to a file – Abhijit Sarkar Jul 05 '23 at 09:26
  • If I do a println("hello") I can see that, but I'm not able to save the output of the git command and print that out. – Kaigo Jul 05 '23 at 10:22

1 Answers1

1
  1. exec {} runs an executable immediately. If you want to define an Exec task, then don't use exec {}, and instead configure your custom getVersionInfo task.

    Using exec {} can be good if you want to run multiple commands in a single Task, but here you're just using one.

  2. the arguments need to be split up into a list, or (if it's available) use the parseSpaceSeparatedArgs() utility.

  3. Piping the output to a file. Git will interpret > as its own arguments, and you'll get an error like fatal: ambiguous argument '>': unknown revision or path not in the working tree.

    Instead, capture the output and write it to a file.

  4. It's a good idea to register task inputs and outputs, so that Gradle is able to monitor tasks and avoid re-running them if nothing has changed.

After applying those updates, you'll get something like this:

import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs
import java.io.ByteArrayOutputStream

val getVersionInfo by tasks.registering(Exec::class) {
  executable("git")
  args(parseSpaceSeparatedArgs("rev-parse HEAD"))
  // or manually pass a list
  //args("rev-parse", "HEAD")

  val gitReleaseVersionOutput = layout.projectDirectory.file("gitReleaseVersion.txt")
  outputs.file(gitReleaseVersionOutput)

  // capture the standard output
  standardOutput = ByteArrayOutputStream()

  doLast {
    // after the task has run save the standard output to the output file
    val capturedOutput = standardOutput.toString()
    gitReleaseVersionOutput.asFile.apply {
      parentFile.mkdirs()
      createNewFile()
      writeText(capturedOutput)
    }
  }
}

Be aware that this implementation is not compatible with Configuration Cache, and will cause these errors:

> Task :getVersionInfo FAILED
bc00f347a22805f720fd975304b31335bd5fb665

2 problems were found storing the configuration cache.
- Task `:gitVersion` of type `org.gradle.api.tasks.Exec`: cannot deserialize object of type 'java.io.OutputStream' as these are not supported with the configuration cache.
  See https://docs.gradle.org/8.2/userguide/configuration_cache.html#config_cache:requirements:disallowed_types
- Task `:getVersionInfo` of type `org.gradle.api.tasks.Exec`: cannot serialize object of type 'java.io.ByteArrayOutputStream', a subtype of 'java.io.OutputStream', as these are not supported with the configuration cache.
  See https://docs.gradle.org/8.2/userguide/configuration_cache.html#config_cache:requirements:disallowed_types
aSemy
  • 5,485
  • 2
  • 25
  • 51