Skip to content

Commit 73387c5

Browse files
committed
Move compile --output to SharedOptions and rename it to --compile-output; prevent the -d underlying compiler flag from being set repeatedly and default it to --compile-output
1 parent 8905579 commit 73387c5

File tree

11 files changed

+78
-35
lines changed

11 files changed

+78
-35
lines changed

modules/cli-options/src/main/scala/scala/cli/commands/CompileOptions.scala

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,6 @@ final case class CompileOptions(
1818
@HelpMessage("Print the resulting class path")
1919
printClassPath: Boolean = false,
2020

21-
@Name("output-directory")
22-
@Name("d")
23-
@Name("destination")
24-
@HelpMessage("Copy compilation results to output directory using either relative or absolute path")
25-
@ValueDescription("/example/path")
26-
output: Option[String] = None,
27-
2821
@HelpMessage("Compile test scope")
2922
test: Boolean = false
3023
)

modules/cli-options/src/main/scala/scala/cli/commands/SharedOptions.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@ final case class SharedOptions(
117117

118118
@Hidden
119119
strictBloopJsonCheck: Option[Boolean] = None,
120+
121+
@Name("output-directory")
122+
@Name("d")
123+
@Name("destination")
124+
@Name("compileOutput")
125+
@Name("compileOut")
126+
@HelpMessage("Copy compilation results to output directory using either relative or absolute path")
127+
@ValueDescription("/example/path")
128+
compilationOutput: Option[String] = None,
120129
)
121130
// format: on
122131

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,18 @@ package scala.cli.commands
33
import caseapp._
44

55
import java.io.File
6-
76
import scala.build.options.Scope
87
import scala.build.{Build, BuildThreads, Builds, Os}
98
import scala.cli.CurrentParams
9+
import scala.cli.commands.util.BuildCommandHelpers
1010
import scala.cli.commands.util.SharedOptionsUtil._
1111
import scala.cli.config.{ConfigDb, Keys}
1212
import scala.cli.commands.util.CommonOps.SharedDirectoriesOptionsOps
1313

14-
object Compile extends ScalaCommand[CompileOptions] {
14+
object Compile extends ScalaCommand[CompileOptions] with BuildCommandHelpers {
1515
override def group = "Main"
1616
override def sharedOptions(options: CompileOptions): Option[SharedOptions] = Some(options.shared)
1717

18-
def outputPath(options: CompileOptions): Option[os.Path] =
19-
options.output.filter(_.nonEmpty).map(p => os.Path(p, Os.pwd))
20-
2118
def run(options: CompileOptions, args: RemainingArgs): Unit = {
2219
maybePrintGroupHelp(options)
2320
maybePrintSimpleScalacOutput(options, options.shared.buildOptions())
@@ -71,8 +68,7 @@ object Compile extends ScalaCommand[CompileOptions] {
7168
val cp = s.fullClassPath.map(_.toString).mkString(File.pathSeparator)
7269
println(cp)
7370
}
74-
for (output <- outputPath(options); s <- successulBuildOpt)
75-
os.copy.over(s.output, output)
71+
successulBuildOpt.foreach(_.copyOutput(options.shared))
7672
}
7773
}
7874

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
8484
) { res =>
8585
res.orReport(logger).map(_.main).foreach {
8686
case s: Build.Successful =>
87+
s.copyOutput(options.shared)
8788
val mtimeDestPath = doPackage(
8889
logger = logger,
8990
outputOpt = options.output.filter(_.nonEmpty),
@@ -123,6 +124,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
123124
.orExit(logger)
124125
builds.main match {
125126
case s: Build.Successful =>
127+
s.copyOutput(options.shared)
126128
val res0 = doPackage(
127129
logger = logger,
128130
outputOpt = options.output.filter(_.nonEmpty),

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
222222
)
223223
.orReport(logger)
224224
.flatten
225+
s.copyOutput(options.shared)
225226
if (options.sharedRun.watch.restart)
226227
processOpt = maybeProcess
227228
else
@@ -250,6 +251,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
250251
.orExit(logger)
251252
builds.main match {
252253
case s: Build.Successful =>
254+
s.copyOutput(options.shared)
253255
val res = maybeRun(
254256
s,
255257
allowTerminate = true,

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package scala.cli.commands.util
22

33
import scala.build.{Build, Logger}
44
import scala.build.errors.MainClassError
5-
import scala.cli.commands.ScalaCommand
5+
import scala.cli.commands.{ScalaCommand, SharedOptions}
6+
import scala.build.Os
67

78
trait BuildCommandHelpers { self: ScalaCommand[_] =>
9+
import scala.cli.commands.util.ScalacOptionsUtil.*
810
extension (successfulBuild: Build.Successful) {
911
def retainedMainClass(
1012
logger: Logger,
@@ -15,5 +17,13 @@ trait BuildCommandHelpers { self: ScalaCommand[_] =>
1517
self.argvOpt.map(_.mkString(" ")).getOrElse(actualFullCommand),
1618
logger
1719
)
20+
21+
/** -O -d defaults to --compile-output; if both are defined, --compile-output takes precedence
22+
*/
23+
def copyOutput(sharedOptions: SharedOptions): Unit =
24+
sharedOptions.compilationOutput.filter(_.nonEmpty)
25+
.orElse(sharedOptions.scalac.getForKey("-d").headOption)
26+
.filter(_.nonEmpty)
27+
.map(os.Path(_, Os.pwd)).foreach(output => os.copy.over(successfulBuild.output, output))
1828
}
1929
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,10 @@ object SharedOptionsUtil extends CommandHelpers {
172172
scalacOptions = ShadowingSeq.from(
173173
scalac
174174
.scalacOptionKeyFilter(
175-
_ != "-classpath"
176-
) // -O -classpath should be redirected as --extra-jars instead
175+
// -O -classpath should be redirected as --extra-jars instead
176+
// similarly for -O -d, it should be redirected as --compilation-output
177+
key => key != "-classpath" && key != "-d"
178+
)
177179
.filter(_.nonEmpty)
178180
.map(ScalacOpt(_))
179181
.map(Positioned.commandLine)

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ abstract class CompileTestDefinitions(val scalaVersionOpt: Option[String])
9494
test("copy compile output") {
9595
mainAndTestInputs.fromRoot { root =>
9696
val tempOutput = root / "output"
97-
os.proc(TestUtil.cli, "compile", "--output", tempOutput, extraOptions, ".").call(cwd = root)
97+
os.proc(TestUtil.cli, "compile", "--compile-output", tempOutput, extraOptions, ".").call(cwd =
98+
root
99+
)
98100
checkIfCompileOutputIsCopied("Main", tempOutput)
99101
}
100102
}
@@ -107,7 +109,7 @@ abstract class CompileTestDefinitions(val scalaVersionOpt: Option[String])
107109
TestUtil.cli,
108110
"compile",
109111
"--test",
110-
"--output",
112+
"--compile-output",
111113
tempOutput,
112114
"--print-class-path",
113115
extraOptions,

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

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2251,9 +2251,36 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
22512251
extraOptions
22522252
).call(cwd = root / runDir)
22532253
expect(runRes.out.trim == expectedOutput)
2254+
}
2255+
}
2256+
2257+
test("-O -classpath allows to run with scala-cli compile -O -d option pre-compiled classes") {
2258+
val preCompileDir = "PreCompileDir"
2259+
val preCompiledInput = "Message.scala"
2260+
val runDir = "RunDir"
2261+
val mainInput = "Main.scala"
2262+
val expectedOutput = "Hello"
2263+
TestInputs(
2264+
os.rel / preCompileDir / preCompiledInput -> "case class Message(value: String)",
2265+
os.rel / runDir / mainInput -> s"""object Main extends App { println(Message("$expectedOutput").value) }"""
2266+
).fromRoot { (root: os.Path) =>
2267+
val preCompileOutputDir = "out"
2268+
2269+
// first, precompile to an explicitly specified output directory with -O -d
2270+
val compileRes = os.proc(
2271+
TestUtil.cli,
2272+
"compile",
2273+
preCompiledInput,
2274+
"-O",
2275+
"-d",
2276+
"-O",
2277+
preCompileOutputDir,
2278+
extraOptions
2279+
).call(cwd = root / preCompileDir, stderr = os.Pipe)
2280+
expect(!compileRes.err.trim.contains("Warning: Flag -d set repeatedly"))
22542281

2255-
// ensure the same behaviour can be expected when passing -classpath with -O
2256-
val runRes2 = os.proc(
2282+
// next, run while relying on the pre-compiled class, specifying the path with -O -classpath
2283+
val runRes = os.proc(
22572284
TestUtil.cli,
22582285
"run",
22592286
mainInput,
@@ -2263,8 +2290,8 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
22632290
(os.rel / os.up / preCompileDir / preCompileOutputDir).toString,
22642291
extraOptions
22652292
).call(cwd = root / runDir, stderr = os.Pipe)
2266-
expect(!runRes2.err.trim.contains("Warning: Flag -classpath set repeatedly"))
2267-
expect(runRes2.out.trim == expectedOutput)
2293+
expect(!runRes.err.trim.contains("Warning: Flag -classpath set repeatedly"))
2294+
expect(runRes.out.trim == expectedOutput)
22682295
}
22692296
}
22702297

website/docs/reference/cli-options.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,6 @@ Aliases: `-p`, `--print-classpath`
119119

120120
Print the resulting class path
121121

122-
### `--output`
123-
124-
Aliases: `--output-directory`, `-d`, `--destination`
125-
126-
Copy compilation results to output directory using either relative or absolute path
127-
128122
### `--test`
129123

130124
Compile test scope
@@ -1286,6 +1280,12 @@ Add dependency for stubs needed to make $ivy and $dep imports to work.
12861280
### `--strict-bloop-json-check`
12871281

12881282
[Internal]
1283+
### `--compilation-output`
1284+
1285+
Aliases: `--output-directory`, `-d`, `--destination`, `--compile-output`, `--compile-out`
1286+
1287+
Copy compilation results to output directory using either relative or absolute path
1288+
12891289
## Snippet options
12901290

12911291
Available in commands:

website/docs/reference/scala-command/cli-options.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,6 @@ Aliases: `-p`, `--print-classpath`
103103

104104
Print the resulting class path
105105

106-
### `--output`
107-
108-
Aliases: `--output-directory`, `-d`, `--destination`
109-
110-
Copy compilation results to output directory using either relative or absolute path
111-
112106
### `--test`
113107

114108
Compile test scope
@@ -696,6 +690,12 @@ Add dependency for stubs needed to make $ivy and $dep imports to work.
696690
### `--strict-bloop-json-check`
697691

698692
[Internal]
693+
### `--compilation-output`
694+
695+
Aliases: `--output-directory`, `-d`, `--destination`, `--compile-output`, `--compile-out`
696+
697+
Copy compilation results to output directory using either relative or absolute path
698+
699699
## Snippet options
700700

701701
Available in commands:

0 commit comments

Comments
 (0)