Skip to content

Commit

Permalink
Fix document checker
Browse files Browse the repository at this point in the history
  • Loading branch information
romanowski committed Oct 11, 2021
1 parent 65c6820 commit 0bc8787
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 117 deletions.
8 changes: 4 additions & 4 deletions docs_checker/Readme.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# Docs checker - simple tool to verify scala-cli cookbooks

Docs checker tests documentation is using simple regexes to run following actions:
- extract/override code snippet to file in workspace for snippets starting with ````scala name:<file-name>` for example:
- extract/override code snippet to file in workspace for snippets starting with ````scala title=<file-name>` for example:

````
```scala-cli
```bash
scala-cli ScalaVersion.scala
```
````

- run scala-cli commands (or any commands) for snippets starting with ````scala-cli` for example:
- run scala-cli commands (or any commands) for snippets starting with ````bash` for example:

````
```scala name:ScalaVersion.scala
```scala title=ScalaVersion.scala
object ScalaVersion extends App
```
````
Expand Down
67 changes: 39 additions & 28 deletions docs_checker/check.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ import scala.util.matching.Regex

import munit.Assertions.assert

val ScalaCodeBlock = """ *```scala name\:([\w\.]+)+""".r
val CodeBlockEnds = """ *```""".r
val ScalaCliBlock = """ *```scala-cli( +fail)?""".r
val CheckBlock = """ *\<\!\-\- Expected(-regex):""".r
val CheckBlockEnd = """ *\-\-\>""".r
val ScalaCodeBlock = """ *```scala title=([\w\.]+) *""".r
val CodeBlockEnds = """ *``` *""".r
val ScalaCliBlock = """ *```bash *(fail)? *""".r
val CheckBlock = """ *\<\!\-\- Expected(-regex)?: *""".r
val CheckBlockEnd = """ *\-\-\> *""".r

enum Commands:
def context: Context

case Snippet(name: String, lines: Seq[String], context: Context)
case Run(cmd: Seq[String], shouldFail: Boolean, context: Context)
case Run(cmd: Seq[Seq[String]], shouldFail: Boolean, context: Context)
case Check(patterns: Seq[String], regex: Boolean, context: Context)

