diff --git a/build.sbt b/build.sbt index 33a410a47..295ce27fe 100644 --- a/build.sbt +++ b/build.sbt @@ -64,11 +64,15 @@ lazy val lm = (project in file("librarymanagement")) .settings( commonSettings, name := "librarymanagement", - libraryDependencies ++= Seq( - ivy, jsch, scalaReflect.value, launcherInterface, gigahorseOkhttp, okhttpUrlconnection, - sjsonnewScalaJson.value % Optional, - scalaTest - ), + libraryDependencies ++= Seq(ivy, + jsch, + scalaReflect.value, + scalaCompiler.value, + launcherInterface, + gigahorseOkhttp, + okhttpUrlconnection, + sjsonnewScalaJson.value % Optional, + scalaTest), libraryDependencies ++= scalaXml.value, resourceGenerators in Compile += Def.task( Util.generateVersionFile( diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala index d1848b1c0..42c20e392 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -9,7 +9,7 @@ final class Artifact private ( val `type`: String, val extension: String, val classifier: Option[String], - val configurations: Vector[sbt.librarymanagement.Configuration], + val configurations: Vector[String], val url: Option[java.net.URL], val extraAttributes: Map[String, String], val checksum: Option[sbt.librarymanagement.Checksum]) extends sbt.librarymanagement.ArtifactExtra with Serializable { @@ -26,7 +26,7 @@ final class Artifact private ( override def toString: String = { "Artifact(" + name + ", " + `type` + ", " + extension + ", " + classifier + ", " + configurations + ", " + url + ", " + extraAttributes + ", " + checksum + ")" } - protected[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum): Artifact = { + protected[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[String] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum): Artifact = { new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) } def withName(name: String): Artifact = { @@ -41,7 +41,7 @@ final class Artifact private ( def withClassifier(classifier: Option[String]): Artifact = { copy(classifier = classifier) } - def withConfigurations(configurations: Vector[sbt.librarymanagement.Configuration]): Artifact = { + def withConfigurations(configurations: Vector[String]): Artifact = { copy(configurations = configurations) } def withUrl(url: Option[java.net.URL]): Artifact = { @@ -57,5 +57,5 @@ final class Artifact private ( object Artifact extends sbt.librarymanagement.ArtifactFunctions { def apply(name: String): Artifact = new Artifact(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None) - def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.Configuration], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[String], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) } diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala index 08bd9cadb..514cd83fc 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ArtifactFormats { self: sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol => +trait ArtifactFormats { self: sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = new JsonFormat[sbt.librarymanagement.Artifact] { override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Artifact = { jsOpt match { @@ -15,7 +15,7 @@ implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = n val `type` = unbuilder.readField[String]("type") val extension = unbuilder.readField[String]("extension") val classifier = unbuilder.readField[Option[String]]("classifier") - val configurations = unbuilder.readField[Vector[sbt.librarymanagement.Configuration]]("configurations") + val configurations = unbuilder.readField[Vector[String]]("configurations") val url = unbuilder.readField[Option[java.net.URL]]("url") val extraAttributes = unbuilder.readField[Map[String, String]]("extraAttributes") val checksum = unbuilder.readField[Option[sbt.librarymanagement.Checksum]]("checksum") diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala index 9745a4d1a..8d1cf1a46 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala @@ -5,7 +5,6 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement trait LibraryManagementCodec extends sjsonnew.BasicJsonProtocol - with sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.ChecksumFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ArtifactTypeFilterFormats @@ -24,6 +23,7 @@ trait LibraryManagementCodec extends sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ConflictManagerFormats with sbt.librarymanagement.DeveloperFormats with sbt.librarymanagement.FileConfigurationFormats + with sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.IvyScalaFormats with sbt.librarymanagement.ChainedResolverFormats with sbt.librarymanagement.MavenRepoFormats diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 71b18d691..7ceabeb73 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -13,7 +13,7 @@ { "name": "type", "type": "String", "default": "Artifact.DefaultType", "since": "0.0.1" }, { "name": "extension", "type": "String", "default": "Artifact.DefaultExtension", "since": "0.0.1" }, { "name": "classifier", "type": "Option[String]", "default": "None", "since": "0.0.1" }, - { "name": "configurations", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "url", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, { "name": "checksum", "type": "Option[sbt.librarymanagement.Checksum]", "default": "None", "since": "0.0.1" } @@ -61,22 +61,6 @@ ], "toString": "s\"$caller\"" }, - { - "name": "Configuration", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "doc": "Represents an Ivy configuration.", - "parents": "sbt.librarymanagement.ConfigurationExtra", - "fields": [ - { "name": "name", "type": "String" }, - { "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "isPublic", "type": "boolean", "default": "true", "since": "0.0.1" }, - { "name": "extendsConfigs", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "transitive", "type": "boolean", "default": "true", "since": "0.0.1" } - ], - "toString": "name" - }, { "name": "ConfigurationReport", "namespace": "sbt.librarymanagement", diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index e7fcdd204..121e8d929 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -238,9 +238,9 @@ final class IvySbt(val configuration: IvyConfiguration) { self => import ic._ val moduleID = newConfiguredModuleID(module, moduleInfo, configurations) IvySbt.setConflictManager(moduleID, conflictManager, ivy.getSettings) - val defaultConf = defaultConfiguration getOrElse Configurations.config( - ModuleDescriptor.DEFAULT_CONFIGURATION - ) + val defaultConf = defaultConfiguration getOrElse Configuration( + "Default", + ModuleDescriptor.DEFAULT_CONFIGURATION) log.debug( "Using inline dependencies specified in Scala" + (if (ivyXML.isEmpty) "." else " and XML.") @@ -859,7 +859,7 @@ private[sbt] object IvySbt { ): Unit = { val confs = if (artifact.configurations.isEmpty) allConfigurations - else artifact.configurations.map(_.name) + else artifact.configurations confs foreach addConfiguration } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index d76f7556d..85eb001c2 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -217,7 +217,7 @@ object IvyRetrieve { getType, getExt, Option(getExtraAttribute("classifier")), - getConfigurations.toVector map Configurations.config, + getConfigurations.toVector, Option(getUrl) ) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala index d3f7a6e7e..92b9fdf1c 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala @@ -11,7 +11,7 @@ abstract class ArtifactExtra { def `type`: String def extension: String def classifier: Option[String] - def configurations: Vector[Configuration] + def configurations: Vector[String] def url: Option[URL] def extraAttributes: Map[String, String] def checksum: Option[Checksum] @@ -21,7 +21,7 @@ abstract class ArtifactExtra { `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, - configurations: Vector[Configuration] = configurations, + configurations: Vector[String] = configurations, url: Option[URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[Checksum] = checksum @@ -58,7 +58,7 @@ abstract class ArtifactFunctions { `type`: String, extension: String, classifier: Option[String], - configurations: Vector[Configuration], + configurations: Vector[String], url: Option[URL] ): Artifact = Artifact(name, `type`, extension, classifier, configurations, url, empty, None) @@ -67,7 +67,7 @@ abstract class ArtifactFunctions { def sources(name: String) = classified(name, SourceClassifier) def javadoc(name: String) = classified(name, DocClassifier) - def pom(name: String) = Artifact(name, PomType, PomType, None, Vector(Pom), None) + def pom(name: String) = Artifact(name, PomType, PomType, None, Vector(Pom.name), None) // Possible ivy artifact types such that sbt will treat those artifacts at sources / docs val DefaultSourceTypes = Set("src", "source", "sources") diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala new file mode 100644 index 000000000..7527f085a --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -0,0 +1,77 @@ +package sbt +package librarymanagement + +/** Represents an Ivy configuration. */ +final class Configuration private[sbt] ( + val id: String, + val name: String, + val description: String, + val isPublic: Boolean, + val extendsConfigs: Vector[sbt.librarymanagement.Configuration], + val transitive: Boolean) + extends sbt.librarymanagement.ConfigurationExtra + with Serializable { + + require(name != null, "name cannot be null") + require(name.size > 0, "name cannot be empty") + require(id != null, "id cannot be null") + require(id.size > 0, "id cannot be empty") + require(id.head.isUpper, s"id must be capitalized: $id") + + private def this(id: String, name: String) = + this(id, name, "", true, Vector.empty, true) + + override def equals(o: Any): Boolean = o match { + case x: Configuration => + (this.id == x.id) && + (this.name == x.name) && + (this.description == x.description) && + (this.isPublic == x.isPublic) && + (this.extendsConfigs == x.extendsConfigs) && + (this.transitive == x.transitive) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (17 + id.##) + name.##) + description.##) + isPublic.##) + extendsConfigs.##) + transitive.##) + } + override def toString: String = { + name + } + protected[this] def copy(id: String = id, + name: String = name, + description: String = description, + isPublic: Boolean = isPublic, + extendsConfigs: Vector[sbt.librarymanagement.Configuration] = + extendsConfigs, + transitive: Boolean = transitive): Configuration = { + new Configuration(id, name, description, isPublic, extendsConfigs, transitive) + } + + def withDescription(description: String): Configuration = { + copy(description = description) + } + + def withIsPublic(isPublic: Boolean): Configuration = { + copy(isPublic = isPublic) + } + + def withExtendsConfigs( + extendsConfigs: Vector[sbt.librarymanagement.Configuration]): Configuration = { + copy(extendsConfigs = extendsConfigs) + } + + def withTransitive(transitive: Boolean): Configuration = { + copy(transitive = transitive) + } +} +object Configuration { + private[sbt] def apply(id: String, name: String): Configuration = + new Configuration(id, name, "", true, Vector.empty, true) + private[sbt] def apply(id: String, + name: String, + description: String, + isPublic: Boolean, + extendsConfigs: Vector[sbt.librarymanagement.Configuration], + transitive: Boolean): Configuration = + new Configuration(id, name, description, isPublic, extendsConfigs, transitive) +} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index 9795ff70a..4d019ffff 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -3,8 +3,11 @@ */ package sbt.librarymanagement +import scala.annotation.tailrec +import scala.language.experimental.macros + object Configurations { - def config(name: String) = Configuration(name) + def config(name: String) = macro ConfigurationMacro.configMacroImpl def default: Seq[Configuration] = defaultMavenConfigurations def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional) @@ -25,24 +28,26 @@ object Configurations { case _ => c } - def internal(base: Configuration, ext: Configuration*) = - config(base.name + "-internal").extend(ext: _*).hide - def fullInternal(base: Configuration): Configuration = internal(base, base, Optional, Provided) - def optionalInternal(base: Configuration): Configuration = internal(base, base, Optional) + private[sbt] def internal(base: Configuration, ext: Configuration*) = + Configuration(base.id + "Internal", base.name + "-internal").extend(ext: _*).hide + private[sbt] def fullInternal(base: Configuration): Configuration = + internal(base, base, Optional, Provided) + private[sbt] def optionalInternal(base: Configuration): Configuration = + internal(base, base, Optional) - lazy val Default = config("default") - lazy val Compile = config("compile") - lazy val IntegrationTest = config("it") extend (Runtime) - lazy val Provided = config("provided") - lazy val Runtime = config("runtime") extend (Compile) - lazy val Test = config("test") extend (Runtime) - lazy val System = config("system") - lazy val Optional = config("optional") - lazy val Pom = config("pom") + lazy val Default = Configuration("Default", "default") + lazy val Compile = Configuration("Compile", "compile") + lazy val IntegrationTest = Configuration("IntegrationTest", "it") extend (Runtime) + lazy val Provided = Configuration("Provided", "provided") + lazy val Runtime = Configuration("Runtime", "runtime") extend (Compile) + lazy val Test = Configuration("Test", "test") extend (Runtime) + lazy val System = Configuration("System", "system") + lazy val Optional = Configuration("Optional", "optional") + lazy val Pom = Configuration("Pom", "pom") - lazy val ScalaTool = config("scala-tool").hide - lazy val CompilerPlugin = config("plugin").hide - lazy val Component = config("component").hide + lazy val ScalaTool = Configuration("ScalaTool", "scala-tool").hide + lazy val CompilerPlugin = Configuration("CompilerPlugin", "plugin").hide + lazy val Component = Configuration("Component", "component").hide private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true) private[sbt] val DefaultIvyConfiguration = defaultConfiguration(false) @@ -70,6 +75,7 @@ object Configurations { } abstract class ConfigurationExtra { + def id: String def name: String def description: String def isPublic: Boolean @@ -80,10 +86,51 @@ abstract class ConfigurationExtra { require(description != null) def describedAs(newDescription: String) = - Configuration(name, newDescription, isPublic, extendsConfigs, transitive) + Configuration(id, name, newDescription, isPublic, extendsConfigs, transitive) def extend(configs: Configuration*) = - Configuration(name, description, isPublic, configs.toVector ++ extendsConfigs, transitive) + Configuration(id, name, description, isPublic, configs.toVector ++ extendsConfigs, transitive) def notTransitive = intransitive - def intransitive = Configuration(name, description, isPublic, extendsConfigs, false) - def hide = Configuration(name, description, false, extendsConfigs, transitive) + def intransitive = Configuration(id, name, description, isPublic, extendsConfigs, false) + def hide = Configuration(id, name, description, false, extendsConfigs, transitive) +} + +private[sbt] object ConfigurationMacro { + import scala.reflect.macros._ + + def configMacroImpl(c: Context)(name: c.Expr[String]): c.Expr[Configuration] = { + import c.universe._ + val enclosingValName = definingValName( + c, + methodName => + s"""$methodName must be directly assigned to a val, such as `val x = $methodName`.""") + val id = c.Expr[String](Literal(Constant(enclosingValName))) + reify { Configuration(id.splice, name.splice) } + } + + def definingValName(c: blackbox.Context, invalidEnclosingTree: String => String): String = { + import c.universe.{ Apply => ApplyTree, _ } + val methodName = c.macroApplication.symbol.name + def processName(n: Name): String = + n.decodedName.toString.trim // trim is not strictly correct, but macros don't expose the API necessary + @tailrec def enclosingVal(trees: List[c.Tree]): String = { + trees match { + case vd @ ValDef(_, name, _, _) :: ts => processName(name) + case (_: ApplyTree | _: Select | _: TypeApply) :: xs => enclosingVal(xs) + // lazy val x: X = has this form for some reason (only when the explicit type is present, though) + case Block(_, _) :: DefDef(mods, name, _, _, _, _) :: xs if mods.hasFlag(Flag.LAZY) => + processName(name) + case _ => + c.error(c.enclosingPosition, invalidEnclosingTree(methodName.decodedName.toString)) + "" + } + } + enclosingVal(enclosingTrees(c).toList) + } + + def enclosingTrees(c: blackbox.Context): Seq[c.Tree] = + c.asInstanceOf[reflect.macros.runtime.Context] + .callsiteTyper + .context + .enclosingContextChain + .map(_.tree.asInstanceOf[c.Tree]) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala new file mode 100644 index 000000000..30c09a453 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala @@ -0,0 +1,46 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ +package sbt +package librarymanagement + +import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } +trait ConfigurationFormats { + self: sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => + implicit lazy val ConfigurationFormat: JsonFormat[sbt.librarymanagement.Configuration] = + new JsonFormat[sbt.librarymanagement.Configuration] { + override def read[J](jsOpt: Option[J], + unbuilder: Unbuilder[J]): sbt.librarymanagement.Configuration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val id = unbuilder.readField[String]("id") + val name = unbuilder.readField[String]("name") + val description = unbuilder.readField[String]("description") + val isPublic = unbuilder.readField[Boolean]("isPublic") + val extendsConfigs = + unbuilder.readField[Vector[sbt.librarymanagement.Configuration]]("extendsConfigs") + val transitive = unbuilder.readField[Boolean]("transitive") + unbuilder.endObject() + new sbt.librarymanagement.Configuration(id, + name, + description, + isPublic, + extendsConfigs, + transitive) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Configuration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("id", obj.id) + builder.addField("name", obj.name) + builder.addField("description", obj.description) + builder.addField("isPublic", obj.isPublic) + builder.addField("extendsConfigs", obj.extendsConfigs) + builder.addField("transitive", obj.transitive) + builder.endObject() + } + } +} diff --git a/librarymanagement/src/test/scala/ConfigMacroSpec.scala b/librarymanagement/src/test/scala/ConfigMacroSpec.scala new file mode 100644 index 000000000..93810a96a --- /dev/null +++ b/librarymanagement/src/test/scala/ConfigMacroSpec.scala @@ -0,0 +1,61 @@ +package sbt.internal.librarymanagement + +import sbt.librarymanagement.Configuration +import sbt.librarymanagement.Configurations.config +import scala.util.control.NonFatal +import org.scalacheck._ +import Prop._ + +class ConfigDefs { + lazy val Kompile = config("kompile") + val X = config("x") + val Z = config("z").hide + val A: Configuration = config("a") + lazy val Aa: Configuration = config("aa") +} + +object ConfigMacroSpec extends Properties("ConfigMacroSpec") { + lazy val cd = new ConfigDefs + import cd._ + + def secure(f: => Prop): Prop = + try { + Prop.secure(f) + } catch { + case NonFatal(e) => + e.printStackTrace + throw e + } + + property("Explicit type on lazy val supported") = secure { + check(Aa, "Aa", "aa", true) + } + + property("Explicit type on val supported") = secure { + check(A, "A", "a", true) + } + + property("lazy vals supported") = secure { + check(Kompile, "Kompile", "kompile", true) + } + + property("plain vals supported") = secure { + check(X, "X", "x", true) + } + + property("Directory overridable") = secure { + check(Z, "Z", "z", false) + } + + def check(c: Configuration, id: String, name: String, isPublic: Boolean): Prop = { + s"Expected id: $id" |: + s"Expected name: $name" |: + s"Expected isPublic: $isPublic" |: + s"Actual id: ${c.id}" |: + s"Actual name: ${c.name}" |: + s"Actual isPublic: ${c.isPublic}" |: + (c.id == id) && + (c.name == name) && + (c.isPublic == isPublic) + } +} diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 73f3d42c3..1f8e6f5f2 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -43,6 +43,7 @@ object Dependencies { val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-a3314352b638afbf0dca19f127e8263ed6f898bd" val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } + val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5") val scalaTest = "org.scalatest" %% "scalatest" % "3.0.1" % Test val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value }