10000 Ensure a main class element is findable in Scala code passed by `stdin` by Gedochao · Pull Request #933 · VirtusLab/scala-cli · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Ensure a main class element is findable in Scala code passed by stdin #933

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion modules/build/src/main/scala/scala/build/CrossSources.scala
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,10 @@ object CrossSources {
}

val mainClassOpt = for {
mainClassPath <- inputs.mainClassElement.map(_.path).map(ScopePath.fromPath(_).path)
mainClassPath <- inputs.mainClassElement.map {
case sf: Inputs.SourceFile => ScopePath.fromPath(sf.path).path
case vsf: Inputs.VirtualScalaFile => vsf.scopePath.path
}
processedMainClass <- preprocessedSources.find(_.scopePath.path == mainClassPath)
mainClass <- processedMainClass.mainClassOpt
} yield mainClass
Expand Down
7 changes: 4 additions & 3 deletions modules/build/src/main/scala/scala/build/Inputs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import scala.util.matching.Regex

final case class Inputs(
elements: Seq[Inputs.Element],
mainClassElement: Option[Inputs.SourceFile],
mainClassElement: Option[Inputs.SingleElement],
workspace: os.Path,
baseProjectName: String,
mayAppendHash: Boolean,
Expand Down Expand Up @@ -204,7 +204,7 @@ object Inputs {
final case class VirtualScript(content: Array[Byte], source: String, wrapperPath: os.SubPath)
extends Virtual with AnyScalaFile with AnyScript
final case class VirtualScalaFi 8000 le(content: Array[Byte], source: String)
extends Virtual with AnyScalaFile
extends Virtual with AnyScalaFile { def isStdin: Boolean = source == "<stdin>" }
final case class VirtualJavaFile(content: Array[Byte], source: String)
extends Virtual with Compiled
final case class VirtualData(content: Array[Byte], source: String)
Expand Down Expand Up @@ -281,7 +281,8 @@ object Inputs {
}
val mainClassElemOpt = validElems
.collectFirst {
case f: SourceFile => f
case f: SourceFile => f
case vsf: VirtualScalaFile => vsf
}
Inputs(
updatedElems,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ case object ScalaPreprocessor extends Preprocessor {
updatedContent: Option[String]
)

val usingDirectiveHandlers = Seq(
val usingDirectiveHandlers: Seq[UsingDirectiveHandler] = Seq(
UsingDependencyDirectiveHandler,
UsingScalaVersionDirectiveHandler,
UsingRepositoryDirectiveHandler,
Expand All @@ -60,7 +60,7 @@ case object ScalaPreprocessor extends Preprocessor {
UsingPublishDirectiveHandler
)

val requireDirectiveHandlers = Seq[RequireDirectiveHandler](
val requireDirectiveHandlers: Seq[RequireDirectiveHandler] = Seq(
RequireScalaVersionDirectiveHandler,
RequirePlatformsDirectiveHandler,
RequireScopeDirectiveHandler
Expand Down Expand Up @@ -114,6 +114,11 @@ case object ScalaPreprocessor extends Preprocessor {

case v: Inputs.VirtualScalaFile =>
val res = either {
val relPath = if (v.isStdin) os.sub / "stdin.scala" else v.subPath
val className = {
val (pkg, wrapper) = AmmUtil.pathToPackageWrapper(relPath)
(pkg :+ wrapper).map(_.raw).mkString(".")
}
val content = new String(v.content, StandardCharsets.UTF_8)
val (requirements, scopedRequirements, options, updatedContentOpt) =
value(
Expand All @@ -123,15 +128,15 @@ case object ScalaPreprocessor extends Preprocessor {
(reqs, scopedReqs, opts, updatedContent)
}.getOrElse((BuildRequirements(), Nil, BuildOptions(), None))
val s = PreprocessedSource.InMemory(
Left(v.source),
v.subPath,
originalPath = Left(v.source),
relPath = relPath,
updatedContentOpt.getOrElse(content),
0,
Some(options),
Some(requirements),
ignoreLen = 0,
options = Some(options),
requirements = Some(requirements),
scopedRequirements,
None,
v.scopePath
mainClassOpt = Some(className),
scopePath = v.scopePath
)
Seq(s)
}
Expand Down Expand Up @@ -235,7 +240,7 @@ case object ScalaPreprocessor extends Preprocessor {
// for standard imports.
val buf = content.toCharArray
for (t <- dependencyTrees) {
val substitute = (t.prefix(0) + ".A").padTo(t.end - t.start, ' ')
val substitute = (t.prefix.head + ".A").padTo(t.end - t.start, ' ')
assert(substitute.length == (t.end - t.start))
System.arraycopy(substitute.toArray, 0, buf, t.start, substitute.length)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])

// warm-up run that downloads compiler bridges
// The "Downloading compiler-bridge (from bloop?) pollute the output, and would make the first test fail.
lazy val warmupTest = {
lazy val warmupTest: Unit = {
System.err.println("Running RunTests warmup test…")
simpleScriptTest(ignoreErrors = true)
System.err.println("Done running RunTests warmup test.")
Expand Down Expand Up @@ -95,9 +95,9 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
}
}

def platformNl = if (Properties.isWin) "\\r\\n" else "\\n"
def platformNl: String = if (Properties.isWin) "\\r\\n" else "\\n"

def canRunScWithNative(): Boolean =
def canRunScWithNative: Boolean =
!(actualScalaVersion.startsWith("2.12") || actualScalaVersion.startsWith("3.0"))

def simpleNativeTests(): Unit = {
Expand All @@ -124,7 +124,7 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
}
}

if (canRunScWithNative())
if (canRunScWithNative)
test("simple script native") {
simpleNativeTests()
}
Expand Down Expand Up @@ -289,7 +289,7 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
}
}

if (canRunScWithNative())
if (canRunScWithNative)
test("Multiple scripts native") {
multipleScriptsNative()
}
Expand Down Expand Up @@ -618,7 +618,7 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
exceptionLines.length == expectedLines.length,
clues(output, exceptionLines.length, expectedLines.length)
)
for (i <- 0 until exceptionLines.length)
for (i <- exceptionLines.indices)
assert(
exceptionLines(i) == expectedLines(i),
clues(output, exceptionLines(i), expectedLines(i))
Expand Down Expand Up @@ -675,7 +675,7 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
exceptionLines.length == expectedLines.length,
clues(output, exceptionLines.length, expectedLines.length)
)
for (i <- 0 until exceptionLines.length)
for (i <- exceptionLines.indices)
assert(
exceptionLines(i) == expectedLines(i),
clues(output, exceptionLines(i), expectedLines(i))
Expand All @@ -688,11 +688,7 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
scriptStackTraceScala3()
}

val emptyInputs = TestInputs(
Seq(
os.rel / ".placeholder" -> ""
)
)
val emptyInputs: TestInputs = TestInputs(Seq(os.rel / ".placeholder" -> ""))

def piping(): Unit = {
emptyInputs.fromRoot { root =>
Expand All @@ -718,6 +714,32 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
expect(output == message)
}
}
test("Scala code accepted as piped input") {
val expectedOutput = "Hello"
val pipedInput = s"object Test extends App { println(\"$expectedOutput\") }"
emptyInputs.fromRoot { root =>
val output = os.proc(TestUtil.cli, "_.scala", extraOptions)
.call(cwd = root, stdin = pipedInput)
.out.text().trim
expect(output == expectedOutput)
}
}
test("Scala code with references to existing files accepted as piped input") {
val expectedOutput = "Hello"
val pipedInput =
s"""object Test extends App {
| val data = SomeData(value = "$expectedOutput")
| println(data.value)
|}""".stripMargin
val inputs =
TestInputs(Seq(os.rel / "SomeData.scala" -> "case class SomeData(value: String)"))
inputs.fromRoot { root =>
val output = os.proc(TestUtil.cli, ".", "_.scala", extraOptions)
.call(cwd = root, stdin = pipedInput)
.out.text().trim
expect(output == expectedOutput)
}
}
}

def fd(): Unit = {
Expand Down Expand Up @@ -787,6 +809,30 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
}
}

test("Zip with multiple Scala files") {
val inputs = TestInputs(
Seq(
os.rel / "Hello.scala" ->
s"""object Hello extends App {
| println(Messages.hello)
|}
|""".stripMargin,
os.rel / "Messages.scala" ->
s"""object Messages {
| def hello: String = "Hello"
|}
|""".stripMargin
)
)
inputs.asZip { (root, zipPath) =>
val message = "Hello"
val output = os.proc(TestUtil.cli, extraOptions, zipPath.toString)
.call(cwd = root)
.out.text().trim
expect(output == message)
}
}

test("Zip with Scala containing resource directive") {
val inputs = TestInputs(
Seq(
Expand Down Expand Up @@ -1015,7 +1061,7 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
// format: off
val cmd = Seq[os.Shellable](
"docker", "run", "--rm", termOpt,
"-v", s"${root}:/data",
"-v", s"$root:/data",
"-w", "/data",
ciOpt,
baseImage,
Expand Down Expand Up @@ -1450,7 +1496,7 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
// format: off
val cmd = Seq[os.Shellable](
"docker", "run", "--rm", termOpt,
"-v", s"${root}:/data",
"-v", s"$root:/data",
"-w", "/data",
ciOpt,
baseImage,
Expand Down Expand Up @@ -1535,7 +1581,7 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
}
}

def runAuthProxyTest =
def runAuthProxyTest: Boolean =
Properties.isLinux || (Properties.isMac && !TestUtil.isCI)
if (runAuthProxyTest)
test("auth proxy") {
Expand Down
2 changes: 1 addition & 1 deletion scala-cli-src
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
LAUNCHER="$(cd "$SCRIPT_DIR" && ./mill show cli.launcher | jq -r . | sed 's/ref:[a-z0-9]*://')"
LAUNCHER="$(cd "$SCRIPT_DIR" && ./mill show cli.launcher </dev/null | jq -r . | sed 's/ref:[a-z0-9]*://')"
exec "$LAUNCHER" "$@"
0