Skip to content

Commit

Permalink
Native and ScalaJS support + ci fixed (#289)
Browse files Browse the repository at this point in the history
* crossplatform ci

* changing JVM

* repaired

* changed path imports

* fixed tests

* changed path import

* changed path imports

* fixed tests imports

* ci

* ci
  • Loading branch information
pablf authored Jan 25, 2024
1 parent 4c22441 commit 8b82983
Show file tree
Hide file tree
Showing 37 changed files with 514 additions and 223 deletions.
9 changes: 4 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,11 @@ jobs:
distribution: temurin
java-version: ${{ matrix.java }}
check-latest: true
- name: Install libuv
if: matrix.platform == 'Native'
run: sudo apt-get update && sudo apt-get install -y libuv1-dev
- name: Run tests
if: ${{ !startsWith(matrix.scala, '3.') }}
run: sbt "++${{ matrix.scala }} test"
- name: Run dotty tests
if: ${{ startsWith(matrix.scala, '3.') && matrix.platform == 'JVM' }}
run: sbt "++${{ matrix.scala }} test"
run: sbt ++${{ matrix.scala }} zioCli${{ matrix.platform }}/test

publish:
runs-on: ubuntu-20.04
Expand Down
80 changes: 43 additions & 37 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -38,46 +38,48 @@ lazy val root = project
crossScalaVersions := Nil
)
.aggregate(
zioCliJVM,
zioCliJS,
examplesJVM,
examplesJS,
zioCli.jvm,
zioCli.js,
zioCli.native,
examples.jvm,
examples.js,
examples.native,
docs,
sbtZioCli,
testkitJVM,
testkitJS
testkit.jvm,
testkit.js,
testkit.native
)

lazy val zioCli = crossProject(JSPlatform, JVMPlatform)
lazy val zioCli = crossProject(JSPlatform, JVMPlatform, NativePlatform)
.in(file("zio-cli"))
.settings(stdSettings("zio-cli"))
.settings(crossProjectSettings)
.settings(buildInfoSettings("zio.cli"))
.settings(
libraryDependencies ++= Seq(
"dev.zio" %% "zio" % zioVersion,
"dev.zio" %% "zio-json" % "0.6.2",
"dev.zio" %% "zio-process" % "0.7.1",
"dev.zio" %% "zio-streams" % zioVersion,
"dev.zio" %% "zio-test" % zioVersion % Test,
"dev.zio" %% "zio-test-sbt" % zioVersion % Test
"dev.zio" %%% "zio" % zioVersion,
"dev.zio" %%% "zio-json" % "0.6.2",
"dev.zio" %%% "zio-streams" % zioVersion,
"dev.zio" %%% "zio-test" % zioVersion % Test,
"dev.zio" %%% "zio-test-sbt" % zioVersion % Test
)
)
.jvmSettings(
libraryDependencies += "dev.zio" %% "zio-process" % "0.7.1"
)
.nativeSettings(Test / fork := false)
.nativeSettings(
libraryDependencies += "io.github.cquiroz" %%% "scala-java-time" % "2.5.0" % Test
)
.jsSettings(
libraryDependencies += "io.github.cquiroz" %%% "scala-java-time" % "2.5.0" % Test
)
.jvmSettings(dottySettings)
.jsSettings(scalaJSUseMainModuleInitializer := true)
.settings(testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework"))

lazy val zioCliJVM = zioCli.jvm
.settings(dottySettings)

lazy val zioCliJS = zioCli.js
.settings(scalaJSUseMainModuleInitializer := true)

lazy val examplesJVM = examples.jvm
.settings(dottySettings)

lazy val examplesJS = examples.js
.settings(scalaJSUseMainModuleInitializer := true)

lazy val examples = crossProject(JSPlatform, JVMPlatform)
lazy val examples = crossProject(JSPlatform, JVMPlatform, NativePlatform)
.in(file("examples"))
.settings(stdSettings("examples"))
.settings(crossProjectSettings)
Expand All @@ -88,6 +90,8 @@ lazy val examples = crossProject(JSPlatform, JVMPlatform)
"dev.zio" %% "zio-streams" % zioVersion
)
)
.jvmSettings(dottySettings)
.jsSettings(scalaJSUseMainModuleInitializer := true)
.dependsOn(zioCli)

