diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 1de20aaf3..360564cfb 100644 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -306,6 +306,7 @@ object Defaults extends BuildCommon { crossVersion :== Disabled(), buildDependencies := Classpaths.constructBuildDependencies.value, version :== "0.1.0-SNAPSHOT", + versionScheme :== None, classpathTypes :== Set("jar", "bundle", "maven-plugin", "test-jar") ++ CustomPomParser.JarPackagings, artifactClassifier :== None, checksums := Classpaths.bootChecksums(appConfiguration.value), @@ -2804,7 +2805,7 @@ object Classpaths { val report = (updateTask tag (Tags.Update, Tags.Network)).value val log = streams.value.log val ew = - EvictionWarning(ivyModule.value, (evictionWarningOptions in evicted).value, report) + EvictionWarning(ivyModule.value, (evicted / evictionWarningOptions).value, report) ew.lines foreach { log.warn(_) } ew.infoAllTheThings foreach { log.info(_) } ew @@ -2922,13 +2923,20 @@ object Classpaths { } private[sbt] def defaultProjectID: Initialize[ModuleID] = Def.setting { - val base = ModuleID(organization.value, moduleName.value, version.value) + val p0 = ModuleID(organization.value, moduleName.value, version.value) .cross(crossVersion in projectID value) .artifacts(artifacts.value: _*) - apiURL.value match { - case Some(u) => base.extra(SbtPomExtraProperties.POM_API_KEY -> u.toExternalForm) - case _ => base + val p1 = apiURL.value match { + case Some(u) => p0.extra(SbtPomExtraProperties.POM_API_KEY -> u.toExternalForm) + case _ => p0 } + val p2 = versionScheme.value match { + case Some(x) => + VersionSchemes.validateScheme(x) + p1.extra(SbtPomExtraProperties.VERSION_SCHEME_KEY -> x) + case _ => p1 + } + p2 } def pluginProjectID: Initialize[ModuleID] = Def.setting { diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index c6b713386..504b69a74 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -508,6 +508,7 @@ object Keys { val packagedArtifact = taskKey[(Artifact, File)]("Generates a packaged artifact, returning the Artifact and the produced File.").withRank(CTask) val checksums = settingKey[Seq[String]]("The list of checksums to generate and to verify for dependencies.").withRank(BSetting) val forceUpdatePeriod = settingKey[Option[FiniteDuration]]("Duration after which to force a full update to occur").withRank(CSetting) + val versionScheme = settingKey[Option[String]]("""Version scheme used for the subproject: Supported values are Some("early-semver"), Some("pvp"), and Some("semver-spec")""").withRank(BSetting) val classifiersModule = taskKey[GetClassifiersModule]("classifiers-module").withRank(CTask) val compatibilityWarningOptions = settingKey[CompatibilityWarningOptions]("Configures warnings around Maven incompatibility.").withRank(CSetting) diff --git a/main/src/main/scala/sbt/coursierint/CoursierInputsTasks.scala b/main/src/main/scala/sbt/coursierint/CoursierInputsTasks.scala index 42eb7d173..9059f36ef 100644 --- a/main/src/main/scala/sbt/coursierint/CoursierInputsTasks.scala +++ b/main/src/main/scala/sbt/coursierint/CoursierInputsTasks.scala @@ -28,6 +28,7 @@ import lmcoursier.definitions.{ } import lmcoursier.credentials.DirectCredentials import lmcoursier.{ FallbackDependency, FromSbt, Inputs } +import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties import sbt.librarymanagement.ivy.{ FileCredentials, Credentials, @@ -46,6 +47,7 @@ object CoursierInputsTasks { auOpt: Option[URL], description: String, homepage: Option[URL], + vsOpt: Option[String], log: Logger ): CProject = { @@ -60,12 +62,16 @@ object CoursierInputsTasks { ) val proj1 = auOpt match { case Some(au) => - val props = proj0.properties :+ ("info.apiURL" -> au.toString) - proj0.withProperties(props) + proj0.withProperties(proj0.properties :+ (SbtPomExtraProperties.POM_API_KEY -> au.toString)) case _ => proj0 } - proj1.withInfo( - proj1.info.withDescription(description).withHomePage(homepage.fold("")(_.toString)) + val proj2 = vsOpt match { + case Some(vs) => + proj1.withProperties(proj1.properties :+ (SbtPomExtraProperties.VERSION_SCHEME_KEY -> vs)) + case _ => proj1 + } + proj2.withInfo( + proj2.info.withDescription(description).withHomePage(homepage.fold("")(_.toString)) ) } @@ -80,6 +86,7 @@ object CoursierInputsTasks { apiURL.value, description.value, homepage.value, + versionScheme.value, streams.value.log ) } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index f6b238b17..2b5a340f9 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -13,7 +13,7 @@ object Dependencies { // sbt modules private val ioVersion = nightlyVersion.getOrElse("1.4.0-M6") private val lmVersion = - sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.4.0-M1") + sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.4.0-M2") val zincVersion = nightlyVersion.getOrElse("1.4.0-M8") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion diff --git a/sbt/src/sbt-test/dependency-management/evicted-semver-spec/build.sbt b/sbt/src/sbt-test/dependency-management/evicted-semver-spec/build.sbt new file mode 100644 index 000000000..d8824283f --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/evicted-semver-spec/build.sbt @@ -0,0 +1,62 @@ +// ThisBuild / useCoursier := false +ThisBuild / organization := "com.example" +ThisBuild / scalaVersion := "2.12.11" +ThisBuild / versionScheme := Some("semver-spec") + +def commonSettings: Seq[Def.Setting[_]] = + Seq( + ivyPaths := IvyPaths( + (ThisBuild / baseDirectory).value, + Some((LocalRootProject / target).value / "ivy-cache") + ), + csrCacheDirectory := (LocalRootProject / target).value / "cache", + fullResolvers := fullResolvers.value.filterNot(_.name == "inter-project"), + publishTo := Some(MavenCache("local-maven", (LocalRootProject / target).value / "local-maven")), + resolvers += MavenCache("local-maven", (LocalRootProject / target).value / "local-maven"), + ) + +lazy val root = (project in file(".")) + .settings(commonSettings) + +val `v1-0-0` = (project in file("v1.0.0")) + .settings(commonSettings) + .settings( + name := "semver-spec-test", + version := "1.0.0", + ) + +val `v1-1-0` = (project in file("v1.1.0")) + .settings(commonSettings) + .settings( + name := "semver-spec-test", + version := "1.1.0", + ) + +val middle = project + .settings(commonSettings) + .settings( + name := "middle", + version := "1.0.0", + libraryDependencies += "com.example" %% "semver-spec-test" % "1.0.0", + ) + +val use = project + .settings(commonSettings) + .settings( + name := "use", + libraryDependencies ++= Seq( + "com.example" %% "semver-spec-test" % "1.1.0", + "com.example" %% "middle" % "1.0.0", + ), + TaskKey[Unit]("check") := { + val report = updateFull.value + val log = streams.value.log + val extraAttributes = (report.allModules flatMap { _.extraAttributes}) collect { + case ("info.versionScheme", v) => v + } + log.info(s"extraAttributes = $extraAttributes") + assert(extraAttributes.nonEmpty, s"$extraAttributes is empty") + val ew = EvictionWarning(ivyModule.value, (evicted / evictionWarningOptions).value, report) + assert(ew.directEvictions.isEmpty, s"${ew.directEvictions} is not empty") + }, + ) diff --git a/sbt/src/sbt-test/dependency-management/evicted-semver-spec/test b/sbt/src/sbt-test/dependency-management/evicted-semver-spec/test new file mode 100644 index 000000000..eb5f0c784 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/evicted-semver-spec/test @@ -0,0 +1,5 @@ +> v1-0-0/publish +> v1-1-0/publish +> middle/publish + +> use/check diff --git a/sbt/src/sbt-test/dependency-management/evicted-semver-spec/v1.0.0/LibraryTest.scala b/sbt/src/sbt-test/dependency-management/evicted-semver-spec/v1.0.0/LibraryTest.scala new file mode 100644 index 000000000..fbfda9e74 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/evicted-semver-spec/v1.0.0/LibraryTest.scala @@ -0,0 +1,3 @@ +package example + +trait Foo {} diff --git a/sbt/src/sbt-test/dependency-management/evicted-semver-spec/v1.1.0/LibraryTest.scala b/sbt/src/sbt-test/dependency-management/evicted-semver-spec/v1.1.0/LibraryTest.scala new file mode 100644 index 000000000..fbfda9e74 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/evicted-semver-spec/v1.1.0/LibraryTest.scala @@ -0,0 +1,3 @@ +package example + +trait Foo {}