Skip to content

Commit a2aa3b1

Browse files
committed
Add position to ComputeVersion
1 parent 5dc6b3e commit a2aa3b1

File tree

6 files changed

+92
-22
lines changed

6 files changed

+92
-22
lines changed

modules/build/src/test/scala/scala/build/options/publish/ComputeVersionTests.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class ComputeVersionTests extends munit.FunSuite {
1515
os.rel / "version" -> ver
1616
)
1717
inputs.fromRoot { root =>
18-
val cv = ComputeVersion.Command(Seq("cat", "version"))
18+
val cv = ComputeVersion.Command(Nil, Seq("cat", "version"))
1919
val readVersion = cv.get(root)
2020
.fold(ex => throw new Exception(ex), identity)
2121
expect(readVersion == ver)
@@ -31,7 +31,7 @@ class ComputeVersionTests extends munit.FunSuite {
3131
os.proc("git", "clone", repo)
3232
.call(cwd = root, stdin = os.Inherit, stdout = os.Inherit)
3333
val dir = root / "compute-version-test"
34-
val cv = ComputeVersion.GitTag(os.rel, true, "0.0.1-SNAPSHOT")
34+
val cv = ComputeVersion.GitTag(Nil, os.rel, true, "0.0.1-SNAPSHOT")
3535

3636
val commitExpectedVersions = Seq(
3737
"8ea4e87f202fbcc369bec9615e7ddf2c14b39e9d" -> "0.2.0-1-g8ea4e87-SNAPSHOT",
@@ -56,7 +56,7 @@ class ComputeVersionTests extends munit.FunSuite {
5656
expect(!hasHead)
5757

5858
val defaultVersion = "0.0.2-SNAPSHOT"
59-
val cv = ComputeVersion.GitTag(os.rel, true, defaultVersion)
59+
val cv = ComputeVersion.GitTag(Nil, os.rel, true, defaultVersion)
6060

6161
val version = cv.get(root)
6262
.fold(ex => throw new Exception(ex), identity)

modules/build/src/test/scala/scala/build/tests/SourceGeneratorTests.scala

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,4 +382,47 @@ class SourceGeneratorTests extends munit.FunSuite {
382382
)
383383
}
384384
}
385+
386+
test("BuildInfo no git repository error") {
387+
val usingPrefix = "//> using computeVersion \""
388+
val usingValue = "git:tag"
389+
val usingSuffix = "\""
390+
391+
val inputs = TestInputs(
392+
os.rel / "main.scala" ->
393+
s"""
394+
|$usingPrefix$usingValue$usingSuffix
395+
|//> using buildInfo
396+
|
397+
|import scala.cli.build.BuildInfo
398+
|
399+
|object Main extends App {
400+
| println(s"Scala version: $${BuildInfo.projectVersion}")
401+
|}
402+
|""".stripMargin
403+
)
404+
405+
inputs.withBuild(baseOptions, buildThreads, bloopConfigOpt) {
406+
(root, _, maybeBuild) =>
407+
maybeBuild match {
408+
case Left(buildException) =>
409+
expect(buildException.positions.size == 1)
410+
val position = buildException.positions.head
411+
412+
assertEquals(
413+
position,
414+
scala.build.Position.File(
415+
Right(root / "main.scala"),
416+
(1, usingPrefix.length),
417+
(1, (usingPrefix + usingValue).length)
418+
)
419+
)
420+
assertNoDiff(
421+
buildException.message,
422+
s"BuildInfo generation error: $root doesn't look like a Git repository"
423+
)
424+
case _ => fail("Build should fail")
425+
}
426+
}
427+
}
385428
}

modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
370370
name
371371
}
372372
def defaultComputeVersion(mayDefaultToGitTag: Boolean): Option[ComputeVersion] =
373-
if (mayDefaultToGitTag) Some(ComputeVersion.GitTag(os.rel, dynVer = false))
373+
if (mayDefaultToGitTag) Some(ComputeVersion.GitTag(Nil, os.rel, dynVer = false))
374374
else None
375375
def defaultVersionError =
376376
new MissingPublishOptionError("version", "--version", "publish.version")
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
package scala.build.errors
22

