mirror of https://github.com/sbt/sbt.git
Merge pull request #2345 from eed3si9n/wip/testtest
Maven compatibility changes (intransitive warnings and "configuration not public")
This commit is contained in:
commit
886b3647e3
|
|
@ -0,0 +1,26 @@
|
|||
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) 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 ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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] =
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -66,16 +66,22 @@
|
|||
[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<flag>` options to the local Java compiler. [#1968][1968]/[#2272][2272] by [@Duhemm][@Duhemm]
|
||||
|
||||
### 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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
> realCommonsIoClient/update
|
||||
|
||||
> fakeCommonsIoClient/update
|
||||
|
|
@ -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 <type> 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 <type> 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")}")
|
||||
}
|
||||
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 <type> 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")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
> checkPom
|
||||
> checkPom
|
||||
|
|
|
|||
Loading…
Reference in New Issue