Skip to content

Commit 6322c18

Browse files
committed
cross compile and flags
1 parent 166d6b1 commit 6322c18

File tree

5 files changed

+223
-19
lines changed

5 files changed

+223
-19
lines changed

build.sbt

Lines changed: 95 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,86 @@ val jacksonVersion = "2.11.3"
88
val mockitoScalaVersion = "1.16.0"
99
val junitVersion = "4.13.1"
1010

11+
scalaVersion := scala213
12+
13+
// Source: https://nathankleyn.com/2019/05/13/recommended-scalac-flags-for-2-13/
14+
lazy val scalacOptions213 = Seq(
15+
"-deprecation", // Emit warning and location for usages of deprecated APIs.
16+
"-explaintypes", // Explain type errors in more detail.
17+
"-feature", // Emit warning and location for usages of features that should be imported explicitly.
18+
"-language:existentials", // Existential types (besides wildcard types) can be written and inferred
19+
"-language:experimental.macros", // Allow macro definition (besides implementation and application)
20+
"-language:higherKinds", // Allow higher-kinded types
21+
"-language:implicitConversions", // Allow definition of implicit functions called views
22+
"-unchecked", // Enable additional warnings where generated code depends on assumptions.
23+
"-Xcheckinit", // Wrap field accessors to throw an exception on uninitialized access.
24+
"-Xfatal-warnings", // Fail the compilation if there are any warnings.
25+
"-Xlint:adapted-args", // Warn if an argument list is modified to match the receiver.
26+
"-Xlint:constant", // Evaluation of a constant arithmetic expression results in an error.
27+
"-Xlint:delayedinit-select", // Selecting member of DelayedInit.
28+
"-Xlint:doc-detached", // A Scaladoc comment appears to be detached from its element.
29+
"-Xlint:inaccessible", // Warn about inaccessible types in method signatures.
30+
"-Xlint:infer-any", // Warn when a type argument is inferred to be `Any`.
31+
"-Xlint:missing-interpolator", // A string literal appears to be missing an interpolator id.
32+
// "-Xlint:nullary-override", // Warn when non-nullary `def f()' overrides nullary `def f'.
33+
"-Xlint:nullary-unit", // Warn when nullary methods return Unit.
34+
"-Xlint:option-implicit", // Option.apply used implicit view.
35+
"-Xlint:package-object-classes", // Class or object defined in package object.
36+
"-Xlint:poly-implicit-overload", // Parameterized overloaded implicit methods are not visible as view bounds.
37+
"-Xlint:private-shadow", // A private field (or class parameter) shadows a superclass field.
38+
"-Xlint:stars-align", // Pattern sequence wildcard must align with sequence component.
39+
"-Xlint:type-parameter-shadow", // A local type parameter shadows a type already in scope.
40+
"-Ywarn-dead-code", // Warn when dead code is identified.
41+
"-Ywarn-extra-implicit", // Warn when more than one implicit parameter section is defined.
42+
"-Ywarn-numeric-widen", // Warn when numerics are widened.
43+
"-Ywarn-unused:implicits", // Warn if an implicit parameter is unused.
44+
"-Ywarn-unused:imports", // Warn if an import selector is not referenced.
45+
"-Ywarn-unused:locals", // Warn if a local definition is unused.
46+
"-Ywarn-unused:params", // Warn if a value parameter is unused.
47+
"-Ywarn-unused:patvars", // Warn if a variable bound in a pattern is unused.
48+
"-Ywarn-unused:privates", // Warn if a private member is unused.
49+
"-Ywarn-value-discard", // Warn when non-Unit expression results are unused.
50+
"-Ybackend-parallelism", "8", // Enable paralellisation — change to desired number!
51+
"-Ycache-plugin-class-loader:last-modified", // Enables caching of classloaders for compiler plugins
52+
"-Ycache-macro-class-loader:last-modified", // and macro definitions. This can lead to performance improvements.
53+
)
54+
55+
val scalacOptions212 = Seq(
56+
"-deprecation", // Emit warning and location for usages of deprecated APIs.
57+
"-encoding", "utf-8", // Specify character encoding used by source files.
58+
"-feature", // Emit warning and location for usages of features that should be imported explicitly.
59+
"-language:implicitConversions", // Allow definition of implicit functions called views
60+
)
61+
62+
val scalacOptions211 = Seq(
63+
"-deprecation",
64+
"-encoding", "UTF-8", // yes, this is 2 args
65+
"-feature",
66+
"-language:implicitConversions"
67+
)
68+
1169
lazy val commonSettings = Seq(
1270
organization := "io.cucumber",
13-
scalaVersion := scala213,
14-
libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test
71+
libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test,
72+
scalacOptions += "-target:jvm-1.8",
73+
scalacOptions ++= {
74+
CrossVersion.partialVersion(scalaVersion.value) match {
75+
case Some((2, 11)) => scalacOptions211
76+
case Some((2, 12)) => scalacOptions212
77+
case Some((2, 13)) => scalacOptions213
78+
case _ => Seq()
79+
}
80+
},
1581
)
1682

17-
lazy val root = project
18-
.in(file("."))
83+
lazy val root = (project in file("."))
1984
.settings(commonSettings)
2085
.aggregate(
21-
cucumberScala,
22-
examples
86+
cucumberScala.projectRefs ++
87+
examples.projectRefs: _*
2388
)
2489

25-
lazy val cucumberScala = project
26-
.in(file("cucumber-scala"))
90+
lazy val cucumberScala = (projectMatrix in file("cucumber-scala"))
2791
.settings(commonSettings)
2892
.settings(
2993
name := "cucumber-scala",
@@ -37,11 +101,25 @@ lazy val cucumberScala = project
37101
"junit" % "junit" % junitVersion % Test,
38102
"io.cucumber" % "cucumber-junit" % cucumberVersion % Test,
39103
"org.mockito" %% "mockito-scala" % mockitoScalaVersion % Test
40-
)
104+
),
105+
libraryDependencies ++= {
106+
CrossVersion.partialVersion(scalaVersion.value) match {
107+
case Some((2, n)) if n <= 12 => List("org.scala-lang.modules" %% "scala-collection-compat" % "2.2.0")
108+
case _ => Nil
109+
}
110+
},
111+
unmanagedSourceDirectories in Compile ++= {
112+
val sourceDir = (sourceDirectory in Compile).value
113+
CrossVersion.partialVersion(scalaVersion.value) match {
114+
case Some((2, n)) if n <= 11 => Seq(sourceDir / "scala-2.11")
115+
case _ => Seq()
116+
}
117+
},
118+
scalacOptions ++= Seq()
41119
)
120+
.jvmPlatform(scalaVersions = Seq(scala213, scala212, scala211))
42121

43-
lazy val examples = project
44-
.in(file("examples"))
122+
lazy val examples = (projectMatrix in file("examples"))
45123
.settings(commonSettings)
46124
.settings(
47125
name := "scala-examples",
@@ -51,15 +129,16 @@ lazy val examples = project
51129
)
52130
)
53131
.dependsOn(cucumberScala % Test)
54-
55-
// TODO cross build
132+
.jvmPlatform(scalaVersions = Seq(scala213, scala212))
56133

57134
// TODO code generation for i18n
58135

59-
// TODO scla compiler flags
60-
61136
// TODO OSS publish settings
62137
// But not the examples
63138