3-
final class BuildInfoGenerationError(cause: Exception)
4-
extends BuildException(s"BuildInfo generation error: ${cause.getMessage}", cause = cause)
3+
import scala.build.Position
4+
5+
final class BuildInfoGenerationError(msg: String, positions: Seq[Position], cause: Exception)
6+
extends BuildException(
7+
s"BuildInfo generation error: $msg",
8+
positions = positions,
9+
cause = cause
10+
)

modules/options/src/main/scala/scala/build/info/BuildInfo.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,23 @@ object BuildInfo {
100100
def apply(
101101
options: BuildOptions,
102102
workspace: os.Path
103-
): Either[BuildException, BuildInfo] = either {
103+
): Either[BuildException, BuildInfo] = either[Exception] {
104104
Seq(
105105
BuildInfo(
106106
mainClass = options.mainClass,
107107
projectVersion = options.sourceGeneratorOptions.computeVersion
108108
.map(cv => value(cv.get(workspace)))
109-
.orElse(ComputeVersion.GitTag(os.rel, dynVer = false).get(workspace).toOption)
109+
.orElse(ComputeVersion.GitTag(Nil, os.rel, dynVer = false).get(workspace).toOption)
110110
),
111111
scalaVersionSettings(options),
112112
platformSettings(options)
113113
)
114114
.reduceLeft(_ + _)
115-
}.left.map(BuildInfoGenerationError(_))
115+
}.left.map {
116+
case e: BuildException =>
117+
BuildInfoGenerationError(e.message, positions = e.positions, cause = e)
118+
case e => BuildInfoGenerationError(e.getMessage, Nil, e)
119+
}
116120

117121
def escapeBackslashes(s: String): String =
118122
s.replace("\\", "\\\\")

modules/options/src/main/scala/scala/build/options/ComputeVersion.scala

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,29 @@ import com.github.plokhotnyuk.jsoniter_scala.macros.*
55
import org.eclipse.jgit.api.Git
66
import org.eclipse.jgit.lib.{Constants, Ref}
77

8-
import scala.build.Positioned
8+
import scala.build.{Position, Positioned}
99
import scala.build.errors.{BuildException, MalformedInputError}
1010
import scala.io.Codec
1111
import scala.jdk.CollectionConverters.*
1212
import scala.util.{Success, Try, Using}
1313

1414
sealed abstract class ComputeVersion extends Product with Serializable {
1515
def get(workspace: os.Path): Either[BuildException, String]
16+
17+
val positions: Seq[Position]
1618
}
1719

