-
Notifications
You must be signed in to change notification settings - Fork 326
/
Copy pathBuildInfo.scala
164 lines (157 loc) · 5.17 KB
/
BuildInfo.scala
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import sbt._
import sbt.internal.util.ManagedLogger
import scala.sys.process._
object BuildInfo {
/** Writes build-time information to a Java class that can be used by the
* components.
*
* If the `ENSO_RELEASE_MODE` environment variable is set to `true`, will set
* an `isRelease` flag to true. This flag can be used to disable
* development-specific features.
*
* @param file location where to write the Scala code
* @param log a logger instance for diagnostics
* @param defaultDevEnsoVersion the default version used for dev builds
* @param ensoVersion Enso version
* @param scalacVersion Scala compiler version used in the project
* @param graalVersion GraalVM version used in the project
* @param javaVersion Java language version used in the project.
* @param currentEdition name of the edition associated with the Enso
* version; this should be removed once #1831 is
* implemented
* @return sequence of modified files
*/
def writeBuildInfoFile(
file: File,
log: ManagedLogger,
defaultDevEnsoVersion: String,
ensoVersion: String,
scalacVersion: String,
graalVersion: String,
javaVersion: String,
currentEdition: String
): Seq[File] = {
val gitInfo = getGitInformation(log).getOrElse(fallbackGitInformation)
val isRelease = isReleaseMode
val className = file.getName.stripSuffix(".java")
val fileContents =
s"""
|package org.enso.version;
|
|final class ${className} {
| private GeneratedVersion() {}
|
| static String defaultDevEnsoVersion() {
| return "${defaultDevEnsoVersion}";
| }
|
| static String ensoVersion() {
| return "${ensoVersion}";
| }
|
| static String scalacVersion() {
| return "${scalacVersion}";
| }
|
| static String graalVersion() {
| return "${graalVersion}";
| }
|
| static String javaVersion() {
| return "${javaVersion}";
| }
|
| static String currentEdition() {
| return "${currentEdition}";
| }
|
| static String commit() {
| return "${gitInfo.commitHash}";
| }
|
| static String ref() {
| return "${gitInfo.ref}";
| }
|
| static boolean isDirty() {
| return ${gitInfo.isDirty};
| }
|
| static String latestCommitDate() {
| return "${gitInfo.latestCommitDate}";
| }
|
| static boolean isRelease() {
| return ${isRelease};
| }
|}
|""".stripMargin
IO.write(file, fileContents)
log.debug("Build info updated.")
Seq(file)
}
def isReleaseMode: Boolean =
sys.env.get("ENSO_RELEASE_MODE").contains("true")
/** Information regarding the Git repository that was used in the build.
*
* @param ref if available, name of the branch that was checked out; if a
* branch is not available, but the current commit is tagged, name
* of that tag is used, otherwise falls back to `HEAD`
* @param commitHash hash of the currently checked out commit
* @param isDirty indicates if there are any uncommitted changes
* @param latestCommitDate date of the current commit
*/
private case class GitInformation(
ref: String,
commitHash: String,
isDirty: Boolean,
latestCommitDate: String
)
private def getGitInformation(log: ManagedLogger): Option[GitInformation] =
try {
val hash = "git rev-parse HEAD".!!.trim
val ref =
try {
val branchCommand = "git symbolic-ref -q --short HEAD"
val tagCommand = "git describe --tags --exact-match"
val refCommand =
branchCommand #|| tagCommand
refCommand.!!.trim
} catch {
case e: Exception =>
log.warn(
"Cannot get name of git branch/tag, defaulting to \"HEAD\". " +
s"(Caused by: $e)"
)
"HEAD"
}
val isDirty = "git status --porcelain".!!.trim.nonEmpty
val latestCommitDate = "git log HEAD -1 --format=%cd".!!.trim
Some(
GitInformation(
ref = ref,
commitHash = hash,
isDirty = isDirty,
latestCommitDate = latestCommitDate
)
)
} catch {
case e: Exception =>
log.warn(
"Could not get any git information. The build will proceed but it " +
s"will not contain the git metadata. (Caused by: $e)"
)
None
}
/** Fallback instance of [[GitInformation]] that can be used if the build is
* outside of a repository or the git information cannot be obtained for
* other reasons.
*/
private def fallbackGitInformation: GitInformation =
GitInformation(
"<built outside of a git repository>",
"<built outside of a git repository>",
isDirty = false,
"<built outside of a git repository>"
)
}