case class Context(file: String, line: Int)
Expand All @@ -38,18 +38,19 @@ def parse(content: Seq[String], currentCommands: Seq[Commands], context: Context
case Nil => currentCommands
case ScalaCodeBlock(name) :: tail =>
val (codeLines, rest, newContext) = untilEndOfSnippet(tail)(using context)

parse(rest, currentCommands :+ Commands.Snippet(name, codeLines, context), newContext)
case ScalaCliBlock(failGroup) :: tail =>
val (codeLines, rest, newContext) = untilEndOfSnippet(tail)
assert(codeLines.size != 0)
val runCmd = Commands.Run(codeLines.head.split(" ").toList, failGroup != null, newContext)
val runCmd = Commands.Run(codeLines.filterNot(_.trim.startsWith("#")).map(_.split(" ").toList), failGroup != null, newContext)
parse(rest, currentCommands :+ runCmd, newContext)
case CheckBlock(regexOpt) :: tail =>
val isRegex = regexOpt == "-regex"
val (patterns, rest, newContext) = untilEndOfSnippet(tail, CheckBlockEnd)
parse(rest, currentCommands :+ Commands.Check(patterns, isRegex, context), newContext)
case _ :: tail => parse(tail, currentCommands, context.copy(line = context.line + 1))
case _ :: tail =>
parse(tail, currentCommands, context.copy(line = context.line + 1))

case class TestCase(path: os.Path, failure: Option[Throwable])

Expand Down Expand Up @@ -77,7 +78,7 @@ def checkFile(file: os.Path, dest: Option[os.Path]) =
val destName = file.last.stripSuffix(".md")
val out = os.temp.dir(prefix = destName)

var lastOutput = ""
var lastOutput: String = null
val allSources = Set.newBuilder[os.Path]

try
Expand All @@ -86,29 +87,39 @@ def checkFile(file: os.Path, dest: Option[os.Path]) =
commands.foreach { cmd =>
given Context = cmd.context
cmd match
case Commands.Run(cmd, shouldFail, _) =>
println(s"### Running: ${cmd.mkString(" ")}")
val res = os.proc(cmd).call(cwd = out, check = false)
if shouldFail then
assert(res.exitCode != 0)
else
assert(res.exitCode == 0)
val outputChunks = res.chunks.map {
case Left(c) =>
c
case Right(c) =>
c
case Commands.Run(cmds, shouldFail, _) =>
cmds.foreach { cmd =>
println(s"### Running: ${cmd.mkString(" ")}:")
val res = os.proc(cmd).call(cwd = out,mergeErrIntoOut=true, check = false)
println(res.out.text())
if shouldFail then
assert(res.exitCode != 0)
else
assert(res.exitCode == 0)

val outputChunks = res.chunks.map {
case Left(c) =>
c
case Right(c) =>
c
}
lastOutput = res.out.text()
}
lastOutput = geny.ByteData.Chunks(outputChunks).text()

case Commands.Snippet(name, code, c) =>
println(s"### Writting $name with:\n${code.mkString("\n")}\n---")
val prefix = (fakeLineMarker + "\n") * c.line
val (prefixLines, codeLines) = code match
case shbang :: tail if shbang.startsWith("#!") =>
List(shbang + "\n") -> tail
case other =>
Nil -> other

val file = out / name
allSources += file
println(s"### Writting $name with:\n${codeLines.mkString("\n")}\n---")

val prefix = prefixLines.mkString("", "",s"$fakeLineMarker\n" * c.line)
os.write(file, code.mkString(prefix, "\n", ""))
case Commands.Check(patterns, regex, line) =>
assert(lastOutput != "", msg("No output stored from previous commands"))
assert(lastOutput != null, msg("No output stored from previous commands"))
val lines = lastOutput.linesIterator.toList

if regex then
Expand All @@ -123,7 +134,7 @@ def checkFile(file: os.Path, dest: Option[os.Path]) =
patterns.foreach { pattern =>
assert(
lines.exists(_.contains(pattern)),
msg(s"Pattern: $pattern does not exisits in any line in:\n$lastOutput")
msg(s"Pattern: $pattern does not exists in any line in:\n$lastOutput")
)
}
}
Expand Down
1 change: 1 addition & 0 deletions examples/index/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
File was generated from based on docs/cookbooks/index.md, do not edit manually!
-->


# Cookbook

This part contains a set of recipes how to use scala-cli within given situations.
9 changes: 4 additions & 5 deletions examples/scala-jvm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ You can use Scala CLI to test your code compatibility with various versions of `

The following snippet uses the new method `Files.writeString` from Java 11.

```scala name:Main.scala
```scala title=Main.scala
import java.nio.file.Files
import java.nio.file.Paths

Expand All @@ -19,12 +19,11 @@ object Main extends App {
val fileContent: String = Files.readString(filePath)
println(fileContent)
}
```

```

Pass `--jvm` to the `scala-cli` command to run your application with the specified java version.

```scala-cli
```bash
scala-cli Main.scala --jvm 11
```

Expand All @@ -33,7 +32,7 @@ Hello from ScalaCli
-->

To test your application with Java 8, change the value of `--jvm` parameter.
```scala-cli fail
```bash fail
scala-cli Main.scala --jvm 8
# In this case, it raises an error because the `Files.createTempFile` method is not available in java 8
#
Expand Down
26 changes: 23 additions & 3 deletions examples/scala-package/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Scala CLI allows you to package your application into a lightweight JAR file, th
It only contains the byte code of your sources, and automatically downloads its dependencies on its first run.

The following snippet contains a short application to detect the OS:
```scala name:DetectOsApp.scala
```scala title=DetectOsApp.scala
object DetectOSApp extends App {
def getOperatingSystem(): String = {
val os: String = System.getProperty("os.name")
Expand All @@ -21,7 +21,7 @@ object DetectOSApp extends App {

By default, the `package` sub-command generates a lightweight JAR.

```scala-cli
```bash
scala-cli package DetectOsApp.scala
```

Expand All @@ -37,6 +37,26 @@ Lightweight JARs require the `java` command to be available, and access to inter
./DetectOsApp
# os: Mac OS X
```
<details open><summary>
os: Mac OS X
</summary>
os: Mac OS X
</details>


```bash
# Run DetectOsApp on MacOs
./DetectOsApp
# os: Mac OS X
```
<details open><summary></summary>

```
os: Mac OS X
```

</details>


In the previous example, a Lightweight JAR that was built in a MacOs environment could also run on Linux.

Expand All @@ -53,7 +73,7 @@ Only Jars built on MacOs / Linux are easily portable between this system. The Li
### Assemblies
Passing `--assembly` to the `package` sub-command generates so-called "assemblies" or "fat JARs".

```scala-cli
```bash
scala-cli package --assembly DetectOsApp.scala
```

Expand Down
26 changes: 18 additions & 8 deletions examples/scala-scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,27 @@ Scala Scripts are files containing Scala code without main method required. Thes

You can use `scala-cli` to run Scala scripts (no further setup is required):

```scala name:HelloScript.sc
```scala title=HelloScript.sc
val sv = scala.util.Properties.versionNumberString

val message = s"Hello from Scala ${sv}, Java ${System.getProperty("java.version")}"
println(message)
```

```scala-cli
```bash
scala-cli run HelloScript.sc
```

<!-- Expected:
Hello from Scala *, Java *
<!-- Expected-regex:
Hello from Scala .*, Java .*
-->


Alternatively, add a shebang header to your script, make your script executable, and execute it directly. `scala-cli` needs to be installed for this to work.

```scala name:HelloScriptSheBang.sc
```scala title=HelloScriptSheBang.sc
#!/usr/bin/env scala-cli

val sv = scala.util.Properties.versionNumberString

def printMessage(): Unit =
Expand All @@ -47,22 +48,31 @@ chmod +x HelloScriptSheBang.sc
# Hello from Scala 2.13.6, Java 16.0.1
```

<!-- Expected-regex:
Hello from Scala .*, Java .*
-->

## Features

All the features from non-scripts are working with Scala Scripts, such as waiting for changes (watch mode), dependencies menagement, packaging, compiling and many others.

### Package

Pass `--package` to the Scala CLI to package your script to Leighweight JAR file.
Run `package` to the Scala CLI to package your script to Leighweight JAR file.

```bash
scala-cli --package HelloScript.sc
scala-cli package HelloScript.sc
./HelloScript
```

<!-- Expected-regex:
Hello from Scala .*, Java .*
-->

### Watch mode

Pass `--watch` to the Scala CLI to watch all sources for changes, and re-run them upon changes.

```bash
```bash ignore
scala-cli --watch HelloScript.sc
```
Loading

0 comments on commit 0bc8787

Please sign in to comment.