Skip to content

Commit

Permalink
Add decoding of class names before showing them to the user with inte…
Browse files Browse the repository at this point in the history
…ractive (#2364)
  • Loading branch information
MaciejG604 authored Sep 1, 2023
1 parent 35397d5 commit c2d4468
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 2 deletions.
11 changes: 9 additions & 2 deletions modules/build/src/main/scala/scala/build/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import scala.build.errors.*
import scala.build.input.VirtualScript.VirtualScriptNameRegex
import scala.build.input.*
import scala.build.internal.resource.ResourceMapper
import scala.build.internal.{Constants, MainClass, Util}
import scala.build.internal.{Constants, MainClass, Name, Util}
import scala.build.options.ScalaVersionUtil.asVersion
import scala.build.options.*
import scala.build.options.validation.ValidationException
Expand Down Expand Up @@ -76,12 +76,19 @@ object Build {
case _ =>
inferredMainClass(mainClasses, logger)
.left.flatMap { mainClasses =>
// decode the names to present them to the user,
// but keep the link to each original name to account for package prefixes:
// "pack.Main$minus1" decodes to "pack.Main-1", which encodes back to "pack$u002EMain$minus1"
// ^^^^^^^^^^^^^^^^----------------NOT THE SAME-----------------------^^^^^^^^^^^^^^^^^^^^^
val decodedToEncoded = mainClasses.map(mc => Name.decoded(mc) -> mc).toMap

options.interactive.flatMap { interactive =>
interactive
.chooseOne(
"Found several main classes. Which would you like to run?",
mainClasses.toList
decodedToEncoded.keys.toList
)
.map(decodedToEncoded(_)) // encode back the name of the chosen class
.toRight {
SeveralMainClassesFoundError(
::(mainClasses.head, mainClasses.tail.toList),
Expand Down
2 changes: 2 additions & 0 deletions modules/core/src/main/scala/scala/build/internals/Name.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ case class Name(raw: String) {

object Name {

def decoded(name: String) = NameTransformer.decode(name)

val alphaKeywords = Set(
"abstract",
"case",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1555,6 +1555,39 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
}
}

test("decoded classNames in interactive ask") {
val fileName = "watch.scala"

val inputs = TestInputs(
os.rel / fileName ->
"""object `Run-1` extends App {println("Run-1 launched")}
|object `Run-2` extends App {println("Run-2 launched")}
|""".stripMargin
)
inputs.fromRoot { root =>
val confDir = root / "config"
val confFile = confDir / "test-config.json"

os.write(confFile, "{\"interactive-was-suggested\":true}", createFolders = true)

if (!Properties.isWin)
os.perms.set(confDir, "rwx------")

val configEnv = Map("SCALA_CLI_CONFIG" -> confFile.toString)

val proc = os.proc(TestUtil.cli, "run", "--interactive", fileName)
.call(
cwd = root,
mergeErrIntoOut = true,
env = Map("SCALA_CLI_INTERACTIVE_INPUTS" -> "Run-1") ++ configEnv
)

expect(proc.out.trim.contains("[0] Run-1"))
expect(proc.out.trim.contains("[1] Run-2"))
expect(proc.out.trim.contains("Run-1 launched"))
}
}

test("BuildInfo fields should be reachable") {
val inputs = TestInputs(
os.rel / "Main.scala" ->
Expand Down

0 comments on commit c2d4468

Please sign in to comment.