lazy val docs = project
Expand All @@ -99,12 +103,12 @@ lazy val docs = project
libraryDependencies ++= Seq("dev.zio" %% "zio" % zioVersion),
ScalaUnidoc / unidoc / unidocProjectFilter := inProjects(zioCli.jvm),
projectName := "ZIO CLI",
mainModuleName := (zioCliJVM / moduleName).value,
mainModuleName := (zioCli.jvm / moduleName).value,
projectStage := ProjectStage.Experimental,
docsPublishBranch := "master",
ScalaUnidoc / unidoc / unidocProjectFilter := inProjects(zioCliJVM)
ScalaUnidoc / unidoc / unidocProjectFilter := inProjects(zioCli.jvm)
)
.dependsOn(zioCliJVM)
.dependsOn(zioCli.jvm)
.enablePlugins(WebsitePlugin)

lazy val sbtZioCli = project
Expand All @@ -119,7 +123,7 @@ lazy val sbtZioCli = project
)
.enablePlugins(SbtPlugin)

lazy val testkit = crossProject(JSPlatform, JVMPlatform)
lazy val testkit = crossProject(JSPlatform, JVMPlatform, NativePlatform)
.in(file("zio-cli-testkit"))
.settings(stdSettings("zio-cli-testkit"))
.settings(buildInfoSettings("zio.cli.testkit"))
Expand All @@ -132,12 +136,14 @@ lazy val testkit = crossProject(JSPlatform, JVMPlatform)
"dev.zio" %% "zio-test-magnolia" % zioVersion
)
)
.nativeSettings(Test / fork := false)
.nativeSettings(
libraryDependencies += "io.github.cquiroz" %%% "scala-java-time" % "2.5.0" % Test
)
.jsSettings(
libraryDependencies += "io.github.cquiroz" %%% "scala-java-time" % "2.5.0" % Test
)
.jvmSettings(dottySettings)
.jsSettings(scalaJSUseMainModuleInitializer := true)
.dependsOn(zioCli)

lazy val testkitJVM = testkit.jvm
.settings(dottySettings)

lazy val testkitJS = testkit.js
.settings(scalaJSUseMainModuleInitializer := true)

Global / onChangedBuildSource := ReloadOnSourceChanges
32 changes: 0 additions & 32 deletions project/BuildHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -212,38 +212,6 @@ object BuildHelper {
unusedCompileDependenciesFilter -= moduleFilter("org.scala-js", "scalajs-library")
)

def macroExpansionSettings = Seq(
scalacOptions ++= {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 13)) => Seq("-Ymacro-annotations")
case _ => Seq.empty
}
},
libraryDependencies ++= {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, x)) if x <= 12 =>
Seq(compilerPlugin(("org.scalamacros" % "paradise" % "2.1.1").cross(CrossVersion.full)))
case _ => Seq.empty
}
}
)

def macroDefinitionSettings = Seq(
scalacOptions += "-language:experimental.macros",
libraryDependencies ++= {
if (scalaVersion.value == Scala3) Seq()
else
Seq(
"org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided",
"org.scala-lang" % "scala-compiler" % scalaVersion.value % "provided"
)
}
)

def testJsSettings = Seq(
libraryDependencies += "io.github.cquiroz" %%% "scala-java-time" % "2.0.0-RC5" % Test
)

implicit class ModuleHelper(p: Project) {
def module: Project = p.in(file(p.id)).settings(stdSettings(p.id))
}
Expand Down
32 changes: 17 additions & 15 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.13")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.11.0")
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0")
addSbtPlugin("com.github.sbt" % "sbt-unidoc" % "0.5.0")
addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.11")
addSbtPlugin("com.github.cb372" % "sbt-explicit-dependencies" % "0.2.16")
addSbtPlugin("com.thoughtworks.sbt-api-mappings" % "sbt-api-mappings" % "3.0.0")
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.3.2")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.14.0")
addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.3.2")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.9")
addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.6")
addSbtPlugin("org.scalameta" % "sbt-native-image" % "0.3.2")
addSbtPlugin("dev.zio" % "zio-sbt-website" % "0.3.6")
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.13")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.11.0")
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0")
addSbtPlugin("com.github.sbt" % "sbt-unidoc" % "0.5.0")
addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.11")
addSbtPlugin("com.github.cb372" % "sbt-explicit-dependencies" % "0.2.16")
addSbtPlugin("com.thoughtworks.sbt-api-mappings" % "sbt-api-mappings" % "3.0.0")
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.3.2")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.14.0")
addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.3.2")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.16")
addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.3.2")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.9")
addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.6")
addSbtPlugin("org.scalameta" % "sbt-native-image" % "0.3.2")
addSbtPlugin("dev.zio" % "zio-sbt-website" % "0.3.6")

resolvers += Resolver.sonatypeRepo("public")
6 changes: 6 additions & 0 deletions zio-cli/js/src/main/scala/zio/cli/ArgsPlatformSpecific.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package zio.cli

