From 472edce5f21da27721498152605c79b7a50c2f95 Mon Sep 17 00:00:00 2001 From: Cody Allen Date: Mon, 17 Jun 2019 15:49:19 -0700 Subject: [PATCH] Scala.js support Resolves #53 --- .travis.yml | 50 ++++++--- build.sbt | 105 +++++++++++++----- project/Dependencies.scala | 17 --- project/plugins.sbt | 2 + scripts/builds.sh | 32 ++++++ shell.nix | 1 + .../src/test/scala/IrrecSuite.scala | 0 .../src/test/scala/KleeneFTests.scala | 0 .../src/test/scala/NoShrink.scala | 0 .../src/test/scala/parse}/ParserTests.scala | 0 .../test/scala/regex-gen}/RegexGenTests.scala | 0 .../scala/regex-gen}/RegexShrinkTests.scala | 0 .../src/test/scala/regex}/GlushkovTests.scala | 0 .../regex}/IndexedSeqFoldableTests.scala | 0 .../regex}/KleeneOptimizationTests.scala | 0 .../src/test/scala/regex}/NFATests.scala | 0 .../regex}/RegexPrettyPrinterTests.scala | 0 17 files changed, 146 insertions(+), 61 deletions(-) delete mode 100644 project/Dependencies.scala create mode 100755 scripts/builds.sh rename {kleene => tests}/src/test/scala/IrrecSuite.scala (100%) rename {kleene => tests}/src/test/scala/KleeneFTests.scala (100%) rename {kleene => tests}/src/test/scala/NoShrink.scala (100%) rename {parser/src/test/scala => tests/src/test/scala/parse}/ParserTests.scala (100%) rename {regex-gen/src/test/scala => tests/src/test/scala/regex-gen}/RegexGenTests.scala (100%) rename {regex-gen/src/test/scala => tests/src/test/scala/regex-gen}/RegexShrinkTests.scala (100%) rename {regex/src/test/scala => tests/src/test/scala/regex}/GlushkovTests.scala (100%) rename {regex/src/test/scala => tests/src/test/scala/regex}/IndexedSeqFoldableTests.scala (100%) rename {regex/src/test/scala => tests/src/test/scala/regex}/KleeneOptimizationTests.scala (100%) rename {regex/src/test/scala => tests/src/test/scala/regex}/NFATests.scala (100%) rename {regex/src/test/scala => tests/src/test/scala/regex}/RegexPrettyPrinterTests.scala (100%) diff --git a/.travis.yml b/.travis.yml index 62ef162..a2cff89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,6 @@ -language: scala -sudo: false -jdk: -- oraclejdk8 - -before_install: - - git fetch --tags +# parts of this were adapted from https://github.com/higherkindness/droste/blob/bad7dae60a0c32e66918613068d6713d209cc6b4/.travis.yml +language: nix +sudo: required stages: - name: test @@ -14,22 +10,36 @@ stages: jobs: include: - env: TEST="docs" - script: sbt docs/mdoc - - env: TEST="test" - script: sbt +test + script: ./scripts/builds.sh docs + - env: TEST="test JVM" + script: ./scripts/builds.sh testJVM + - env: TEST="test JS" + script: ./scripts/builds.sh testJS + - env: TEST="lint" + script: ./scripts/builds.sh lint - env: TEST="coverage" - script: sbt coverage test && sbt coverageReport && bash <(curl -s https://codecov.io/bash) + script: ./scripts/builds.sh coverage - stage: release - script: sbt ci-release + script: ./scripts/builds.sh release + +before_install: + - git fetch --tags + +install: | + if [ "$(ls -A $HOME/nix-cache)" ]; then + sudo rm -rf /nix/* + cp -a $HOME/nix-cache/* /nix + fi # These directories are cached to S3 at the end of the build cache: -directories: - - $HOME/.sbt/1.0/dependency - - $HOME/.sbt/boot/scala* - - $HOME/.sbt/launchers - - $HOME/.ivy2/cache - - $HOME/.coursier + directories: + - $HOME/.sbt/1.0/dependency + - $HOME/.sbt/boot/scala* + - $HOME/.sbt/launchers + - $HOME/.ivy2/cache + - $HOME/.coursier + - $HOME/nix-cache before_cache: - du -h -d 1 $HOME/.ivy2/cache @@ -37,3 +47,7 @@ before_cache: - find $HOME/.sbt -name "*.lock" -type f -delete - find $HOME/.ivy2/cache -name "ivydata-*.properties" -type f -delete - rm -rf $HOME/.ivy2/local + - | + if [ ! "$(ls -A $HOME/nix-cache)" ]; then + cp -a /nix/* $HOME/nix-cache + fi diff --git a/build.sbt b/build.sbt index 61f677e..c22da93 100644 --- a/build.sbt +++ b/build.sbt @@ -1,7 +1,22 @@ -import dependencies._ +// shadow sbt-scalajs' crossProject and CrossType from Scala.js 0.6.x +import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType} val stableVersion = "0.2.1" +val catsVersion = "1.4.0" +val scalacheckVersion = "1.13.5" +val drosteVersion = "0.6.0" +val fastParseVersion = "2.1.0" + +val catsOrg = "org.typelevel" + +val scalacheckOrg = "org.scalacheck" + +val drosteOrg = "io.higherkindness" + +val isTravisBuild = + settingKey[Boolean]("Flag indicating whether the current build is running under Travis") + inThisBuild( List( organization := "net.ceedubs", @@ -14,46 +29,61 @@ inThisBuild( "ceedubs@gmail.com", url("https://github.com/ceedubs") ) - ) + ), + isTravisBuild := sys.env.get("TRAVIS").isDefined )) coverageExcludedPackages in ThisBuild := "ceedubs.irrec.bench" -lazy val kleene = (project in file("kleene")) +lazy val kleene = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("kleene")) .settings( moduleName := "irrec-kleene", - libraryDependencies ++= Seq(cats.core, cats.testkit % Test)) + libraryDependencies += catsOrg %%% "cats-core" % catsVersion) .settings(commonSettings) -lazy val regex = (project in file("regex")) - .settings(moduleName := "irrec-regex", libraryDependencies ++= Seq(droste, cats.testkit % Test)) +lazy val regex = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("regex")) + .dependsOn(kleene) + .settings( + moduleName := "irrec-regex", + libraryDependencies += drosteOrg %%% "droste-core" % drosteVersion) .settings(commonSettings) - // see https://github.com/sbt/sbt/issues/2698#issuecomment-311417188 + +lazy val tests = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("tests")) + .dependsOn(regexGen, parser) .settings( - unmanagedClasspath in Test ++= - (fullClasspath in (regexGenRef, Compile)).value ++ - (fullClasspath in (parserRef, Compile)).value) - .dependsOn(kleene % "test->test;compile->compile") + moduleName := "irrec-tests", + libraryDependencies += catsOrg %%% "cats-testkit" % catsVersion % Test) + .settings(commonSettings) + .settings(noPublishSettings) -lazy val regexGen = (project in file("regex-gen")) +lazy val regexGen = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .dependsOn(kleene, regex) + .in(file("regex-gen")) .settings( moduleName := "irrec-regex-gen", - libraryDependencies ++= Seq(scalacheck, cats.testkit % Test)) + libraryDependencies += scalacheckOrg %%% "scalacheck" % scalacheckVersion) .settings(commonSettings) - .dependsOn(regex % "test->test;compile->compile") -lazy val regexGenRef = LocalProject("regexGen") - -lazy val parser = (project in file("parser")) - .settings(moduleName := "irrec-parser", libraryDependencies += fastparse) +lazy val parser = crossProject(JSPlatform, JVMPlatform) + .crossType(CrossType.Pure) + .in(file("parser")) + .settings( + moduleName := "irrec-parser", + libraryDependencies += "com.lihaoyi" %%% "fastparse" % fastParseVersion) .settings(commonSettings) - .dependsOn(regex % "test->test;compile->compile", regexGen % Test) - -lazy val parserRef = LocalProject("parser") + .dependsOn(kleene, regex) -lazy val docs = (project in file("irrec-docs")) +lazy val docs = project + .in(file("irrec-docs")) .enablePlugins(MdocPlugin) - .dependsOn(regex, regexGen, parser) + .dependsOn(regex.jvm, regexGen.jvm, parser.jvm) .settings( mdocOut := (baseDirectory in LocalRootProject).value, mdocVariables := Map( @@ -63,18 +93,35 @@ lazy val docs = (project in file("irrec-docs")) ) .settings(noPublishSettings) -lazy val benchmarks = (project in file("benchmarks")) +lazy val benchmarks = project + .in(file("benchmarks")) .settings(moduleName := "irrec-benchmarks") .enablePlugins(JmhPlugin) .settings(commonSettings) .settings(noPublishSettings) - .dependsOn(regex) + .dependsOn(regex.jvm) + +lazy val jvm = project + .settings( + moduleName := "irrec-root-jvm" + ) + .aggregate(kleene.jvm, regex.jvm, regexGen.jvm, parser.jvm, tests.jvm, benchmarks) + .settings(commonSettings) + .settings(noPublishSettings) + +lazy val js = project + .settings( + moduleName := "irrec-root-js" + ) + .aggregate(kleene.js, regex.js, regexGen.js, parser.js, tests.js) + .settings(commonSettings) + .settings(noPublishSettings) lazy val root = project .settings( moduleName := "irrec-root" ) - .aggregate(kleene, regex, regexGen, parser) + .aggregate(jvm, js) .settings(commonSettings) .settings(noPublishSettings) @@ -160,6 +207,12 @@ val commonSettings: Seq[Setting[_]] = Seq( crossScalaVersions := List("2.11.12", "2.12.8") ) ++ scalacOptionSettings +val commonJsSettings: Seq[Setting[_]] = Seq( + parallelExecution := false, + // batch mode decreases the amount of memory needed to compile Scala.js code + scalaJSOptimizerOptions := scalaJSOptimizerOptions.value.withBatchMode(isTravisBuild.value) +) + val noPublishSettings = Seq( publish := {}, publishLocal := {}, diff --git a/project/Dependencies.scala b/project/Dependencies.scala deleted file mode 100644 index 25b72a4..0000000 --- a/project/Dependencies.scala +++ /dev/null @@ -1,17 +0,0 @@ -import sbt._ - -object dependencies { - object cats { - val version = "1.4.0" - val org = "org.typelevel" - - val core = org %% "cats-core" % version - val testkit = org %% "cats-testkit" % version - } - - val scalacheck = "org.scalacheck" %% "scalacheck" % "1.13.5" - - val droste = "io.higherkindness" %% "droste-core" % "0.6.0" - - val fastparse = "com.lihaoyi" %% "fastparse" % "2.1.0" -} diff --git a/project/plugins.sbt b/project/plugins.sbt index 2a2d81f..a099b95 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,3 +4,5 @@ addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.1") addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.3.4") addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.2.6") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.0") +addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "0.6.0") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.28") diff --git a/scripts/builds.sh b/scripts/builds.sh new file mode 100755 index 0000000..37b4ca0 --- /dev/null +++ b/scripts/builds.sh @@ -0,0 +1,32 @@ +#! /usr/bin/env nix-shell +#! nix-shell ../shell.nix -i bash + +# adapted from https://github.com/higherkindness/droste/blob/bad7dae60a0c32e66918613068d6713d209cc6b4/scripts/ci-jobs.sh + +set -euxo pipefail + +case "$1" in + "docs") + sbt 'docs/mdoc' + ;; + "lint") + sbt 'lint' + ;; + "testJVM") + sbt '+jvm/test' + ;; + "testJS") + sbt '+js/test' + ;; + "coverage") + sbt ';coverage;jvm/test;coverageReport' + bash <(curl -s https://codecov.io/bash) + ;; + "release") + sbt 'ci-release' + ;; + *) + echo "no command specified!" + exit 1 + ;; +esac diff --git a/shell.nix b/shell.nix index 1fcff21..5d02beb 100644 --- a/shell.nix +++ b/shell.nix @@ -28,5 +28,6 @@ in sbt git # used by sbt-dynver graphviz # used for ScalaDoc diagrams + nodejs # used by scala.js ]; } diff --git a/kleene/src/test/scala/IrrecSuite.scala b/tests/src/test/scala/IrrecSuite.scala similarity index 100% rename from kleene/src/test/scala/IrrecSuite.scala rename to tests/src/test/scala/IrrecSuite.scala diff --git a/kleene/src/test/scala/KleeneFTests.scala b/tests/src/test/scala/KleeneFTests.scala similarity index 100% rename from kleene/src/test/scala/KleeneFTests.scala rename to tests/src/test/scala/KleeneFTests.scala diff --git a/kleene/src/test/scala/NoShrink.scala b/tests/src/test/scala/NoShrink.scala similarity index 100% rename from kleene/src/test/scala/NoShrink.scala rename to tests/src/test/scala/NoShrink.scala diff --git a/parser/src/test/scala/ParserTests.scala b/tests/src/test/scala/parse/ParserTests.scala similarity index 100% rename from parser/src/test/scala/ParserTests.scala rename to tests/src/test/scala/parse/ParserTests.scala diff --git a/regex-gen/src/test/scala/RegexGenTests.scala b/tests/src/test/scala/regex-gen/RegexGenTests.scala similarity index 100% rename from regex-gen/src/test/scala/RegexGenTests.scala rename to tests/src/test/scala/regex-gen/RegexGenTests.scala diff --git a/regex-gen/src/test/scala/RegexShrinkTests.scala b/tests/src/test/scala/regex-gen/RegexShrinkTests.scala similarity index 100% rename from regex-gen/src/test/scala/RegexShrinkTests.scala rename to tests/src/test/scala/regex-gen/RegexShrinkTests.scala diff --git a/regex/src/test/scala/GlushkovTests.scala b/tests/src/test/scala/regex/GlushkovTests.scala similarity index 100% rename from regex/src/test/scala/GlushkovTests.scala rename to tests/src/test/scala/regex/GlushkovTests.scala diff --git a/regex/src/test/scala/IndexedSeqFoldableTests.scala b/tests/src/test/scala/regex/IndexedSeqFoldableTests.scala similarity index 100% rename from regex/src/test/scala/IndexedSeqFoldableTests.scala rename to tests/src/test/scala/regex/IndexedSeqFoldableTests.scala diff --git a/regex/src/test/scala/KleeneOptimizationTests.scala b/tests/src/test/scala/regex/KleeneOptimizationTests.scala similarity index 100% rename from regex/src/test/scala/KleeneOptimizationTests.scala rename to tests/src/test/scala/regex/KleeneOptimizationTests.scala diff --git a/regex/src/test/scala/NFATests.scala b/tests/src/test/scala/regex/NFATests.scala similarity index 100% rename from regex/src/test/scala/NFATests.scala rename to tests/src/test/scala/regex/NFATests.scala diff --git a/regex/src/test/scala/RegexPrettyPrinterTests.scala b/tests/src/test/scala/regex/RegexPrettyPrinterTests.scala similarity index 100% rename from regex/src/test/scala/RegexPrettyPrinterTests.scala rename to tests/src/test/scala/regex/RegexPrettyPrinterTests.scala