Skip to content

Commit 7013b86

Browse files
authored
Merge pull request #1389 from wleczny/debug-option-for-run-command
Enable debugging for run and test commands
2 parents 810405f + a070146 commit 7013b86

File tree

16 files changed

+194
-41
lines changed

16 files changed

+194
-41
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package scala.cli.commands
2+
3+
import caseapp.*
4+
import caseapp.core.help.Help
5+
6+
import scala.cli.commands.BloopExitOptions.parser
7+
8+
// format: off
9+
final case class SharedDebugOptions(
10+
@Group("Debug")
11+
@HelpMessage("Turn debugging on")
12+
debug: Boolean = false,
13+
@Group("Debug")
14+
@HelpMessage("Debug port (5005 by default)")
15+
debugPort: Option[String] = None,
16+
@Group("Debug")
17+
@HelpMessage("Debug mode (attach by default)")
18+
@ValueDescription("attach|a|listen|l")
19+
debugMode: Option[String] = None
20+
)
21+
// format: on
22+
23+
object SharedDebugOptions {
24+
implicit lazy val parser: Parser[SharedDebugOptions] = Parser.derive
25+
implicit lazy val help: Help[SharedDebugOptions] = Help.derive
26+
// Parser.Aux for using SharedDebugOptions with @Recurse in other options
27+
implicit lazy val parserAux: Parser.Aux[SharedDebugOptions, parser.D] = parser
28+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import com.github.plokhotnyuk.jsoniter_scala.macros._
66

77
// format: off
88
final case class SharedJvmOptions(
9+
@Recurse
10+
sharedDebug: SharedDebugOptions = SharedDebugOptions(),
911

1012
@Group("Java")
1113
@HelpMessage("Set the Java home directory")

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ object BloopStart extends ScalaCommand[BloopStartOptions] {
2424
private def mkBloopRifleConfig(opts: BloopStartOptions): BloopRifleConfig = {
2525
import opts._
2626
val buildOptions = BuildOptions(
27-
javaOptions = JvmUtils.javaOptions(jvm),
27+
javaOptions = JvmUtils.javaOptions(jvm).orExit(logging.logger),
2828
internal = InternalOptions(
2929
cache = Some(coursier.coursierCache(logging.logger.coursierLogger("")))
3030
)

modules/cli/src/main/scala/scala/cli/commands/config/Config.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ object Config extends ScalaCommand[ConfigOptions] {
5858
logger,
5959
coursierCache,
6060
() =>
61-
JvmUtils.javaOptions(options.jvm).javaHome(
61+
JvmUtils.javaOptions(options.jvm).orExit(logger).javaHome(
6262
ArchiveCache().withCache(coursierCache),
6363
coursierCache,
6464
logger.verbosity

modules/cli/src/main/scala/scala/cli/commands/pgp/PgpExternalCommand.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ abstract class PgpExternalCommand extends ExternalCommand {
8989
logger,
9090
allowExecve = true,
9191
() =>
92-
JvmUtils.javaOptions(options.jvm).javaHome(
92+
JvmUtils.javaOptions(options.jvm).orExit(logger).javaHome(
9393
ArchiveCache().withCache(cache),
9494
cache,
9595
logger.verbosity

modules/cli/src/main/scala/scala/cli/commands/pgp/PgpPush.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ object PgpPush extends ScalaCommand[PgpPushOptions] {
4444
val keyContent = os.read(path)
4545

4646
val javaCommand = () =>
47-
JvmUtils.javaOptions(options.jvm).javaHome(
47+
JvmUtils.javaOptions(options.jvm).orExit(logger).javaHome(
4848
ArchiveCache().withCache(coursierCache),
4949
coursierCache,
5050
logger.verbosity

modules/cli/src/main/scala/scala/cli/commands/publish/checks/PgpSecretKeyCheck.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,14 @@ final case class PgpSecretKeyCheck(
5151
else
5252
Base64.getEncoder().encodeToString(input)
5353

54-
def javaCommand: () => String =
54+
def javaCommand: Either[BuildException, () => String] = either {
5555
() =>
56-
JvmUtils.javaOptions(options.sharedJvm).javaHome(
56+
value(JvmUtils.javaOptions(options.sharedJvm)).javaHome(
5757
ArchiveCache().withCache(coursierCache),
5858
coursierCache,
5959
logger.verbosity
6060
).value.javaCommand
61+
}
6162

6263
def defaultValue(): Either[BuildException, OptionCheck.DefaultValue] =
6364
either {
@@ -114,7 +115,7 @@ final case class PgpSecretKeyCheck(
114115
password,
115116
logger,
116117
coursierCache,
117-
javaCommand
118+
value(javaCommand)
118119
)
119120
}
120121
val pgpSecretBase64 = pgpSecret0.map(Base64.getEncoder.encodeToString)
@@ -150,7 +151,7 @@ final case class PgpSecretKeyCheck(
150151
"[generated key]",
151152
coursierCache,
152153
logger,
153-
javaCommand
154+
value(javaCommand)
154155
)
155156
}
156157
val keyServers = value {

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ package util
33

44
import java.io.File
55

6-
import scala.build.options.JavaOptions
6+
import scala.build.EitherCps.{either, value}
7+
import scala.build.errors.{BuildException, UnrecognizedDebugModeError}
8+
import scala.build.options.{JavaOpt, JavaOptions, ShadowingSeq}
79
import scala.build.{Os, Position, Positioned}
810
import scala.util.Properties
911

1012
object JvmUtils {
11-
def javaOptions(opts: SharedJvmOptions) = {
13+
def javaOptions(opts: SharedJvmOptions): Either[BuildException, JavaOptions] = either {
1214
import opts._
1315

1416
val (javacFilePlugins, javacPluginDeps) =
@@ -20,6 +22,28 @@ object JvmUtils {
2022
input.count(_ == ':') < 2
2123
}
2224

25+
val javaOptsSeq = {
26+
val isDebug =
27+
opts.sharedDebug.debug ||
28+
opts.sharedDebug.debugMode.nonEmpty ||
29+
opts.sharedDebug.debugPort.nonEmpty
30+
if (isDebug) {
31+
val server = value {
32+
opts.sharedDebug.debugMode match {
33+
case Some("attach") | Some("a") | None => Right("y")
34+
case Some("listen") | Some("l") => Right("n")
35+
case Some(m) => Left(new UnrecognizedDebugModeError(m))
36+
}
37+
}
38+
val port = opts.sharedDebug.debugPort.getOrElse("5005")
39+
Seq(Positioned.none(
40+
JavaOpt(s"-agentlib:jdwp=transport=dt_socket,server=$server,suspend=y,address=$port")
41+
))
42+
}
43+
else
44+
Seq.empty
45+
}
46+
2347
JavaOptions(
2448
javaHomeOpt = javaHome.filter(_.nonEmpty).map(v =>
2549
Positioned(Seq(Position.CommandLine("--java-home")), os.Path(v, Os.pwd))
@@ -28,6 +52,7 @@ object JvmUtils {
2852
jvmIndexOpt = jvmIndex.filter(_.nonEmpty),
2953
jvmIndexOs = jvmIndexOs.map(_.trim).filter(_.nonEmpty),
3054
jvmIndexArch = jvmIndexArch.map(_.trim).filter(_.nonEmpty),
55+
javaOpts = ShadowingSeq.from(javaOptsSeq),
3156
javacPluginDependencies = SharedOptionsUtil.parseDependencies(
3257
javacPluginDeps.map(Positioned.none(_)),
3358
ignoreErrors = false

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ object SharedOptionsUtil extends CommandHelpers {
202202
),
203203
scalaJsOptions = scalaJsOptions(js),
204204
scalaNativeOptions = scalaNativeOptions(native),
205-
javaOptions = scala.cli.commands.util.JvmUtils.javaOptions(jvm),
205+
javaOptions = value(scala.cli.commands.util.JvmUtils.javaOptions(jvm)),
206206
internalDependencies = bo.InternalDependenciesOptions(
207207
addStubsDependencyOpt = addStubs,
208208
addRunnerDependencyOpt = runner
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package scala.build.errors
2+
3+
final class UnrecognizedDebugModeError(mode: String) extends BuildException(
4+
s"Unrecognized debug mode: $mode."
5+
)

0 commit comments

Comments
 (0)