64139
// TODO src jar ?
65-
// TODO javadoc jar
140+
// TODO javadoc jar
141+
142+
// TODO Travis
143+
144+
// TODO Makefile
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package io.cucumber
2+
3+
import java.lang.reflect.Type
4+
import java.util.function.Supplier
5+
import java.util.{List => JavaList, Map => JavaMap}
6+
7+
import io.cucumber.cucumberexpressions.{CaptureGroupTransformer, ParameterByTypeTransformer}
8+
import io.cucumber.datatable._
9+
import io.cucumber.docstring.DocStringType.Transformer
10+
11+
/**
12+
* Only for Scala 2.11 which does not support some Single Abstract Method
13+
*/
14+
package object scala {
15+
16+
import language.implicitConversions
17+
18+
// Cucumber Scala Types
19+
20+
implicit def function1AsDataTableEntryDefinitionBody[T](f: (Map[String, String]) => T): DataTableEntryDefinitionBody[T] = new DataTableEntryDefinitionBody[T] {
21+
override def transform(entry: Map[String, String]): T = f.apply(entry)
22+
}
23+
24+
implicit def function1AsDataTableOptionalEntryDefinitionBody[T](f: (Map[String, Option[String]]) => T): DataTableOptionalEntryDefinitionBody[T] = new DataTableOptionalEntryDefinitionBody[T] {
25+
override def transform(entry: Map[String, Option[String]]): T = f.apply(entry)
26+
}
27+
28+
implicit def function1AsDataTableRowDefinitionBody[T](f: (Seq[String]) => T): DataTableRowDefinitionBody[T] = new DataTableRowDefinitionBody[T] {
29+
override def transform(row: Seq[String]): T = f.apply(row)
30+
}
31+
32+
implicit def function1AsDataTableOptionalRowDefinitionBody[T](f: (Seq[Option[String]]) => T): DataTableOptionalRowDefinitionBody[T] = new DataTableOptionalRowDefinitionBody[T] {
33+
override def transform(row: Seq[Option[String]]): T = f.apply(row)
34+
}
35+
36+
implicit def function1AsDataTableCellDefinitionBody[T](f: (String) => T): DataTableCellDefinitionBody[T] = new DataTableCellDefinitionBody[T] {
37+
override def transform(cell: String): T = f.apply(cell)
38+
}
39+
40+
implicit def function1AsDataTableOptionalCellDefinitionBody[T](f: (Option[String]) => T): DataTableOptionalCellDefinitionBody[T] = new DataTableOptionalCellDefinitionBody[T] {
41+
override def transform(cell: Option[String]): T = f.apply(cell)
42+
}
43+
44+
implicit def function1AsDataTableDefinitionBody[T](f: (DataTable) => T): DataTableDefinitionBody[T] = new DataTableDefinitionBody[T] {
45+
override def transform(dataTable: DataTable): T = f.apply(dataTable)
46+
}
47+
48+
// Cucumber Core Types
49+
50+
implicit def function1AsTableCellTransformer[T](f: String => T): TableCellTransformer[T] = {
51+
new TableCellTransformer[T] {
52+
override def transform(cell: String): T = f.apply(cell)
53+
}
54+
}
55+
56+
implicit def function1AsTableTransformer[T](f: DataTable => T): TableTransformer[T] = {
57+
new TableTransformer[T] {
58+
override def transform(table: DataTable): T = f.apply(table)
59+
}
60+
}
61+
62+
implicit def function1AsTableEntryTransformer[T](f: JavaMap[String, String] => T): TableEntryTransformer[T] = {
63+
new TableEntryTransformer[T] {
64+
override def transform(entry: JavaMap[String, String]): T = f.apply(entry)
65+
}
66+
}
67+
68+
implicit def function1AsTableRowTransformer[T](f: JavaList[String] => T): TableRowTransformer[T] = {
69+
new TableRowTransformer[T] {
70+
override def transform(row: JavaList[String]): T = f.apply(row)
71+
}
72+
}
73+
74+
implicit def function1AsTableCellByTypeTransformer(f: (String, Type) => AnyRef): TableCellByTypeTransformer = {
75+
new TableCellByTypeTransformer {
76+
override def transform(fromValue: String, toTypeValue: Type): AnyRef = {
77+
f.apply(fromValue, toTypeValue)
78+
}
79+
}
80+
}
81+
82+
implicit def function1AsTableEntryByTypeTransformer(f: (JavaMap[String, String], Type, TableCellByTypeTransformer) => AnyRef): TableEntryByTypeTransformer = {
83+
new TableEntryByTypeTransformer {
84+
override def transform(fromValue: JavaMap[String, String], toValueType: Type, tableCellByTypeTransformer: TableCellByTypeTransformer): AnyRef = {
85+
f.apply(fromValue, toValueType, tableCellByTypeTransformer)
86+
}
87+
}
88+
}
89+
90+
implicit def function1AsParameterByTypeTransformer(f: (String, Type) => AnyRef): ParameterByTypeTransformer = {
91+
new ParameterByTypeTransformer {
92+
override def transform(fromValue: String, toValue: Type): AnyRef = {
93+
f.apply(fromValue, toValue)
94+
}
95+
}
96+
}
97+
98+
implicit def function1AsTransformer[T](f: (String) => T): Transformer[T] = {
99+
new Transformer[T] {
100+
override def transform(s: String): T = {
101+
f.apply(s)
102+
}
103+
}
104+
}
105+
106+
implicit def function1AsCaptureGroupTransformer[T](f: (Array[String]) => T): CaptureGroupTransformer[T] = {
107+
new CaptureGroupTransformer[T] {
108+
override def transform(parameterContent: Array[String]): T = {
109+
f.apply(parameterContent)
110+
}
111+
}
112+
}
113+
114+
// For tests
115+
116+
implicit def function1AsSupplier[T](f: () => T): Supplier[T] = {
117+
new Supplier[T] {
118+
override def get(): T = f.apply()
119+
}
120+
}
121+
122+
}

examples/src/main/scala/cucumber/examples/scalacalculator/RpnCalculator.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,17 @@ class RpnCalculator {
1919
private def op(f: (Double, Double) => Double) =
2020
stack += f(stack.dequeue(), stack.dequeue())
2121

22-
def push(arg: Arg) {
22+
def push(arg: Arg): Unit = {
2323
arg match {
2424
case Op("+") => op(_ + _)
2525
case Op("-") => op(_ - _)
2626
case Op("*") => op(_ * _)
2727
case Op("/") => op(_ / _)
2828
case Val(value) => stack += value
29+
case _ => ()
2930
}
31+
()
3032
}
3133

32-
def value = stack.head
34+
def value: Double = stack.head
3335
}

examples/src/test/scala/cucumber/examples/scalacalculator/RpnCalculatorStepDefinitions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ class RpnCalculatorStepDefinitions extends ScalaDsl with EN {
1818
}
1919

2020
Before("not @foo"){ scenario : Scenario =>
21-
println("Runs before scenarios *not* tagged with @foo")
21+
println(s"Runs before scenarios *not* tagged with @foo (${scenario.getId})")
2222
}
2323
}

project/plugins.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
addSbtPlugin("com.eed3si9n" % "sbt-projectmatrix" % "0.6.0")

0 commit comments

Comments
 (0)