From e82e6652d094e3122474fb37c6cc691a34134a69 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 30 Dec 2015 13:41:31 -0500 Subject: [PATCH 1/5] Move intransitive warning to update. Ref #2127 --- .../main/scala/sbt/CompatibilityWarning.scala | 25 +++++++++++++ ivy/src/main/scala/sbt/MakePom.scala | 37 +++++++------------ main/src/main/scala/sbt/Defaults.scala | 8 ++-- notes/0.13.10.markdown | 2 +- .../dependency-management/pom-type/build.sbt | 37 ++++++++++--------- .../dependency-management/pom-type/test | 2 +- 6 files changed, 66 insertions(+), 45 deletions(-) create mode 100644 ivy/src/main/scala/sbt/CompatibilityWarning.scala diff --git a/ivy/src/main/scala/sbt/CompatibilityWarning.scala b/ivy/src/main/scala/sbt/CompatibilityWarning.scala new file mode 100644 index 000000000..7c7a7c1fb --- /dev/null +++ b/ivy/src/main/scala/sbt/CompatibilityWarning.scala @@ -0,0 +1,25 @@ +package sbt + +private[sbt] object CompatibilityWarning { + def apply(module: IvySbt#Module, mavenStyle: Boolean, log: Logger): Unit = { + if (mavenStyle) { + processIntransitive(module, log) + } + } + + def processIntransitive(module: IvySbt#Module, log: Logger): Unit = { + val directDependencies: Seq[ModuleID] = module.moduleSettings match { + case x: InlineConfiguration => x.dependencies + case x: InlineConfigurationWithExcludes => x.dependencies + case _ => Seq() + } + directDependencies foreach { m => + if (!m.isTransitive) { + log.warn( + s"""Found intransitive dependency ($m), but maven does not support intransitive dependencies. + | Use exclusions instead so transitive dependencies will be correctly excluded in dependent projects. + """.stripMargin) + } else () + } + } +} diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index e2018612f..742b7b8b4 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -235,30 +235,21 @@ class MakePom(val log: Logger) { def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = makeDependency(dependency, includeTypes, Nil) - def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String], excludes: Seq[ExcludeRule]): NodeSeq = { - def warnIntransitve(): Unit = - if (!dependency.isTransitive) - log.warn( - s"""Translating intransitive dependency (${dependency.getDependencyId}) into pom.xml, but maven does not support intransitive dependencies. - | Please use exclusions instead so transitive dependencies will be correctly excluded in dependent projects. - """.stripMargin) - else () - val artifacts = dependency.getAllDependencyArtifacts - val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) - if (artifacts.isEmpty) { - val configs = dependency.getModuleConfigurations - if (!configs.forall(Set("sources", "docs"))) { - warnIntransitve() - val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) - makeDependencyElem(dependency, scope, optional, None, None, excludes) - } else NodeSeq.Empty - } else if (includeArtifacts.isEmpty) { - NodeSeq.Empty - } else { - warnIntransitve() - NodeSeq.fromSeq(artifacts.flatMap(a => makeDependencyElem(dependency, a, excludes))) + def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String], excludes: Seq[ExcludeRule]): NodeSeq = + { + val artifacts = dependency.getAllDependencyArtifacts + val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) + if (artifacts.isEmpty) { + val configs = dependency.getModuleConfigurations + if (configs.filterNot(Set("sources", "docs")).nonEmpty) { + val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) + makeDependencyElem(dependency, scope, optional, None, None, excludes) + } else NodeSeq.Empty + } else if (includeArtifacts.isEmpty) + NodeSeq.Empty + else + NodeSeq.fromSeq(artifacts.flatMap(a => makeDependencyElem(dependency, a, excludes))) } - } @deprecated("Use `makeDependencyElem` variant which takes excludes", "0.13.9") def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor): Option[Elem] = diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 9c68b0e23..c713eabf7 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -1384,6 +1384,7 @@ object Classpaths { val logicalClock = LogicalClock(st.hashCode) val depDir = dependencyCacheDirectory.value val uc0 = updateConfiguration.value + val ms = publishMavenStyle.value // Normally, log would capture log messages at all levels. // Ivy logs are treated specially using sbt.UpdateConfiguration.logging. // This code bumps up the sbt.UpdateConfiguration.logging to Full when logLevel is Debug. @@ -1399,17 +1400,17 @@ object Classpaths { cachedUpdate(s.cacheDirectory / updateCacheName.value, show, ivyModule.value, uc, transform, skip = (skip in update).value, force = isRoot || forceUpdateByTime, depsUpdated = depsUpdated, uwConfig = uwConfig, logicalClock = logicalClock, depDir = Some(depDir), - ewo = ewo, log = s.log) + ewo = ewo, mavenStyle = ms, log = s.log) } @deprecated("Use cachedUpdate with the variant that takes unresolvedHandler instead.", "0.13.6") def cachedUpdate(cacheFile: File, label: String, module: IvySbt#Module, config: UpdateConfiguration, transform: UpdateReport => UpdateReport, skip: Boolean, force: Boolean, depsUpdated: Boolean, log: Logger): UpdateReport = cachedUpdate(cacheFile, label, module, config, transform, skip, force, depsUpdated, - UnresolvedWarningConfiguration(), LogicalClock.unknown, None, EvictionWarningOptions.empty, log) + UnresolvedWarningConfiguration(), LogicalClock.unknown, None, EvictionWarningOptions.empty, true, log) private[sbt] def cachedUpdate(cacheFile: File, label: String, module: IvySbt#Module, config: UpdateConfiguration, transform: UpdateReport => UpdateReport, skip: Boolean, force: Boolean, depsUpdated: Boolean, uwConfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], - ewo: EvictionWarningOptions, log: Logger): UpdateReport = + ewo: EvictionWarningOptions, mavenStyle: Boolean, log: Logger): UpdateReport = { implicit val updateCache = updateIC type In = IvyConfiguration :+: ModuleSettings :+: UpdateConfiguration :+: HNil @@ -1428,6 +1429,7 @@ object Classpaths { val ew = EvictionWarning(module, ewo, result, log) ew.lines foreach { log.warn(_) } ew.infoAllTheThings foreach { log.info(_) } + val cw = CompatibilityWarning(module, mavenStyle, log) result } def uptodate(inChanged: Boolean, out: UpdateReport): Boolean = diff --git a/notes/0.13.10.markdown b/notes/0.13.10.markdown index bac68befa..d78f348e9 100644 --- a/notes/0.13.10.markdown +++ b/notes/0.13.10.markdown @@ -75,7 +75,7 @@ ### Improvements - Scala version used by the build is updated to 2.10.6. [#2311][2311] by [@eed3si9n][@eed3si9n] -- `makePom` warns when it sees intransitive dependencies, which do not translate to Maven. [#2127][2127] by [@jsuereth][@jsuereth] +- If `publishMavenStyle` is `true`, `update` task warns when it sees intransitive dependencies, which do not translate to Maven. [#2127][2127] by [@jsuereth][@jsuereth] - Adds `Def.settings`, which facilitates mixing settings with seq of settings. See below. - Adds configurable compiler bridge. See below. - sbt Serialization is updated to 0.1.2. [2117][#2117] by [@dwijnand][@dwijnand] diff --git a/sbt/src/sbt-test/dependency-management/pom-type/build.sbt b/sbt/src/sbt-test/dependency-management/pom-type/build.sbt index 79af2c7af..b83e9fbbb 100644 --- a/sbt/src/sbt-test/dependency-management/pom-type/build.sbt +++ b/sbt/src/sbt-test/dependency-management/pom-type/build.sbt @@ -1,19 +1,22 @@ -scalaVersion := "2.10.2" - -libraryDependencies += "org.scala-sbt" %% "sbinary" % "0.4.1" withSources() withJavadoc() -libraryDependencies += "org.scala-sbt" % "io" % "0.13.8" intransitive() - lazy val checkPom = taskKey[Unit]("check pom to ensure no sections are generated") -checkPom := { - val pomFile = makePom.value - val pom = xml.XML.loadFile(pomFile) - val tpe = pom \\ "type" - if(tpe.nonEmpty) { - sys.error("Expected no sections, got: " + tpe + " in \n\n" + pom) - } - val dir = (streams in makePom).value.cacheDirectory / "out" - val lines = IO.readLines(dir) - val hasError = lines exists { line => line contains "Translating intransitive dependency "} - assert(hasError, s"Failed to detect intransitive dependencies, got: ${lines.mkString("\n")}") -} \ No newline at end of file +lazy val root = (project in file(".")). + settings( + scalaVersion := "2.10.6", + libraryDependencies += "org.scala-tools.sbinary" %% "sbinary" % "0.4.1" withSources() withJavadoc(), + libraryDependencies += "org.scala-sbt" % "io" % "0.13.8" intransitive(), + checkPom := { + val pomFile = makePom.value + val pom = xml.XML.loadFile(pomFile) + val tpe = pom \\ "type" + if(tpe.nonEmpty) { + sys.error("Expected no sections, got: " + tpe + " in \n\n" + pom) + } + val ur = update.value + val dir = (streams in update).value.cacheDirectory / "out" + val lines = IO.readLines(dir) + val hasError = lines exists { line => line contains "Found intransitive dependency "} + assert(hasError, s"Failed to detect intransitive dependencies, got: ${lines.mkString("\n")}") + }, + resolvers += Resolver.typesafeIvyRepo("releases") + ) diff --git a/sbt/src/sbt-test/dependency-management/pom-type/test b/sbt/src/sbt-test/dependency-management/pom-type/test index 0e9f0f7b6..8d831496e 100644 --- a/sbt/src/sbt-test/dependency-management/pom-type/test +++ b/sbt/src/sbt-test/dependency-management/pom-type/test @@ -1 +1 @@ -> checkPom \ No newline at end of file +> checkPom From 182374c71226892e7712e96e464457494233f8aa Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 31 Dec 2015 00:25:21 -0500 Subject: [PATCH 2/5] Reproduce "configuration not public" on local test->test. #1827 --- .../chainresolver/build.sbt | 36 +++++++++++++++++++ .../dependency-management/chainresolver/test | 3 ++ 2 files changed, 39 insertions(+) create mode 100644 sbt/src/sbt-test/dependency-management/chainresolver/build.sbt create mode 100644 sbt/src/sbt-test/dependency-management/chainresolver/test diff --git a/sbt/src/sbt-test/dependency-management/chainresolver/build.sbt b/sbt/src/sbt-test/dependency-management/chainresolver/build.sbt new file mode 100644 index 000000000..f9454c341 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/chainresolver/build.sbt @@ -0,0 +1,36 @@ +lazy val check = taskKey[Unit]("Runs the check") + +def commonSettings: Seq[Def.Setting[_]] = + Seq( + ivyPaths := new IvyPaths( (baseDirectory in ThisBuild).value, Some((target in LocalRootProject).value / "ivy-cache")), + scalaVersion in ThisBuild := "2.11.7", + organization in ThisBuild := "com.example", + version in ThisBuild := "0.1.0-SNAPSHOT", + autoScalaLibrary := false, + crossPaths := false + ) + +lazy val realCommonsIoClient = project. + settings( + commonSettings, + name := "a", + libraryDependencies := Seq( + "commons-io" % "commons-io" % "1.3" + ), + fullResolvers := fullResolvers.value.filterNot(_.name == "inter-project") + ) + +lazy val fakeCommonsIo = project. + settings( + commonSettings, + organization := "commons-io", + name := "commons-io", + version := "1.3" + ) + +lazy val fakeCommonsIoClient = project. + dependsOn(fakeCommonsIo % "test->test"). + settings( + commonSettings, + name := "c" + ) diff --git a/sbt/src/sbt-test/dependency-management/chainresolver/test b/sbt/src/sbt-test/dependency-management/chainresolver/test new file mode 100644 index 000000000..c3786f997 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/chainresolver/test @@ -0,0 +1,3 @@ +> realCommonsIoClient/update + +> fakeCommonsIoClient/update From f244815f7d9bf3d303fe4bb9f32186a9dc98d7bd Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 31 Dec 2015 00:41:23 -0500 Subject: [PATCH 3/5] Update warning message a bit. --- ivy/src/main/scala/sbt/CompatibilityWarning.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/CompatibilityWarning.scala b/ivy/src/main/scala/sbt/CompatibilityWarning.scala index 7c7a7c1fb..10ef1685d 100644 --- a/ivy/src/main/scala/sbt/CompatibilityWarning.scala +++ b/ivy/src/main/scala/sbt/CompatibilityWarning.scala @@ -16,7 +16,7 @@ private[sbt] object CompatibilityWarning { directDependencies foreach { m => if (!m.isTransitive) { log.warn( - s"""Found intransitive dependency ($m), but maven does not support intransitive dependencies. + s"""Found intransitive dependency ($m), but Maven repositories do not support intransitive dependencies. | Use exclusions instead so transitive dependencies will be correctly excluded in dependent projects. """.stripMargin) } else () From 0d925630df90afec92568b78ff557a10adead181 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 31 Dec 2015 01:22:27 -0500 Subject: [PATCH 4/5] Fixes #1827. Adds withInterProjectFirst to update option. withInterProjectFirst when set to true will prioritize inter-project resolver over all other resolver and Ivy cache. This aimed to workaround the fact that on Maven Test configuration is considered private, and thus project dependency with `test->test` configuration may not under some condition. The condition is when someone resolves `x:y:1.0` and you have a subproject named and versioned exactly that, and some other subproject tries to depend on it. This happens when the project does not change the version number on the Github. --- ivy/src/main/scala/sbt/UpdateOptions.scala | 9 ++ .../scala/sbt/ivyint/SbtChainResolver.scala | 96 ++++++++++--------- notes/0.13.10.markdown | 6 ++ notes/0.13.10/fix-snapshots.md | 14 --- 4 files changed, 67 insertions(+), 58 deletions(-) delete mode 100644 notes/0.13.10/fix-snapshots.md diff --git a/ivy/src/main/scala/sbt/UpdateOptions.scala b/ivy/src/main/scala/sbt/UpdateOptions.scala index 3f640867d..ba82e5053 100644 --- a/ivy/src/main/scala/sbt/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/UpdateOptions.scala @@ -14,6 +14,8 @@ import org.apache.ivy.core.settings.IvySettings final class UpdateOptions private[sbt] ( /** If set to CircularDependencyLevel.Error, halt the dependency resolution. */ val circularDependencyLevel: CircularDependencyLevel, + // If set to true, prioritize inter-project resolver + val interProjectFirst: Boolean, /** If set to true, check all resolvers for snapshots. */ val latestSnapshots: Boolean, /** If set to true, use consolidated resolution. */ @@ -24,6 +26,8 @@ final class UpdateOptions private[sbt] ( val resolverConverter: UpdateOptions.ResolverConverter) { def withCircularDependencyLevel(circularDependencyLevel: CircularDependencyLevel): UpdateOptions = copy(circularDependencyLevel = circularDependencyLevel) + def withInterProjectFirst(interProjectFirst: Boolean): UpdateOptions = + copy(interProjectFirst = interProjectFirst) def withLatestSnapshots(latestSnapshots: Boolean): UpdateOptions = copy(latestSnapshots = latestSnapshots) @deprecated("Use withCachedResolution instead.", "0.13.7") @@ -39,11 +43,13 @@ final class UpdateOptions private[sbt] ( private[sbt] def copy( circularDependencyLevel: CircularDependencyLevel = this.circularDependencyLevel, + interProjectFirst: Boolean = this.interProjectFirst, latestSnapshots: Boolean = this.latestSnapshots, consolidatedResolution: Boolean = this.consolidatedResolution, cachedResolution: Boolean = this.cachedResolution, resolverConverter: UpdateOptions.ResolverConverter = this.resolverConverter): UpdateOptions = new UpdateOptions(circularDependencyLevel, + interProjectFirst, latestSnapshots, consolidatedResolution, cachedResolution, @@ -52,6 +58,7 @@ final class UpdateOptions private[sbt] ( override def equals(o: Any): Boolean = o match { case o: UpdateOptions => this.circularDependencyLevel == o.circularDependencyLevel && + this.interProjectFirst == o.interProjectFirst && this.latestSnapshots == o.latestSnapshots && this.cachedResolution == o.cachedResolution && this.resolverConverter == o.resolverConverter @@ -62,6 +69,7 @@ final class UpdateOptions private[sbt] ( { var hash = 1 hash = hash * 31 + this.circularDependencyLevel.## + hash = hash * 31 + this.interProjectFirst.## hash = hash * 31 + this.latestSnapshots.## hash = hash * 31 + this.cachedResolution.## hash = hash * 31 + this.resolverConverter.## @@ -75,6 +83,7 @@ object UpdateOptions { def apply(): UpdateOptions = new UpdateOptions( circularDependencyLevel = CircularDependencyLevel.Warn, + interProjectFirst = true, latestSnapshots = true, consolidatedResolution = false, cachedResolution = false, diff --git a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala index 7323f4aec..cc6f67816 100644 --- a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala @@ -112,6 +112,7 @@ private[sbt] case class SbtChainResolver( else resolvedOrCached // Cast resolvers to something useful. TODO - we dropping anything here? val resolvers = getResolvers.toArray.toVector collect { case x: DependencyResolver => x } + val interProjResolver = resolvers find { x => x.getName == ProjectResolver.InterProject } // Here we do an attempt to resolve the artifact from each of the resolvers in the chain. // - If we have a return value already, AND isReturnFirst is true AND useLatest is false, we DO NOT resolve anything @@ -119,7 +120,7 @@ private[sbt] case class SbtChainResolver( // RETURNS: Left -> Error // Right -> Some(resolved module) // Found in this resolver, can use this result. // Right -> None // Do not use this resolver - val results = resolvers map { x => + lazy val results = resolvers map { x => // if the revision is cached and isReturnFirst is set, don't bother hitting any resolvers, just return None for this guy. if (isReturnFirst && temp.isDefined && !useLatest) Right(None) else { @@ -150,50 +151,57 @@ private[sbt] case class SbtChainResolver( } } } - val errors = results collect { case Left(e) => e } - val foundRevisions: Vector[(ResolvedModuleRevision, DependencyResolver)] = results collect { case Right(Some(x)) => x } - val sorted = - if (useLatest) (foundRevisions.sortBy { - case (rmr, resolver) => - Message.warn(s"Sorrting results from $rmr, using ${rmr.getPublicationDate} and ${rmr.getDescriptor.getPublicationDate}") - // Just issue warning about issues with publication date, and fake one on it for now. - Option(rmr.getPublicationDate) orElse Option(rmr.getDescriptor.getPublicationDate) match { - case None => - (resolver.findIvyFileRef(dd, data), rmr.getDescriptor) match { - case (null, _) => - // In this instance, the dependency is specified by a direct URL or some other sort of "non-ivy" file - if (dd.isChanging) - Message.warn(s"Resolving a changing dependency (${rmr.getId}) with no ivy/pom file!, resolution order is undefined!") - 0L - case (ivf, dmd: DefaultModuleDescriptor) => - val lmd = new java.util.Date(ivf.getLastModified) - Message.debug(s"Getting no publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}") - dmd.setPublicationDate(lmd) - ivf.getLastModified - case _ => - Message.warn(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, resolution order is undefined!") - 0L - } - case Some(date) => // All other cases ok - date.getTime - } - }).reverse.headOption map { - case (rmr, resolver) => - Message.warn(s"Choosing $resolver for ${rmr.getId}") - // Now that we know the real latest revision, let's force Ivy to use it - val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) - artifactOpt match { - case Some(artifactRef) => - val systemMd = toSystem(rmr.getDescriptor) - getRepositoryCacheManager.cacheModuleDescriptor(resolver, artifactRef, - toSystem(dd), systemMd.getAllArtifacts.head, None.orNull, getCacheOptions(data)) - case None => // do nothing. There are modules without artifacts - } - rmr - } - else foundRevisions.reverse.headOption map { _._1 } // we have to reverse because resolvers are hit in reverse order. + lazy val errors = results collect { case Left(e) => e } + // If the value is arleady in cache, SORTED will be a Seq(None, None, ...) which means we'll fall over to the prevously cached or resolved version. - val mrOpt: Option[ResolvedModuleRevision] = sorted orElse resolvedOrCached + val mrOpt: Option[ResolvedModuleRevision] = { + val interProj: Option[ResolvedModuleRevision] = + if (updateOptions.interProjectFirst) interProjResolver flatMap { x => Option(x.getDependency(dd, data)) } + else None + def foundRevisions: Vector[(ResolvedModuleRevision, DependencyResolver)] = results collect { case Right(Some(x)) => x } + def sorted = + if (useLatest) (foundRevisions.sortBy { + case (rmr, resolver) => + Message.warn(s"Sorrting results from $rmr, using ${rmr.getPublicationDate} and ${rmr.getDescriptor.getPublicationDate}") + // Just issue warning about issues with publication date, and fake one on it for now. + Option(rmr.getPublicationDate) orElse Option(rmr.getDescriptor.getPublicationDate) match { + case None => + (resolver.findIvyFileRef(dd, data), rmr.getDescriptor) match { + case (null, _) => + // In this instance, the dependency is specified by a direct URL or some other sort of "non-ivy" file + if (dd.isChanging) + Message.warn(s"Resolving a changing dependency (${rmr.getId}) with no ivy/pom file!, resolution order is undefined!") + 0L + case (ivf, dmd: DefaultModuleDescriptor) => + val lmd = new java.util.Date(ivf.getLastModified) + Message.debug(s"Getting no publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}") + dmd.setPublicationDate(lmd) + ivf.getLastModified + case _ => + Message.warn(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, resolution order is undefined!") + 0L + } + case Some(date) => // All other cases ok + date.getTime + } + }).reverse.headOption map { + case (rmr, resolver) => + Message.warn(s"Choosing $resolver for ${rmr.getId}") + // Now that we know the real latest revision, let's force Ivy to use it + val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) + artifactOpt match { + case Some(artifactRef) => + val systemMd = toSystem(rmr.getDescriptor) + getRepositoryCacheManager.cacheModuleDescriptor(resolver, artifactRef, + toSystem(dd), systemMd.getAllArtifacts.head, None.orNull, getCacheOptions(data)) + case None => // do nothing. There are modules without artifacts + } + rmr + } + else foundRevisions.reverse.headOption map { _._1 } // we have to reverse because resolvers are hit in reverse order. + + interProj orElse sorted orElse resolvedOrCached + } mrOpt match { case None if errors.size == 1 => errors.head match { diff --git a/notes/0.13.10.markdown b/notes/0.13.10.markdown index d78f348e9..666d9f9cc 100644 --- a/notes/0.13.10.markdown +++ b/notes/0.13.10.markdown @@ -66,10 +66,16 @@ [2324]: https://github.com/sbt/sbt/issues/2324 [2325]: https://github.com/sbt/sbt/pull/2325 [2336]: https://github.com/sbt/sbt/issues/2336 + [1514]: https://github.com/sbt/sbt/issues/1514 + [1616]: https://github.com/sbt/sbt/issues/1616 + [2313]: https://github.com/sbt/sbt/pull/2313 ### Fixes with compatibility implications - sbt 0.13.10 adds a new setting `useJCenter`, which is set to `false` by default. When set to `true`, JCenter will be placed as the first external resolver to find library dependencies. [#2217][2217] by [@eed3si9n][@eed3si9n] +- Adds `withInterProjectFirst` to the update option, which is enabled by default. When set to `true`, `inter-project` resolver will be prioritized above all resolvers and Ivy cache. [#1827][1827] by [@eed3si9n][@eed3si9n] +- Fixes update option's `withLatestSnapshots` so it handles modules without an artifact. This flag will be enabled by default. + [#1514][1514]/[#1616][1616]/[#2313][2313] by [@eed3si9n][@eed3si9n] - sbt will no longer pass `-J` options to the local Java compiler. [#1968][1968]/[#2272][2272] by [@Duhemm][@Duhemm] ### Improvements diff --git a/notes/0.13.10/fix-snapshots.md b/notes/0.13.10/fix-snapshots.md deleted file mode 100644 index 59e946757..000000000 --- a/notes/0.13.10/fix-snapshots.md +++ /dev/null @@ -1,14 +0,0 @@ - - [@eed3si9n]: https://github.com/eed3si9n - [1514]: https://github.com/sbt/sbt/issues/1514 - [1616]: https://github.com/sbt/sbt/issues/1616 - [2313]: https://github.com/sbt/sbt/pull/2313 - -### Fixes with compatibility implications - -- Fixes update option's `withLatestSnapshots` so it handles modules without an artifact. This flag will be enabled by default. - [#1514][1514]/[#1616][1616]/[#2313][2313] by [@eed3si9n][@eed3si9n] - -### Improvements - -### Bug fixes From bdffad284529097e065b257698e8ee4c6d5e9ec9 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 31 Dec 2015 22:36:04 -0500 Subject: [PATCH 5/5] Improve warning message --- ivy/src/main/scala/sbt/CompatibilityWarning.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/CompatibilityWarning.scala b/ivy/src/main/scala/sbt/CompatibilityWarning.scala index 10ef1685d..ead6b517b 100644 --- a/ivy/src/main/scala/sbt/CompatibilityWarning.scala +++ b/ivy/src/main/scala/sbt/CompatibilityWarning.scala @@ -16,8 +16,9 @@ private[sbt] object CompatibilityWarning { directDependencies foreach { m => if (!m.isTransitive) { log.warn( - s"""Found intransitive dependency ($m), but Maven repositories do not support intransitive dependencies. - | Use exclusions instead so transitive dependencies will be correctly excluded in dependent projects. + s"""Found intransitive dependency ($m) while publishMavenStyle is true, but Maven repositories + | do not support intransitive dependencies. Use exclusions instead so transitive dependencies + | will be correctly excluded in dependent projects. """.stripMargin) } else () }