LoginSignup
5
3

More than 5 years have passed since last update.

バージョニングが億劫なので、Gitのコミットハッシュ値を埋めこむ

Posted at

目的

AWS Lambdaで動いてMarkdown記法のテキストを出力する、小さな社内サービスを開発しています。
きちんとバージョニングするほどでもないのですが、デバッグのために出力時のコードは特定できるようにする必要があります。
そこでGitのコミットハッシュ値、せっかくなのでGitHubのリンクまで出力するようにしてみました。

出力イメージ

(本文)


commit: e83c516 [modified]
log: (ログストリームへのリンク)

仕組み

Scalaで開発しているため、ビルドツールはsbtを使っているのですが、探してみたところsbt-git-stampというプラグインがありました。
これはJGitを利用して、sbt assemblyで生成されるJARのマニフェストファイルに、その時点のGit情報を埋めこむシンプルなプラグインです。あとはその情報を実行時に読みだせばOKというわけです。
他の言語でも同様のことができると思います。まぁ何となれば、ビルド時に直接Gitコマンド叩いて、それをよしなに埋めこめばいいですしね。そういえばSubversionを使っていた頃、svnversionで取得したリビジョン番号をソースに直接書きこむリリース用スクリプトを見かけた記憶が……。

コード

次のようなシングルトンを書いてみました。
"manifest-reader"は、build.sbtで設定したプロジェクト名です。

src/main/scala/ManifestReader.scala
import java.util.jar.Manifest

import scala.collection.JavaConversions._
import scala.util.control.Exception.allCatch

/** 自身のマニフェストファイル読みこみ */
object ManifestReader {
  // クラスパスにあるマニフェスト列
  private[this] val manifests = getClass.getClassLoader.
    getResources("META-INF/MANIFEST.MF").toSeq.
    map(mu => new Manifest(mu.openStream()))

  // プロジェクト名で自身のマニフェストファイルを検索
  private[this] val mainAttributes = manifests.
    map(_.getMainAttributes).
    find(_.getValue("Implementation-Title") == "manifest-reader")

  def value(key: String): Option[String] = mainAttributes.
    flatMap(as => Option(as.getValue(key)))

  /** sbt-git-stampが埋めこむGitのローカル状態 */
  def gitClean: Option[Boolean] = value("Git-Repo-Is-Clean").
    flatMap(s => allCatch.opt(s.toBoolean))

  /** sbt-git-stampが埋めこむGitのハッシュ値 */
  def gitRev: Option[String] = value("Git-Head-Rev")
}

これを利用してテキスト出力するところは、こんな感じ。

src/main/scala/Main.scala
object Main extends App {
  val githubUrl = "https://github.com/git/git"
  val text = "commit: " +
    ManifestReader.gitRev.map(r =>
      "[" + r.take(7) + "](" + githubUrl + "/commit/" + r + ")"
    ).getOrElse("?") + " " +
    ManifestReader.gitClean.map {
      case false => "[modified]"
      case true => ""
    }.getOrElse("")

  println(text)
}

なお仕組み上、sbt runによる実行では、JARファイルを経由しないためGit情報を取得できません。
sbt assemblyで生成したJARファイルを、scala target/scala-2.11/manifest-reader-assembly-0.0.0.jarのようにして実行する必要があります。

確認環境

build.sbt
name := "manifest-reader"
version := "0.0.0"
scalaVersion := "2.11.7"

Seq(com.atlassian.labs.gitstamp.GitStampPlugin.gitStampSettings: _*)
project/plugins.sbt
addSbtPlugin("com.atlassian.labs" % "sbt-git-stamp" % "0.1.2")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.1")
project/build.properties
sbt.version=0.13.9
5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3