From 5ff32f2a996422b2ec853f96996809598b435885 Mon Sep 17 00:00:00 2001 From: jvican Date: Mon, 8 May 2017 20:03:30 +0200 Subject: [PATCH] Add a frozen mode to update configuration The frozen mode is used by the dependency lock file. It makes sure that the resolution is always intransitive and that ivy does not check for changed dependencies and stores that information in the resolved ivy files. Following the ivy documentation, the last change may bring a slight performance improvement: http://ant.apache.org/ivy/history/latest-milestone/use/resolve.html --- .../main/contraband/librarymanagement.json | 3 +- .../librarymanagement/IvyActions.scala | 8 +++ .../DefaultLibraryManagement.scala | 1 + .../src/test/scala/BaseIvySpecification.scala | 3 +- .../src/test/scala/FrozenModeSpec.scala | 55 +++++++++++++++++++ 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 librarymanagement/src/test/scala/FrozenModeSpec.scala diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 810ecc1ac..d28da3b69 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -635,7 +635,8 @@ { "name": "missingOk", "type": "boolean" }, { "name": "logging", "type": "sbt.librarymanagement.UpdateLogging" }, { "name": "artifactFilter", "type": "sbt.librarymanagement.ArtifactTypeFilter" }, - { "name": "offline", "type": "boolean" } + { "name": "offline", "type": "boolean" }, + { "name": "frozen", "type": "boolean" } ] }, { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 4d8465a10..638aa4770 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -469,6 +469,10 @@ object IvyActions { resolveOptions.setArtifactFilter(updateConfiguration.artifactFilter) resolveOptions.setUseCacheOnly(updateConfiguration.offline) resolveOptions.setLog(ivyLogLevel(logging)) + if (updateConfiguration.frozen) { + resolveOptions.setTransitive(false) + resolveOptions.setCheckIfChanged(false) + } ResolutionCache.cleanModule( moduleDescriptor.getModuleRevisionId, resolveId, @@ -522,6 +526,10 @@ object IvyActions { resolveOptions.setArtifactFilter(updateConfiguration.artifactFilter) resolveOptions.setUseCacheOnly(updateConfiguration.offline) resolveOptions.setLog(ivyLogLevel(updateConfiguration.logging)) + if (updateConfiguration.frozen) { + resolveOptions.setTransitive(false) + resolveOptions.setCheckIfChanged(false) + } val acceptError = updateConfiguration.missingOk resolver.customResolve(descriptor, acceptError, logicalClock, resolveOptions, cache, log) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala index 3c5d38167..49af3cb71 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala @@ -69,6 +69,7 @@ class DefaultLibraryManagement(ivyConfiguration: IvyConfiguration, log: Logger) true, UpdateLogging.DownloadOnly, artifactFilter, + false, false ) diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 20041ab04..d87baa862 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -74,7 +74,8 @@ trait BaseIvySpecification extends UnitSpec { false, UpdateLogging.Full, ArtifactTypeFilter.forbid(Set("src", "doc")), - offline) + offline, + false) } def ivyUpdateEither(module: IvySbt#Module): Either[UnresolvedWarning, UpdateReport] = { diff --git a/librarymanagement/src/test/scala/FrozenModeSpec.scala b/librarymanagement/src/test/scala/FrozenModeSpec.scala new file mode 100644 index 000000000..e84abfe99 --- /dev/null +++ b/librarymanagement/src/test/scala/FrozenModeSpec.scala @@ -0,0 +1,55 @@ +package sbt.librarymanagement + +import sbt.internal.librarymanagement._ +import sbt.internal.librarymanagement.impl.DependencyBuilders + +class FrozenModeSpec extends BaseIvySpecification with DependencyBuilders { + private final val targetDir = Some(currentDependency) + private final val onlineConf = makeUpdateConfiguration(false) + private final val frozenConf = makeUpdateConfiguration(false).withFrozen(true) + private final val noClock = LogicalClock.unknown + private final val warningConf = UnresolvedWarningConfiguration() + private final val normalOptions = UpdateOptions() + + final val stoml = Vector("me.vican.jorge" % "stoml_2.12" % "0.4" % "compile") + + /* https://repo1.maven.org/maven2/me/vican/jorge/stoml_2.12/0.4/stoml_2.12-0.4.jar + * https://repo1.maven.org/maven2/org/scala-lang/scala-library/2.12.0/scala-library-2.12.0.jar + * https://repo1.maven.org/maven2/com/lihaoyi/fastparse_2.12/0.4.2/fastparse_2.12-0.4.2.jar + * https://repo1.maven.org/maven2/com/lihaoyi/fastparse-utils_2.12/0.4.2/fastparse-utils_2.12-0.4.2.jar + * https://repo1.maven.org/maven2/com/lihaoyi/sourcecode_2.12/0.1.3/sourcecode_2.12-0.1.3.jar */ + final val explicitStoml = Vector( + "me.vican.jorge" % "stoml_2.12" % "0.4" % "compile", + "org.scala-lang" % "scala-library" % "2.12.0" % "compile", + "com.lihaoyi" % "fastparse_2.12" % "0.4.2" % "compile", + "com.lihaoyi" % "fastparse-utils_2.12" % "0.4.2" % "compile", + "com.lihaoyi" % "sourcecode_2.12" % "0.1.3" % "compile" + ) + + it should "fail when artifacts are missing in the cache" in { + cleanIvyCache() + def update(module: IvySbt#Module, conf: UpdateConfiguration) = + IvyActions.updateEither(module, conf, warningConf, noClock, targetDir, log) + + val toResolve = module(defaultModuleId, stoml, None, normalOptions) + val onlineResolution = update(toResolve, onlineConf) + assert(onlineResolution.isRight) + val numberResolved = onlineResolution.right.get.allModules.size + + cleanIvyCache() + val singleFrozenResolution = update(toResolve, frozenConf) + assert(singleFrozenResolution.isRight) + assert( + singleFrozenResolution.right.get.allModules.size == 1, + s"The number of explicit modules in frozen mode should 1" + ) + + cleanIvyCache() + // This relies on the fact that stoml has 5 transitive dependencies + val toExplicitResolve = module(defaultModuleId, explicitStoml, None, normalOptions) + val frozenResolution = update(toExplicitResolve, frozenConf) + assert(frozenResolution.isRight) + assert(frozenResolution.right.get.allModules.size == numberResolved, + s"The number of explicit modules in frozen mode should be equal than $numberResolved") + } +}