summaryrefslogtreecommitdiff
path: root/project/VersionUtil.scala
blob: 71de772b08881411e91ffa78563f08af602da3b3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import sbt._
import Keys._
import java.util.Properties
import java.io.FileInputStream
import scala.collection.JavaConverters._

object VersionUtil {
  lazy val copyrightString = settingKey[String]("Copyright string.")
  lazy val versionProperties = settingKey[Versions]("Version properties.")
  lazy val generateVersionPropertiesFile = taskKey[File]("Generating version properties file.")

  lazy val versionPropertiesSettings = Seq[Setting[_]](
    versionProperties := versionPropertiesImpl.value
  )

  lazy val generatePropertiesFileSettings = Seq[Setting[_]](
    copyrightString := "Copyright 2002-2015, LAMP/EPFL",
    resourceGenerators in Compile += generateVersionPropertiesFile.map(file => Seq(file)).taskValue,
    versionProperties := versionPropertiesImpl.value,
    generateVersionPropertiesFile := generateVersionPropertiesFileImpl.value
  )

  case class Versions(canonicalVersion: String, mavenVersion: String, osgiVersion: String, commitSha: String, commitDate: String, isRelease: Boolean) {
    val githubTree =
      if(isRelease) "v" + mavenVersion
      else if(commitSha != "unknown") commitSha
      else "master"

    override def toString = s"Canonical: $canonicalVersion, Maven: $mavenVersion, OSGi: $osgiVersion, github: $githubTree"

    def toProperties: Properties = {
      val props = new Properties
      props.put("version.number", canonicalVersion)
      props.put("maven.version.number", mavenVersion)
      props.put("osgi.version.number", osgiVersion)
      props
    }
  }

  lazy val versionPropertiesImpl: Def.Initialize[Versions] = Def.setting {
    /** Regexp that splits version number split into two parts: version and suffix.
      * Examples of how the split is performed:
      *
      *  "2.11.5": ("2.11.5", null)
      *  "2.11.5-acda7a": ("2.11.5", "-acda7a")
      *  "2.11.5-SNAPSHOT": ("2.11.5", "-SNAPSHOT") */
    val versionSplitted = """([\w+\.]+)(-[\w+\.]+)??""".r

    val versionSplitted(ver, suffixOrNull) = version.value

    val osgiSuffix = suffixOrNull match {
      case null => "-VFINAL"
      case "-SNAPSHOT" => ""
      case suffixStr => suffixStr
    }

    def executeTool(tool: String) = {
      val cmd =
        if (System.getProperty("os.name").toLowerCase.contains("windows"))
          s"cmd.exe /c tools\\$tool.bat -p"
        else s"tools/$tool"
      Process(cmd).lines.head
    }

    val commitDate = executeTool("get-scala-commit-date")
    val commitSha = executeTool("get-scala-commit-sha")

    Versions(
      canonicalVersion = s"$ver-$commitDate-$commitSha",
      mavenVersion = s"${version.value}",
      osgiVersion = s"$ver.v$commitDate$osgiSuffix-$commitSha",
      commitSha = commitSha,
      commitDate = commitDate,
      isRelease = !osgiSuffix.isEmpty
    )
  }

  lazy val generateVersionPropertiesFileImpl: Def.Initialize[Task[File]] = Def.task {
    val props = versionProperties.value.toProperties
    val propFile = (resourceManaged in Compile).value / s"${thisProject.value.id}.properties"
    props.put("copyright.string", copyrightString.value)

    // unfortunately, this will write properties in arbitrary order
    // this makes it harder to test for stability of generated artifacts
    // consider using https://github.com/etiennestuder/java-ordered-properties
    // instead of java.util.Properties
    IO.write(props, null, propFile)
    propFile
  }

  /** The global versions.properties data */
  lazy val versionProps: Map[String, String] = {
    val props = new Properties()
    val in = new FileInputStream(file("versions.properties"))
    try props.load(in)
    finally in.close()
    props.asScala.toMap
  }

  /** Get a subproject version number from `versionProps` */
  def versionNumber(name: String): String =
    versionProps(s"$name.version.number")
}