mirror of https://github.com/sbt/sbt.git
Merge pull request #92 from scalacenter/offline-mode
Add offline mode to `UpdateConfiguration`
This commit is contained in:
commit
498367dbf4
|
|
@ -19,6 +19,7 @@ def commonSettings: Seq[Setting[_]] = Seq(
|
|||
mimaPreviousArtifacts := Set(), // Some(organization.value %% moduleName.value % "1.0.0"),
|
||||
publishArtifact in Compile := true,
|
||||
publishArtifact in Test := false,
|
||||
parallelExecution in Test := false,
|
||||
commands += Command.command("scalafmtCheck") { state =>
|
||||
sys.process.Process("git diff --name-only --exit-code").! match {
|
||||
case 0 => // ok
|
||||
|
|
|
|||
|
|
@ -634,7 +634,8 @@
|
|||
{ "name": "retrieve", "type": "sbt.internal.librarymanagement.RetrieveConfiguration?" },
|
||||
{ "name": "missingOk", "type": "boolean" },
|
||||
{ "name": "logging", "type": "sbt.librarymanagement.UpdateLogging" },
|
||||
{ "name": "artifactFilter", "type": "sbt.librarymanagement.ArtifactTypeFilter" }
|
||||
{ "name": "artifactFilter", "type": "sbt.librarymanagement.ArtifactTypeFilter" },
|
||||
{ "name": "offline", "type": "boolean" }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -728,7 +729,6 @@
|
|||
{ "name": "resolvers", "type": "sbt.librarymanagement.Resolver*" },
|
||||
{ "name": "otherResolvers", "type": "sbt.librarymanagement.Resolver*" },
|
||||
{ "name": "moduleConfigurations", "type": "sbt.librarymanagement.ModuleConfiguration*" },
|
||||
{ "name": "localOnly", "type": "boolean" },
|
||||
{ "name": "checksums", "type": "String*" },
|
||||
{ "name": "resolutionCacheDir", "type": "java.io.File?" }
|
||||
],
|
||||
|
|
@ -738,7 +738,6 @@
|
|||
" resolvers: Vector[sbt.librarymanagement.Resolver],",
|
||||
" otherResolvers: Vector[sbt.librarymanagement.Resolver],",
|
||||
" moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration],",
|
||||
" localOnly: Boolean,",
|
||||
" lock: Option[xsbti.GlobalLock],",
|
||||
" checksums: Vector[String],",
|
||||
" resolutionCacheDir: Option[java.io.File],",
|
||||
|
|
@ -746,7 +745,7 @@
|
|||
" log: xsbti.Logger",
|
||||
") =",
|
||||
" this(lock, paths.baseDirectory, log, updateOptions, paths, resolvers, otherResolvers,",
|
||||
" moduleConfigurations, localOnly, checksums, resolutionCacheDir)"
|
||||
" moduleConfigurations, checksums, resolutionCacheDir)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ private[sbt] object ConvertResolver {
|
|||
resolver
|
||||
}
|
||||
case repo: ChainedResolver =>
|
||||
IvySbt.resolverChain(repo.name, repo.resolvers, false, settings, log)
|
||||
IvySbt.resolverChain(repo.name, repo.resolvers, settings, log)
|
||||
case repo: RawRepository => repo.resolver
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,16 +88,10 @@ final class IvySbt(val configuration: IvyConfiguration) { self =>
|
|||
case i: InlineIvyConfiguration =>
|
||||
is.setVariable("ivy.checksums", i.checksums mkString ",")
|
||||
i.paths.ivyHome foreach is.setDefaultIvyUserDir
|
||||
IvySbt.configureCache(is, i.localOnly, i.resolutionCacheDir)
|
||||
IvySbt.setResolvers(
|
||||
is,
|
||||
i.resolvers,
|
||||
i.otherResolvers,
|
||||
i.localOnly,
|
||||
configuration.updateOptions,
|
||||
configuration.log
|
||||
)
|
||||
IvySbt.setModuleConfigurations(is, i.moduleConfigurations, configuration.log)
|
||||
val log = configuration.log
|
||||
IvySbt.configureCache(is, i.resolutionCacheDir)
|
||||
IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, configuration.updateOptions, log)
|
||||
IvySbt.setModuleConfigurations(is, i.moduleConfigurations, log)
|
||||
}
|
||||
is
|
||||
}
|
||||
|
|
@ -342,13 +336,12 @@ private[sbt] object IvySbt {
|
|||
settings: IvySettings,
|
||||
resolvers: Seq[Resolver],
|
||||
other: Seq[Resolver],
|
||||
localOnly: Boolean,
|
||||
updateOptions: UpdateOptions,
|
||||
log: Logger
|
||||
): Unit = {
|
||||
def makeChain(label: String, name: String, rs: Seq[Resolver]) = {
|
||||
log.debug(label + " repositories:")
|
||||
val chain = resolverChain(name, rs, localOnly, settings, updateOptions, log)
|
||||
val chain = resolverChain(name, rs, settings, updateOptions, log)
|
||||
settings.addResolver(chain)
|
||||
chain
|
||||
}
|
||||
|
|
@ -362,18 +355,17 @@ private[sbt] object IvySbt {
|
|||
module.revision endsWith "-SNAPSHOT"
|
||||
private[sbt] def isChanging(mrid: ModuleRevisionId): Boolean =
|
||||
mrid.getRevision endsWith "-SNAPSHOT"
|
||||
|
||||
def resolverChain(
|
||||
name: String,
|
||||
resolvers: Seq[Resolver],
|
||||
localOnly: Boolean,
|
||||
settings: IvySettings,
|
||||
log: Logger
|
||||
): DependencyResolver =
|
||||
resolverChain(name, resolvers, localOnly, settings, UpdateOptions(), log)
|
||||
): DependencyResolver = resolverChain(name, resolvers, settings, UpdateOptions(), log)
|
||||
|
||||
def resolverChain(
|
||||
name: String,
|
||||
resolvers: Seq[Resolver],
|
||||
localOnly: Boolean,
|
||||
settings: IvySettings,
|
||||
updateOptions: UpdateOptions,
|
||||
log: Logger
|
||||
|
|
@ -446,19 +438,12 @@ private[sbt] object IvySbt {
|
|||
)
|
||||
}
|
||||
}
|
||||
private def configureCache(
|
||||
settings: IvySettings,
|
||||
localOnly: Boolean,
|
||||
resCacheDir: Option[File]
|
||||
): Unit = {
|
||||
configureResolutionCache(settings, localOnly, resCacheDir)
|
||||
configureRepositoryCache(settings, localOnly)
|
||||
|
||||
private def configureCache(settings: IvySettings, resCacheDir: Option[File]): Unit = {
|
||||
configureResolutionCache(settings, resCacheDir)
|
||||
configureRepositoryCache(settings)
|
||||
}
|
||||
private[this] def configureResolutionCache(
|
||||
settings: IvySettings,
|
||||
localOnly: Boolean,
|
||||
resCacheDir: Option[File]
|
||||
): Unit = {
|
||||
private[this] def configureResolutionCache(settings: IvySettings, resCacheDir: Option[File]) = {
|
||||
val base = resCacheDir getOrElse settings.getDefaultResolutionCacheBasedir
|
||||
settings.setResolutionCacheManager(new ResolutionCache(base, settings))
|
||||
}
|
||||
|
|
@ -485,7 +470,7 @@ private[sbt] object IvySbt {
|
|||
)
|
||||
}
|
||||
|
||||
private[this] def configureRepositoryCache(settings: IvySettings, localOnly: Boolean): Unit = {
|
||||
private[this] def configureRepositoryCache(settings: IvySettings): Unit = {
|
||||
val cacheDir = settings.getDefaultRepositoryCacheBasedir()
|
||||
val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) {
|
||||
override def findModuleInCache(
|
||||
|
|
@ -529,12 +514,8 @@ private[sbt] object IvySbt {
|
|||
manager.setDataFilePattern(PluginPattern + manager.getDataFilePattern)
|
||||
manager.setIvyPattern(PluginPattern + manager.getIvyPattern)
|
||||
manager.setUseOrigin(true)
|
||||
if (localOnly)
|
||||
manager.setDefaultTTL(java.lang.Long.MAX_VALUE)
|
||||
else {
|
||||
manager.setChangingMatcher(PatternMatcher.REGEXP)
|
||||
manager.setChangingPattern(".*-SNAPSHOT")
|
||||
}
|
||||
manager.setChangingMatcher(PatternMatcher.REGEXP)
|
||||
manager.setChangingPattern(".*-SNAPSHOT")
|
||||
settings.addRepositoryCacheManager(manager)
|
||||
settings.setDefaultRepositoryCacheManager(manager)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -467,6 +467,7 @@ object IvyActions {
|
|||
val resolveId = ResolveOptions.getDefaultResolveId(moduleDescriptor)
|
||||
resolveOptions.setResolveId(resolveId)
|
||||
resolveOptions.setArtifactFilter(updateConfiguration.artifactFilter)
|
||||
resolveOptions.setUseCacheOnly(updateConfiguration.offline)
|
||||
resolveOptions.setLog(ivyLogLevel(logging))
|
||||
ResolutionCache.cleanModule(
|
||||
moduleDescriptor.getModuleRevisionId,
|
||||
|
|
@ -519,6 +520,7 @@ object IvyActions {
|
|||
val resolveId = ResolveOptions.getDefaultResolveId(descriptor)
|
||||
resolveOptions.setResolveId(resolveId)
|
||||
resolveOptions.setArtifactFilter(updateConfiguration.artifactFilter)
|
||||
resolveOptions.setUseCacheOnly(updateConfiguration.offline)
|
||||
resolveOptions.setLog(ivyLogLevel(updateConfiguration.logging))
|
||||
val acceptError = updateConfiguration.missingOk
|
||||
resolver.customResolve(descriptor, acceptError, logicalClock, resolveOptions, cache, log)
|
||||
|
|
|
|||
|
|
@ -108,7 +108,6 @@ class IvyCache(val ivyHome: Option[File]) {
|
|||
Vector(local),
|
||||
Vector.empty,
|
||||
Vector.empty,
|
||||
false,
|
||||
lock,
|
||||
IvySbt.DefaultChecksums,
|
||||
None,
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ class DefaultLibraryManagement(ivyConfiguration: IvyConfiguration, log: Logger)
|
|||
Some(retrieveConfiguration),
|
||||
true,
|
||||
UpdateLogging.DownloadOnly,
|
||||
artifactFilter
|
||||
artifactFilter,
|
||||
false
|
||||
)
|
||||
|
||||
log.debug(s"Attempting to fetch ${dependenciesNames(module)}. This operation may fail.")
|
||||
|
|
|
|||
|
|
@ -54,14 +54,12 @@ trait BaseIvySpecification extends UnitSpec {
|
|||
val paths = IvyPaths(currentBase, Some(currentTarget))
|
||||
val other = Vector.empty
|
||||
val moduleConfs = Vector(ModuleConfiguration("*", chainResolver))
|
||||
val off = false
|
||||
val check = Vector.empty
|
||||
val resCacheDir = currentTarget / "resolution-cache"
|
||||
new InlineIvyConfiguration(paths,
|
||||
resolvers,
|
||||
other,
|
||||
moduleConfs,
|
||||
off,
|
||||
None,
|
||||
check,
|
||||
Some(resCacheDir),
|
||||
|
|
@ -69,18 +67,19 @@ trait BaseIvySpecification extends UnitSpec {
|
|||
log)
|
||||
}
|
||||
|
||||
def makeUpdateConfiguration: UpdateConfiguration = {
|
||||
def makeUpdateConfiguration(offline: Boolean): UpdateConfiguration = {
|
||||
val retrieveConfig =
|
||||
RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern).withSync(false)
|
||||
UpdateConfiguration(Some(retrieveConfig),
|
||||
false,
|
||||
UpdateLogging.Full,
|
||||
ArtifactTypeFilter.forbid(Set("src", "doc")))
|
||||
ArtifactTypeFilter.forbid(Set("src", "doc")),
|
||||
offline)
|
||||
}
|
||||
|
||||
def ivyUpdateEither(module: IvySbt#Module): Either[UnresolvedWarning, UpdateReport] = {
|
||||
// IO.delete(currentTarget)
|
||||
val config = makeUpdateConfiguration
|
||||
val config = makeUpdateConfiguration(false)
|
||||
IvyActions.updateEither(module,
|
||||
config,
|
||||
UnresolvedWarningConfiguration(),
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ class CustomPomParserTest extends UnitSpec {
|
|||
Vector(local),
|
||||
Vector.empty,
|
||||
Vector.empty,
|
||||
false,
|
||||
None,
|
||||
Vector("sha1", "md5"),
|
||||
None,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
package sbt.librarymanagement
|
||||
|
||||
import org.scalatest.Assertion
|
||||
import sbt.internal.librarymanagement._
|
||||
import sbt.internal.librarymanagement.impl.DependencyBuilders
|
||||
import sbt.io.IO
|
||||
|
||||
class OfflineModeSpec extends BaseIvySpecification with DependencyBuilders {
|
||||
private final def targetDir = Some(currentDependency)
|
||||
private final def onlineConf = makeUpdateConfiguration(false)
|
||||
private final def offlineConf = makeUpdateConfiguration(true)
|
||||
private final def warningConf = UnresolvedWarningConfiguration()
|
||||
private final def normalOptions = UpdateOptions()
|
||||
private final def cachedOptions = UpdateOptions().withCachedResolution(true)
|
||||
private final def noClock = LogicalClock.unknown
|
||||
|
||||
def avro177 = ModuleID("org.apache.avro", "avro", "1.7.7")
|
||||
def dataAvro1940 = ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40")
|
||||
def netty320 = ModuleID("org.jboss.netty", "netty", "3.2.0.Final")
|
||||
final def dependencies: Vector[ModuleID] =
|
||||
Vector(avro177, dataAvro1940, netty320).map(_.withConfigurations(Some("compile")))
|
||||
|
||||
def cleanAll(): Unit = {
|
||||
cleanIvyCache()
|
||||
IO.delete(currentTarget)
|
||||
IO.delete(currentManaged)
|
||||
IO.delete(currentDependency)
|
||||
}
|
||||
|
||||
def checkOnlineAndOfflineResolution(updateOptions: UpdateOptions): Assertion = {
|
||||
cleanAll()
|
||||
val toResolve = module(defaultModuleId, dependencies, None, updateOptions)
|
||||
if (updateOptions.cachedResolution)
|
||||
cleanCachedResolutionCache(toResolve)
|
||||
|
||||
val onlineResolution =
|
||||
IvyActions.updateEither(toResolve, onlineConf, warningConf, noClock, targetDir, log)
|
||||
assert(onlineResolution.isRight)
|
||||
assert(onlineResolution.right.exists(report => report.stats.resolveTime > 0))
|
||||
|
||||
// Compute an estimate to ensure that the second resolution does indeed use the cache
|
||||
val originalResolveTime = onlineResolution.right.get.stats.resolveTime
|
||||
val estimatedCachedTime = originalResolveTime * 0.15
|
||||
|
||||
val offlineResolution =
|
||||
IvyActions.updateEither(toResolve, offlineConf, warningConf, noClock, targetDir, log)
|
||||
assert(offlineResolution.isRight)
|
||||
|
||||
val resolveTime = offlineResolution.right.get.stats.resolveTime
|
||||
// Only check the estimate for the non cached resolution, otherwise resolution is cached
|
||||
assert(resolveTime <= estimatedCachedTime,
|
||||
"Offline resolution took more than 15% of normal resolution's running time.")
|
||||
}
|
||||
|
||||
"Offline update configuration" should "reuse the caches when offline is enabled" in {
|
||||
checkOnlineAndOfflineResolution(normalOptions)
|
||||
}
|
||||
|
||||
it should "reuse the caches when offline and cached resolution are enabled" in {
|
||||
checkOnlineAndOfflineResolution(cachedOptions)
|
||||
}
|
||||
|
||||
def checkFailingResolution(updateOptions: UpdateOptions): Assertion = {
|
||||
cleanAll()
|
||||
val toResolve = module(defaultModuleId, dependencies, None, updateOptions)
|
||||
if (updateOptions.cachedResolution) cleanCachedResolutionCache(toResolve)
|
||||
val failedOfflineResolution =
|
||||
IvyActions.updateEither(toResolve, offlineConf, warningConf, noClock, targetDir, log)
|
||||
assert(failedOfflineResolution.isLeft)
|
||||
}
|
||||
|
||||
it should "fail when artifacts are missing in the cache" in {
|
||||
checkFailingResolution(normalOptions)
|
||||
}
|
||||
|
||||
it should "fail when artifacts are missing in the cache for cached resolution" in {
|
||||
checkFailingResolution(cachedOptions)
|
||||
}
|
||||
}
|
||||
|
|
@ -44,7 +44,7 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders {
|
|||
val m = makeModuleForDepWithSources
|
||||
|
||||
// the "default" configuration used in updateEither.
|
||||
val c = makeUpdateConfiguration
|
||||
val c = makeUpdateConfiguration(false)
|
||||
|
||||
val ivyScala = m.moduleSettings.ivyScala
|
||||
val srcTypes = Set("src")
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ object Dependencies {
|
|||
def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache)
|
||||
|
||||
val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0"
|
||||
val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-48dd0744422128446aee9ac31aa356ee203cc9f4"
|
||||
val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-a3314352b638afbf0dca19f127e8263ed6f898bd"
|
||||
val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive ()
|
||||
val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value }
|
||||
val scalaXml = scala211Module("scala-xml", "1.0.5")
|
||||
|
|
|
|||
Loading…
Reference in New Issue