Skip to content
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

Add support for passing Markdown code as snippets #1583

Merged
merged 1 commit into from Nov 16, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 17 additions & 3 deletions modules/build/src/main/scala/scala/build/input/Inputs.scala
Expand Up @@ -210,7 +210,8 @@ object Inputs {
def validateSnippets(
scriptSnippetList: List[String] = List.empty,
scalaSnippetList: List[String] = List.empty,
javaSnippetList: List[String] = List.empty
javaSnippetList: List[String] = List.empty,
markdownSnippetList: List[String] = List.empty
): Seq[Either[String, Seq[Element]]] = {
def validateSnippet(
snippetList: List[String],
Expand All @@ -236,6 +237,15 @@ object Inputs {
javaSnippetList,
(content, snippetNameSuffix) =>
VirtualJavaFile(content, s"<snippet>-java-$snippetNameSuffix")
),
validateSnippet(
markdownSnippetList,
(content, snippetNameSuffix) =>
VirtualMarkdownFile(
content,
s"<snippet>-markdown-$snippetNameSuffix",
os.sub / s"$snippetNameSuffix.md"
)
)
).flatten
}
Expand Down Expand Up @@ -299,6 +309,7 @@ object Inputs {
scriptSnippetList: List[String],
scalaSnippetList: List[String],
javaSnippetList: List[String],
markdownSnippetList: List[String],
acceptFds: Boolean,
forcedWorkspace: Option[os.Path],
enableMarkdown: Boolean,
Expand All @@ -308,7 +319,7 @@ object Inputs {
val validatedArgs: Seq[Either[String, Seq[Element]]] =
validateArgs(args, cwd, download, stdinOpt, acceptFds, enableMarkdown)
val validatedSnippets: Seq[Either[String, Seq[Element]]] =
validateSnippets(scriptSnippetList, scalaSnippetList, javaSnippetList)
validateSnippets(scriptSnippetList, scalaSnippetList, javaSnippetList, markdownSnippetList)
val validatedArgsAndSnippets = validatedArgs ++ validatedSnippets
val invalid = validatedArgsAndSnippets.collect {
case Left(msg) => msg
Expand Down Expand Up @@ -342,14 +353,16 @@ object Inputs {
scriptSnippetList: List[String] = List.empty,
scalaSnippetList: List[String] = List.empty,
javaSnippetList: List[String] = List.empty,
markdownSnippetList: List[String] = List.empty,
acceptFds: Boolean = false,
forcedWorkspace: Option[os.Path] = None,
enableMarkdown: Boolean = false,
allowRestrictedFeatures: Boolean,
extraClasspathWasPassed: Boolean
): Either[BuildException, Inputs] =
if (
args.isEmpty && scriptSnippetList.isEmpty && scalaSnippetList.isEmpty && javaSnippetList.isEmpty && !extraClasspathWasPassed
args.isEmpty && scriptSnippetList.isEmpty && scalaSnippetList.isEmpty && javaSnippetList.isEmpty &&
markdownSnippetList.isEmpty && !extraClasspathWasPassed
)
defaultInputs().toRight(new InputsException(
"No inputs provided (expected files with .scala, .sc, .java or .md extensions, and / or directories)."
Expand All @@ -364,6 +377,7 @@ object Inputs {
scriptSnippetList,
scalaSnippetList,
javaSnippetList,
markdownSnippetList,
acceptFds,
forcedWorkspace,
enableMarkdown,
Expand Down
Expand Up @@ -32,6 +32,17 @@ final case class SnippetOptions(
@Group("Java")
@HelpMessage("A synonym to --scala-snippet, which defaults the sub-command to `run` when no sub-command is passed explicitly")
executeJava: List[String] = List.empty,

@Group("Markdown")
@HelpMessage("[experimental] Allows to execute a passed string as Markdown code")
@Name("mdSnippet")
markdownSnippet: List[String] = List.empty,

@Group("Markdown")
@HelpMessage("[experimental] A synonym to --markdown-snippet, which defaults the sub-command to `run` when no sub-command is passed explicitly")
@Name("executeMd")
@Hidden
executeMarkdown: List[String] = List.empty,
)
// format: on

Expand Down
Expand Up @@ -40,6 +40,7 @@ class Default(
val shouldDefaultToRun =
args.remaining.nonEmpty || options.shared.snippet.executeScript.nonEmpty ||
options.shared.snippet.executeScala.nonEmpty || options.shared.snippet.executeJava.nonEmpty ||
options.shared.snippet.executeMarkdown.nonEmpty ||
(options.shared.extraJarsAndClassPath.nonEmpty && options.sharedRun.mainClass.mainClass.nonEmpty)
if shouldDefaultToRun then RunOptions.parser else ReplOptions.parser
}.parse(rawArgs) match
Expand Down
Expand Up @@ -56,6 +56,7 @@ object PublishSetup extends ScalaCommand[PublishSetupOptions] {
options.input.forbid,
Nil,
Nil,
Nil,
Nil
)
maybeInputs match {
Expand Down
Expand Up @@ -60,6 +60,7 @@ object SharedOptionsUtil extends CommandHelpers {
scriptSnippetList: List[String],
scalaSnippetList: List[String],
javaSnippetList: List[String],
markdownSnippetList: List[String],
enableMarkdown: Boolean = false,
extraClasspathWasPassed: Boolean = false
): Either[BuildException, Inputs] = {
Expand All @@ -80,6 +81,7 @@ object SharedOptionsUtil extends CommandHelpers {
scriptSnippetList = scriptSnippetList,
scalaSnippetList = scalaSnippetList,
javaSnippetList = javaSnippetList,
markdownSnippetList = markdownSnippetList,
acceptFds = !Properties.isWin,
forcedWorkspace = forcedWorkspaceOpt,
enableMarkdown = enableMarkdown,
Expand Down Expand Up @@ -407,13 +409,15 @@ object SharedOptionsUtil extends CommandHelpers {
scriptSnippetList = allScriptSnippets,
scalaSnippetList = allScalaSnippets,
javaSnippetList = allJavaSnippets,
markdownSnippetList = allMarkdownSnippets,
enableMarkdown = v.markdown.enableMarkdown,
extraClasspathWasPassed = v.extraJarsAndClassPath.nonEmpty
)

def allScriptSnippets: List[String] = v.snippet.scriptSnippet ++ v.snippet.executeScript
def allScalaSnippets: List[String] = v.snippet.scalaSnippet ++ v.snippet.executeScala
def allJavaSnippets: List[String] = v.snippet.javaSnippet ++ v.snippet.executeJava
def allScriptSnippets: List[String] = v.snippet.scriptSnippet ++ v.snippet.executeScript
def allScalaSnippets: List[String] = v.snippet.scalaSnippet ++ v.snippet.executeScala
def allJavaSnippets: List[String] = v.snippet.javaSnippet ++ v.snippet.executeJava
def allMarkdownSnippets: List[String] = v.snippet.markdownSnippet ++ v.snippet.executeMarkdown

def validateInputArgs(args: Seq[String]): Seq[Either[String, Seq[Element]]] =
Inputs.validateArgs(
Expand Down
Expand Up @@ -77,6 +77,26 @@ class DefaultTests extends ScalaCliSuite {
}
}

test("default to the run sub-command when a md snippet is passed with --execute-markdown") {
TestInputs.empty.fromRoot { root =>
val msg = "Hello world"
val quotation = TestUtil.argQuotationMark
val res =
os.proc(
TestUtil.cli,
"--execute-markdown",
s"""# A Markdown snippet
|With some scala code
|```scala
|println($quotation$msg$quotation)
|```""".stripMargin,
TestUtil.extraOptions
)
.call(cwd = root)
expect(res.out.trim() == msg)
}
}

test("running scala-cli with a script snippet passed with -e shouldn't allow repl-only options") {
TestInputs.empty.fromRoot { root =>
val replSpecificOption = "--repl-dry-run"
Expand Down
Expand Up @@ -53,6 +53,27 @@ trait RunSnippetTestDefinitions { _: RunTestDefinitions =>
}
}

test("correctly run a markdown snippet") {
emptyInputs.fromRoot { root =>
val msg = "Hello world"
val quotation = TestUtil.argQuotationMark
val res =
os.proc(
TestUtil.cli,
"run",
"--markdown-snippet",
s"""# A Markdown snippet
|With some scala code
|```scala
|println($quotation$msg$quotation)
|```""".stripMargin,
extraOptions
)
.call(cwd = root)
expect(res.out.trim() == msg)
}
}

test("correctly run multiple snippets") {
emptyInputs.fromRoot { root =>
val quotation = TestUtil.argQuotationMark
Expand Down
18 changes: 18 additions & 0 deletions website/docs/guides/snippets.md
Expand Up @@ -80,6 +80,24 @@ Hello

</ChainedSnippets>

- Markdown code (experimental)

<ChainedSnippets>

````bash
scala-cli run --markdown-snippet '# Markdown snippet
with a code block
```scala
println("Hello")
```'
````

```text
Hello
```

</ChainedSnippets>

- a mix of Scala, Java and scripts

<ChainedSnippets>
Expand Down
13 changes: 13 additions & 0 deletions website/docs/reference/cli-options.md
Expand Up @@ -1399,6 +1399,19 @@ Allows to execute a passed string as Java code

A synonym to --scala-snippet, which defaults the sub-command to `run` when no sub-command is passed explicitly

### `--markdown-snippet`

Aliases: `--md-snippet`

[experimental] Allows to execute a passed string as Markdown code

### `--execute-markdown`

Aliases: `--execute-md`

[Internal]
[experimental] A synonym to --markdown-snippet, which defaults the sub-command to `run` when no sub-command is passed explicitly

## Test options

Available in commands:
Expand Down