Merge branch 'develop' into pr/4617

This commit is contained in:
Eugene Yokota 2019-04-28 17:22:54 -04:00
commit f5444f7715
132 changed files with 1912 additions and 245 deletions

View File

@ -10,13 +10,14 @@ env:
# WHITESOURCE_PASSWORD=
- secure: d3bu2KNwsVHwfhbGgO+gmRfDKBJhfICdCJFGWKf2w3Gv86AJZX9nuTYRxz0KtdvEHO5Xw8WTBZLPb2thSJqhw9OCm4J8TBAVqCP0ruUj4+aqBUFy4bVexQ6WKE6nWHs4JPzPk8c6uC1LG3hMuzlC8RGETXtL/n81Ef1u7NjyXjs=
matrix:
- SBT_CMD=";mimaReportBinaryIssues ;scalafmtCheckAll ;headerCheck ;test:headerCheck ;whitesourceOnPush ;test:compile ;mainSettingsProj/test ;safeUnitTests ;otherUnitTests; doc"
- SBT_CMD=";mimaReportBinaryIssues ;scalafmtCheckAll ;headerCheck ;test:headerCheck ;whitesourceOnPush ;test:compile; publishLocal ;mainSettingsProj/test ;safeUnitTests ;otherUnitTests; doc"
- SBT_CMD="scripted actions/*"
- SBT_CMD="scripted apiinfo/* compiler-project/* ivy-deps-management/*"
- SBT_CMD="scripted dependency-management/*1of4"
- SBT_CMD="scripted dependency-management/*2of4"
- SBT_CMD="scripted dependency-management/*3of4"
- SBT_CMD="scripted dependency-management/*4of4"
- SBT_CMD="scripted plugins/*"
- SBT_CMD="scripted package/* reporter/* run/* project-load/*"
- SBT_CMD="scripted project/*1of2"
- SBT_CMD="scripted project/*2of2"

View File