/**
* A `Args` represents arguments that can be passed to a command-line application.
*/
private[cli] trait ArgsPlatformSpecific {}
25 changes: 25 additions & 0 deletions zio-cli/js/src/main/scala/zio/cli/CompgenPlatformSpecific.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package zio.cli.completion

import zio._
import java.io.File
import scala.annotation.nowarn

/**
* `Compgen` simplifies the process of calling Bash's built-in `compgen` command.
*/

private[cli] trait CompgenPlatformSpecific {
def live: Compgen = create(None)
def test(workingDirectory: File): Compgen = create(Some(workingDirectory))

@nowarn
private def create(workingDirectory: Option[File]): Compgen = new Compgen {

type CommandError = Nothing

def completeFileNames(word: String): ZIO[Any, CommandError, List[String]] = ZIO.succeed(Nil)

def completeDirectoryNames(word: String): ZIO[Any, CommandError, List[String]] = ZIO.succeed(Nil)

}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
package zio
package cli

private[cli] trait OptionsPlatformSpecific { self: Options.type => }
private[cli] trait OptionsPlatformSpecific extends PathPlatformSpecific { self: Options.type =>

/**
* Creates a parameter expecting path to the file.
*/
def file(name: String, exists: Exists = Exists.Either): Options[JPath] =
Single(name, Vector.empty, PrimType.Path(PathType.File, exists))
}
13 changes: 13 additions & 0 deletions zio-cli/js/src/main/scala/zio/cli/PathPlatformSpecific.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package zio.cli

private[cli] trait PathPlatformSpecific {

type JPath = String

}

private[cli] object PathPlatformSpecific {

type JPath = String

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package zio.cli.files

import zio.{IO, UIO, ZIO}
import zio.cli.PathPlatformSpecific

private[cli] trait FileSystemPlatformSpecific extends PathPlatformSpecific {

val live: FileSystem = new FileSystem {

override def parsePath(path: String): IO[String, JPath] =
ZIO.fail("FileSystem is not available in ScalaJS")

override def exists(path: JPath): UIO[Boolean] =
ZIO.succeed(false)

override def isDirectory(path: JPath): UIO[Boolean] =
ZIO.succeed(false)

override def isRegularFile(path: JPath): UIO[Boolean] =
ZIO.succeed(false)
}

}
87 changes: 87 additions & 0 deletions zio-cli/jvm/src/main/scala/zio/cli/ArgsPlatformSpecific.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package zio.cli

import java.nio.file.{Path => JPath}

/**
* A `Args` represents arguments that can be passed to a command-line application.
*/
private[cli] trait ArgsPlatformSpecific {

import zio.cli.Args._

/**
* Creates a file argument with a custom argument name
*
* @param name
* Argument name
* @param exists
* Yes if path is expected to exists, No otherwise or Either is both are acceptable.
* @return
* File argument
*/
def file(name: String, exists: Exists = Exists.Either): Args[JPath] =
Single(Some(name), PrimType.Path(PathType.File, exists))

/**
* Creates a file argument with 'file' as argument name
*
* @param exists
* Yes if path is expected to exists, No otherwise or Either is both are acceptable.
* @return
* File argument
*/
def file(exists: Exists): Args[JPath] =
Single(None, PrimType.Path(PathType.File, exists))

/**
* Creates a file argument with 'file' as argument name, and exists being 'Either'
*/
val file: Args[JPath] = file(Exists.Either)

/**
* Creates a directory argument with a custom argument name
*
* @param name
* Argument name
* @param exists
* Yes if path is expected to exists, No otherwise or Either is both are acceptable.
* @return
* Directory argument
*/
def directory(name: String, exists: Exists = Exists.Either): Args[JPath] =
Single(Some(name), PrimType.Path(PathType.Directory, exists))

/**
* Creates a directory argument with 'directory' as argument name
*
* @param exists
* Yes if path is expected to exists, No otherwise or Either is both are acceptable.
* @return
* Directory argument
*/
def directory(exists: Exists): Args[JPath] =
Single(None, PrimType.Path(PathType.Directory, exists))

/**
* Creates a directory argument with 'directory' as argument name, and exists being 'Either'
*/
val directory: Args[JPath] = directory(Exists.Either)

/**
* Creates a path argument with a custom argument name
*
* @param name
* Argument name
* @return
* Path argument
*/
def path(name: String): Args[JPath] =
Single(Some(name), PrimType.Path(PathType.Either, Exists.Either))

/**
* Creates a path argument with 'path' as argument name
*/
val path: Args[JPath] =
Single(None, PrimType.Path(PathType.Either, Exists.Either))

}
Loading

0 comments on commit 8b82983

Please sign in to comment.