1820
object ComputeVersion {
1921

20-
final case class Command(command: Seq[String]) extends ComputeVersion {
22+
final case class Command(positions: Seq[Position], command: Seq[String]) extends ComputeVersion {
2123
def get(workspace: os.Path): Either[BuildException, String] = {
2224
val maybeRes = Try(os.proc(command).call(stdin = os.Inherit, cwd = workspace, check = false))
2325
maybeRes match {
2426
case Success(res) if res.exitCode == 0 =>
2527
Right(res.out.trim(Codec.default))
2628
case _ =>
2729
Left(new Command.ComputeVersionCommandError(
30+
positions,
2831
command,
2932
maybeRes.map(_.exitCode).getOrElse(1)
3033
))
@@ -33,13 +36,18 @@ object ComputeVersion {
3336
}
3437

3538
object Command {
36-
final class ComputeVersionCommandError(command: Seq[String], exitCode: Int)
37-
extends BuildException(
38-
s"Error running command ${command.mkString(" ")} (exit code: $exitCode)"
39+
final class ComputeVersionCommandError(
40+
positions: Seq[Position],
41+
command: Seq[String],
42+
exitCode: Int
43+
) extends BuildException(
44+
s"Error running command ${command.mkString(" ")} (exit code: $exitCode)",
45+
positions = positions
3946
)
4047
}
4148

4249
final case class GitTag(
50+
positions: Seq[Position],
4351
repo: os.FilePath,
4452
dynVer: Boolean,
4553
defaultFirstVersion: String = "0.1.0-SNAPSHOT"
@@ -115,17 +123,19 @@ object ComputeVersion {
115123
Option(tagOrNull) match {
116124
case None =>
117125
Left(new GitTagError(
126+
positions,
118127
s"Unexpected error when running git describe from Git repository $repo0 (git describe doesn't find back tag $tag)"
119128
))
120129
case Some(tag) =>
121130
versionOf(tag).map(_ + "-SNAPSHOT").toRight(
122131
new GitTagError(
132+
positions,
123133
s"Unexpected error when running git describe from Git repository $repo0 (git describe-provided tag $tag doesn't have the expected shape)"
124134
)
125135
)
126136
}
127137
case (Some(_), None) =>
128-
Left(new GitTagError(s"No stable tag found in Git repository $repo0"))
138+
Left(new GitTagError(positions, s"No stable tag found in Git repository $repo0"))
129139
case (_, Some((tag, name))) =>
130140
val idx = name.lastIndexOf('.')
131141
if (
@@ -134,6 +144,7 @@ object ComputeVersion {
134144
Right(name.take(idx + 1) + (name.drop(idx + 1).toInt + 1).toString + "-SNAPSHOT")
135145
else
136146
Left(new GitTagError(
147+
positions,
137148
s"Don't know how to bump version in tag $tag in Git repository $repo0"
138149
))
139150
}
@@ -142,32 +153,38 @@ object ComputeVersion {
142153
Right(defaultFirstVersion)
143154
}
144155
else
145-
Left(new GitTagError(s"$repo0 doesn't look like a Git repository"))
156+
Left(new GitTagError(positions, s"$repo0 doesn't look like a Git repository"))
146157
}
147158
}
148159
object GitTag {
149-
final class GitTagError(message: String) extends BuildException(message)
160+
final class GitTagError(positions: Seq[Position], message: String)
161+
extends BuildException(message, positions)
150162
}
151163

152164
private lazy val commandCodec: JsonValueCodec[List[String]] =
153165
JsonCodecMaker.make
154166

155167
def parse(input: Positioned[String]): Either[BuildException, ComputeVersion] =
156168
if (input.value == "git" || input.value == "git:tag")
157-
Right(ComputeVersion.GitTag(os.rel, dynVer = false))
169+
Right(ComputeVersion.GitTag(input.positions, os.rel, dynVer = false))
158170
else if (input.value.startsWith("git:tag:"))
159-
Right(ComputeVersion.GitTag(os.FilePath(input.value.stripPrefix("git:tag:")), dynVer = false))
171+
Right(ComputeVersion.GitTag(
172+
input.positions,
173+
os.FilePath(input.value.stripPrefix("git:tag:")),
174+
dynVer = false
175+
))
160176
else if (input.value == "git:dynver")
161-
Right(ComputeVersion.GitTag(os.rel, dynVer = true))
177+
Right(ComputeVersion.GitTag(input.positions, os.rel, dynVer = true))
162178
else if (input.value.startsWith("git:dynver:"))
163179
Right(ComputeVersion.GitTag(
180+
input.positions,
164181
os.FilePath(input.value.stripPrefix("git:dynver:")),
165182
dynVer = true
166183
))
167184
else if (input.value.startsWith("command:["))
168185
try {
169186
val command = readFromString(input.value.stripPrefix("command:"))(commandCodec)
170-
Right(ComputeVersion.Command(command))
187+
Right(ComputeVersion.Command(input.positions, command))
171188
}
172189
catch {
173190
case e: JsonReaderException =>
@@ -183,7 +200,7 @@ object ComputeVersion {
183200
}
184201
else if (input.value.startsWith("command:")) {
185202
val command = input.value.stripPrefix("command:").split("\\s+").toSeq
186-
Right(ComputeVersion.Command(command))
203+
Right(ComputeVersion.Command(input.positions, command))
187204
}
188205
else
189206
Left(

0 commit comments

Comments
 (0)