Skip to content

Commit 0e768fa

Browse files
committed
Allow to skip passing inputs to the run command when the -classpath option is passed
1 parent 96c7331 commit 0e768fa

File tree

6 files changed

+53
-14
lines changed

6 files changed

+53
-14
lines changed

modules/build/src/main/scala/scala/build/Build.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ object Build {
5757
def outputOpt: Some[os.Path] = Some(output)
5858
def dependencyClassPath: Seq[os.Path] = sources.resourceDirs ++ artifacts.classPath
5959
def fullClassPath: Seq[os.Path] = Seq(output) ++ dependencyClassPath
60-
def foundMainClasses(): Seq[String] = MainClass.find(output)
60+
def foundMainClasses(): Seq[String] =
61+
MainClass.find(output) ++ options.classPathOptions.extraClassPath.flatMap(MainClass.find)
6162
def retainedMainClass(
6263
mainClasses: Seq[String],
6364
commandString: String,

modules/build/src/main/scala/scala/build/Inputs.scala

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,11 @@ object Inputs {
302302
directories: Directories,
303303
forcedWorkspace: Option[os.Path],
304304
enableMarkdown: Boolean,
305-
allowRestrictedFeatures: Boolean
305+
allowRestrictedFeatures: Boolean,
306+
extraClasspathWasPassed: Boolean
306307
): Inputs = {
307308

308-
assert(validElems.nonEmpty)
309+
assert(extraClasspathWasPassed || validElems.nonEmpty)
309310

310311
val (inferredWorkspace, inferredNeedsHash, workspaceOrigin) = {
311312
val settingsFiles = projectSettingsFiles(validElems)
@@ -490,7 +491,8 @@ object Inputs {
490491
acceptFds: Boolean,
491492
forcedWorkspace: Option[os.Path],
492493
enableMarkdown: Boolean,
493-
allowRestrictedFeatures: Boolean
494+
allowRestrictedFeatures: Boolean,
495+
extraClasspathWasPassed: Boolean
494496
): Either[BuildException, Inputs] = {
495497
val validatedArgs: Seq[Either[String, Seq[Element]]] =
496498
validateArgs(args, cwd, download, stdinOpt, acceptFds)
@@ -504,15 +506,16 @@ object Inputs {
504506
val validElems = validatedArgsAndSnippets.collect {
505507
case Right(elem) => elem
506508
}.flatten
507-
assert(validElems.nonEmpty)
509+
assert(extraClasspathWasPassed || validElems.nonEmpty)
508510

509511
Right(forValidatedElems(
510512
validElems,
511513
baseProjectName,
512514
directories,
513515
forcedWorkspace,
514516
enableMarkdown,
515-
allowRestrictedFeatures
517+
allowRestrictedFeatures,
518+
extraClasspathWasPassed
516519
))
517520
}
518521
else
@@ -533,10 +536,11 @@ object Inputs {
533536
acceptFds: Boolean = false,
534537
forcedWorkspace: Option[os.Path] = None,
535538
enableMarkdown: Boolean = false,
536-
allowRestrictedFeatures: Boolean
539+
allowRestrictedFeatures: Boolean,
540+
extraClasspathWasPassed: Boolean
537541
): Either[BuildException, Inputs] =
538542
if (
539-
args.isEmpty && scriptSnippetList.isEmpty && scalaSnippetList.isEmpty && javaSnippetList.isEmpty
543+
args.isEmpty && scriptSnippetList.isEmpty && scalaSnippetList.isEmpty && javaSnippetList.isEmpty && !extraClasspathWasPassed
540544
)
541545
defaultInputs().toRight(new InputsException(
542546
"No inputs provided (expected files with .scala, .sc, .java or .md extensions, and / or directories)."
@@ -555,7 +559,8 @@ object Inputs {
555559
acceptFds,
556560
forcedWorkspace,
557561
enableMarkdown,
558-
allowRestrictedFeatures
562+
allowRestrictedFeatures,
563+
extraClasspathWasPassed
559564
)
560565

561566
def default(): Option[Inputs] =

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ final case class TestInputs(
4343
tmpDir,
4444
Directories.under(tmpDir / ".data"),
4545
forcedWorkspace = forcedWorkspaceOpt.map(_.resolveFrom(tmpDir)),
46-
allowRestrictedFeatures = true
46+
allowRestrictedFeatures = true,
47+
extraClasspathWasPassed = false
4748
)
4849
res match {
4950
case Left(err) => throw new Exception(err)

modules/cli/src/main/scala/scala/cli/commands/Clean.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ object Clean extends ScalaCommand[CleanOptions] {
1717
options.directories.directories,
1818
defaultInputs = () => Inputs.default(),
1919
forcedWorkspace = options.workspace.forcedWorkspaceOpt,
20-
allowRestrictedFeatures = ScalaCli.allowRestrictedFeatures
20+
allowRestrictedFeatures = ScalaCli.allowRestrictedFeatures,
21+
extraClasspathWasPassed = false
2122
) match {
2223
case Left(message) =>
2324
System.err.println(message)

modules/cli/src/main/scala/scala/cli/commands/util/SharedOptionsUtil.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ object SharedOptionsUtil extends CommandHelpers {
6060
scriptSnippetList: List[String],
6161
scalaSnippetList: List[String],
6262
javaSnippetList: List[String],
63-
enableMarkdown: Boolean = false
63+
enableMarkdown: Boolean = false,
64+
extraClasspathWasPassed: Boolean = false
6465
): Either[BuildException, Inputs] = {
6566
val resourceInputs = resourceDirs
6667
.map(os.Path(_, Os.pwd))
@@ -83,7 +84,8 @@ object SharedOptionsUtil extends CommandHelpers {
8384
acceptFds = !Properties.isWin,
8485
forcedWorkspace = forcedWorkspaceOpt,
8586
enableMarkdown = enableMarkdown,
86-
allowRestrictedFeatures = ScalaCli.allowRestrictedFeatures
87+
allowRestrictedFeatures = ScalaCli.allowRestrictedFeatures,
88+
extraClasspathWasPassed = extraClasspathWasPassed
8789
)
8890
maybeInputs.map { inputs =>
8991
val forbiddenDirs =
@@ -349,7 +351,8 @@ object SharedOptionsUtil extends CommandHelpers {
349351
scriptSnippetList = allScriptSnippets,
350352
scalaSnippetList = allScalaSnippets,
351353
javaSnippetList = allJavaSnippets,
352-
enableMarkdown = v.markdown.enableMarkdown
354+
enableMarkdown = v.markdown.enableMarkdown,
355+
extraClasspathWasPassed = v.extraJarsAndClasspath.nonEmpty
353356
)
354357

355358
def allScriptSnippets: List[String] = v.snippet.scriptSnippet ++ v.snippet.executeScript

modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,6 +2295,34 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
22952295
}
22962296
}
22972297

2298+
test("run main class from -classpath even when no explicit inputs are passed") {
2299+
val expectedOutput = "Hello"
2300+
TestInputs(
2301+
os.rel / "Main.scala" -> s"""object Main extends App { println("$expectedOutput") }"""
2302+
).fromRoot { (root: os.Path) =>
2303+
val compilationOutputDir = os.rel / "compilationOutput"
2304+
// first, precompile to an explicitly specified output directory with -d
2305+
os.proc(
2306+
TestUtil.cli,
2307+
"compile",
2308+
".",
2309+
"-d",
2310+
compilationOutputDir,
2311+
extraOptions
2312+
).call(cwd = root)
2313+
2314+
// next, run while relying on the pre-compiled class instead of passing inputs
2315+
val runRes = os.proc(
2316+
TestUtil.cli,
2317+
"run",
2318+
"-classpath",
2319+
(os.rel / compilationOutputDir).toString,
2320+
extraOptions
2321+
).call(cwd = root)
2322+
expect(runRes.out.trim == expectedOutput)
2323+
}
2324+
}
2325+
22982326
if (actualScalaVersion.startsWith("3"))
22992327
test("should throw exception for code compiled by scala 3.1.3") {
23002328
val exceptionMsg = "Throw exception in Scala"

0 commit comments

Comments
 (0)