Skip to content

Commit 860815e

Browse files
committed
Restrict options based on the message
1 parent be3a048 commit 860815e

File tree

4 files changed

+91
-3
lines changed

4 files changed

+91
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import caseapp.*
55
// format: off
66
final case class MarkdownOptions(
77
@Group("Markdown")
8-
@HelpMessage("Enable markdown support (experimental)")
8+
@HelpMessage("[experimental] Enable markdown support.")
99
@Name("md")
1010
@Name("markdown")
1111
enableMarkdown: Boolean = false // TODO: add a separate scope for Markdown and remove this option once it's stable
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package scala.cli.commands
2+
3+
import caseapp.Name
4+
import caseapp.core.app.Command
5+
import caseapp.core.parser.Parser
6+
import caseapp.core.util.Formatter
7+
import caseapp.core.{Arg, Error}
8+
9+
object RestrictedCommandsParser {
10+
def isExperimentalOrRestricted(a: Arg) =
11+
a.helpMessage.exists(m =>
12+
m.message.contains("[experimental]") || m.message.contains("[restricted]")
13+
)
14+
15+
def apply[T, TD](parser: Parser.Aux[T, TD]): Parser.Aux[T, TD] = new Parser[T] {
16+
17+
type D = TD
18+
19+
private def isArgSupported(a: Arg): Boolean =
20+
scala.cli.ScalaCli.allowRestrictedFeatures || !isExperimentalOrRestricted(a)
21+
22+
def args: Seq[caseapp.core.Arg] = parser.args.filter(isArgSupported)
23+
24+
def get(
25+
d: D,
26+
nameFormatter: caseapp.core.util.Formatter[caseapp.Name]
27+
): Either[caseapp.core.Error, T] =
28+
parser.get(d, nameFormatter)
29+
30+
def init: D = parser.init
31+
32+
def withDefaultOrigin(origin: String): caseapp.core.parser.Parser.Aux[T, D] =
33+
RestrictedCommandsParser(parser.withDefaultOrigin(origin))
34+
35+
override def step(
36+
args: List[String],
37+
index: Int,
38+
d: D,
39+
nameFormatter: Formatter[Name]
40+
): Either[(Error, Arg, List[String]), Option[(D, Arg, List[String])]] =
41+
parser.step(args, index, d, nameFormatter) match {
42+
case Right(Some(_, arg, _)) if !isArgSupported(arg) =>
43+
Left((
44+
Error.UnrecognizedArgument(
45+
s"`${args(index)}` option is not supported in `scala` command.\n Please run it with `scala-cli` command or with `--power` flag."
46+
),
47+
arg,
48+
Nil
49+
))
50+
case other =>
51+
other
52+
}
53+
}
54+
}

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@ import scala.cli.commands.util.CommandHelpers
1717
import scala.cli.commands.util.SharedOptionsUtil.*
1818
import scala.util.{Properties, Try}
1919

20-
abstract class ScalaCommand[T](implicit parser: Parser[T], help: Help[T])
21-
extends Command()(parser, help) with NeedsArgvCommand with CommandHelpers {
20+
abstract class ScalaCommand[T](implicit myParser: Parser[T], help: Help[T])
21+
extends Command()(myParser, help) with NeedsArgvCommand with CommandHelpers {
22+
2223
def sharedOptions(t: T): Option[SharedOptions] = // hello borked unused warning
2324
None
2425
override def hasFullHelp = true
2526

27+
override def parser: Parser[T] =
28+
RestrictedCommandsParser(myParser)
29+
2630
def isRestricted: Boolean = false
2731

2832
protected var argvOpt = Option.empty[Array[String]]

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,32 @@ class SipScalaTests extends ScalaCliSuite {
5858
expect(output.contains(s"directive is not supported"))
5959
}
6060

61+
def noMarkdownOptions(): Unit = TestInputs.empty.fromRoot { root =>
62+
val code =
63+
"""
64+
| println("ala")
65+
|""".stripMargin
66+
67+
val source = root / "A.sc"
68+
os.write(source, code)
69+
70+
val cliPath = os.Path(TestUtil.cliPath, os.pwd)
71+
72+
os.proc(cliPath, "--markdown", source).call(cwd = root)
73+
74+
os.copy(cliPath, root / "scala")
75+
os.perms.set(root / "scala", "rwxr-xr-x")
76+
77+
val res = os.proc(root / "scala", "--markdown", source).call(
78+
cwd = root,
79+
check = false,
80+
mergeErrIntoOut = true
81+
)
82+
expect(res.exitCode == 1)
83+
val output = res.out.text()
84+
expect(output.contains(s"option is not supported"))
85+
}
86+
6187
if (TestUtil.isNativeCli && !Properties.isWin) {
6288
test("no directories command when run as scala") {
6389
noDirectoriesCommandTest("scala")
@@ -69,6 +95,10 @@ class SipScalaTests extends ScalaCliSuite {
6995
test("no publish directives when run as scala") {
7096
noPublishDirectives()
7197
}
98+
99+
test("no markdown option when run as scala") {
100+
noMarkdownOptions()
101+
}
72102
}
73103

74104
def runVersionCommand(binaryName: String) =

0 commit comments

Comments
 (0)