@ -606,7 +606,12 @@ lazy val mainProj = (project in file("main"))
if (xs exists { s => s.contains(s""""$sv"""") }) ()
else sys.error("PluginCross.scala does not match up with the scalaVersion " + sv)
},
libraryDependencies ++= scalaXml.value ++ Seq(launcherInterface) ++ log4jDependencies ++ Seq(scalaCacheCaffeine),
libraryDependencies ++= {
scalaXml.value ++
Seq(launcherInterface) ++
log4jDependencies ++
Seq(scalaCacheCaffeine, lmCoursierShaded)
},
Compile / scalacOptions -= "-Xfatal-warnings",
managedSourceDirectories in Compile +=
baseDirectory.value / "src" / "main" / "contraband-scala",
@ -666,6 +671,7 @@ lazy val sbtProj = (project in file("sbt"))
)
.configure(addSbtIO, addSbtCompilerBridge)
/*
lazy val sbtBig = (project in file(".big"))
.dependsOn(sbtProj)
.settings(
@ -701,6 +707,7 @@ lazy val sbtBig = (project in file(".big"))
}).transform(node).head
},
)
*/
lazy val sbtIgnoredProblems = {
Vector(

View File

@ -450,6 +450,7 @@ object TaskMacro {
def expand(nme: String, tpe: Type, tree: Tree): Converted[c.type] = nme match {
case WrapInitTaskName => Converted.Success(wrapInitTask(tree)(c.WeakTypeTag(tpe)))
case WrapPreviousName => Converted.Success(wrapInitTask(tree)(c.WeakTypeTag(tpe)))
case ParserInput.WrapInitName => Converted.Success(wrapInitParser(tree)(c.WeakTypeTag(tpe)))
case WrapInitInputName => Converted.Success(wrapInitInput(tree)(c.WeakTypeTag(tpe)))
case WrapInputName => Converted.Success(wrapInput(tree)(c.WeakTypeTag(tpe)))

View File

@ -12,6 +12,7 @@ import java.net.{ URI, URL, URLClassLoader }
import java.util.Optional
import java.util.concurrent.{ Callable, TimeUnit }
import lmcoursier.definitions.{ Configuration => CConfiguration }
import org.apache.ivy.core.module.descriptor.ModuleDescriptor
import org.apache.ivy.core.module.id.ModuleRevisionId
import sbt.Def.{ Initialize, ScopedKey, Setting, SettingsDefinition }
@ -200,6 +201,7 @@ object Defaults extends BuildCommon {
exportJars :== false,
trackInternalDependencies :== TrackLevel.TrackAlways,
exportToInternal :== TrackLevel.TrackAlways,
useCoursier :== LibraryManagement.defaultUseCoursier,
retrieveManaged :== false,
retrieveManagedSync :== false,
configurationsToRetrieve :== None,
@ -213,7 +215,7 @@ object Defaults extends BuildCommon {
crossVersion :== Disabled(),
buildDependencies := Classpaths.constructBuildDependencies.value,
version :== "0.1.0-SNAPSHOT",
classpathTypes :== Set("jar", "bundle") ++ CustomPomParser.JarPackagings,
classpathTypes :== Set("jar", "bundle", "maven-plugin", "test-jar") ++ CustomPomParser.JarPackagings,
artifactClassifier :== None,
checksums := Classpaths.bootChecksums(appConfiguration.value),
conflictManager := ConflictManager.default,
@ -224,7 +226,12 @@ object Defaults extends BuildCommon {
pomAllRepositories :== false,
pomIncludeRepository :== Classpaths.defaultRepositoryFilter,
updateOptions := UpdateOptions(),
forceUpdatePeriod :== None
forceUpdatePeriod :== None,
// coursier settings
csrExtraCredentials :== Nil,
csrLogger :== None,
csrCachePath :== LMCoursier.defaultCacheLocation,
csrMavenProfiles :== Set.empty,
)
/** Core non-plugin settings for sbt builds. These *must* be on every build or the sbt engine will fail to run at all. */
@ -1909,6 +1916,7 @@ object Classpaths {
managedClasspath := {
val isMeta = isMetaBuild.value
val force = reresolveSbtArtifacts.value
val csr = useCoursier.value
val app = appConfiguration.value
val sbtCp0 = app.provider.mainClasspath.toList
val sbtCp = sbtCp0 map { Attributed.blank(_) }
@ -1917,7 +1925,7 @@ object Classpaths {
classpathTypes.value,
update.value
)
if (isMeta && !force) mjars ++ sbtCp
if (isMeta && !force && !csr) mjars ++ sbtCp
else mjars
},
exportedProducts := trackedExportedProducts(TrackLevel.TrackAlways).value,
@ -2125,6 +2133,18 @@ object Classpaths {
}).value,
moduleName := normalizedName.value,
ivyPaths := IvyPaths(baseDirectory.value, bootIvyHome(appConfiguration.value)),
csrCachePath := {
val old = csrCachePath.value
val ip = ivyPaths.value
val defaultIvyCache = bootIvyHome(appConfiguration.value)
if (old != LMCoursier.defaultCacheLocation) old
else if (ip.ivyHome == defaultIvyCache) old
else
ip.ivyHome match {
case Some(home) => home / "coursier-cache"
case _ => old
}
},
dependencyCacheDirectory := {
val st = state.value
BuildPaths.getDependencyDirectory(st, BuildPaths.getGlobalBase(st))
@ -2181,10 +2201,7 @@ object Classpaths {
)
else None
},
dependencyResolution := IvyDependencyResolution(
ivyConfiguration.value,
CustomHttp.okhttpClient.value
),
dependencyResolution := LibraryManagement.dependencyResolutionTask.value,
publisher := IvyPublisher(ivyConfiguration.value, CustomHttp.okhttpClient.value),
ivyConfiguration := mkIvyConfiguration.value,
ivyConfigurations := {
@ -2198,6 +2215,44 @@ object Classpaths {
if (managedScalaInstance.value && scalaHome.value.isEmpty) Configurations.ScalaTool :: Nil
else Nil
},
// Coursier needs these
ivyConfigurations := {
val confs = ivyConfigurations.value
val names = confs.map(_.name).toSet
val extraSources =
if (names("sources"))
None
else
Some(
Configuration.of(
id = "Sources",
name = "sources",
description = "",
isPublic = true,
extendsConfigs = Vector.empty,
transitive = false
)
)
val extraDocs =
if (names("docs"))
None
else
Some(
Configuration.of(
id = "Docs",
name = "docs",
description = "",
isPublic = true,
extendsConfigs = Vector.empty,
transitive = false
)
)
val use = useCoursier.value
if (use) confs ++ extraSources.toSeq ++ extraDocs.toSeq
else confs
},
moduleSettings := moduleSettings0.value,
makePomConfiguration := MakePomConfiguration()
.withFile((artifactPath in makePom).value)
@ -2278,7 +2333,8 @@ object Classpaths {
unresolvedWarningConfiguration in update := UnresolvedWarningConfiguration(
dependencyPositions.value
),
update := (updateTask tag (Tags.Update, Tags.Network)).value,
updateFull := (updateTask tag (Tags.Update, Tags.Network)).value,
update := (updateWithoutDetails("update") tag (Tags.Update, Tags.Network)).value,
update := {
val report = update.value
val log = streams.value.log
@ -2297,52 +2353,70 @@ object Classpaths {
ew.infoAllTheThings foreach { log.info(_) }
ew
},
classifiersModule in updateClassifiers := {
implicit val key = (m: ModuleID) => (m.organization, m.name, m.revision)
val projectDeps = projectDependencies.value.iterator.map(key).toSet
val externalModules = update.value.allModules.filterNot(m => projectDeps contains key(m))
GetClassifiersModule(
projectID.value,
None,
externalModules,
ivyConfigurations.in(updateClassifiers).value.toVector,
transitiveClassifiers.in(updateClassifiers).value.toVector
) ++
inTask(updateClassifiers)(
Seq(
classifiersModule := {
implicit val key = (m: ModuleID) => (m.organization, m.name, m.revision)
val projectDeps = projectDependencies.value.iterator.map(key).toSet
val externalModules = update.value.allModules.filterNot(m => projectDeps contains key(m))
GetClassifiersModule(
projectID.value,
None,
externalModules,
ivyConfigurations.value.toVector,
transitiveClassifiers.value.toVector
)
},
dependencyResolution := LibraryManagement.dependencyResolutionTask.value,
csrConfiguration := LMCoursier.coursierConfigurationTask(true, false).value,
updateClassifiers in TaskGlobal := (Def.task {
val s = streams.value
val is = ivySbt.value
val lm = dependencyResolution.value
val mod = classifiersModule.value
val updateConfig0 = updateConfiguration.value
val updateConfig = updateConfig0
.withMetadataDirectory(dependencyCacheDirectory.value)
.withArtifactFilter(
updateConfig0.artifactFilter.map(af => af.withInverted(!af.inverted))
)
val app = appConfiguration.value
val srcTypes = sourceArtifactTypes.value
val docTypes = docArtifactTypes.value
val out = is.withIvy(s.log)(_.getSettings.getDefaultIvyUserDir)
val uwConfig = (unresolvedWarningConfiguration in update).value
withExcludes(out, mod.classifiers, lock(app)) { excludes =>
lm.updateClassifiers(
GetClassifiersConfiguration(
mod,
excludes.toVector,
updateConfig,
// scalaModule,
srcTypes.toVector,
docTypes.toVector
),
uwConfig,
Vector.empty,
s.log
) match {
case Left(_) => ???
case Right(ur) => ur
}
}
} tag (Tags.Update, Tags.Network)).value,
)
},
updateClassifiers := (Def.task {
val s = streams.value
val is = ivySbt.value
val lm = dependencyResolution.value
val mod = (classifiersModule in updateClassifiers).value
val updateConfig0 = updateConfiguration.value
val updateConfig = updateConfig0
.withMetadataDirectory(dependencyCacheDirectory.value)
.withArtifactFilter(updateConfig0.artifactFilter.map(af => af.withInverted(!af.inverted)))
val app = appConfiguration.value
val srcTypes = sourceArtifactTypes.value
val docTypes = docArtifactTypes.value
val out = is.withIvy(s.log)(_.getSettings.getDefaultIvyUserDir)
val uwConfig = (unresolvedWarningConfiguration in update).value
withExcludes(out, mod.classifiers, lock(app)) { excludes =>
lm.updateClassifiers(
GetClassifiersConfiguration(
mod,
excludes.toVector,
updateConfig,
// scalaModule,
srcTypes.toVector,
docTypes.toVector
),
uwConfig,
Vector.empty,
s.log
) match {
case Left(_) => ???
case Right(ur) => ur
}
}
} tag (Tags.Update, Tags.Network)).value
)
) ++ Seq(
csrProject := CoursierInputsTasks.coursierProjectTask.value,
csrConfiguration := LMCoursier.coursierConfigurationTask(false, false).value,
csrResolvers := CoursierRepositoriesTasks.coursierResolversTask.value,
csrRecursiveResolvers := CoursierRepositoriesTasks.coursierRecursiveResolversTask.value,
csrSbtResolvers := LMCoursier.coursierSbtResolversTask.value,
csrInterProjectDependencies := CoursierInputsTasks.coursierInterProjectDependenciesTask.value,
csrFallbackDependencies := CoursierInputsTasks.coursierFallbackDependenciesTask.value,
) ++
IvyXml.generateIvyXmlSettings() ++
LMCoursier.publicationsSetting(Seq(Compile, Test).map(c => c -> CConfiguration(c.name)))
val jvmBaseSettings: Seq[Setting[_]] = Seq(
libraryDependencies ++= autoLibraryDependency(
@ -2375,19 +2449,18 @@ object Classpaths {
val isMeta = isMetaBuild.value
val force = reresolveSbtArtifacts.value
val excludes = excludeDependencies.value
val sbtModules = Vector(
"sbt",
"zinc_2.12",
"librarymanagement-core_2.12",
"librarymanagement-ivy_2.12",
"util-logging_2.12",
"util-position_2.12",
"io_2.12"
val csr = useCoursier.value
val o = sbtdeps.organization
val sbtModulesExcludes = Vector[ExclusionRule](
o % "sbt",
o %% "scripted-plugin",
o %% "librarymanagement-core",
o %% "librarymanagement-ivy",
o %% "util-logging",
o %% "util-position",
o %% "io"
)
val sbtModulesExcludes = sbtModules map { nm: String =>
ExclusionRule(organization = sbtdeps.organization, name = nm)
}
if (isMeta && !force) excludes.toVector ++ sbtModulesExcludes
if (isMeta && !force && !csr) excludes.toVector ++ sbtModulesExcludes
else excludes
},
dependencyOverrides ++= {
@ -2503,10 +2576,8 @@ object Classpaths {
).withScalaOrganization(scalaOrganization.value)
)
},
dependencyResolution := IvyDependencyResolution(
ivyConfiguration.value,
CustomHttp.okhttpClient.value
),
dependencyResolution := LibraryManagement.dependencyResolutionTask.value,
csrConfiguration := LMCoursier.coursierConfigurationTask(false, true).value,
updateSbtClassifiers in TaskGlobal := (Def.task {
val lm = dependencyResolution.value
val s = streams.value
@ -2656,9 +2727,23 @@ object Classpaths {
}
}
def updateTask: Initialize[Task[UpdateReport]] = Def.task {
def updateTask: Initialize[Task[UpdateReport]] = updateTask0("updateFull", true, true)
def updateWithoutDetails(label: String): Initialize[Task[UpdateReport]] =
updateTask0(label, false, false)
/**
* cacheLabel - label to identify an update cache
* includeCallers - include the caller information
* includeDetails - include module reports for the evicted modules
*/
private def updateTask0(
cacheLabel: String,
includeCallers: Boolean,
includeDetails: Boolean
): Initialize[Task[UpdateReport]] = Def.task {
val s = streams.value
val cacheDirectory = streams.value.cacheDirectory
val cacheDirectory = crossTarget.value / cacheLabel / updateCacheName.value
val cacheStoreFactory: CacheStoreFactory = CacheStoreFactory.directory(cacheDirectory)
val isRoot = executionRoots.value contains resolvedScoped.value
val shouldForce = isRoot || {
@ -2721,7 +2806,7 @@ object Classpaths {
lm = dependencyResolution.value,
// Ivy-free ModuleDescriptor
module = ivyModule.value,
s.cacheStoreFactory.sub(updateCacheName.value),
cacheStoreFactory = cacheStoreFactory,
label = label,
updateConf,
substituteScalaFiles(scalaOrganization.value, _)(providedScalaJars),
@ -2732,6 +2817,8 @@ object Classpaths {
ewo = evictionOptions,
mavenStyle = publishMavenStyle.value,
compatWarning = compatibilityWarningOptions.value,
includeCallers = includeCallers,
includeDetails = includeDetails,
log = s.log
)
}

View File

@ -32,6 +32,8 @@ import sbt.librarymanagement.ivy.{ Credentials, IvyConfiguration, IvyPaths, Upda
import sbt.testing.Framework
import sbt.util.{ Level, Logger }
import xsbti.compile._
import lmcoursier.definitions.CacheLogger
import lmcoursier.{ CoursierConfiguration, FallbackDependency }
import scala.concurrent.duration.{ Duration, FiniteDuration }
import scala.xml.{ NodeSeq, Node => XNode }
@ -351,6 +353,20 @@ object Keys {
val fullClasspathAsJars = taskKey[Classpath]("The exported classpath, consisting of build products and unmanaged and managed, internal and external dependencies, all as JARs.")
val internalDependencyConfigurations = settingKey[Seq[(ProjectRef, Set[String])]]("The project configurations that this configuration depends on")
val useCoursier = settingKey[Boolean]("Use Coursier for dependency resolution.").withRank(BSetting)
val csrCachePath = settingKey[File]("Coursier cache path").withRank(CSetting)
val csrMavenProfiles = settingKey[Set[String]]("").withRank(CSetting)
private[sbt] val csrConfiguration = taskKey[CoursierConfiguration]("General dependency management (Coursier) settings, such as the resolvers and options to use.").withRank(DTask)
private[sbt] val csrProject = taskKey[lmcoursier.definitions.Project]("")
private[sbt] val csrResolvers = taskKey[Seq[Resolver]]("")
private[sbt] val csrRecursiveResolvers = taskKey[Seq[Resolver]]("Resolvers of the current project, plus those of all from its inter-dependency projects")
private[sbt] val csrSbtResolvers = taskKey[Seq[Resolver]]("Resolvers used for sbt artifacts.")
private[sbt] val csrInterProjectDependencies = taskKey[Seq[lmcoursier.definitions.Project]]("Projects the current project depends on, possibly transitively")
private[sbt] val csrFallbackDependencies = taskKey[Seq[FallbackDependency]]("")
private[sbt] val csrLogger = taskKey[Option[CacheLogger]]("")
private[sbt] val csrExtraCredentials = taskKey[Seq[lmcoursier.credentials.Credentials]]("")
private[sbt] val csrPublications = taskKey[Seq[(lmcoursier.definitions.Configuration, lmcoursier.definitions.Publication)]]("")
val internalConfigurationMap = settingKey[Configuration => Configuration]("Maps configurations to the actual configuration used to define the classpath.").withRank(CSetting)
val classpathConfiguration = taskKey[Configuration]("The configuration used to define the classpath.").withRank(CTask)
val ivyConfiguration = taskKey[IvyConfiguration]("General dependency management (Ivy) settings, such as the resolvers and paths to use.").withRank(DTask)
@ -370,6 +386,7 @@ object Keys {
val ivyModule = taskKey[IvySbt#Module]("Provides the sbt interface to a configured Ivy module.").withRank(CTask)
val updateCacheName = taskKey[String]("Defines the directory name used to store the update cache files (inside the streams cacheDirectory).").withRank(DTask)
val update = taskKey[UpdateReport]("Resolves and optionally retrieves dependencies, producing a report.").withRank(ATask)
val updateFull = taskKey[UpdateReport]("Resolves and optionally retrieves dependencies, producing a full report with callers.").withRank(CTask)
val evicted = taskKey[EvictionWarning]("Display detailed eviction warnings.").withRank(CTask)
val evictionWarningOptions = settingKey[EvictionWarningOptions]("Options on eviction warnings after resolving managed dependencies.").withRank(DSetting)
val transitiveUpdate = taskKey[Seq[UpdateReport]]("UpdateReports for the internal dependencies of this project.").withRank(DTask)

View File

@ -758,6 +758,28 @@ object Project extends ProjectExtra {
def updateExtraBuilds(s: State, f: List[URI] => List[URI]): State =
setExtraBuilds(s, f(extraBuilds(s)))
// used by Coursier integration
private[sbt] def transitiveInterDependencies(
state: State,
projectRef: ProjectRef
): Seq[ProjectRef] = {
def dependencies(map: Map[ProjectRef, Seq[ProjectRef]], id: ProjectRef): Set[ProjectRef] = {
def helper(map: Map[ProjectRef, Seq[ProjectRef]], acc: Set[ProjectRef]): Set[ProjectRef] =
if (acc.exists(map.contains)) {
val (kept, rem) = map.partition { case (k, _) => acc(k) }
helper(rem, acc ++ kept.valuesIterator.flatten)
} else
acc
helper(map - id, map.getOrElse(id, Nil).toSet)
}
val allProjectsDeps: Map[ProjectRef, Seq[ProjectRef]] =
(for {
(p, ref) <- Project.structure(state).allProjectPairs
} yield ref -> p.dependencies.map(_.project)).toMap
val deps = dependencies(allProjectsDeps.toMap, projectRef)
Project.structure(state).allProjectRefs.filter(p => deps(p))
}
object LoadAction extends Enumeration {
val Return, Current, Plugins = Value
}

View File

@ -38,6 +38,12 @@ final class BuildStructure(
case (build, unit) => refs(build, unit.defined.values.toSeq)
}
def allProjectRefs(build: URI): Seq[ProjectRef] = refs(build, allProjects(build))
def allProjectPairs: Seq[(ResolvedProject, ProjectRef)] =
for {
(build, unit) <- units.toSeq
p: ResolvedProject <- unit.defined.values.toSeq
} yield (p, ProjectRef(build, p.id))
val extra: BuildUtil[ResolvedProject] = BuildUtil(root, units, index.keyIndex, data)
private[this] def refs(build: URI, projects: Seq[ResolvedProject]): Seq[ProjectRef] =
projects.map { p =>

View File

@ -0,0 +1,126 @@
/*
* sbt
* Copyright 2011 - 2018, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt
package internal
import java.io.File
import lmcoursier.definitions.{ Classifier, Configuration => CConfiguration }
import lmcoursier._
import sbt.librarymanagement._
import Keys._
import sbt.internal.librarymanagement.{ CoursierArtifactsTasks, CoursierInputsTasks }
private[sbt] object LMCoursier {
def defaultCacheLocation: File = CoursierDependencyResolution.defaultCacheLocation
def coursierConfigurationTask(
withClassifiers: Boolean,
sbtClassifiers: Boolean
): Def.Initialize[Task[CoursierConfiguration]] =
Def.taskDyn {
val s = streams.value
val log = s.log
val resolversTask =
if (sbtClassifiers)
csrSbtResolvers
else
csrRecursiveResolvers
val classifiersTask: sbt.Def.Initialize[sbt.Task[Option[Seq[Classifier]]]] =
if (withClassifiers && !sbtClassifiers)
Def.task(Some(sbt.Keys.transitiveClassifiers.value.map(Classifier(_))))
else
Def.task(None)
Def.task {
val rs = resolversTask.value
val scalaOrg = scalaOrganization.value
val scalaVer = scalaVersion.value
val interProjectDependencies = csrInterProjectDependencies.value
val excludeDeps = Inputs.exclusions(
allExcludeDependencies.value,
scalaVer,
scalaBinaryVersion.value,
streams.value.log
)
val fallbackDeps = csrFallbackDependencies.value
val autoScalaLib = autoScalaLibrary.value && scalaModuleInfo.value.forall(
_.overrideScalaVersion
)
val profiles = csrMavenProfiles.value
val credentials = CoursierInputsTasks.credentialsTask.value
val createLogger = csrLogger.value
val cache = csrCachePath.value
val internalSbtScalaProvider = appConfiguration.value.provider.scalaProvider
val sbtBootJars = internalSbtScalaProvider.jars()
val sbtScalaVersion = internalSbtScalaProvider.version()
val sbtScalaOrganization = "org.scala-lang" // always assuming sbt uses mainline scala
val classifiers = classifiersTask.value
Classpaths.warnResolversConflict(rs, log)
CoursierConfiguration()
.withResolvers(rs.toVector)
.withInterProjectDependencies(interProjectDependencies.toVector)
.withFallbackDependencies(fallbackDeps.toVector)
.withExcludeDependencies(
excludeDeps.toVector.map {
case (o, n) =>
(o.value, n.value)
}.sorted
)
.withAutoScalaLibrary(autoScalaLib)
.withSbtScalaJars(sbtBootJars.toVector)
.withSbtScalaVersion(sbtScalaVersion)
.withSbtScalaOrganization(sbtScalaOrganization)
.withClassifiers(classifiers.toVector.flatten.map(_.value))
.withHasClassifiers(classifiers.nonEmpty)
.withMavenProfiles(profiles.toVector.sorted)
.withScalaOrganization(scalaOrg)
.withScalaVersion(scalaVer)
.withCredentials(credentials)
.withLogger(createLogger)
.withCache(cache)
.withLog(log)
}
}
private val pluginIvySnapshotsBase = Resolver.SbtRepositoryRoot.stripSuffix("/") + "/ivy-snapshots"
def coursierSbtResolversTask: Def.Initialize[sbt.Task[Seq[Resolver]]] = Def.task {
val resolvers =
sbt.Classpaths
.bootRepositories(appConfiguration.value)
.toSeq
.flatten ++ // required because of the hack above it seems
externalResolvers.in(updateSbtClassifiers).value
val pluginIvySnapshotsFound = resolvers.exists {
case repo: URLRepository =>
repo.patterns.artifactPatterns.headOption
.exists(_.startsWith(pluginIvySnapshotsBase))
case _ => false
}
val resolvers0 =
if (pluginIvySnapshotsFound && !resolvers.contains(Classpaths.sbtPluginReleases))
resolvers :+ Classpaths.sbtPluginReleases
else
resolvers
val keepPreloaded = true // coursierKeepPreloaded.value
if (keepPreloaded)
resolvers0
else
resolvers0.filter { r =>
!r.name.startsWith("local-preloaded")
}
}
def publicationsSetting(packageConfigs: Seq[(Configuration, CConfiguration)]): Def.Setting[_] = {
csrPublications := CoursierArtifactsTasks.coursierPublicationsTask(packageConfigs: _*).value
}
}

View File

@ -5,12 +5,15 @@
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt.internal
package sbt
package internal
import lmcoursier.CoursierDependencyResolution
import java.io.File
import sbt.internal.librarymanagement._
import sbt.internal.util.{ ConsoleAppender, LogOption }
import sbt.librarymanagement._
import sbt.librarymanagement.ivy.IvyDependencyResolution
import sbt.librarymanagement.syntax._
import sbt.util.{ CacheStore, CacheStoreFactory, Logger, Tracked }
import sbt.io.IO
@ -19,6 +22,43 @@ private[sbt] object LibraryManagement {
private type UpdateInputs = (Long, ModuleSettings, UpdateConfiguration)
def defaultUseCoursier: Boolean = {
val coursierOpt = sys.props
.get("sbt.coursier")
.flatMap(
str =>
ConsoleAppender.parseLogOption(str) match {
case LogOption.Always => Some(true)
case LogOption.Never => Some(false)
case _ => None
}
)
val ivyOpt = sys.props
.get("sbt.ivy")
.flatMap(
str =>
ConsoleAppender.parseLogOption(str) match {
case LogOption.Always => Some(true)
case LogOption.Never => Some(false)
case _ => None
}
)
val notIvyOpt = ivyOpt map { !_ }
coursierOpt.orElse(notIvyOpt).getOrElse(true)
}
def dependencyResolutionTask: Def.Initialize[Task[DependencyResolution]] = Def.taskDyn {
if (Keys.useCoursier.value) {
Def.task { CoursierDependencyResolution(Keys.csrConfiguration.value) }
} else
Def.task {
IvyDependencyResolution(
Keys.ivyConfiguration.value,
CustomHttp.okhttpClient.value
)
}
}
def cachedUpdate(
lm: DependencyResolution,
module: ModuleDescriptor,
@ -33,6 +73,8 @@ private[sbt] object LibraryManagement {
ewo: EvictionWarningOptions,
mavenStyle: Boolean,
compatWarning: CompatibilityWarningOptions,
includeCallers: Boolean,
includeDetails: Boolean,
log: Logger
): UpdateReport = {
@ -50,15 +92,15 @@ private[sbt] object LibraryManagement {
throw unresolvedWarning.resolveException
}
log.debug(s"Done updating $label")
val finalReport = transform(report)
val report1 = transform(report)
// Warn of any eviction and compatibility warnings
val ew = EvictionWarning(module, ewo, finalReport)
val ew = EvictionWarning(module, ewo, report1)
ew.lines.foreach(log.warn(_))
ew.infoAllTheThings.foreach(log.info(_))
CompatibilityWarning.run(compatWarning, module, mavenStyle, log)
finalReport
val report2 = transformDetails(report1, includeCallers, includeDetails)
report2
}
/* Check if a update report is still up to date or we must resolve again. */
@ -90,7 +132,9 @@ private[sbt] object LibraryManagement {
import sbt.librarymanagement.LibraryManagementCodec._
val cachedResolve = Tracked.lastOutput[UpdateInputs, UpdateReport](cache) {
case (_, Some(out)) if upToDate(inChanged, out) => markAsCached(out)
case _ => resolve
case pair =>
log.debug(s""""not up to date. inChanged = $inChanged, force = $force""")
resolve
}
import scala.util.control.Exception.catching
catching(classOf[NullPointerException], classOf[OutOfMemoryError])
@ -150,4 +194,24 @@ private[sbt] object LibraryManagement {
.withExtraAttributes(m.extraAttributes)
.withConfigurations(if (confs) m.configurations else None)
.branch(m.branchName)
private[this] def transformDetails(
ur: UpdateReport,
includeCallers: Boolean,
includeDetails: Boolean
): UpdateReport = {
val crs0 = ur.configurations
val crs1 =
if (includeDetails) crs0
else crs0 map { _.withDetails(Vector()) }
val crs2 =
if (includeCallers) crs1
else
crs1 map { cr =>
val mrs0 = cr.modules
val mrs1 = mrs0 map { _.withCallers(Vector()) }
cr.withModules(mrs1)
}
ur.withConfigurations(crs2)
}
}

View File

@ -0,0 +1,157 @@
/*
* sbt
* Copyright 2011 - 2018, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt
package internal
package librarymanagement
import lmcoursier.definitions.{
Classifier,
Configuration => CConfiguration,
Extension => CExtension,
Publication => CPublication,
Type => CType
}
import sbt.librarymanagement._
import sbt.Keys._
object CoursierArtifactsTasks {
def coursierPublicationsTask(
configsMap: (sbt.librarymanagement.Configuration, CConfiguration)*
): Def.Initialize[sbt.Task[Seq[(CConfiguration, CPublication)]]] =
Def.task {
val s = sbt.Keys.state.value
val projectRef = sbt.Keys.thisProjectRef.value
val projId = sbt.Keys.projectID.value
val sv = sbt.Keys.scalaVersion.value
val sbv = sbt.Keys.scalaBinaryVersion.value
val ivyConfs = sbt.Keys.ivyConfigurations.value
val extracted = Project.extract(s)
import extracted._
val sourcesConfigOpt =
if (ivyConfigurations.value.exists(_.name == "sources"))
Some(CConfiguration("sources"))
else
None
val docsConfigOpt =
if (ivyConfigurations.value.exists(_.name == "docs"))
Some(CConfiguration("docs"))
else
None
val sbtBinArtifacts =
for ((config, targetConfig) <- configsMap) yield {
val publish = getOpt(
publishArtifact
.in(projectRef)
.in(packageBin)
.in(config)
).getOrElse(false)
if (publish)
getOpt(
artifact
.in(projectRef)
.in(packageBin)
.in(config)
).map(targetConfig -> _)
else
None
}
val sbtSourceArtifacts =
for ((config, targetConfig) <- configsMap) yield {
val publish = getOpt(
publishArtifact
.in(projectRef)
.in(packageSrc)
.in(config)
).getOrElse(false)
if (publish)
getOpt(
artifact
.in(projectRef)
.in(packageSrc)
.in(config)
).map(sourcesConfigOpt.getOrElse(targetConfig) -> _)
else
None
}
val sbtDocArtifacts =
for ((config, targetConfig) <- configsMap) yield {
val publish =
getOpt(
publishArtifact
.in(projectRef)
.in(packageDoc)
.in(config)
).getOrElse(false)
if (publish)
getOpt(
artifact
.in(projectRef)
.in(packageDoc)
.in(config)
).map(docsConfigOpt.getOrElse(targetConfig) -> _)
else
None
}
val sbtArtifacts = sbtBinArtifacts ++ sbtSourceArtifacts ++ sbtDocArtifacts
def artifactPublication(artifact: Artifact) = {
val name = CrossVersion(projId.crossVersion, sv, sbv)
.fold(artifact.name)(_(artifact.name))
CPublication(
name,
CType(artifact.`type`),
CExtension(artifact.extension),
artifact.classifier.fold(Classifier(""))(Classifier(_))
)
}
val sbtArtifactsPublication = sbtArtifacts.collect {
case Some((config, artifact)) =>
config -> artifactPublication(artifact)
}
val stdArtifactsSet = sbtArtifacts.flatMap(_.map { case (_, a) => a }.toSeq).toSet
// Second-way of getting artifacts from SBT
// No obvious way of getting the corresponding publishArtifact value for the ones
// only here, it seems.
val extraSbtArtifacts = getOpt(
sbt.Keys.artifacts
.in(projectRef)
).getOrElse(Nil)
.filterNot(stdArtifactsSet)
// Seems that SBT does that - if an artifact has no configs,
// it puts it in all of them. See for example what happens to
// the standalone JAR artifact of the coursier cli module.
def allConfigsIfEmpty(configs: Iterable[ConfigRef]): Iterable[ConfigRef] =
if (configs.isEmpty) ivyConfs.filter(_.isPublic).map(c => ConfigRef(c.name)) else configs
val extraSbtArtifactsPublication = for {
artifact <- extraSbtArtifacts
config <- allConfigsIfEmpty(artifact.configurations.map(x => ConfigRef(x.name)))
// FIXME If some configurations from artifact.configurations are not public, they may leak here :\
} yield CConfiguration(config.name) -> artifactPublication(artifact)
sbtArtifactsPublication ++ extraSbtArtifactsPublication
}
}

View File

@ -0,0 +1,235 @@
/*
* sbt
* Copyright 2011 - 2018, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt
package internal
package librarymanagement
import sbt.librarymanagement._
import sbt.util.Logger
import sbt.Keys._
import lmcoursier.definitions.{
Attributes => CAttributes,
Classifier,
Configuration => CConfiguration,
Dependency => CDependency,
// Extension => CExtension,
Info => CInfo,
Module,
ModuleName,
Organization => COrganization,
Project => CProject,
// Publication => CPublication,
Type => CType
}
import lmcoursier.credentials.DirectCredentials
import lmcoursier.{ FallbackDependency, FromSbt, Inputs }
import sbt.librarymanagement.ivy.{
FileCredentials,
Credentials,
DirectCredentials => IvyDirectCredentials
}
import sbt.ScopeFilter.Make._
import scala.collection.JavaConverters._
private[sbt] object CoursierInputsTasks {
private def coursierProject0(
projId: ModuleID,
dependencies: Seq[ModuleID],
excludeDeps: Seq[InclExclRule],
configurations: Seq[sbt.librarymanagement.Configuration],
sv: String,
sbv: String,
log: Logger
): CProject = {
val exclusions0 = Inputs.exclusions(excludeDeps, sv, sbv, log)
val configMap = Inputs.configExtends(configurations)
val proj = FromSbt.project(
projId,
dependencies,
configMap,
sv,
sbv
)
proj.copy(
dependencies = proj.dependencies.map {
case (config, dep) =>
(config, dep.copy(exclusions = dep.exclusions ++ exclusions0))
}
)
}
private[sbt] def coursierProjectTask: Def.Initialize[sbt.Task[CProject]] =
Def.task {
val auOpt = apiURL.value
val proj = coursierProject0(
projectID.value,
allDependencies.value,
allExcludeDependencies.value,
// should projectID.configurations be used instead?
ivyConfigurations.value,
scalaVersion.value,
scalaBinaryVersion.value,
streams.value.log
)
auOpt match {
case Some(au) =>
val props = proj.properties :+ ("info.apiURL" -> au.toString)
proj.copy(properties = props)
case _ => proj
}
}
private def moduleFromIvy(id: org.apache.ivy.core.module.id.ModuleRevisionId): Module =
Module(
COrganization(id.getOrganisation),
ModuleName(id.getName),
id.getExtraAttributes.asScala.map {
case (k0, v0) => k0.asInstanceOf[String] -> v0.asInstanceOf[String]
}.toMap
)
private def dependencyFromIvy(
desc: org.apache.ivy.core.module.descriptor.DependencyDescriptor
): Seq[(CConfiguration, CDependency)] = {
val id = desc.getDependencyRevisionId
val module = moduleFromIvy(id)
val exclusions = desc.getAllExcludeRules.map { rule =>
// we're ignoring rule.getConfigurations and rule.getMatcher here
val modId = rule.getId.getModuleId
// we're ignoring modId.getAttributes here
(COrganization(modId.getOrganisation), ModuleName(modId.getName))
}.toSet
val configurations = desc.getModuleConfigurations.toVector
.flatMap(Inputs.ivyXmlMappings)
def dependency(conf: CConfiguration, attr: CAttributes) = CDependency(
module,
id.getRevision,
conf,
exclusions,
attr,
optional = false,
desc.isTransitive
)
val attributes: CConfiguration => CAttributes = {
val artifacts = desc.getAllDependencyArtifacts
val m = artifacts.toVector.flatMap { art =>
val attr = CAttributes(CType(art.getType), Classifier(""))
art.getConfigurations.map(CConfiguration(_)).toVector.map { conf =>
conf -> attr
}
}.toMap
c => m.getOrElse(c, CAttributes(CType(""), Classifier("")))
}
configurations.map {
case (from, to) =>
from -> dependency(to, attributes(to))
}
}
private[sbt] def coursierInterProjectDependenciesTask: Def.Initialize[sbt.Task[Seq[CProject]]] =
Def.taskDyn {
val state = sbt.Keys.state.value
val projectRef = sbt.Keys.thisProjectRef.value
val projectRefs = Project.transitiveInterDependencies(state, projectRef)
Def.task {
val projects = csrProject.all(ScopeFilter(inProjects(projectRefs: _*))).value
val projectModules = projects.map(_.module).toSet
// this includes org.scala-sbt:global-plugins referenced from meta-builds in particular
val extraProjects = sbt.Keys.projectDescriptors.value
.map {
case (k, v) =>
moduleFromIvy(k) -> v
}
.filter {
case (module, _) =>
!projectModules(module)
}
.toVector
.map {
case (module, v) =>
val configurations = v.getConfigurations.map { c =>
CConfiguration(c.getName) -> c.getExtends.map(CConfiguration(_)).toSeq
}.toMap
val deps = v.getDependencies.flatMap(dependencyFromIvy)
CProject(
module,
v.getModuleRevisionId.getRevision,
deps,
configurations,
Nil,
None,
Nil,
CInfo("", "", Nil, Nil, None)
)
}
projects ++ extraProjects
}
}
private[sbt] def coursierFallbackDependenciesTask
: Def.Initialize[sbt.Task[Seq[FallbackDependency]]] =
Def.taskDyn {
val state = sbt.Keys.state.value
val projectRef = sbt.Keys.thisProjectRef.value
val projects = Project.transitiveInterDependencies(state, projectRef)
Def.task {
val allDeps =
allDependencies.all(ScopeFilter(inProjects(projectRef +: projects: _*))).value.flatten
FromSbt.fallbackDependencies(
allDeps,
scalaVersion.value,
scalaBinaryVersion.value
)
}
}
val credentialsTask = Def.task {
val log = streams.value.log
val creds = sbt.Keys.credentials.value
.flatMap {
case dc: IvyDirectCredentials => List(dc)
case fc: FileCredentials =>
Credentials.loadCredentials(fc.path) match {
case Left(err) =>
log.warn(s"$err, ignoring it")
Nil
case Right(dc) => List(dc)
}
}
.map { c =>
DirectCredentials()
.withHost(c.host)
.withUsername(c.userName)
.withPassword(c.passwd)
.withRealm(Some(c.realm).filter(_.nonEmpty))
.withHttpsOnly(false)
.withMatchHost(true)
}
creds ++ csrExtraCredentials.value
}
}

View File

@ -0,0 +1,130 @@
/*
* sbt
* Copyright 2011 - 2018, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt
package internal
package librarymanagement
import sbt.librarymanagement._
import sbt.Keys._
import sbt.ScopeFilter.Make._
import sbt.io.IO
private[sbt] object CoursierRepositoriesTasks {
private object CResolvers {
private val slowReposBase = Seq(
"https://repo.typesafe.com/",
"https://repo.scala-sbt.org/",
"http://repo.typesafe.com/",
"http://repo.scala-sbt.org/"
)
private val fastReposBase = Seq(
"http://repo1.maven.org/",
"https://repo1.maven.org/"
)
private def url(res: Resolver): Option[String] =
res match {
case m: sbt.librarymanagement.MavenRepository =>
Some(m.root)
case u: URLRepository =>
u.patterns.artifactPatterns.headOption
.orElse(u.patterns.ivyPatterns.headOption)
case _ =>
None
}
private def fastRepo(res: Resolver): Boolean =
url(res).exists(u => fastReposBase.exists(u.startsWith))
private def slowRepo(res: Resolver): Boolean =
url(res).exists(u => slowReposBase.exists(u.startsWith))
def reorderResolvers(resolvers: Seq[Resolver]): Seq[Resolver] =
if (resolvers.exists(fastRepo) && resolvers.exists(slowRepo)) {
val (slow, other) = resolvers.partition(slowRepo)
other ++ slow
} else
resolvers
}
private def resultTask(
bootResOpt: Option[Seq[Resolver]],
overrideFlag: Boolean
): Def.Initialize[sbt.Task[Seq[Resolver]]] =
bootResOpt.filter(_ => overrideFlag) match {
case Some(r) => Def.task(r)
case None =>
Def.taskDyn {
val extRes = externalResolvers.value
val isSbtPlugin = sbtPlugin.value
if (isSbtPlugin)
Def.task {
Seq(
sbtResolver.value,
Classpaths.sbtPluginReleases
) ++ extRes
} else
Def.task(extRes)
}
}
def coursierResolversTask: Def.Initialize[sbt.Task[Seq[Resolver]]] =
Def.taskDyn {
val bootResOpt = bootResolvers.value
val overrideFlag = overrideBuildResolvers.value
Def.task {
val result0 = resultTask(bootResOpt, overrideFlag).value
val reorderResolvers = true // coursierReorderResolvers.value
val keepPreloaded = true // coursierKeepPreloaded.value
val paths = ivyPaths.value
val result1 =
if (reorderResolvers) CResolvers.reorderResolvers(result0)
else result0
val result2 =
paths.ivyHome match {
case Some(ivyHome) =>
val ivyHomeUri = IO.toURI(ivyHome).getSchemeSpecificPart
result1 map {
case r: FileRepository =>
val ivyPatterns = r.patterns.ivyPatterns map {
_.replaceAllLiterally("$" + "{ivy.home}", ivyHomeUri)
}
val artifactPatterns = r.patterns.artifactPatterns map {
_.replaceAllLiterally("$" + "{ivy.home}", ivyHomeUri)
}
val p =
r.patterns.withIvyPatterns(ivyPatterns).withArtifactPatterns(artifactPatterns)
r.withPatterns(p)
case r => r
}
case _ => result1
}
if (keepPreloaded)
result2
else
result2.filter { r =>
!r.name.startsWith("local-preloaded")
}
}
}
def coursierRecursiveResolversTask: Def.Initialize[sbt.Task[Seq[Resolver]]] =
Def.taskDyn {
val state = sbt.Keys.state.value
val projectRef = sbt.Keys.thisProjectRef.value
val projects = Project.transitiveInterDependencies(state, projectRef)
Def.task {
csrResolvers.all(ScopeFilter(inProjects(projectRef +: projects: _*))).value.flatten
}
}
}

View File

@ -0,0 +1,225 @@
/*
* sbt
* Copyright 2011 - 2018, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt
package internal
package librarymanagement
import java.nio.charset.StandardCharsets.UTF_8
import java.nio.file.Files
import lmcoursier.definitions.{ Configuration, Project }
import org.apache.ivy.core.module.id.ModuleRevisionId
import Def.Setting
import sbt.Keys.{
csrProject,
csrPublications,
publishLocalConfiguration,
publishConfiguration,
useCoursier
}
import sbt.librarymanagement.PublishConfiguration
import scala.collection.JavaConverters._
import scala.xml.{ Node, PrefixedAttribute }
object IvyXml {
import sbt.Project._
private def rawContent(
currentProject: Project,
shadedConfigOpt: Option[Configuration]
): String = {
// Important: width = Int.MaxValue, so that no tag gets truncated.
// In particular, that prevents things like <foo /> to be split to
// <foo>
// </foo>
// by the pretty-printer.
// See https://github.com/sbt/sbt/issues/3412.
val printer = new scala.xml.PrettyPrinter(Int.MaxValue, 2)
"""<?xml version="1.0" encoding="UTF-8"?>""" + '\n' +
printer.format(content(currentProject, shadedConfigOpt))
}
// These are required for publish to be fine, later on.
private def writeFiles(
currentProject: Project,
shadedConfigOpt: Option[Configuration],
ivySbt: IvySbt,
log: sbt.util.Logger
): Unit = {
val ivyCacheManager = ivySbt.withIvy(log)(ivy => ivy.getResolutionCacheManager)
val ivyModule = ModuleRevisionId.newInstance(
currentProject.module.organization.value,
currentProject.module.name.value,
currentProject.version,
currentProject.module.attributes.asJava
)
val cacheIvyFile = ivyCacheManager.getResolvedIvyFileInCache(ivyModule)
val cacheIvyPropertiesFile = ivyCacheManager.getResolvedIvyPropertiesInCache(ivyModule)
val content0 = rawContent(currentProject, shadedConfigOpt)
cacheIvyFile.getParentFile.mkdirs()
log.info(s"Writing Ivy file $cacheIvyFile")
Files.write(cacheIvyFile.toPath, content0.getBytes(UTF_8))
// Just writing an empty file here... Are these only used?
cacheIvyPropertiesFile.getParentFile.mkdirs()
Files.write(cacheIvyPropertiesFile.toPath, Array.emptyByteArray)
()
}
private def content(project0: Project, shadedConfigOpt: Option[Configuration]): Node = {
val filterOutDependencies =
shadedConfigOpt.toSet[Configuration].flatMap { shadedConfig =>
project0.dependencies
.collect { case (conf, dep) if conf.value == shadedConfig.value => dep }
}
val project: Project = project0.copy(
dependencies = project0.dependencies.collect {
case p @ (_, dep) if !filterOutDependencies(dep) => p
}
)
val infoAttrs =
(project.module.attributes.toSeq ++ project.properties).foldLeft[xml.MetaData](xml.Null) {
case (acc, (k, v)) =>
new PrefixedAttribute("e", k, v, acc)
}
val licenseElems = project.info.licenses.map {
case (name, urlOpt) =>
val n = <license name={name} />
urlOpt.fold(n) { url =>
n % <x url={url} />.attributes
}
}
val infoElem = {
<info
organisation={project.module.organization.value}
module={project.module.name.value}
revision={project.version}
>
{licenseElems}
<description>{project.info.description}</description>
</info>
} % infoAttrs
val confElems = project.configurations.toVector.collect {
case (name, extends0) if !shadedConfigOpt.exists(_.value == name.value) =>
val extends1 = shadedConfigOpt.fold(extends0)(c => extends0.filter(_.value != c.value))
val n = <conf name={name.value} visibility="public" description="" />
if (extends1.nonEmpty)
n % <x extends={extends1.map(_.value).mkString(",")} />.attributes
else
n
}
val publications = project.publications
.groupBy { case (_, p) => p }
.mapValues { _.map { case (cfg, _) => cfg } }
val publicationElems = publications.map {
case (pub, configs) =>
val n =
<artifact name={pub.name} type={pub.`type`.value} ext={pub.ext.value} conf={
configs.map(_.value).mkString(",")
} />
if (pub.classifier.value.nonEmpty)
n % <x e:classifier={pub.classifier.value} />.attributes
else
n
}
val dependencyElems = project.dependencies.toVector.map {
case (conf, dep) =>
val excludes = dep.exclusions.toSeq.map {
case (org, name) =>
<exclude org={org.value} module={name.value} name="*" type="*" ext="*" conf="" matcher="exact"/>
}
val n =
<dependency org={dep.module.organization.value} name={dep.module.name.value} rev={
dep.version
} conf={s"${conf.value}->${dep.configuration.value}"}>
{excludes}
</dependency>
val moduleAttrs = dep.module.attributes.foldLeft[xml.MetaData](xml.Null) {
case (acc, (k, v)) =>
new PrefixedAttribute("e", k, v, acc)
}
n % moduleAttrs
}
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
{infoElem}
<configurations>{confElems}</configurations>
<publications>{publicationElems}</publications>
<dependencies>{dependencyElems}</dependencies>
</ivy-module>
}
private def makeIvyXmlBefore[T](
task: TaskKey[T],
shadedConfigOpt: Option[Configuration]
): Setting[Task[T]] =
task := task.dependsOn {
Def.taskDyn {
val doGen = useCoursier.value
if (doGen)
Def.task {
val currentProject = {
val proj = csrProject.value
val publications = csrPublications.value
proj.copy(publications = publications)
}
IvyXml.writeFiles(
currentProject,
shadedConfigOpt,
sbt.Keys.ivySbt.value,
sbt.Keys.streams.value.log
)
} else
Def.task(())
}
}.value
private lazy val needsIvyXmlLocal = Seq(publishLocalConfiguration) ++ getPubConf(
"makeIvyXmlLocalConfiguration"
)
private lazy val needsIvyXml = Seq(publishConfiguration) ++ getPubConf(
"makeIvyXmlConfiguration"
)
private[this] def getPubConf(method: String): List[TaskKey[PublishConfiguration]] =
try {
val cls = sbt.Keys.getClass
val m = cls.getMethod(method)
val task = m.invoke(sbt.Keys).asInstanceOf[TaskKey[PublishConfiguration]]
List(task)
} catch {
case _: Throwable => // FIXME Too wide
Nil
}
def generateIvyXmlSettings(
shadedConfigOpt: Option[Configuration] = None
): Seq[Setting[_]] =
(needsIvyXml ++ needsIvyXmlLocal).map(makeIvyXmlBefore(_, shadedConfigOpt))
}

View File

@ -29,23 +29,7 @@ object Dependencies {
private val utilScripted = "org.scala-sbt" %% "util-scripted" % utilVersion
private val libraryManagementCore = "org.scala-sbt" %% "librarymanagement-core" % lmVersion
private val libraryManagementIvy = "org.scala-sbt" %% "librarymanagement-ivy" % lmVersion
private val libraryManagementImpl = {
val lmOrganization =
sys.props.get("sbt.build.lm.organization") match {
case Some(impl) => impl
case _ => "org.scala-sbt"
}
val lmModuleName =
sys.props.get("sbt.build.lm.moduleName") match {
case Some(impl) => impl
case _ => "librarymanagement-ivy"
}
lmOrganization %% lmModuleName % lmVersion
}
private val libraryManagementImpl = "org.scala-sbt" %% "librarymanagement-ivy" % lmVersion
val launcherVersion = "1.0.4"
val launcherInterface = "org.scala-sbt" % "launcher-interface" % launcherVersion
@ -126,6 +110,9 @@ object Dependencies {
def addSbtZincCompileCore(p: Project): Project =
addSbtModule(p, sbtZincPath, "zincCompileCore", zincCompileCore)
val lmCoursierVersion = "1.1.0-M14-1"
val lmCoursierShaded = "io.get-coursier" %% "lm-coursier-shaded" % lmCoursierVersion
val sjsonNewScalaJson = Def.setting {
"com.eed3si9n" %% "sjson-new-scalajson" % contrabandSjsonNewVersion.value
}

View File

@ -1,3 +1,6 @@
// https://github.com/coursier/coursier/issues/1123
ThisBuild / useCoursier := false
Seq(
autoAPIMappings in ThisBuild := true,
publishArtifact in (ThisBuild, packageDoc) := false,

View File

@ -0,0 +1,10 @@
import sjsonnew.BasicJsonProtocol._
val cacheTask = taskKey[Int]("task")
cacheTask := 1
val checkTask = inputKey[Unit]("validate that the correct value is set by cacheTask")
checkTask := {
val expected = Def.spaceDelimited("").parsed.head.toInt
assert(cacheTask.previous.getOrElse(0) == expected)
}

View File

@ -0,0 +1,5 @@
> checkTask 0
> cacheTask
> checkTask 1

View File

@ -1,9 +1,10 @@
import java.nio.file.Files
import java.nio.file.attribute.FileTime
import scala.collection.JavaConverters._
val rewriteIvy = inputKey[Unit]("Rewrite ivy directory")
ThisBuild / useCoursier := false
val snapshot = (project in file(".")).settings(
name := "akka-test",
scalaVersion := "2.12.8",

View File

@ -0,0 +1,6 @@
ThisBuild / scalaVersion := "2.11.12"
libraryDependencies += ("com.rengwuxian.materialedittext" % "library" % "2.1.4")
.exclude("com.android.support", "support-v4")
.exclude("com.android.support", "support-annotations")
.exclude("com.android.support", "appcompat-v7")

View File

@ -0,0 +1,6 @@
import java.io.File
import java.nio.file.Files
object Main extends App {
Files.write(new File("output").toPath, "OK".getBytes("UTF-8"))
}

View File

@ -0,0 +1,3 @@
$ delete output
> run
$ exists output

View File

@ -3,8 +3,10 @@ import sbt.internal.inc.classpath.ClasspathUtilities
lazy val checkFull = taskKey[Unit]("")
lazy val check = taskKey[Unit]("")
lazy val root = (project in file(".")).
settings(
ThisBuild / useCoursier := false
lazy val root = (project in file("."))
.settings(
ivyPaths := IvyPaths(baseDirectory.value, Some(target.value / "ivy-cache")),
publishTo := Some(Resolver.file("Test Publish Repo", file("test-repo"))),
resolvers += (baseDirectory { base => "Test Repo" at (base / "test-repo").toURI.toString }).value,
@ -34,8 +36,10 @@ def publishedID = org % artifactID % vers artifacts(mainArtifact)
def retrieveID = org % "test-retrieve" % "2.0"
// check that the test class is on the compile classpath, either because it was compiled or because it was properly retrieved
def checkTask(classpath: TaskKey[Classpath]) = Def task {
val loader = ClasspathUtilities.toLoader((classpath in Compile).value.files, scalaInstance.value.loader)
def checkTask(classpath: TaskKey[Classpath]) = Def.task {
val deps = libraryDependencies.value
val cp = (classpath in Compile).value.files
val loader = ClasspathUtilities.toLoader(cp, scalaInstance.value.loader)
try { Class.forName("test.Test", false, loader); () }
catch { case _: ClassNotFoundException | _: NoClassDefFoundError => sys.error("Dependency not retrieved properly") }
catch { case _: ClassNotFoundException | _: NoClassDefFoundError => sys.error(s"Dependency not retrieved properly: $deps, $cp") }
}

View File

@ -0,0 +1,20 @@
autoScalaLibrary := false
libraryDependencies += "com.chuusai" % "shapeless_2.12" % "2.3.2"
val checkScalaLibrary = TaskKey[Unit]("checkScalaLibrary")
checkScalaLibrary := {
val scalaLibsJars = managedClasspath
.in(Compile)
.value
.map(_.data.getName)
.filter(_.startsWith("scala-library"))
.sorted
val expectedScalaLibsJars = Seq(
"scala-library-2.12.0.jar"
)
assert(
scalaLibsJars == expectedScalaLibsJars,
s"$scalaLibsJars != $expectedScalaLibsJars"
)
}

View File

@ -0,0 +1 @@
> checkScalaLibrary

View File

@ -1,5 +1,8 @@
ThisBuild / scalaVersion := "2.12.8"
// TTL of Coursier is 24h
ThisBuild / useCoursier := false
def localCache =
ivyPaths := IvyPaths(baseDirectory.value, Some((baseDirectory in ThisBuild).value / "ivy" / "cache"))

View File

@ -31,7 +31,9 @@ lazy val root = (project in file("."))
// sbt resolves dependencies every compile when using %% with dependencyOverrides
TaskKey[Unit]("check") := {
val s = (streams in update).value
val cacheStoreFactory = s.cacheStoreFactory sub updateCacheName.value
val cacheDirectory = crossTarget.value / "update" / updateCacheName.value
val cacheStoreFactory = sbt.util.CacheStoreFactory.directory(cacheDirectory)
val module = ivyModule.value
val updateConfig = updateConfiguration.value
val extraInputHash0 = module.extraInputHash

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
lazy val check = taskKey[Unit]("Runs the check")
def commonSettings: Seq[Def.Setting[_]] =

View File

@ -1,6 +1,8 @@
// https://github.com/sbt/sbt/issues/1649
lazy val check = taskKey[Unit]("Runs the check")
ThisBuild / useCoursier := false
def commonSettings: Seq[Def.Setting[_]] =
Seq(
ivyPaths := IvyPaths( (baseDirectory in ThisBuild).value, Some((baseDirectory in LocalRootProject).value / "ivy-cache")),

View File

@ -3,7 +3,7 @@ lazy val check = taskKey[Unit]("Runs the check")
def commonSettings: Seq[Def.Setting[_]] =
Seq(
ivyPaths := IvyPaths( (baseDirectory in ThisBuild).value, Some((target in LocalRootProject).value / "ivy-cache")),
scalaVersion in ThisBuild := "2.11.7",
scalaVersion in ThisBuild := "2.11.12",
organization in ThisBuild := "com.example",
version in ThisBuild := "0.1.0-SNAPSHOT",
autoScalaLibrary := false,

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
lazy val check = taskKey[Unit]("Runs the check")
def commonSettings: Seq[Def.Setting[_]] =

View File

@ -0,0 +1,2 @@
ThisBuild / scalaVersion := "2.11.12"
libraryDependencies += "org.jclouds.api" % "nova" % "1.5.9" classifier "tests"

View File

@ -0,0 +1,18 @@
import java.io.File
import java.nio.file.Files
import scala.util.Try
object Main extends App {
def classFound(clsName: String) = Try(
Thread.currentThread()
.getContextClassLoader()
.loadClass(clsName)
).toOption.nonEmpty
val name = "org.jclouds.openstack.nova.functions.ParseServerFromJsonResponseTest"
val classifierTest = classFound(name)
assert(classifierTest, s"Couldn't find $name")
}

View File

@ -0,0 +1 @@
> run

View File

@ -1,7 +1,9 @@
scalaVersion := "2.12.6"
ThisBuild / scalaVersion := "2.12.8"
lazy val check = taskKey[Unit]("")
// We can't use "%%" here without breaking the "== bridgeModule" check below
val bridgeModule = "org.scala-sbt" % s"compiler-bridge_2.12" % "1.2.1"
val bridgeModule = "org.scala-sbt" % s"compiler-bridge_2.12" % "1.3.0-M3"
libraryDependencies += bridgeModule % Configurations.ScalaTool
@ -10,7 +12,14 @@ scalaCompilerBridgeSource := "shouldnotbeused" % "dummy" % "dummy"
scalaCompilerBridgeBinaryJar := {
for {
toolReport <- update.value.configuration(Configurations.ScalaTool)
m <- toolReport.modules.find(m => m.module == bridgeModule)
m <- toolReport.modules.find(m => m.module.name == bridgeModule.name)
(_, file) <- m.artifacts.find(art => art._1.`type` == Artifact.DefaultType)
} yield file
}
check := {
val toolReport = update.value.configuration(Configurations.ScalaTool).get
val m = toolReport.modules.find(m => m.module.name == bridgeModule.name)
val bridge = scalaCompilerBridgeBinaryJar.value
bridge.getOrElse(sys.error(s"bridge JAR is missing: $toolReport"))
}

View File

@ -1 +1,2 @@
> check
> compile

View File

@ -1,11 +1,11 @@
configurationsToRetrieve := Some(Vector(Compile))
ThisBuild / useCoursier := false
retrieveManaged := true
libraryDependencies += "log4j" % "log4j" % "1.2.16" % "compile"
autoScalaLibrary := false
managedDirectory := file("dependencies")
retrievePattern := "[conf]/[artifact]-[revision](-[classifier]).[ext]"
lazy val root = (project in file("."))
.settings(
configurationsToRetrieve := Some(Vector(Compile)),
retrieveManaged := true,
libraryDependencies += "log4j" % "log4j" % "1.2.16" % "compile",
autoScalaLibrary := false,
managedDirectory := file("dependencies"),
retrievePattern := "[conf]/[artifact]-[revision](-[classifier]).[ext]",
)

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
libraryDependencies ++= Seq(
"org.spark-project" %% "spark-core" % "0.5.1",
"log4j" % "log4j" % "1.2.17"

View File

@ -1,11 +1,13 @@
ThisBuild / useCoursier := false
resolvers += Resolver.file("buggy", file("repo"))(
Patterns(
ivyPatterns = Vector("[organization]/[module]/[revision]/ivy.xml"),
artifactPatterns = Vector("[organization]/[module]/[revision]/[artifact].[ext]"),
isMavenCompatible = false,
descriptorOptional = true,
skipConsistencyCheck = true
)
Patterns(
ivyPatterns = Vector("[organization]/[module]/[revision]/ivy.xml"),
artifactPatterns = Vector("[organization]/[module]/[revision]/[artifact].[ext]"),
isMavenCompatible = false,
descriptorOptional = true,
skipConsistencyCheck = true
)
)
libraryDependencies += "a" % "b" % "1.0.0" % "compile->runtime" artifacts(Artifact("b1", "jar", "jar"))

View File

@ -1,13 +1,13 @@
<ivy-module xmlns:e="http://ant.apache.org/ivy/extra" version="2.0">
<info organisation="a" module="b" revision="1.0.0" status="release" publication="20160201120702">
<description>a</description>
<description>a</description>
</info>
<configurations>
<conf name="runtime" description="..."/>
<conf name="runtime" description="..."/>
</configurations>
<publications>
<artifact name="b1.jar" type="jar" ext="jar" conf="runtime"/>
<artifact name="b2.jar" type="jar" ext="jar" conf="runtime"/>
<artifact name="b1" type="jar" ext="jar" conf="runtime"/>
<artifact name="fake" type="jar" ext="jar" conf="runtime"/>
</publications>
<dependencies>
</dependencies>

View File

@ -9,14 +9,14 @@ val repatchTwitter = "com.eed3si9n" %% "repatch-twitter-core" % "dispatch0.11.1_
lazy val a = (project in file("a")).
settings(
scalaVersion := "2.11.4",
scalaVersion := "2.11.12",
libraryDependencies += dispatch,
excludeDependencies += "org.slf4j"
)
lazy val b = (project in file("b")).
settings(
scalaVersion := "2.11.4",
scalaVersion := "2.11.12",
libraryDependencies += repatchTwitter,
excludeDependencies += "net.databinder.dispatch" %% "dispatch-core"
)

View File

@ -0,0 +1,11 @@
ThisBuild / scalaVersion := "2.11.12"
organization := "io.get-coursier.test"
name := "sbt-coursier-exclude-dependencies"
version := "0.1.0-SNAPSHOT"
libraryDependencies += "com.github.alexarchambault" %% "argonaut-shapeless_6.1" % "1.0.0-RC1"
excludeDependencies += sbt.ExclusionRule("com.chuusai", "shapeless_2.11")
excludeDependencies += "io.argonaut" %% "argonaut"

View File

@ -0,0 +1,32 @@
import java.io.File
import java.nio.file.Files
import scala.util.Try
object Main extends App {
def classFound(clsName: String) = Try(
Thread.currentThread()
.getContextClassLoader()
.loadClass(clsName)
).toOption.nonEmpty
val shapelessFound = classFound("shapeless.HList")
val argonautFound = classFound("argonaut.Json")
val argonautShapelessFound = classFound("argonaut.derive.MkEncodeJson")
assert(
argonautShapelessFound,
"Expected to find class from argonaut-shapeless"
)
assert(
!shapelessFound,
"Expected not to find classes from shapeless"
)
assert(
!argonautFound,
"Expected not to find classes from argonaut"
)
Files.write(new File("output").toPath, "OK".getBytes("UTF-8"))
}

View File

@ -0,0 +1,5 @@
$ delete output
> run
$ exists output
> publishLocal
$ exec java -jar coursier launch io.get-coursier.test:sbt-coursier-exclude-dependencies_2.11:0.1.0-SNAPSHOT

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
lazy val root = (project in file("."))
.settings(
scalaVersion := "2.12.6",

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
lazy val root = (project in file("."))
.settings(
organization := "org.example",

View File

@ -0,0 +1,6 @@
case class A(msg: String)
object A {
def default = A("OK")
}

View File

@ -0,0 +1,9 @@
import java.io.File
import java.nio.file.Files
object Main extends App {
val msg = shapeless.Generic[A].to(A.default).head
Files.write(new File("output").toPath, msg.getBytes("UTF-8"))
}

View File

@ -0,0 +1,13 @@
ThisBuild / scalaVersion := "2.11.12"
lazy val a = project
.settings(
libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.234" from "https://oss.sonatype.org/content/repositories/releases/com/chuusai/shapeless_2.11/2.3.1/shapeless_2.11-2.3.1.jar"
)
lazy val b = project
.dependsOn(a)
lazy val root = project
.in(file("."))
.aggregate(a, b)

View File

@ -0,0 +1,3 @@
$ delete output
> b/run
$ exists output

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
libraryDependencies += "log4j" % "log4j" % "1.2.16" % "compile"
autoScalaLibrary := false

View File

@ -0,0 +1 @@
scalaVersion := "2.12.8"

View File

@ -0,0 +1,2 @@
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.2.5")
addSbtPlugin("org.scalameta" % "sbt-metals" % "0.4.4")

View File

@ -0,0 +1,2 @@
> metalsEnable
> bloopInstall

View File

@ -0,0 +1,3 @@
ThisBuild / scalaVersion := "2.11.12"
libraryDependencies += "org.apache.hadoop" % "hadoop-yarn-server-resourcemanager" % "2.7.1"

View File

@ -0,0 +1,8 @@
import java.io.File
import java.nio.file.Files
import org.apache.zookeeper.ZooKeeper
object Main extends App {
Files.write(new File("output").toPath, classOf[ZooKeeper].getSimpleName.getBytes("UTF-8"))
}

View File

@ -0,0 +1,3 @@
$ delete output
> run
$ exists output

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
import scala.xml._
lazy val root = (project in file(".")).

View File

@ -0,0 +1,6 @@
case class A(msg: String)
object A {
def default = A("OK")
}

View File

@ -0,0 +1,14 @@
import java.io.File
import java.nio.file.Files
import scalaz.stream._
import scalaz.concurrent.Task
object Main extends App {
val pch = Process.constant((i:Int) => Task.now(())).take(3)
val count = Process.constant(1).toSource.to(pch).runLog.run.size
assert(count == 3)
Files.write(new File("output").toPath, A.default.msg.getBytes("UTF-8"))
}

View File

@ -0,0 +1,17 @@
ThisBuild / scalaVersion := "2.11.12"
lazy val a = project
.settings(
resolvers += "Scalaz Bintray Repo" at "https://dl.bintray.com/scalaz/releases"
)
lazy val b = project
.dependsOn(a)
.settings(
// resolver added in inter-project dependency only - should still be fine
libraryDependencies += "org.scalaz.stream" %% "scalaz-stream" % "0.7.1a"
)
lazy val root = project
.in(file("."))
.aggregate(a, b)

View File

@ -0,0 +1,3 @@
$ delete output
> b/run
$ exists output

View File

@ -0,0 +1,6 @@
object A {
def msg = "OK"
}

View File

@ -0,0 +1,13 @@
import java.io.File
import java.nio.file.Files
import argonaut._, Argonaut._, ArgonautShapeless._
object Main extends App {
case class CC(i: Int, s: String)
val msg = CC(2, A.msg).asJson.spaces2
Files.write(new File("output").toPath, msg.getBytes("UTF-8"))
}

View File

@ -0,0 +1,26 @@
ThisBuild / scalaVersion := "2.11.12"
/** Module with the same Maven coordinates as shapeless 2.3.1 */
lazy val `shapeless-mock` = project
.settings(
organization := "com.chuusai",
name := "shapeless",
version := "2.3.1"
)
lazy val a = project
.settings(
organization := "com.pany",
name := "a",
version := "0.0.1"
)
/** Transitively depends on the - real - shapeless 2.3.1 */
lazy val b = project
.dependsOn(a)
.settings(
organization := "com.pany",
name := "b",
version := "0.0.1",
libraryDependencies += "com.github.alexarchambault" %% "argonaut-shapeless_6.2" % "1.2.0-M1"
)

View File

@ -0,0 +1,3 @@
$ delete output
> b/run
$ exists output

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
externalIvySettings()
externalIvyFile()

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
externalIvySettings()
libraryDependencies += "org.scalacheck" % "scalacheck" % "1.5"

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
lazy val commonSettings = Seq(
autoScalaLibrary := false,
scalaModuleInfo := None,

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
lazy val commonSettings = Seq(
autoScalaLibrary := false,
unmanagedJars in Compile ++= (scalaInstance map (_.allJars.toSeq)).value

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
lazy val a = (project in file(".")).
settings(externalIvySettings()) dependsOn(b)

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
addSbtPlugin("org.example" % "def" % "latest.integration")
resolvers ++= {

View File

@ -0,0 +1,30 @@
lazy val noPomCheck = TaskKey[Unit]("noPomCheck")
noPomCheck := {
val log = streams.value.log
val configReport = update.value
.configuration(Compile)
.getOrElse {
throw new Exception(
"compile configuration not found in update report"
)
}
val artifacts = configReport
.modules
.flatMap(_.artifacts)
.map(_._1)
val pomArtifacts = artifacts
.filter { a =>
a.`type` == "pom" && a.classifier.isEmpty
}
for (a <- pomArtifacts)
log.error(s"Found POM artifact $a")
assert(pomArtifacts.isEmpty)
}

View File

@ -0,0 +1 @@
> noPomCheck

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
import complete._
import complete.DefaultParsers._

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
val checkIvyXml = taskKey[Unit]("Checks the ivy.xml transform was correct")
lazy val root = (project in file(".")).

View File

@ -0,0 +1,5 @@
ThisBuild / scalaVersion := "2.11.12"
Compile / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat
libraryDependencies += "org.apache.spark" %% "spark-sql" % "1.6.2"
csrMavenProfiles += "hadoop-2.6"

View File

@ -0,0 +1 @@
OK

View File

@ -0,0 +1,19 @@
import java.io.File
import java.nio.file.Files
object Main extends App {
val p = new java.util.Properties
p.load(
Thread.currentThread()
.getContextClassLoader
.getResource("common-version-info.properties")
.openStream()
)
val hadoopVersion = p.getProperty("version")
Console.err.println(s"Found hadoop version $hadoopVersion")
assert(hadoopVersion == "2.6.0")
Files.write(new File("output").toPath, "OK".getBytes("UTF-8"))
}

View File

@ -0,0 +1,3 @@
$ delete output
> run
$ exists output

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
retrieveManaged := true
libraryDependencies += "log4j" % "log4j" % "1.2.16"

View File

@ -2,7 +2,7 @@ scalaOrganization := "org.other"
scalaArtifacts += "thing"
scalaVersion := "2.11.8"
ThisBuild / scalaVersion := "2.11.12"
libraryDependencies ++= Seq(
"org.other" % "thing" % "1.2.3",

View File

@ -1,3 +1,5 @@
ThisBuild / useCoursier := false
organization := "org.dummy"
scalaOrganization := "org.other"

View File

@ -1,6 +1,6 @@
// https://github.com/sbt/sbt/issues/1818
scalaVersion := "2.11.5"
ThisBuild / scalaVersion := "2.11.12"
libraryDependencies += "org.scala-lang" %% "scala-actors-migration" % "1.1.0"
libraryDependencies += "org.scala-lang" %% "scala-pickling" % "0.9.1"

View File

@ -0,0 +1,38 @@
ThisBuild / organization := "com.example"
ThisBuild / scalaVersion := "2.12.8"
def customIvyPaths: Seq[Def.Setting[_]] = Seq(
ivyPaths := IvyPaths((baseDirectory in ThisBuild).value, Some((baseDirectory in ThisBuild).value / "ivy-cache"))
)
lazy val sharedResolver: Resolver = {
val r = Resolver.defaultShared
r withConfiguration (r.configuration withIsLocal false)
//MavenRepository("example-shared-repo", "file:///tmp/shared-maven-repo-bad-example")
//Resolver.file("example-shared-repo", repoDir)(Resolver.defaultPatterns)
}
lazy val common = project
.settings(customIvyPaths)
.settings(
organization := "com.badexample",
name := "badexample",
version := "1.0-SNAPSHOT",
publishTo := Some(sharedResolver),
crossVersion := Disabled(),
publishMavenStyle := (sharedResolver match {
case repo: PatternsBasedRepository => repo.patterns.isMavenCompatible
case _: RawRepository => false // TODO - look deeper
case _: MavenRepository => true
case _ => false // TODO - Handle chain repository?
})
)
lazy val dependent = project
.settings(customIvyPaths)
.settings(
// Ignore the inter-project resolver, so we force to look remotely.
resolvers += sharedResolver,
fullResolvers := fullResolvers.value.filterNot(_==projectResolver.value),
libraryDependencies += "com.badexample" % "badexample" % "1.0-SNAPSHOT"
)

View File

@ -0,0 +1,2 @@
object Common {
}

View File

@ -0,0 +1,3 @@
object Common {
def name = "common"
}

View File

@ -0,0 +1,3 @@
object Common {
}

View File

@ -0,0 +1,3 @@
object User {
println(Common.name)
}

View File

@ -0,0 +1,21 @@
# Ivy is able to check for SNAPSHOT across different resolvers
# Coursier seems to be sticky about the resolver within the TTL
> show dependent/fullResolvers
# Validate that a bad dependency fails the compile
$ copy-file changes/BadCommon.scala common/src/main/scala/Common.scala
> common/publishLocal
# Force dep resolution to be successful, then compilation to fail
> dependent/update
-> dependent/compile
# Push new good change to the same repository.
$ copy-file changes/GoodCommon.scala common/src/main/scala/Common.scala
$ sleep 1000
> common/publishLocal
# This should compile now because Coursier checks for local update
> show dependent/update
> dependent/compile

View File

@ -1,6 +1,9 @@
ThisBuild / organization := "com.example"
ThisBuild / scalaVersion := "2.12.8"
// TTL is 24h so we can't detect the change
ThisBuild / useCoursier := false
def customIvyPaths: Seq[Def.Setting[_]] = Seq(
ivyPaths := IvyPaths((baseDirectory in ThisBuild).value, Some((baseDirectory in ThisBuild).value / "ivy-cache"))
)

View File

@ -1,5 +1,7 @@
lazy val root = (project in file(".")).
settings(
ThisBuild / useCoursier := false
lazy val root = (project in file("."))
.settings(
libraryDependencies += "net.liftweb" % "lift-webkit" % "1.0" intransitive(),
libraryDependencies += "org.scalacheck" % "scalacheck" % "1.5" intransitive(),
autoScalaLibrary := false,
@ -11,15 +13,15 @@ lazy val root = (project in file(".")).
def getSources(report: UpdateReport) = report.matching(artifactFilter(`classifier` = "sources") )
def checkSources(report: UpdateReport): Unit =
{
val srcs = getSources(report)
if(srcs.isEmpty)
sys.error("No sources retrieved")
else if(srcs.size != 2)
sys.error("Incorrect sources retrieved:\n\t" + srcs.mkString("\n\t"))
else
()
}
{
val srcs = getSources(report)
if(srcs.isEmpty)
sys.error(s"No sources retrieved\n\n$report")
else if(srcs.size != 2)
sys.error("Incorrect sources retrieved:\n\t" + srcs.mkString("\n\t"))
else
()
}
def checkBinaries(report: UpdateReport): Unit =
{

View File

@ -1,10 +1,10 @@
ThisBuild / useCoursier := false
ivyPaths := {
val base = baseDirectory.value
IvyPaths(base, Some(base / "ivy-cache"))
}
managedScalaInstance := false
autoScalaLibrary := false
crossPaths := false

View File

@ -1,5 +1,6 @@
ThisBuild / scalaVersion := "2.11.12"
organization := "com.test"
name := "maven-version-range-bug"
version := "1.0.0-SNAPSHOT"
scalaVersion := "2.11.6"
libraryDependencies += "com.amazonaws" % "aws-java-sdk" % "1.7.8.1"
libraryDependencies += "com.amazonaws" % "aws-java-sdk" % "1.7.8.1"

View File

@ -1,4 +1,4 @@
scalaVersion := "2.11.11"
ThisBuild / scalaVersion := "2.11.12"
ivyConfiguration := {
throw new RuntimeException("updateSbtClassifiers should use updateSbtClassifiers / ivyConfiguration")

View File

@ -0,0 +1,3 @@
ThisBuild / scalaVersion := "2.11.12"
libraryDependencies += "ccl.northwestern.edu" % "netlogo" % "5.3.1" % "provided" from s"https://github.com/NetLogo/NetLogo/releases/download/5.3.1/NetLogo.jar"

View File

@ -0,0 +1,11 @@
import java.io.File
import java.nio.file.Files
object Main extends App {
// Not using directly the NetLogo 5.x lib, which seems to depend on Scala 2.9
// Can't find a way to check that NetLogo.jar is in the classpath
// These don't work, even with fork := true:
// assert(Thread.currentThread.getContextClassLoader.getResource("org/nlogo/nvm/Task.class") != null)
// Thread.currentThread.getContextClassLoader.getResource("org/nlogo/nvm/Task.class")
Files.write(new File("output").toPath, "OK".getBytes("UTF-8"))
}

Some files were not shown because too many files have changed in this diff Show More