Skip to content

Instantly share code, notes, and snippets.

@ChristopherDavenport
Last active April 23, 2021 02:12
Show Gist options
  • Save ChristopherDavenport/df6526de7d3e8f498df8106141581a60 to your computer and use it in GitHub Desktop.
Save ChristopherDavenport/df6526de7d3e8f498df8106141581a60 to your computer and use it in GitHub Desktop.
Scala Scripting
#!/usr/bin/env sbt -Dsbt.version=1.5.0 -Dsbt.main.class=sbt.ScriptMain -Dsbt.supershell=false -error
// Note that `ScriptMain` doesn't work with Scala 3 yet, and won't unless a
// volunteer steps up: https://github.com/sbt/sbt/issues/6274
/***
scalaVersion := "2.13.5"
onLoadMessage := ""
scalacOptions ++= Seq(
"-deprecation", "-unchecked", "-feature", "-Werror")
libraryDependencies ++= Seq(
"org.http4s" %% "http4s-ember-client" % "1.0.0-M21",
)
*/
import cats.effect._
import cats.effect.std.Console
object HelloWorld extends IOApp.Simple {
val run = Console[IO].println("Hello world!")
}
HelloWorld.main(Array())
import cats.syntax.all._
import cats.effect._
import scala.concurrent.duration._
import java.nio.file.Paths
object Main extends IOApp {
val console = cats.effect.std.Console.make[IO]
def run(args: List[String]): IO[ExitCode] = {
for {
_ <- IO(println(s"Args: $args"))
path <- IO(Paths.get(args.last))
fileContent <- fs2.io.file.Files[IO].readAll(path, 512)
.through(fs2.text.utf8Decode)
.compile
.string
parsed <- Parser.simpleParser(fileContent).liftTo[IO]
_ <- console.println(parsed)
} yield ExitCode.Success
//
//Args: List(./test.scsh)
//(List((interpreter, IOApp.Simple), (scala, 2.13.5), (dependency, "org.http4s" %% "http4s-ember-client" % "1.0.0-M21")),
//
//import cats.effect._
//import cats.effect.std.Console
//
//def main: IO[Unit] = Console[IO].println("Hello world!"))
}
}
// Optional #!
// Uninterrupted section of comments broken by newlines
// Terminated by /n/n or /r/n/r/n
// name/scala/sbt/interpreter/dependency headers defined
object Parser {
def simpleParser(inputText: String): Either[Throwable, (List[(String, String)], String)] = Either.catchNonFatal{
val text = {
val base = inputText
if (base.startsWith("#!")) {
val idx = base.indexOf("\n")+1
val out = base.substring(idx)
out
} else base
}
// println(s"Text: $text")
val (startText, restText) = {
val idx = text.indexOf("\n\n")
if (idx == -1) throw new Throwable("No Headers Found Require name/scala/interpreter")
else text.splitAt(idx)
}
val headersLines = fs2.Stream(startText)
.through(fs2.text.lines)
.takeWhile(_.startsWith("//"))
.filter(x => x.contains(":")) // Comments are allowed that dont follow x:z
.compile
.to(List)
val headers = headersLines.map{
s =>
val idx = s.indexOf(":") // :space is required in for a valid header
val header = s.slice(2, idx).trim()
val value = s.slice(idx + 1, s.length())
(header, value)
}
(headers, restText)
}
}
object Files {
def buildFile(name: String, scala: String, dependencies: List[String]): String = {
s"""
|scalaVersion := "$scala"
|name := "$name"
|
|${dependencies.map(s => s"libraryDependencies += $s").intercalate("\n")}
|""".stripMargin
}
def buildProperties(sbt: String) = s"sbt.version=$sbt\n"
}
#!./core/target/universal/stage/bin/scripting
// interpreter: IOApp.Simple
// scala: 2.13.5
// dependency: "org.http4s" %% "http4s-ember-client" % "1.0.0-M21"
import cats.effect._
import cats.effect.std.Console
def main: IO[Unit] = Console[IO].println("Hello world!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment