From a561f3a901cbff26cf3fd32ccafbe7bc4978561f Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Sun, 16 Jan 2022 21:34:54 +0000 Subject: [PATCH 01/52] Add shortcut for s01.oss.sonatype.org to Resolver Fixes https://github.com/sbt/sbt/issues/6787. See also: https://central.sonatype.org/news/20210223_new-users-on-s01/ --- .../main/scala/sbt/librarymanagement/ResolverExtra.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index cb353df1f..003c6015a 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -102,6 +102,7 @@ private[librarymanagement] abstract class ResolverFunctions { @deprecated("Renamed to SbtRepositoryRoot.", "1.0.0") val SbtPluginRepositoryRoot = SbtRepositoryRoot val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" + val SonatypeS01RepositoryRoot = "https://s01.oss.sonatype.org/content/repositories" val SonatypeReleasesRepository = "https://oss.sonatype.org/service/local/repositories/releases/content/" val JavaNet2RepositoryName = "java.net Maven2 Repository" @@ -159,6 +160,11 @@ private[librarymanagement] abstract class ResolverFunctions { if (status == "releases") SonatypeReleasesRepository else SonatypeRepositoryRoot + "/" + status ) + def sonatypeS01Repo(status: String) = + MavenRepository( + "sonatype-s01-" + status, + SonatypeS01RepositoryRoot + "/" + status + ) def bintrayRepo(owner: String, repo: String) = MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") def bintrayIvyRepo(owner: String, repo: String) = From c17309a91438a45491359fb94099b8828b72d246 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Sun, 16 Jan 2022 19:56:58 +0000 Subject: [PATCH 02/52] Deprecate sonatypeRepo, add sonatypeRepos --- .../main/scala/sbt/librarymanagement/ResolverExtra.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 003c6015a..4bb59b79c 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -5,6 +5,7 @@ package sbt.librarymanagement import java.io.{ IOException, File } import java.net.{ URI, URL } +import scala.annotation.nowarn import scala.xml.XML import org.xml.sax.SAXParseException import sbt.util.Logger @@ -154,17 +155,20 @@ private[librarymanagement] abstract class ResolverFunctions { url("sbt-plugin-" + status, new URL(SbtRepositoryRoot + "/sbt-plugin-" + status + "/"))( ivyStylePatterns ) + @deprecated("Use sonatypeRepos instead", "1.7.0") def sonatypeRepo(status: String) = MavenRepository( "sonatype-" + status, if (status == "releases") SonatypeReleasesRepository else SonatypeRepositoryRoot + "/" + status ) - def sonatypeS01Repo(status: String) = + private def sonatypeS01Repo(status: String) = MavenRepository( "sonatype-s01-" + status, SonatypeS01RepositoryRoot + "/" + status ) + def sonatypeRepos(status: String) = + Vector(sonatypeRepo(status): @nowarn("cat=deprecation"), sonatypeS01Repo(status)) def bintrayRepo(owner: String, repo: String) = MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") def bintrayIvyRepo(owner: String, repo: String) = From 7a2f81ea05ad1228c3c8bad7eccc742cddd07a44 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Mon, 31 Jan 2022 23:23:34 +0000 Subject: [PATCH 03/52] sonatypeRepos -> sonatypeOssRepos --- core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 4bb59b79c..0d6683a91 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -155,7 +155,7 @@ private[librarymanagement] abstract class ResolverFunctions { url("sbt-plugin-" + status, new URL(SbtRepositoryRoot + "/sbt-plugin-" + status + "/"))( ivyStylePatterns ) - @deprecated("Use sonatypeRepos instead", "1.7.0") + @deprecated("Use sonatypeOssRepos instead", "1.7.0") def sonatypeRepo(status: String) = MavenRepository( "sonatype-" + status, @@ -167,7 +167,7 @@ private[librarymanagement] abstract class ResolverFunctions { "sonatype-s01-" + status, SonatypeS01RepositoryRoot + "/" + status ) - def sonatypeRepos(status: String) = + def sonatypeOssRepos(status: String) = Vector(sonatypeRepo(status): @nowarn("cat=deprecation"), sonatypeS01Repo(status)) def bintrayRepo(owner: String, repo: String) = MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") From a07188232146d3a6f3644ec46c7da36d7151e5c0 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 31 Jan 2022 19:22:37 -0500 Subject: [PATCH 04/52] Add predefined list of licenses --- .../scala/sbt/librarymanagement/License.scala | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 core/src/main/scala/sbt/librarymanagement/License.scala diff --git a/core/src/main/scala/sbt/librarymanagement/License.scala b/core/src/main/scala/sbt/librarymanagement/License.scala new file mode 100644 index 000000000..6f335fb24 --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/License.scala @@ -0,0 +1,24 @@ +package sbt.librarymanagement + +import java.net.URL + +/** + * Commonly used software licenses + * Names are SPDX ids: + * https://raw.githubusercontent.com/spdx/license-list-data/master/json/licenses.json + */ +object License { + lazy val Apache2: (String, URL) = + ("Apache-2.0", new URL("https://www.apache.org/licenses/LICENSE-2.0.txt")) + + lazy val MIT: (String, URL) = + ("MIT", new URL("https://opensource.org/licenses/MIT")) + + lazy val CC0: (String, URL) = + ("CC0-1.0", new URL("https://creativecommons.org/publicdomain/zero/1.0/legalcode")) + + def PublicDomain: (String, URL) = CC0 + + lazy val GPL3_or_later: (String, URL) = + ("GPL-3.0-or-later", new URL("https://spdx.org/licenses/GPL-3.0-or-later.html")) +} From 85271660c70bd761d0c58ee73fb36b1a15074500 Mon Sep 17 00:00:00 2001 From: kenji yoshida <6b656e6a69@gmail.com> Date: Sun, 22 May 2022 10:02:26 +0900 Subject: [PATCH 05/52] remove bintray resolver --- build.sbt | 1 - 1 file changed, 1 deletion(-) diff --git a/build.sbt b/build.sbt index 00e45416b..a6d4c6df2 100644 --- a/build.sbt +++ b/build.sbt @@ -45,7 +45,6 @@ def commonSettings: Seq[Setting[_]] = Def.settings( resolvers += Resolver.typesafeIvyRepo("releases"), resolvers += Resolver.sonatypeRepo("snapshots"), resolvers += Resolver.sbtPluginRepo("releases"), - resolvers += "bintray-sbt-maven-releases" at "https://dl.bintray.com/sbt/maven-releases/", testFrameworks += new TestFramework("verify.runner.Framework"), // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), From 91bf2649b25dd13c28f12cb22cee58e79e77c1f7 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 12 Jun 2022 21:55:09 -0400 Subject: [PATCH 06/52] Bump sbt --- .github/workflows/ci.yml | 2 +- .gitignore | 1 + build.sbt | 21 ++++++--------------- project/build.properties | 2 +- project/plugins.sbt | 1 - 5 files changed, 9 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6f16581f8..897e165ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: run: | case ${{ matrix.jobtype }} in 1) - sbt -v -Dfile.encoding=UTF8 scalafmtCheckAll whitesourceCheckPolicies +test +packagedArtifacts + sbt -v -Dfile.encoding=UTF8 scalafmtCheckAll +test +packagedArtifacts ;; *) echo unknown jobtype diff --git a/.gitignore b/.gitignore index 495231475..0cbd43574 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ __pycache__ scripted-test/src/sbt-test/*/*/project/build.properties scripted-test/src/sbt-test/*/*/project/plugins.sbt +metals.sbt diff --git a/build.sbt b/build.sbt index a6d4c6df2..ecc65b8d0 100644 --- a/build.sbt +++ b/build.sbt @@ -6,7 +6,8 @@ val _ = { //https://github.com/sbt/contraband/issues/122 sys.props += ("line.separator" -> "\n") } - +Global / semanticdbEnabled := true +Global / semanticdbVersion := "4.5.9" ThisBuild / version := { val old = (ThisBuild / version).value nightlyVersion match { @@ -118,8 +119,7 @@ lazy val lmCore = (project in file("core")) scalaReflect.value, scalaCompiler.value, launcherInterface, - gigahorseOkhttp, - okhttpUrlconnection, + gigahorseApacheHttp, sjsonnewScalaJson.value % Optional, scalaTest % Test, scalaCheck % Test, @@ -260,7 +260,9 @@ lazy val lmCore = (project in file("core")) "sbt.librarymanagement.ResolverFunctions.validateArtifact" ), exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.*.validateProtocol"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.cross.CrossVersionUtil.TransitionDottyVersion"), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.cross.CrossVersionUtil.TransitionDottyVersion" + ), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ScalaArtifacts.dottyID"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ScalaArtifacts.DottyIDPrefix"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ScalaArtifacts.toolDependencies*"), @@ -387,16 +389,5 @@ def customCommands: Seq[Setting[_]] = Seq( } ) -inThisBuild( - Seq( - whitesourceProduct := "Lightbend Reactive Platform", - whitesourceAggregateProjectName := "sbt-lm-master", - whitesourceAggregateProjectToken := "9bde4ccbaab7401a91f8cda337af84365d379e13abaf473b85cb16e3f5c65cb6", - whitesourceIgnoredScopes += "scalafmt", - whitesourceFailOnError := sys.env.contains("WHITESOURCE_PASSWORD"), // fail if pwd is present - whitesourceForceCheckAllDependencies := true, - ) -) - def inCompileAndTest(ss: SettingsDefinition*): Seq[Setting[_]] = Seq(Compile, Test) flatMap (inConfig(_)(Def.settings(ss: _*))) diff --git a/project/build.properties b/project/build.properties index f0be67b9f..c8fcab543 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.5.1 +sbt.version=1.6.2 diff --git a/project/plugins.sbt b/project/plugins.sbt index f55cc0ddd..279b64f16 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -3,6 +3,5 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.8.1") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.2") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.5.1") -addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.14") scalacOptions += "-language:postfixOps" From 76452e53ff6f7211db2bab5dd3bc8f06dac1bbce Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 12 Jun 2022 22:24:44 -0400 Subject: [PATCH 07/52] Drop OkHttp dependency Ref https://github.com/sbt/sbt/issues/6912 Problem ------- There's apparently a security issue with OkHttp 3.x, which I am not really sure how applicable it is to our usage of OkHttp but it is there. Solution -------- Since most of OkHttp-specic usage within LM is for Apache Ivy downloading, I am going to drop this. Since `sbt.librarymanagement.Http.http` is a public API, I am substituting this with Apache HTTP backed implementation. --- build.sbt | 10 + .../scala/sbt/librarymanagement/Http.scala | 2 +- .../JavaNetAuthenticator.java | 82 ----- .../librarymanagement/CustomHttp.scala | 21 -- .../sbt/internal/librarymanagement/Ivy.scala | 10 +- .../internal/librarymanagement/IvyCache.scala | 2 +- .../ivyint/GigahorseUrlHandler.scala | 339 ------------------ .../ivy/IvyDependencyResolution.scala | 6 +- .../librarymanagement/ivy/IvyPublisher.scala | 6 +- project/Dependencies.scala | 7 +- 10 files changed, 19 insertions(+), 466 deletions(-) delete mode 100644 ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java delete mode 100644 ivy/src/main/scala/sbt/internal/librarymanagement/CustomHttp.scala delete mode 100644 ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala diff --git a/build.sbt b/build.sbt index ecc65b8d0..07e4fc470 100644 --- a/build.sbt +++ b/build.sbt @@ -89,6 +89,7 @@ val mimaSettings = Def settings ( "1.3.0", "1.4.0", "1.5.0", + "1.6.0", ) map ( version => organization.value %% moduleName.value % version @@ -353,6 +354,15 @@ lazy val lmIvy = (project in file("ivy")) "sbt.internal.librarymanagement.CustomPomParser.versionRangeFlag" ), exclude[MissingClassProblem]("sbt.internal.librarymanagement.FixedParser*"), + exclude[MissingClassProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler*"), + exclude[MissingClassProblem]("sbt.internal.librarymanagement.JavaNetAuthenticator"), + exclude[MissingClassProblem]("sbt.internal.librarymanagement.CustomHttp*"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvySbt.http"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvySbt.this"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ivy.IvyPublisher.apply"), + exclude[DirectMissingMethodProblem]( + "sbt.librarymanagement.ivy.IvyDependencyResolution.apply" + ), ), ) diff --git a/core/src/main/scala/sbt/librarymanagement/Http.scala b/core/src/main/scala/sbt/librarymanagement/Http.scala index 2b54f8140..5edf9a746 100644 --- a/core/src/main/scala/sbt/librarymanagement/Http.scala +++ b/core/src/main/scala/sbt/librarymanagement/Http.scala @@ -1,6 +1,6 @@ package sbt.librarymanagement -import gigahorse._, support.okhttp.Gigahorse +import gigahorse._, support.apachehttp.Gigahorse import scala.concurrent.duration.DurationInt object Http { diff --git a/ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java b/ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java deleted file mode 100644 index aa10461cc..000000000 --- a/ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2013 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package sbt.internal.librarymanagement; - -import java.io.IOException; -import java.net.Authenticator.RequestorType; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.PasswordAuthentication; -import java.net.Proxy; -import java.util.List; -import okhttp3.Authenticator; -import okhttp3.Route; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.HttpUrl; -import okhttp3.Challenge; -import okhttp3.Credentials; - -/** - * Adapts java.net.Authenticator to Authenticator. Configure OkHttp to use - * java.net.Authenticator with OkHttpClient.Builder#authenticator or - * OkHttpClient.Builder#proxyAuthenticator(Authenticator). - */ -public final class JavaNetAuthenticator implements Authenticator { - @Override public Request authenticate(Route route, Response response) throws IOException { - List challenges = response.challenges(); - Request request = response.request(); - HttpUrl url = request.url(); - boolean proxyAuthorization = response.code() == 407; - Proxy proxy = null; - if (route != null) { - proxy = route.proxy(); - } - - for (int i = 0, size = challenges.size(); i < size; i++) { - Challenge challenge = challenges.get(i); - if (!"Basic".equalsIgnoreCase(challenge.scheme())) continue; - - PasswordAuthentication auth; - if (proxyAuthorization) { - InetSocketAddress proxyAddress = (InetSocketAddress) proxy.address(); - auth = java.net.Authenticator.requestPasswordAuthentication( - proxyAddress.getHostName(), getConnectToInetAddress(proxy, url), proxyAddress.getPort(), - url.scheme(), challenge.realm(), challenge.scheme(), url.url(), - RequestorType.PROXY); - } else { - auth = java.net.Authenticator.requestPasswordAuthentication( - url.host(), getConnectToInetAddress(proxy, url), url.port(), url.scheme(), - challenge.realm(), challenge.scheme(), url.url(), RequestorType.SERVER); - } - - if (auth != null) { - String credential = Credentials.basic(auth.getUserName(), new String(auth.getPassword())); - return request.newBuilder() - .header(proxyAuthorization ? "Proxy-Authorization" : "Authorization", credential) - .build(); - } - } - - return null; // No challenges were satisfied! - } - - private InetAddress getConnectToInetAddress(Proxy proxy, HttpUrl url) throws IOException { - return (proxy != null && proxy.type() != Proxy.Type.DIRECT) - ? ((InetSocketAddress) proxy.address()).getAddress() - : InetAddress.getByName(url.host()); - } -} diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomHttp.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomHttp.scala deleted file mode 100644 index 9454affc4..000000000 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomHttp.scala +++ /dev/null @@ -1,21 +0,0 @@ -package sbt.internal.librarymanagement - -import gigahorse.HttpClient -import okhttp3.{ JavaNetAuthenticator => _, _ } -import sbt.librarymanagement.Http - -object CustomHttp { - private[this] def http0: HttpClient = Http.http - - private[sbt] def defaultHttpClientBuilder: OkHttpClient.Builder = { - http0 - .underlying[OkHttpClient] - .newBuilder() - .authenticator(new sbt.internal.librarymanagement.JavaNetAuthenticator) - .followRedirects(true) - .followSslRedirects(true) - } - - private[sbt] lazy val defaultHttpClient: OkHttpClient = - defaultHttpClientBuilder.build -} diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index e45a5fcf4..eaab99af1 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -7,7 +7,6 @@ import java.io.File import java.net.URI import java.util.concurrent.Callable -import okhttp3.OkHttpClient import org.apache.ivy.Ivy import org.apache.ivy.core.IvyPatternHelper import org.apache.ivy.core.cache.{ CacheMetadataOptions, DefaultRepositoryCacheManager } @@ -50,17 +49,13 @@ import ivyint.{ CachedResolutionResolveEngine, ParallelResolveEngine, SbtDefaultDependencyDescriptor, - GigahorseUrlHandler } import sjsonnew.JsonFormat import sjsonnew.support.murmurhash.Hasher final class IvySbt( val configuration: IvyConfiguration, - val http: OkHttpClient ) { self => - def this(configuration: IvyConfiguration) = this(configuration, CustomHttp.defaultHttpClient) - /* * ========== Configuration/Setup ============ * This part configures the Ivy instance by first creating the logger interface to ivy, then IvySettings, and then the Ivy instance. @@ -90,7 +85,6 @@ final class IvySbt( } private lazy val basicUrlHandler: URLHandler = new BasicURLHandler - private lazy val gigahorseUrlHandler: URLHandler = new GigahorseUrlHandler(http) private lazy val settings: IvySettings = { val dispatcher: URLHandlerDispatcher = URLHandlerRegistry.getDefault match { @@ -106,8 +100,8 @@ final class IvySbt( disp } - val urlHandler: URLHandler = - if (configuration.updateOptions.gigahorse) gigahorseUrlHandler else basicUrlHandler + // Ignore configuration.updateOptions.gigahorse due to sbt/sbt#6912 + val urlHandler: URLHandler = basicUrlHandler // Only set the urlHandler for the http/https protocols so we do not conflict with any other plugins // that might register other protocol handlers. diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index 397f2e8d7..f5ae6d8fb 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -112,7 +112,7 @@ class IvyCache(val ivyHome: Option[File]) { .withResolvers(Vector(local)) .withLock(lock) .withLog(log) - (new IvySbt(conf, CustomHttp.defaultHttpClient), local) + (new IvySbt(conf), local) } /** Creates a default jar artifact based on the given ID.*/ diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala deleted file mode 100644 index 87ed352b1..000000000 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ /dev/null @@ -1,339 +0,0 @@ -package sbt.internal.librarymanagement -package ivyint - -import java.net.{ URL, UnknownHostException } -import java.io._ - -import scala.util.control.NonFatal - -import okhttp3.{ MediaType, Request, RequestBody } -import okhttp3.internal.http.HttpDate - -import okhttp3.{ JavaNetAuthenticator => _, _ } -import okio._ - -import org.apache.ivy.util.{ CopyProgressEvent, CopyProgressListener, Message } -import org.apache.ivy.util.url.{ AbstractURLHandler, BasicURLHandler, IvyAuthenticator, URLHandler } -import org.apache.ivy.util.url.URLHandler._ -import sbt.io.IO - -// Copied from Ivy's BasicURLHandler. -class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { - - import GigahorseUrlHandler._ - - /** - * Returns the URLInfo of the given url or a #UNAVAILABLE instance, - * if the url is not reachable. - */ - def getURLInfo(url: URL): URLInfo = getURLInfo(url, 0) - - /** - * Returns the URLInfo of the given url or a #UNAVAILABLE instance, - * if the url is not reachable. - */ - def getURLInfo(url0: URL, timeout: Int): URLInfo = { - // Install the ErrorMessageAuthenticator - if ("http" == url0.getProtocol || "https" == url0.getProtocol) { - IvyAuthenticator.install() - ErrorMessageAuthenticator.install() - } - - val url = normalizeToURL(url0) - val request = new Request.Builder() - .url(url) - - if (getRequestMethod == URLHandler.REQUEST_METHOD_HEAD) request.head() else request.get() - - val response = http.newCall(request.build()).execute() - try { - val infoOption = try { - - if (checkStatusCode(url, response)) { - val bodyCharset = - BasicURLHandler.getCharSetFromContentType( - Option(response.body().contentType()).map(_.toString).orNull - ) - Some( - new SbtUrlInfo( - true, - response.body().contentLength(), - lastModifiedTimestamp(response), - bodyCharset - ) - ) - } else None - // - // Commented out for now - can potentially be used for non HTTP urls - // - // val contentLength: Long = con.getContentLengthLong - // if (contentLength <= 0) None - // else { - // // TODO: not HTTP... maybe we *don't* want to default to ISO-8559-1 here? - // val bodyCharset = BasicURLHandler.getCharSetFromContentType(con.getContentType) - // Some(new SbtUrlInfo(true, contentLength, con.getLastModified(), bodyCharset)) - // } - - } catch { - case e: UnknownHostException => - Message.warn("Host " + e.getMessage + " not found. url=" + url) - Message.info( - "You probably access the destination server through " - + "a proxy server that is not well configured." - ) - None - case e: IOException => - Message.error("Server access Error: " + e.getMessage + " url=" + url) - None - } - infoOption.getOrElse(UNAVAILABLE) - } finally { - response.close() - } - } - - //The caller of this *MUST* call Response.close() - private def getUrl(url0: URL): okhttp3.Response = { - // Install the ErrorMessageAuthenticator - if ("http" == url0.getProtocol || "https" == url0.getProtocol) { - IvyAuthenticator.install() - ErrorMessageAuthenticator.install() - } - - val url = normalizeToURL(url0) - val request = new Request.Builder() - .url(url) - .get() - .build() - - val response = http.newCall(request).execute() - try { - if (!checkStatusCode(url, response)) { - throw new IOException( - "The HTTP response code for " + url + " did not indicate a success." - + " See log for more detail." - ) - } - response - } catch { - case NonFatal(e) => - //ensure the response gets closed if there's an error - response.close() - throw e - } - - } - - def openStream(url: URL): InputStream = { - //It's assumed that the caller of this will call close() on the supplied inputstream, - // thus closing the OkHTTP request - getUrl(url).body().byteStream() - } - - def download(url: URL, dest: File, l: CopyProgressListener): Unit = { - - val response = getUrl(url) - try { - - if (l != null) { - l.start(new CopyProgressEvent()) - } - val sink = Okio.buffer(Okio.sink(dest)) - try { - sink.writeAll(response.body().source()) - sink.flush() - } finally { - sink.close() - } - - val contentLength = response.body().contentLength() - if (contentLength != -1 && dest.length != contentLength) { - IO.delete(dest) - throw new IOException( - "Downloaded file size doesn't match expected Content Length for " + url - + ". Please retry." - ) - } - - val lastModified = lastModifiedTimestamp(response) - if (lastModified > 0) { - IO.setModifiedTimeOrFalse(dest, lastModified) - } - - if (l != null) { - l.end(new CopyProgressEvent(EmptyBuffer, contentLength)) - } - - } finally { - response.close() - } - } - - def upload(source: File, dest0: URL, l: CopyProgressListener): Unit = { - - if (("http" != dest0.getProtocol) && ("https" != dest0.getProtocol)) { - throw new UnsupportedOperationException("URL repository only support HTTP PUT at the moment") - } - - IvyAuthenticator.install() - ErrorMessageAuthenticator.install() - - val dest = normalizeToURL(dest0) - - val body = RequestBody.create(MediaType.parse("application/octet-stream"), source) - - val request = new Request.Builder() - .url(dest) - .put(body) - .build() - - if (l != null) { - l.start(new CopyProgressEvent()) - } - val response = http.newCall(request).execute() - try { - if (l != null) { - l.end(new CopyProgressEvent(EmptyBuffer, source.length())) - } - validatePutStatusCode(dest, response) - } finally { - response.close() - } - } - - private val ErrorBodyTruncateLen = 512 // in case some bad service returns files rather than messages in error bodies - private val DefaultErrorCharset = java.nio.charset.StandardCharsets.UTF_8 - - // neurotic resource managemement... - // we could use this elsewhere in the class too - private def borrow[S <: AutoCloseable, T](rsrc: => S)(op: S => T): T = { - val r = rsrc - val out = { - try { - op(r) - } catch { - case NonFatal(t) => { - try { - r.close() - } catch { - case NonFatal(ct) => t.addSuppressed(ct) - } - throw t - } - } - } - r.close() - out - } - - // this is perhaps overly cautious, but oh well - private def readTruncated(byteStream: InputStream): Option[(Array[Byte], Boolean)] = { - borrow(byteStream) { is => - borrow(new ByteArrayOutputStream(ErrorBodyTruncateLen)) { os => - var count = 0 - var b = is.read() - var truncated = false - while (!truncated && b >= 0) { - if (count >= ErrorBodyTruncateLen) { - truncated = true - } else { - os.write(b) - count += 1 - b = is.read() - } - } - if (count > 0) { - Some((os.toByteArray, truncated)) - } else { - None - } - } - } - } - - /* - * Supplements the IOException emitted on a bad status code by our inherited validatePutStatusCode(...) - * method with any message that might be present in an error response body. - * - * after calling this method, the object given as the response parameter must be reliably closed. - */ - private def validatePutStatusCode(dest: URL, response: Response): Unit = { - try { - validatePutStatusCode(dest, response.code(), response.message()) - } catch { - case ioe: IOException => { - val mbBodyMessage = { - for { - body <- Option(response.body()) - is <- Option(body.byteStream) - (bytes, truncated) <- readTruncated(is) - charset <- Option(body.contentType()).map(_.charset(DefaultErrorCharset)) orElse Some( - DefaultErrorCharset - ) - } yield { - val raw = new String(bytes, charset) - if (truncated) raw + "..." else raw - } - } - - mbBodyMessage match { - case Some(bodyMessage) => { // reconstruct the IOException - val newMessage = ioe.getMessage() + s"; Response Body: ${bodyMessage}" - val reconstructed = new IOException(newMessage, ioe.getCause()) - reconstructed.setStackTrace(ioe.getStackTrace()) - throw reconstructed - } - case None => { - throw ioe - } - } - } - } - } -} - -object GigahorseUrlHandler { - // This is requires to access the constructor of URLInfo. - private[sbt] class SbtUrlInfo( - available: Boolean, - contentLength: Long, - lastModified: Long, - bodyCharset: String - ) extends URLInfo(available, contentLength, lastModified, bodyCharset) { - def this(available: Boolean, contentLength: Long, lastModified: Long) = { - this(available, contentLength, lastModified, null) - } - } - - private val EmptyBuffer: Array[Byte] = new Array[Byte](0) - - private def checkStatusCode(url: URL, response: Response): Boolean = - response.code() match { - case 200 => true - case 204 if "HEAD" == response.request().method() => true - case status => - Message.debug("HTTP response status: " + status + " url=" + url) - if (status == 407 /* PROXY_AUTHENTICATION_REQUIRED */ ) { - Message.warn("Your proxy requires authentication.") - } else if (status == 401) { - Message.warn( - "CLIENT ERROR: 401 Unauthorized. Check your resolvers username and password." - ) - } else if (String.valueOf(status).startsWith("4")) { - Message.verbose("CLIENT ERROR: " + response.message() + " url=" + url) - } else if (String.valueOf(status).startsWith("5")) { - Message.error("SERVER ERROR: " + response.message() + " url=" + url) - } - false - } - - private def lastModifiedTimestamp(response: Response): Long = { - val lastModifiedDate = - Option(response.headers().get("Last-Modified")).flatMap { headerValue => - Option(HttpDate.parse(headerValue)) - } - - lastModifiedDate.map(_.getTime).getOrElse(0) - } - -} diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala index bc72f4bc2..3f5aedaca 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala @@ -2,7 +2,6 @@ package sbt package librarymanagement package ivy -import okhttp3.OkHttpClient import sbt.internal.librarymanagement._ import sbt.util.Logger @@ -30,8 +29,5 @@ class IvyDependencyResolution private[sbt] (val ivySbt: IvySbt) object IvyDependencyResolution { def apply(ivyConfiguration: IvyConfiguration): DependencyResolution = - apply(ivyConfiguration, CustomHttp.defaultHttpClient) - - def apply(ivyConfiguration: IvyConfiguration, http: OkHttpClient): DependencyResolution = - DependencyResolution(new IvyDependencyResolution(new IvySbt(ivyConfiguration, http))) + DependencyResolution(new IvyDependencyResolution(new IvySbt(ivyConfiguration))) } diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala index dc15ba7a9..784398744 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala @@ -2,7 +2,6 @@ package sbt package librarymanagement package ivy -import okhttp3.OkHttpClient import sbt.internal.librarymanagement._ import sbt.util.Logger import java.io.File @@ -36,8 +35,5 @@ class IvyPublisher private[sbt] (val ivySbt: IvySbt) extends PublisherInterface object IvyPublisher { def apply(ivyConfiguration: IvyConfiguration): Publisher = - apply(ivyConfiguration, CustomHttp.defaultHttpClient) - - def apply(ivyConfiguration: IvyConfiguration, http: OkHttpClient): Publisher = - Publisher(new IvyPublisher(new IvySbt(ivyConfiguration, http))) + Publisher(new IvyPublisher(new IvySbt(ivyConfiguration))) } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 59367176b..2b9a0d742 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,8 +3,8 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala212 = "2.12.15" - val scala213 = "2.13.6" + val scala212 = "2.12.16" + val scala213 = "2.13.8" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") @@ -61,6 +61,5 @@ object Dependencies { val sjsonnewScalaJson = Def.setting { "com.eed3si9n" %% "sjson-new-scalajson" % contrabandSjsonNewVersion.value } - val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0" - val okhttpUrlconnection = "com.squareup.okhttp3" % "okhttp-urlconnection" % "3.7.0" + val gigahorseApacheHttp = "com.eed3si9n" %% "gigahorse-apache-http" % "0.7.0" } From c896641f1cc9c81d3e552b366657878a2965ee45 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 12 Jun 2022 23:46:55 -0400 Subject: [PATCH 08/52] Turn off semanticdb on CI --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 07e4fc470..54d0c8aa5 100644 --- a/build.sbt +++ b/build.sbt @@ -6,7 +6,7 @@ val _ = { //https://github.com/sbt/contraband/issues/122 sys.props += ("line.separator" -> "\n") } -Global / semanticdbEnabled := true +Global / semanticdbEnabled := !(Global / insideCI).value Global / semanticdbVersion := "4.5.9" ThisBuild / version := { val old = (ThisBuild / version).value From 2318269dc5fd14f31ccfbb8fa8564deabc91d613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rui=20Gonc=CC=A7alves?= Date: Sat, 25 Jun 2022 21:41:10 +0100 Subject: [PATCH 09/52] Add CrossVersionExtra.isBinaryCompatible utility --- .gitignore | 5 ++ .../cross/CrossVersionUtil.scala | 17 +++++++ .../librarymanagement/CrossVersionExtra.scala | 8 ++- .../librarymanagement/CrossVersionTest.scala | 49 +++++++++++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0cbd43574..99e785f4e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,9 @@ __pycache__ scripted-test/src/sbt-test/*/*/project/build.properties scripted-test/src/sbt-test/*/*/project/plugins.sbt + +.idea +.bloop +.metals +.bsp/ metals.sbt diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index fe6b107cf..b09f42ca7 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -84,6 +84,23 @@ object CrossVersionUtil { case _ => full } + // Uses the following rules: + // + // - Forwards and backwards compatibility is guaranteed for Scala 2.N.x (https://docs.scala-lang.org/overviews/core/binary-compatibility-of-scala-releases.html) + // + // - A Scala compiler in version 3.x1.y1 is able to read TASTy files produced by another compiler in version 3.x2.y2 if x1 >= x2 (https://docs.scala-lang.org/scala3/reference/language-versions/binary-compatibility.html) + // + // - For non-stable Scala 3 versions, compiler versions can read TASTy in an older stable format but their TASTY versions are not compatible between each other even if the compilers have the same minor version (https://docs.scala-lang.org/scala3/reference/language-versions/binary-compatibility.html) + // + private[sbt] def isBinaryCompatibleWith(newVersion: String, origVersion: String): Boolean = { + (newVersion, origVersion) match { + case (NonReleaseV_n("2", nMin, _, _), NonReleaseV_n("2", oMin, _, _)) => nMin == oMin + case (ReleaseV("3", nMin, _, _), ReleaseV("3", oMin, _, _)) => nMin.toInt >= oMin.toInt + case (NonReleaseV_1("3", nMin, _, _), ReleaseV("3", oMin, _, _)) => nMin.toInt > oMin.toInt + case _ => newVersion == origVersion + } + } + def binaryScalaVersion(full: String): String = { if (ScalaArtifacts.isScala3(full)) binaryScala3Version(full) else diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 9de8605ea..a60f30325 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -9,7 +9,7 @@ private[librarymanagement] abstract class CrossVersionFunctions { /** Compatibility with 0.13 */ @deprecated( - "use CrossVersion.disabled instead. prior to sbt 1.3.0, Diabled did not work without apply(). sbt/sbt#4977", + "use CrossVersion.disabled instead. prior to sbt 1.3.0, Disabled did not work without apply(). sbt/sbt#4977", "1.3.0" ) final val Disabled = sbt.librarymanagement.Disabled @@ -235,4 +235,10 @@ private[librarymanagement] abstract class CrossVersionFunctions { * Full sbt versions earlier than [[sbt.librarymanagement.CrossVersion.TransitionSbtVersion]] are returned as is. */ def binarySbtVersion(full: String): String = CrossVersionUtil.binarySbtVersion(full) + + /** + * Returns `true` if a project targeting version `origVersion` can run with version `newVersion`. + */ + def isBinaryCompatibleWith(newVersion: String, origVersion: String): Boolean = + CrossVersionUtil.isBinaryCompatibleWith(newVersion, origVersion) } diff --git a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala index d47b17c14..b4e570083 100644 --- a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala @@ -284,6 +284,55 @@ class CrossVersionTest extends UnitSpec { patchVersion("2.11.8-X1.5-bin-extra") shouldBe Some("artefact_2.11.8-X1.5") } + "isBinaryCompatibleWith" should "for (2.10.4, 2.10.5) return true" in { + isBinaryCompatibleWith("2.10.4", "2.10.5") shouldBe true + } + it should "for (2.10.6, 2.10.5) return true" in { + isBinaryCompatibleWith("2.10.6", "2.10.5") shouldBe true + } + it should "for (2.11.0, 2.10.5) return false" in { + isBinaryCompatibleWith("2.11.0", "2.10.5") shouldBe false + } + it should "for (3.0.0, 2.10.5) return false" in { + isBinaryCompatibleWith("3.0.0", "2.10.5") shouldBe false + } + it should "for (3.0.0, 3.1.0) return false" in { + isBinaryCompatibleWith("3.0.0", "3.1.0") shouldBe false + } + it should "for (3.1.0, 3.0.0) return true" in { + isBinaryCompatibleWith("3.1.0", "3.0.0") shouldBe true + } + it should "for (3.1.0, 3.1.1) return true" in { + isBinaryCompatibleWith("3.1.0", "3.1.1") shouldBe true + } + it should "for (3.1.1, 3.1.0) return true" in { + isBinaryCompatibleWith("3.1.1", "3.1.0") shouldBe true + } + it should "for (2.10.0-M1, 2.10.5) return true" in { + isBinaryCompatibleWith("2.10.0-M1", "2.10.5") shouldBe true + } + it should "for (2.10.5, 2.10.0-M1) return true" in { + isBinaryCompatibleWith("2.10.5", "2.10.0-M1") shouldBe true + } + it should "for (2.10.0-M1, 2.10.0-M2) return true" in { + isBinaryCompatibleWith("2.10.0-M1", "2.10.0-M2") shouldBe true + } + it should "for (2.10.0-M1, 2.11.0-M1) return false" in { + isBinaryCompatibleWith("2.10.0-M1", "2.11.0-M1") shouldBe false + } + it should "for (3.1.0-M1, 3.0.0) return true" in { + isBinaryCompatibleWith("3.1.0-M1", "3.0.0") shouldBe true + } + it should "for (3.1.0-M1, 3.1.0) return false" in { + isBinaryCompatibleWith("3.1.0-M1", "3.1.0") shouldBe false + } + it should "for (3.1.0-M1, 3.1.0-M2) return false" in { + isBinaryCompatibleWith("3.1.0-M1", "3.1.0-M2") shouldBe false + } + it should "for (3.1.0-M2, 3.1.0-M1) return false" in { + isBinaryCompatibleWith("3.1.0-M2", "3.1.0-M1") shouldBe false + } + private def constantVersion(value: String) = CrossVersion(CrossVersion.constant(value), "dummy1", "dummy2") map (fn => fn("artefact")) From daec6265c441ba8dedfd893250b4152bd9bcbc9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rui=20Gonc=CC=A7alves?= Date: Sat, 25 Jun 2022 22:54:08 +0100 Subject: [PATCH 10/52] Rename function and extend support to Scala 4+ --- .../cross/CrossVersionUtil.scala | 16 ++++++--- .../librarymanagement/CrossVersionExtra.scala | 4 +-- .../librarymanagement/CrossVersionTest.scala | 34 +++++++++---------- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index b09f42ca7..1f58cfe7d 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -92,12 +92,18 @@ object CrossVersionUtil { // // - For non-stable Scala 3 versions, compiler versions can read TASTy in an older stable format but their TASTY versions are not compatible between each other even if the compilers have the same minor version (https://docs.scala-lang.org/scala3/reference/language-versions/binary-compatibility.html) // - private[sbt] def isBinaryCompatibleWith(newVersion: String, origVersion: String): Boolean = { + private[sbt] def isScalaBinaryCompatibleWith(newVersion: String, origVersion: String): Boolean = { (newVersion, origVersion) match { - case (NonReleaseV_n("2", nMin, _, _), NonReleaseV_n("2", oMin, _, _)) => nMin == oMin - case (ReleaseV("3", nMin, _, _), ReleaseV("3", oMin, _, _)) => nMin.toInt >= oMin.toInt - case (NonReleaseV_1("3", nMin, _, _), ReleaseV("3", oMin, _, _)) => nMin.toInt > oMin.toInt - case _ => newVersion == origVersion + case (NonReleaseV_n("2", nMin, _, _), NonReleaseV_n("2", oMin, _, _)) => + nMin == oMin + case (ReleaseV(nMaj, nMin, _, _), ReleaseV(oMaj, oMin, _, _)) + if nMaj == oMaj && nMaj.toLong >= 3 => + nMin.toInt >= oMin.toInt + case (NonReleaseV_1(nMaj, nMin, _, _), ReleaseV(oMaj, oMin, _, _)) + if nMaj == oMaj && nMaj.toLong >= 3 => + nMin.toInt > oMin.toInt + case _ => + newVersion == origVersion } } diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index a60f30325..03cd97e88 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -239,6 +239,6 @@ private[librarymanagement] abstract class CrossVersionFunctions { /** * Returns `true` if a project targeting version `origVersion` can run with version `newVersion`. */ - def isBinaryCompatibleWith(newVersion: String, origVersion: String): Boolean = - CrossVersionUtil.isBinaryCompatibleWith(newVersion, origVersion) + def isScalaBinaryCompatibleWith(newVersion: String, origVersion: String): Boolean = + CrossVersionUtil.isScalaBinaryCompatibleWith(newVersion, origVersion) } diff --git a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala index b4e570083..aae585b16 100644 --- a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala @@ -284,53 +284,53 @@ class CrossVersionTest extends UnitSpec { patchVersion("2.11.8-X1.5-bin-extra") shouldBe Some("artefact_2.11.8-X1.5") } - "isBinaryCompatibleWith" should "for (2.10.4, 2.10.5) return true" in { - isBinaryCompatibleWith("2.10.4", "2.10.5") shouldBe true + "isScalaBinaryCompatibleWith" should "for (2.10.4, 2.10.5) return true" in { + isScalaBinaryCompatibleWith("2.10.4", "2.10.5") shouldBe true } it should "for (2.10.6, 2.10.5) return true" in { - isBinaryCompatibleWith("2.10.6", "2.10.5") shouldBe true + isScalaBinaryCompatibleWith("2.10.6", "2.10.5") shouldBe true } it should "for (2.11.0, 2.10.5) return false" in { - isBinaryCompatibleWith("2.11.0", "2.10.5") shouldBe false + isScalaBinaryCompatibleWith("2.11.0", "2.10.5") shouldBe false } it should "for (3.0.0, 2.10.5) return false" in { - isBinaryCompatibleWith("3.0.0", "2.10.5") shouldBe false + isScalaBinaryCompatibleWith("3.0.0", "2.10.5") shouldBe false } it should "for (3.0.0, 3.1.0) return false" in { - isBinaryCompatibleWith("3.0.0", "3.1.0") shouldBe false + isScalaBinaryCompatibleWith("3.0.0", "3.1.0") shouldBe false } it should "for (3.1.0, 3.0.0) return true" in { - isBinaryCompatibleWith("3.1.0", "3.0.0") shouldBe true + isScalaBinaryCompatibleWith("3.1.0", "3.0.0") shouldBe true } it should "for (3.1.0, 3.1.1) return true" in { - isBinaryCompatibleWith("3.1.0", "3.1.1") shouldBe true + isScalaBinaryCompatibleWith("3.1.0", "3.1.1") shouldBe true } it should "for (3.1.1, 3.1.0) return true" in { - isBinaryCompatibleWith("3.1.1", "3.1.0") shouldBe true + isScalaBinaryCompatibleWith("3.1.1", "3.1.0") shouldBe true } it should "for (2.10.0-M1, 2.10.5) return true" in { - isBinaryCompatibleWith("2.10.0-M1", "2.10.5") shouldBe true + isScalaBinaryCompatibleWith("2.10.0-M1", "2.10.5") shouldBe true } it should "for (2.10.5, 2.10.0-M1) return true" in { - isBinaryCompatibleWith("2.10.5", "2.10.0-M1") shouldBe true + isScalaBinaryCompatibleWith("2.10.5", "2.10.0-M1") shouldBe true } it should "for (2.10.0-M1, 2.10.0-M2) return true" in { - isBinaryCompatibleWith("2.10.0-M1", "2.10.0-M2") shouldBe true + isScalaBinaryCompatibleWith("2.10.0-M1", "2.10.0-M2") shouldBe true } it should "for (2.10.0-M1, 2.11.0-M1) return false" in { - isBinaryCompatibleWith("2.10.0-M1", "2.11.0-M1") shouldBe false + isScalaBinaryCompatibleWith("2.10.0-M1", "2.11.0-M1") shouldBe false } it should "for (3.1.0-M1, 3.0.0) return true" in { - isBinaryCompatibleWith("3.1.0-M1", "3.0.0") shouldBe true + isScalaBinaryCompatibleWith("3.1.0-M1", "3.0.0") shouldBe true } it should "for (3.1.0-M1, 3.1.0) return false" in { - isBinaryCompatibleWith("3.1.0-M1", "3.1.0") shouldBe false + isScalaBinaryCompatibleWith("3.1.0-M1", "3.1.0") shouldBe false } it should "for (3.1.0-M1, 3.1.0-M2) return false" in { - isBinaryCompatibleWith("3.1.0-M1", "3.1.0-M2") shouldBe false + isScalaBinaryCompatibleWith("3.1.0-M1", "3.1.0-M2") shouldBe false } it should "for (3.1.0-M2, 3.1.0-M1) return false" in { - isBinaryCompatibleWith("3.1.0-M2", "3.1.0-M1") shouldBe false + isScalaBinaryCompatibleWith("3.1.0-M2", "3.1.0-M1") shouldBe false } private def constantVersion(value: String) = From 457af6978fcfee61c618643986fa78d93a1f7b0c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 26 Jun 2022 21:05:52 -0400 Subject: [PATCH 11/52] Fix isScalaBinaryCompatibleWith Problem ------- Current impl is relaxed about comparing non-release Scala 2.x versions. Solutution ---------- Use scalaApiVersion to compare two Scala 2 versions. --- .../librarymanagement/cross/CrossVersionUtil.scala | 6 ++++-- .../sbt/librarymanagement/CrossVersionTest.scala | 12 ++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index 1f58cfe7d..8f84cad47 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -94,8 +94,10 @@ object CrossVersionUtil { // private[sbt] def isScalaBinaryCompatibleWith(newVersion: String, origVersion: String): Boolean = { (newVersion, origVersion) match { - case (NonReleaseV_n("2", nMin, _, _), NonReleaseV_n("2", oMin, _, _)) => - nMin == oMin + case (NonReleaseV_n("2", _, _, _), NonReleaseV_n("2", _, _, _)) => + val api1 = scalaApiVersion(newVersion) + val api2 = scalaApiVersion(origVersion) + (api1.isDefined && api1 == api2) || (newVersion == origVersion) case (ReleaseV(nMaj, nMin, _, _), ReleaseV(oMaj, oMin, _, _)) if nMaj == oMaj && nMaj.toLong >= 3 => nMin.toInt >= oMin.toInt diff --git a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala index aae585b16..96b3d164f 100644 --- a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala @@ -308,14 +308,14 @@ class CrossVersionTest extends UnitSpec { it should "for (3.1.1, 3.1.0) return true" in { isScalaBinaryCompatibleWith("3.1.1", "3.1.0") shouldBe true } - it should "for (2.10.0-M1, 2.10.5) return true" in { - isScalaBinaryCompatibleWith("2.10.0-M1", "2.10.5") shouldBe true + it should "for (2.10.0-M1, 2.10.5) return false" in { + isScalaBinaryCompatibleWith("2.10.0-M1", "2.10.5") shouldBe false } - it should "for (2.10.5, 2.10.0-M1) return true" in { - isScalaBinaryCompatibleWith("2.10.5", "2.10.0-M1") shouldBe true + it should "for (2.10.5, 2.10.0-M1) return false" in { + isScalaBinaryCompatibleWith("2.10.5", "2.10.0-M1") shouldBe false } - it should "for (2.10.0-M1, 2.10.0-M2) return true" in { - isScalaBinaryCompatibleWith("2.10.0-M1", "2.10.0-M2") shouldBe true + it should "for (2.10.0-M1, 2.10.0-M2) return false" in { + isScalaBinaryCompatibleWith("2.10.0-M1", "2.10.0-M2") shouldBe false } it should "for (2.10.0-M1, 2.11.0-M1) return false" in { isScalaBinaryCompatibleWith("2.10.0-M1", "2.11.0-M1") shouldBe false From 5dd056fa4dbc9f47e84449426f47c065c2985c3b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jul 2022 05:28:16 -0400 Subject: [PATCH 12/52] util 1.7.0 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 2b9a0d742..ac0f037e4 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -9,8 +9,8 @@ object Dependencies { def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.6.0") - private val utilVersion = nightlyVersion.getOrElse("1.6.0") + private val ioVersion = nightlyVersion.getOrElse("1.7.0") + private val utilVersion = nightlyVersion.getOrElse("1.7.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 925c461aa84c0855b104bd6672029286edc13891 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jul 2022 23:09:51 -0400 Subject: [PATCH 13/52] sbt 1.7.0 --- .github/workflows/ci.yml | 36 ++++++++++-------------------------- build.sbt | 2 +- project/build.properties | 2 +- 3 files changed, 12 insertions(+), 28 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 897e165ce..6ef1c3dab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,31 +21,15 @@ jobs: JVM_OPTS: -Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M steps: - name: Checkout - uses: actions/checkout@v1 - - name: Setup - uses: olafurpg/setup-scala@v10 + uses: actions/checkout@v3 + - name: Setup JDK + uses: actions/setup-java@v3 with: - java-version: "adopt@1.${{ matrix.java }}" - - name: Coursier cache - uses: coursier/cache-action@v5 - - name: Cache sbt - uses: actions/cache@v1 - with: - path: $HOME/.sbt - key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} - - name: Build and test + distribution: temurin + java-version: "${{ matrix.java }}" + cache: sbt + - name: Build and test (1) + if: ${{ matrix.jobtype == 1 }} + shell: bash run: | - case ${{ matrix.jobtype }} in - 1) - sbt -v -Dfile.encoding=UTF8 scalafmtCheckAll +test +packagedArtifacts - ;; - *) - echo unknown jobtype - exit 1 - esac - rm -rf "$HOME/.ivy2/local" - find $HOME/Library/Caches/Coursier/v1 -name "ivydata-*.properties" -delete || true - find $HOME/.ivy2/cache -name "ivydata-*.properties" -delete || true - find $HOME/.ivy2/cache -name "*-LM-SNAPSHOT*" -delete || true - find $HOME/.cache/coursier/v1 -name "ivydata-*.properties" -delete || true - find $HOME/.sbt -name "*.lock" -delete || true + sbt -v -Dfile.encoding=UTF8 scalafmtCheckAll +test +packagedArtifacts diff --git a/build.sbt b/build.sbt index 54d0c8aa5..b47005ad0 100644 --- a/build.sbt +++ b/build.sbt @@ -7,7 +7,7 @@ val _ = { sys.props += ("line.separator" -> "\n") } Global / semanticdbEnabled := !(Global / insideCI).value -Global / semanticdbVersion := "4.5.9" +// Global / semanticdbVersion := "4.5.9" ThisBuild / version := { val old = (ThisBuild / version).value nightlyVersion match { diff --git a/project/build.properties b/project/build.properties index c8fcab543..5b12c1dc6 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.6.2 +sbt.version=1.7.0 From d2fba6fde0a616382322a92f451cb86810394fe5 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Fri, 29 Jul 2022 19:32:14 -0700 Subject: [PATCH 14/52] Better deprecation message for `sonatypeRepo` --- core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 0d6683a91..d80df66a2 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -155,7 +155,7 @@ private[librarymanagement] abstract class ResolverFunctions { url("sbt-plugin-" + status, new URL(SbtRepositoryRoot + "/sbt-plugin-" + status + "/"))( ivyStylePatterns ) - @deprecated("Use sonatypeOssRepos instead", "1.7.0") + @deprecated("""Use sonatypeOssRepos instead e.g. `resolvers ++= Resolver.sonatypeOssRepos("snapshots")`""", "1.7.0") def sonatypeRepo(status: String) = MavenRepository( "sonatype-" + status, From f17280780dc7de5e7bd0b3c24e616f549b602d02 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Sat, 30 Jul 2022 02:51:02 +0000 Subject: [PATCH 15/52] Formatting --- .../src/main/scala/sbt/librarymanagement/ResolverExtra.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index d80df66a2..e08b97f31 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -155,7 +155,10 @@ private[librarymanagement] abstract class ResolverFunctions { url("sbt-plugin-" + status, new URL(SbtRepositoryRoot + "/sbt-plugin-" + status + "/"))( ivyStylePatterns ) - @deprecated("""Use sonatypeOssRepos instead e.g. `resolvers ++= Resolver.sonatypeOssRepos("snapshots")`""", "1.7.0") + @deprecated( + """Use sonatypeOssRepos instead e.g. `resolvers ++= Resolver.sonatypeOssRepos("snapshots")`""", + "1.7.0" + ) def sonatypeRepo(status: String) = MavenRepository( "sonatype-" + status, From 90795c3590f54cbd566b4dff74894145a5dd1b3e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 2 Oct 2022 21:49:45 -0400 Subject: [PATCH 16/52] Util 1.7.1 --- build.sbt | 2 +- project/Dependencies.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index b47005ad0..b44f77bdb 100644 --- a/build.sbt +++ b/build.sbt @@ -13,7 +13,7 @@ ThisBuild / version := { nightlyVersion match { case Some(v) => v case _ => - if ((ThisBuild / isSnapshot).value) "1.4.0-SNAPSHOT" + if ((ThisBuild / isSnapshot).value) "1.7.2-SNAPSHOT" else old } } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index ac0f037e4..b990e4be6 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -10,7 +10,7 @@ object Dependencies { sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") private val ioVersion = nightlyVersion.getOrElse("1.7.0") - private val utilVersion = nightlyVersion.getOrElse("1.7.0") + private val utilVersion = nightlyVersion.getOrElse("1.7.1") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From adc682c9266c5f1e3ff048022c9cdd8b68ca40a0 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 10 Nov 2022 10:04:52 -0500 Subject: [PATCH 17/52] Ivy 2.3.0-sbt-a8f9eb5bf09d0539ea3658a2c2d4e09755b5133e --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b990e4be6..e726ce267 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -43,7 +43,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-fbc4f586aeeb1591710b14eb4f41b94880dcd745" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-a8f9eb5bf09d0539ea3658a2c2d4e09755b5133e" val sbtV = "1.0" val scalaV = "2.12" From adc246ea9a6659896d11b43829d2497acd61793f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 10 Nov 2022 13:40:09 -0500 Subject: [PATCH 18/52] Bump io, util, and scala-xml --- project/Dependencies.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index e726ce267..7424830d9 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,14 +3,14 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala212 = "2.12.16" + val scala212 = "2.12.17" val scala213 = "2.13.8" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.7.0") - private val utilVersion = nightlyVersion.getOrElse("1.7.1") + private val ioVersion = nightlyVersion.getOrElse("1.8.0") + private val utilVersion = nightlyVersion.getOrElse("1.8.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion @@ -51,7 +51,7 @@ object Dependencies { val jsch = "com.jcraft" % "jsch" % "0.1.54" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } - val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "1.2.0" + val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "2.1.0" val scalaTest = "org.scalatest" %% "scalatest" % "3.2.0" val scalaVerify = "com.eed3si9n.verify" %% "verify" % "1.0.0" val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.14.0" From 5a0e9b2fe743e1159528314a039a655baf808ffe Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 23 Dec 2022 16:05:43 +0100 Subject: [PATCH 19/52] Try resolve sbt plugin from valid Maven pattern sbt plugins were published to an invalid path with regard to Maven's specifictation. As of sbt 1.9 we produce two POMs, a deprecated one and a new one, that is valid with regard to Maven resolution. When resolving, we first try to resolve the new valid POM and we fallback to the invalid one if needed. In the new POM format, we append the sbt cross-version to all artifactIds of sbt plugins. This is because we want Maven to be able to resolve the plugin and all its dependencies. When parsing it, we remove the cross-version suffix so that the result of parsing the valid POM format is exactly the same as parsing the deprecated POM format. Hence conflict resolution happens as intended. More details can be found at https://github.com/sbt/sbt/pull/7096 --- .../librarymanagement/ConvertResolver.scala | 41 ++++++++++- .../librarymanagement/CustomPomParser.scala | 30 +++++++- .../sbt/internal/librarymanagement/Ivy.scala | 73 +++++++++++++------ .../BaseIvySpecification.scala | 5 +- .../librarymanagement/IvyModuleSpec.scala | 38 ++++++++++ 5 files changed, 162 insertions(+), 25 deletions(-) create mode 100644 ivy/src/test/scala/sbt/internal/librarymanagement/IvyModuleSpec.scala diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index f682a785e..94e82974a 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -27,10 +27,16 @@ import org.apache.ivy.plugins.resolver.{ import org.apache.ivy.plugins.repository.url.{ URLRepository => URLRepo } import org.apache.ivy.plugins.repository.file.{ FileResource, FileRepository => FileRepo } import java.io.{ File, IOException } +import java.util.Date -import org.apache.ivy.util.{ ChecksumHelper, FileUtil, Message } import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } +import org.apache.ivy.core.module.id.ModuleRevisionId +import org.apache.ivy.core.module.descriptor.DefaultArtifact import org.apache.ivy.core.report.DownloadReport +import org.apache.ivy.plugins.resolver.util.{ ResolvedResource, ResourceMDParser } +import org.apache.ivy.util.{ ChecksumHelper, FileUtil, Message } +import scala.collection.JavaConverters._ +import sbt.internal.librarymanagement.mavenint.PomExtraDependencyAttributes import sbt.io.IO import sbt.util.Logger import sbt.librarymanagement._ @@ -173,6 +179,32 @@ private[sbt] object ConvertResolver { setArtifactPatterns(pattern) setIvyPatterns(pattern) } + override protected def findResourceUsingPattern( + mrid: ModuleRevisionId, + pattern: String, + artifact: IArtifact, + rmdparser: ResourceMDParser, + date: Date + ): ResolvedResource = { + val extraAttributes = + mrid.getExtraAttributes.asScala.toMap.asInstanceOf[Map[String, String]] + getSbtPluginCrossVersion(extraAttributes) match { + case Some(sbtCrossVersion) => + // if the module is an sbt plugin + // we first try to resolve the artifact with the sbt cross version suffix + // and we fallback to the one without the suffix + val newArtifact = DefaultArtifact.cloneWithAnotherName( + artifact, + artifact.getName + sbtCrossVersion + ) + val resolved = + super.findResourceUsingPattern(mrid, pattern, newArtifact, rmdparser, date) + if (resolved != null) resolved + else super.findResourceUsingPattern(mrid, pattern, artifact, rmdparser, date) + case None => + super.findResourceUsingPattern(mrid, pattern, artifact, rmdparser, date) + } + } } val resolver = new PluginCapableResolver if (repo.localIfFile) resolver.setRepository(new LocalIfFileRepo) @@ -230,6 +262,13 @@ private[sbt] object ConvertResolver { } } + private def getSbtPluginCrossVersion(extraAttributes: Map[String, String]): Option[String] = { + for { + sbtVersion <- extraAttributes.get(PomExtraDependencyAttributes.SbtVersionKey) + scalaVersion <- extraAttributes.get(PomExtraDependencyAttributes.ScalaVersionKey) + } yield s"_${scalaVersion}_$sbtVersion" + } + private sealed trait DescriptorRequired extends BasicResolver { // Works around implementation restriction to access protected method `get` def getResource(resource: Resource, dest: File): Long diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index e81ef45cd..3ec3282f6 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -75,6 +75,31 @@ object CustomPomParser { private[this] val unqualifiedKeys = Set(SbtVersionKey, ScalaVersionKey, ExtraAttributesKey, ApiURLKey, VersionSchemeKey) + /** In the new POM format of sbt plugins, the dependency to an sbt plugin + * contains the sbt cross-version _2.12_1.0. The reason is we want Maven to be able + * to resolve the dependency using the pattern: + * /_2.12_1.0//_2.12_1.0-.pom + * In sbt 1.x we use extra-attributes to resolve sbt plugins, so here we must remove + * the sbt cross-version and keep the extra-attributes. + * Parsing a dependency found in the new POM format produces the same module as + * if it is found in the old POM format. It used not to contain the sbt cross-version + * suffix, but that was invalid. + * Hence we can resolve conflicts between new and old POM formats. + * + * To compare the two formats you can look at the POMs in: + * https://repo1.maven.org/maven2/ch/epfl/scala/sbt-plugin-example-diamond_2.12_1.0/0.5.0/ + */ + private def removeSbtCrossVersion( + properties: Map[String, String], + moduleName: String + ): String = { + val sbtCrossVersion = for { + sbtVersion <- properties.get(s"e:$SbtVersionKey") + scalaVersion <- properties.get(s"e:$ScalaVersionKey") + } yield s"_${scalaVersion}_$sbtVersion" + sbtCrossVersion.map(moduleName.stripSuffix).getOrElse(moduleName) + } + // packagings that should be jars, but that Ivy doesn't handle as jars // TODO - move this elsewhere. val JarPackagings = Set("eclipse-plugin", "hk2-jar", "orbit", "scala-jar") @@ -163,9 +188,12 @@ object CustomPomParser { import collection.JavaConverters._ val oldExtra = qualifiedExtra(id) val newExtra = (oldExtra ++ properties).asJava + // remove the sbt plugin cross version from the resolved ModuleRevisionId + // sbt-plugin-example_2.12_1.0 => sbt-plugin-example + val nameWithoutCrossVersion = removeSbtCrossVersion(properties, id.getName) ModuleRevisionId.newInstance( id.getOrganisation, - id.getName, + nameWithoutCrossVersion, id.getBranch, id.getRevision, newExtra diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index eaab99af1..270d08546 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -219,9 +219,28 @@ final class IvySbt( else IvySbt.cachedResolutionResolveCache.clean() } - final class Module(rawModuleSettings: ModuleSettings) + /** + * In the new POM format of sbt plugins, we append the sbt-cross version _2.12_1.0 to + * the module artifactId, and the artifactIds of its dependencies that are sbt plugins. + * + * The goal is to produce a valid Maven POM, a POM that Maven can resolve: + * Maven will try and succeed to resolve the POM of pattern: + * /_2.12_1.0//_2.12_1.0-.pom + */ + final class Module(rawModuleSettings: ModuleSettings, appendSbtCrossVersion: Boolean) extends sbt.librarymanagement.ModuleDescriptor { self => - val moduleSettings: ModuleSettings = IvySbt.substituteCross(rawModuleSettings) + + def this(rawModuleSettings: ModuleSettings) = + this(rawModuleSettings, appendSbtCrossVersion = false) + + val moduleSettings: ModuleSettings = + rawModuleSettings match { + case ic: InlineConfiguration => + val icWithCross = IvySbt.substituteCross(ic) + if (appendSbtCrossVersion) IvySbt.appendSbtCrossVersion(icWithCross) + else icWithCross + case m => m + } def directDependencies: Vector[ModuleID] = moduleSettings match { @@ -696,32 +715,44 @@ private[sbt] object IvySbt { ) } - private def substituteCross(m: ModuleSettings): ModuleSettings = { - m.scalaModuleInfo match { - case None => m - case Some(is) => substituteCross(m, is.scalaFullVersion, is.scalaBinaryVersion) + private def substituteCross(ic: InlineConfiguration): InlineConfiguration = { + ic.scalaModuleInfo match { + case None => ic + case Some(is) => substituteCross(ic, is.scalaFullVersion, is.scalaBinaryVersion) } } private def substituteCross( - m: ModuleSettings, + ic: InlineConfiguration, scalaFullVersion: String, scalaBinaryVersion: String - ): ModuleSettings = { - m match { - case ic: InlineConfiguration => - val applyCross = CrossVersion(scalaFullVersion, scalaBinaryVersion) - def propagateCrossVersion(moduleID: ModuleID): ModuleID = { - val crossExclusions: Vector[ExclusionRule] = - moduleID.exclusions.map(CrossVersion.substituteCross(_, ic.scalaModuleInfo)) - applyCross(moduleID) - .withExclusions(crossExclusions) - } - ic.withModule(applyCross(ic.module)) - .withDependencies(ic.dependencies.map(propagateCrossVersion)) - .withOverrides(ic.overrides map applyCross) - case _ => m + ): InlineConfiguration = { + val applyCross = CrossVersion(scalaFullVersion, scalaBinaryVersion) + def propagateCrossVersion(moduleID: ModuleID): ModuleID = { + val crossExclusions: Vector[ExclusionRule] = + moduleID.exclusions.map(CrossVersion.substituteCross(_, ic.scalaModuleInfo)) + applyCross(moduleID) + .withExclusions(crossExclusions) } + ic.withModule(applyCross(ic.module)) + .withDependencies(ic.dependencies.map(propagateCrossVersion)) + .withOverrides(ic.overrides map applyCross) + } + + private def appendSbtCrossVersion(ic: InlineConfiguration): InlineConfiguration = + ic.withModule(appendSbtCrossVersion(ic.module)) + .withDependencies(ic.dependencies.map(appendSbtCrossVersion)) + .withOverrides(ic.overrides.map(appendSbtCrossVersion)) + + private def appendSbtCrossVersion(mid: ModuleID): ModuleID = { + val crossVersion = for { + scalaVersion <- mid.extraAttributes.get("e:scalaVersion") + sbtVersion <- mid.extraAttributes.get("e:sbtVersion") + } yield s"_${scalaVersion}_$sbtVersion" + crossVersion + .filter(!mid.name.endsWith(_)) + .map(cv => mid.withName(mid.name + cv)) + .getOrElse(mid) } private def toIvyArtifact( diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala index f6bcba917..a1bd6d31f 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala @@ -37,7 +37,8 @@ trait BaseIvySpecification extends AbstractEngineSpec { deps: Vector[ModuleID], scalaFullVersion: Option[String], uo: UpdateOptions = UpdateOptions(), - overrideScalaVersion: Boolean = true + overrideScalaVersion: Boolean = true, + appendSbtCrossVersion: Boolean = false ): IvySbt#Module = { val scalaModuleInfo = scalaFullVersion map { fv => ScalaModuleInfo( @@ -55,7 +56,7 @@ trait BaseIvySpecification extends AbstractEngineSpec { .withConfigurations(configurations) .withScalaModuleInfo(scalaModuleInfo) val ivySbt = new IvySbt(mkIvyConfiguration(uo)) - new ivySbt.Module(moduleSetting) + new ivySbt.Module(moduleSetting, appendSbtCrossVersion) } def resolvers: Vector[Resolver] = Vector(Resolver.mavenCentral) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyModuleSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyModuleSpec.scala new file mode 100644 index 000000000..ac9474912 --- /dev/null +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyModuleSpec.scala @@ -0,0 +1,38 @@ +package sbt.internal.librarymanagement + +import sbt.internal.librarymanagement.mavenint.PomExtraDependencyAttributes.{ + SbtVersionKey, + ScalaVersionKey +} +import sbt.librarymanagement.{ CrossVersion, ModuleDescriptorConfiguration } + +object IvyModuleSpec extends BaseIvySpecification { + + test("The Scala binary version of a Scala module should be appended to its name") { + val m = module( + defaultModuleId.withCrossVersion(CrossVersion.Binary()), + Vector.empty, + Some("2.13.10") + ) + m.moduleSettings match { + case configuration: ModuleDescriptorConfiguration => + assert(configuration.module.name == "foo_2.13") + case _ => fail() + } + } + + test("The sbt cross-version should be appended to the name of an sbt plugin") { + val m = module( + defaultModuleId.extra(SbtVersionKey -> "1.0", ScalaVersionKey -> "2.12"), + Vector.empty, + Some("2.12.17"), + appendSbtCrossVersion = true + ) + m.moduleSettings match { + case configuration: ModuleDescriptorConfiguration => + assert(configuration.module.name == "foo_2.12_1.0") + case _ => fail() + } + } + +} From 3cee90bd55c9d1dfd279c9a4a37589f51a050f03 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Mon, 13 Feb 2023 04:05:10 +0000 Subject: [PATCH 20/52] Add `POM_RELEASE_NOTES_KEY` --- .../librarymanagement/mavenint/SbtPomExtraProperties.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java b/core/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java index 8bc61d549..b7033925c 100644 --- a/core/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java +++ b/core/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java @@ -14,6 +14,7 @@ public class SbtPomExtraProperties { public static final String POM_SBT_VERSION = "sbtVersion"; public static final String POM_API_KEY = "info.apiURL"; public static final String VERSION_SCHEME_KEY = "info.versionScheme"; + public static final String POM_RELEASE_NOTES_KEY = "info.releaseNotesUrl"; public static final String LICENSE_COUNT_KEY = "license.count"; From 63d3dccb9efc2b8d683dd5b0bb460fc046063789 Mon Sep 17 00:00:00 2001 From: Matthew de Detrich Date: Sat, 18 Feb 2023 10:42:21 +0100 Subject: [PATCH 21/52] Add Apache Maven Snapshots Repository --- .../src/main/scala/sbt/librarymanagement/ResolverExtra.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index e08b97f31..7e16ee39b 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -180,6 +180,11 @@ private[librarymanagement] abstract class ResolverFunctions { ) def jcenterRepo = JCenterRepository + val ApacheMavenSnapshotsRepo = MavenRepository( + "apache-snapshots", + "https://repository.apache.org/content/repositories/snapshots/" + ) + /** Add the local and Maven Central repositories to the user repositories. */ def combineDefaultResolvers(userResolvers: Vector[Resolver]): Vector[Resolver] = combineDefaultResolvers(userResolvers, mavenCentral = true) From e8cce49ba622c88059477b0c34c182b96e08c6d2 Mon Sep 17 00:00:00 2001 From: Nicolas Rinaudo Date: Sun, 9 Apr 2023 15:46:23 +0200 Subject: [PATCH 22/52] Expand properties found in maven settings --- .../sbt/librarymanagement/ResolverExtra.scala | 13 +++++- .../librarymanagement/ResolverExtraTest.scala | 43 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 7e16ee39b..10dd77e8f 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -391,6 +391,17 @@ private[librarymanagement] abstract class ResolverFunctions { def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" + private[librarymanagement] def expandMavenSettings(str: String): String = { + // Aren't regular expressions beautifully clear and concise. + // This means "find all ${...}" blocks, with the first group of each being the text between curly brackets. + val findQuoted = "\\$\\{([^\\}]*)\\}".r + val env = "env\\.(.*)".r + + findQuoted.replaceAllIn(str, _.group(1) match { + case env(variable) => sys.env.getOrElse(variable, "") + case property => sys.props.getOrElse(property, "") + }) + } private[this] def mavenLocalDir: File = { def loadHomeFromSettings(f: () => File): Option[File] = try { @@ -399,7 +410,7 @@ private[librarymanagement] abstract class ResolverFunctions { else ((XML.loadFile(file) \ "localRepository").text match { case "" => None - case e @ _ => Some(new File(e)) + case e @ _ => Some(new File(expandMavenSettings(e))) }) } catch { // Occurs inside File constructor when property or environment variable does not exist diff --git a/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala b/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala new file mode 100644 index 000000000..10cad9012 --- /dev/null +++ b/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala @@ -0,0 +1,43 @@ +package sbt.librarymanagement + +import verify.BasicTestSuite +import scala.annotation.nowarn + +@nowarn // Necessary because our test cases look like interpolated strings. +object ResolverExtraTest extends BasicTestSuite { + test("expandMavenSettings should expand existing environment variables") { + assertExpansion( + input = "User home: ${env.HOME}", + expected = s"User home: ${env("HOME")}" + ) + } + + test("expandMavenSettings should expand existing system properties") { + assertExpansion( + input = "User dir: ${user.dir}", + expected = s"User dir: ${prop("user.dir")}" + ) + } + + test("expandMavenSettings should expand unknown system properties to the empty string") { + assertExpansion( + input = "Unknown system property: ${IF_THIS_EXISTS_WE_NEED_TO_HAVE_A_CHAT}", + expected = s"Unknown system property: " + ) + } + + test("expandMavenSettings should expand unknown environment variables to the empty string") { + assertExpansion( + input = "Unknown environment variable: ${IF_THIS_EXISTS_I_WORRY_ABOUT_YOU}", + expected = s"Unknown environment variable: " + ) + } + + // - Helper functions ---------------------------------------------------------------------------- + // ----------------------------------------------------------------------------------------------- + def assertExpansion(input: String, expected: String) = + assert(Resolver.expandMavenSettings(input) == s"$expected") + + def env(name: String) = sys.env.getOrElse(name, "") + def prop(name: String) = sys.props.getOrElse(name, "") +} From 7d052bde8f7944e9f949fd4688e37fb77e1d1d3d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 24 Apr 2023 00:23:43 -0400 Subject: [PATCH 23/52] Deprecate IntegrationTest We plan to remove IntegrationTest configuration. See https://eed3si9n.com/sbt-drop-custom-config/ for details. --- .../scala/sbt/librarymanagement/ConfigurationExtra.scala | 6 +++++- .../sbt/librarymanagement/LibraryManagementSyntax.scala | 1 + project/build.properties | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index 7431e8950..ecdd2d875 100644 --- a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -3,7 +3,7 @@ */ package sbt.librarymanagement -import scala.annotation.tailrec +import scala.annotation.{ nowarn, tailrec } import scala.language.experimental.macros object Configurations { @@ -19,9 +19,11 @@ object Configurations { lazy val RuntimeInternal = optionalInternal(Runtime) lazy val TestInternal = fullInternal(Test) + @nowarn lazy val IntegrationTestInternal = fullInternal(IntegrationTest) lazy val CompileInternal = fullInternal(Compile) + @nowarn def internalMap(c: Configuration) = c match { case Compile => CompileInternal case Test => TestInternal @@ -39,6 +41,7 @@ object Configurations { lazy val Default = Configuration.of("Default", "default") lazy val Compile = Configuration.of("Compile", "compile") + @deprecated("Create a separate subproject for testing instead", "1.9.0") lazy val IntegrationTest = Configuration.of("IntegrationTest", "it") extend (Runtime) lazy val Provided = Configuration.of("Provided", "provided") lazy val Runtime = Configuration.of("Runtime", "runtime") extend (Compile) @@ -67,6 +70,7 @@ object Configurations { ) /** Returns true if the configuration should be under the influence of scalaVersion. */ + @nowarn private[sbt] def underScalaVersion(c: Configuration): Boolean = c match { case Default | Compile | IntegrationTest | Provided | Runtime | Test | Optional | diff --git a/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala b/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala index 8d177c835..1ab5629d7 100644 --- a/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala +++ b/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala @@ -28,6 +28,7 @@ trait LibraryManagementSyntax final val Compile = C.Compile final val Test = C.Test final val Runtime = C.Runtime + @deprecated("Create a separate subproject for testing instead", "1.9.0") final val IntegrationTest = C.IntegrationTest final val Default = C.Default final val Provided = C.Provided diff --git a/project/build.properties b/project/build.properties index 5b12c1dc6..46e43a97e 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.7.0 +sbt.version=1.8.2 From 2821443c80582f22adddebc73eb1283efffef94e Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 4 May 2023 21:04:29 +0200 Subject: [PATCH 24/52] Simplify processEvictions by inlining calculateCompatible --- .../sbt/librarymanagement/EvictionError.scala | 64 +++++++++---------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 6d0d0c274..52b056e6d 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -83,47 +83,43 @@ object EvictionError { } }: _*) - def calculateCompatible(p: EvictionPair): (Boolean, String, Boolean, String) = { - val winnerOpt = p.winner map { _.module } - val extraAttributes = ((p.winner match { - case Some(r) => r.extraAttributes.toMap - case _ => Map.empty - }): collection.immutable.Map[String, String]) ++ (winnerOpt match { - case Some(w) => w.extraAttributes.toMap - case _ => Map.empty - }) - // prioritize user-defined version scheme to allow overriding the real scheme - val schemeOpt = userDefinedSchemes - .get((p.organization, p.name)) - .orElse(userDefinedSchemes.get((p.organization, "*"))) - .orElse(VersionSchemes.extractFromExtraAttributes(extraAttributes)) - .orElse(userDefinedSchemes.get(("*", "*"))) - val f = (winnerOpt, schemeOpt) match { - case (Some(_), Some(scheme)) => VersionSchemes.evalFunc(scheme) - case _ => EvictionWarningOptions.guessTrue - } - val scheme = - if (isNameScalaSuffixed(p.name)) assumedVersionScheme - else assumedVersionSchemeJava - val guess = VersionSchemes.evalFunc(scheme) - (p.evicteds forall { r => - f((r.module, winnerOpt, module.scalaModuleInfo)) - }, schemeOpt.getOrElse("?"), p.evicteds forall { r => - guess((r.module, winnerOpt, module.scalaModuleInfo)) - }, scheme) - } pairs foreach { // don't report on a transitive eviction that does not have a winner // https://github.com/sbt/sbt/issues/4946 case p if p.winner.isDefined => - val r = calculateCompatible(p) - if (!r._1) { - incompatibleEvictions += (p -> r._2) - } else if (!r._3) { - assumedIncompatEvictions += (p -> r._4) + val winner = p.winner.get + def lookupUserDefined(org: String = "*", mod: String = "*") = + userDefinedSchemes.get((org, mod)) + def fromWinnerPom = VersionSchemes.extractFromExtraAttributes( + winner.extraAttributes.toMap ++ winner.module.extraAttributes + ) + // prioritize user-defined version scheme to allow overriding the real scheme + val userDefinedSchemeOrFromPom = + lookupUserDefined(p.organization, p.name) + .orElse(lookupUserDefined(p.organization)) + .orElse(fromWinnerPom) + .orElse(lookupUserDefined()) + + val assumedScheme = + if (isNameScalaSuffixed(p.name)) assumedVersionScheme + else assumedVersionSchemeJava + + def hasIncompatibleVersionForScheme(scheme: Option[String]) = { + val isCompat = + scheme.map(VersionSchemes.evalFunc).getOrElse(EvictionWarningOptions.guessTrue) + p.evicteds.exists { r => + !isCompat((r.module, Some(winner.module), module.scalaModuleInfo)) + } } + + if (hasIncompatibleVersionForScheme(userDefinedSchemeOrFromPom)) + incompatibleEvictions += (p -> userDefinedSchemeOrFromPom.getOrElse("?")) + else if (hasIncompatibleVersionForScheme(Some(assumedScheme))) + assumedIncompatEvictions += (p -> assumedScheme) + case _ => () } + new EvictionError( incompatibleEvictions.toList, assumedIncompatEvictions.toList, From 87f8089ba8b647e76b2102658959d32fbcbcb8f9 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 4 May 2023 21:04:29 +0200 Subject: [PATCH 25/52] More readability for processEvictions --- .../sbt/librarymanagement/EvictionError.scala | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 52b056e6d..9711a4d6f 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -88,33 +88,34 @@ object EvictionError { // https://github.com/sbt/sbt/issues/4946 case p if p.winner.isDefined => val winner = p.winner.get - def lookupUserDefined(org: String = "*", mod: String = "*") = + def fromLibraryDependencySchemes(org: String = "*", mod: String = "*") = userDefinedSchemes.get((org, mod)) def fromWinnerPom = VersionSchemes.extractFromExtraAttributes( winner.extraAttributes.toMap ++ winner.module.extraAttributes ) // prioritize user-defined version scheme to allow overriding the real scheme val userDefinedSchemeOrFromPom = - lookupUserDefined(p.organization, p.name) - .orElse(lookupUserDefined(p.organization)) + fromLibraryDependencySchemes(p.organization, p.name) + .orElse(fromLibraryDependencySchemes(p.organization)) .orElse(fromWinnerPom) - .orElse(lookupUserDefined()) + .orElse(fromLibraryDependencySchemes()) val assumedScheme = if (isNameScalaSuffixed(p.name)) assumedVersionScheme else assumedVersionSchemeJava - def hasIncompatibleVersionForScheme(scheme: Option[String]) = { + def hasIncompatibleVersionForScheme(scheme: String) = { val isCompat = - scheme.map(VersionSchemes.evalFunc).getOrElse(EvictionWarningOptions.guessTrue) + VersionSchemes.evalFunc(scheme) p.evicteds.exists { r => !isCompat((r.module, Some(winner.module), module.scalaModuleInfo)) } } - if (hasIncompatibleVersionForScheme(userDefinedSchemeOrFromPom)) + val userDefinedSchemeOrAlways = userDefinedSchemeOrFromPom.getOrElse(VersionSchemes.Always) + if (hasIncompatibleVersionForScheme(userDefinedSchemeOrAlways)) incompatibleEvictions += (p -> userDefinedSchemeOrFromPom.getOrElse("?")) - else if (hasIncompatibleVersionForScheme(Some(assumedScheme))) + else if (hasIncompatibleVersionForScheme(assumedScheme)) assumedIncompatEvictions += (p -> assumedScheme) case _ => () From 998df8b692415bdfad5bb6af2a4853dcb45e0967 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 4 May 2023 21:04:29 +0200 Subject: [PATCH 26/52] Allow user to suppress eviction errors for a specific library ... even if they would result in an incompatible eviction based on the assumed version scheme. --- .../sbt/librarymanagement/EvictionError.scala | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 9711a4d6f..27333fb2f 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -88,35 +88,43 @@ object EvictionError { // https://github.com/sbt/sbt/issues/4946 case p if p.winner.isDefined => val winner = p.winner.get - def fromLibraryDependencySchemes(org: String = "*", mod: String = "*") = - userDefinedSchemes.get((org, mod)) - def fromWinnerPom = VersionSchemes.extractFromExtraAttributes( - winner.extraAttributes.toMap ++ winner.module.extraAttributes - ) - // prioritize user-defined version scheme to allow overriding the real scheme - val userDefinedSchemeOrFromPom = - fromLibraryDependencySchemes(p.organization, p.name) - .orElse(fromLibraryDependencySchemes(p.organization)) - .orElse(fromWinnerPom) - .orElse(fromLibraryDependencySchemes()) - - val assumedScheme = - if (isNameScalaSuffixed(p.name)) assumedVersionScheme - else assumedVersionSchemeJava def hasIncompatibleVersionForScheme(scheme: String) = { - val isCompat = - VersionSchemes.evalFunc(scheme) + val isCompat = VersionSchemes.evalFunc(scheme) p.evicteds.exists { r => !isCompat((r.module, Some(winner.module), module.scalaModuleInfo)) } } - val userDefinedSchemeOrAlways = userDefinedSchemeOrFromPom.getOrElse(VersionSchemes.Always) - if (hasIncompatibleVersionForScheme(userDefinedSchemeOrAlways)) - incompatibleEvictions += (p -> userDefinedSchemeOrFromPom.getOrElse("?")) - else if (hasIncompatibleVersionForScheme(assumedScheme)) - assumedIncompatEvictions += (p -> assumedScheme) + // from libraryDependencyScheme or defined in the pom using the `info.versionScheme` attribute + val userDefinedSchemeOrFromPom = { + def fromLibraryDependencySchemes(org: String = "*", mod: String = "*") = + userDefinedSchemes.get((org, mod)) + def fromWinnerPom = VersionSchemes.extractFromExtraAttributes( + winner.extraAttributes.toMap ++ winner.module.extraAttributes + ) + + fromLibraryDependencySchemes(p.organization, p.name) // by org and name + .orElse(fromLibraryDependencySchemes(p.organization)) // for whole org + .orElse(fromWinnerPom) // from pom + .orElse(fromLibraryDependencySchemes()) // global + } + + // We want the user to be able to suppress eviction errors for a specific library, + // which would result in an incompatible eviction based on the assumed version scheme. + // So, only fall back to the assumed scheme if there is no given scheme by the user or the pom. + userDefinedSchemeOrFromPom match { + case Some(givenScheme) => + if (hasIncompatibleVersionForScheme(givenScheme)) + incompatibleEvictions += (p -> givenScheme) + case None => + val assumedScheme = + if (isNameScalaSuffixed(p.name)) assumedVersionScheme + else assumedVersionSchemeJava + + if (hasIncompatibleVersionForScheme(assumedScheme)) + assumedIncompatEvictions += (p -> assumedScheme) + } case _ => () } From d4296d3e919709ac3bc53b5291275648c1d8ad04 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 6 May 2023 22:52:59 -0400 Subject: [PATCH 27/52] Reproduce sbt/sbt#6745 --- .../librarymanagement/EvictionErrorSpec.scala | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala index a6b97c99e..f4b2c53e2 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala @@ -97,6 +97,23 @@ object EvictionErrorSpec extends BaseIvySpecification { assert(EvictionError(report, m, overrideRules).incompatibleEvictions.isEmpty) } + test("it should selectively allow opt-out from the error despite assumed scheme") { + val deps = Vector(`scala2.12.17`, `akkaActor2.6.0`, `swagger-akka-http1.4.0`) + val m = module(defaultModuleId, deps, Some("2.12.17")) + val report = ivyUpdate(m) + val overrideRules = List("org.scala-lang.modules" %% "scala-java8-compat" % "always") + assert( + EvictionError( + report = report, + module = m, + schemes = overrideRules, + assumedVersionScheme = "early-semver", + assumedVersionSchemeJava = "always", + assumedEvictionErrorLevel = Level.Error, + ).assumedIncompatibleEvictions.isEmpty + ) + } + // older Akka was on pvp def oldAkkaPvp = List("com.typesafe.akka" % "*" % "pvp") @@ -104,8 +121,12 @@ object EvictionErrorSpec extends BaseIvySpecification { ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary lazy val `akkaActor2.3.0` = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + lazy val `akkaActor2.6.0` = + ModuleID("com.typesafe.akka", "akka-actor", "2.6.0").withConfigurations(Some("compile")) cross CrossVersion.binary lazy val `scala2.10.4` = ModuleID("org.scala-lang", "scala-library", "2.10.4").withConfigurations(Some("compile")) + lazy val `scala2.12.17` = + ModuleID("org.scala-lang", "scala-library", "2.12.17").withConfigurations(Some("compile")) lazy val `scala2.13.3` = ModuleID("org.scala-lang", "scala-library", "2.13.3").withConfigurations(Some("compile")) lazy val `bananaSesame0.4` = @@ -122,6 +143,9 @@ object EvictionErrorSpec extends BaseIvySpecification { ("org.typelevel" %% "cats-parse" % "0.1.0").withConfigurations(Some("compile")) lazy val `cats-parse0.2.0` = ("org.typelevel" %% "cats-parse" % "0.2.0").withConfigurations(Some("compile")) + lazy val `swagger-akka-http1.4.0` = + ("com.github.swagger-akka-http" %% "swagger-akka-http" % "1.4.0") + .withConfigurations(Some("compile")) def dummyScalaModuleInfo(v: String): ScalaModuleInfo = ScalaModuleInfo( From b2ecf69b96d05ccf3c5bc8e5953dcc74d1c16529 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 2 Jun 2023 01:36:05 -0400 Subject: [PATCH 28/52] util 1.9.0 --- project/Dependencies.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 7424830d9..cd168495a 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,14 +3,14 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala212 = "2.12.17" - val scala213 = "2.13.8" + val scala212 = "2.12.18" + val scala213 = "2.13.10" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.8.0") - private val utilVersion = nightlyVersion.getOrElse("1.8.0") + private val ioVersion = nightlyVersion.getOrElse("1.9.0") + private val utilVersion = nightlyVersion.getOrElse("1.9.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 363c0fe015a2492bb9e8c4ec84eb3cdf9eafb644 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Sun, 25 Jun 2023 09:46:39 +0900 Subject: [PATCH 29/52] avoid deprecated `java.net.URL` constructor - https://bugs.openjdk.org/browse/JDK-8295949 - openjdk/jdk@4338f52 --- core/src/main/scala/sbt/librarymanagement/License.scala | 9 +++++---- .../main/scala/sbt/librarymanagement/ModuleIDExtra.scala | 4 ++-- .../main/scala/sbt/librarymanagement/ResolverExtra.scala | 9 +++++---- .../test/scala/sbt/librarymanagement/ResolverTest.scala | 4 ++-- .../sbt/internal/librarymanagement/ConvertResolver.scala | 6 +++--- .../sbt/internal/librarymanagement/FakeResolver.scala | 4 ++-- .../internal/librarymanagement/DMSerializationSpec.scala | 4 ++-- .../sbt/internal/librarymanagement/ResolverSpec.scala | 4 ++-- 8 files changed, 23 insertions(+), 21 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/License.scala b/core/src/main/scala/sbt/librarymanagement/License.scala index 6f335fb24..a8ac31088 100644 --- a/core/src/main/scala/sbt/librarymanagement/License.scala +++ b/core/src/main/scala/sbt/librarymanagement/License.scala @@ -1,6 +1,7 @@ package sbt.librarymanagement import java.net.URL +import java.net.URI /** * Commonly used software licenses @@ -9,16 +10,16 @@ import java.net.URL */ object License { lazy val Apache2: (String, URL) = - ("Apache-2.0", new URL("https://www.apache.org/licenses/LICENSE-2.0.txt")) + ("Apache-2.0", new URI("https://www.apache.org/licenses/LICENSE-2.0.txt").toURL) lazy val MIT: (String, URL) = - ("MIT", new URL("https://opensource.org/licenses/MIT")) + ("MIT", new URI("https://opensource.org/licenses/MIT").toURL) lazy val CC0: (String, URL) = - ("CC0-1.0", new URL("https://creativecommons.org/publicdomain/zero/1.0/legalcode")) + ("CC0-1.0", new URI("https://creativecommons.org/publicdomain/zero/1.0/legalcode").toURL) def PublicDomain: (String, URL) = CC0 lazy val GPL3_or_later: (String, URL) = - ("GPL-3.0-or-later", new URL("https://spdx.org/licenses/GPL-3.0-or-later.html")) + ("GPL-3.0-or-later", new URI("https://spdx.org/licenses/GPL-3.0-or-later.html").toURL) } diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index cb68eaf78..912e832fa 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -3,7 +3,7 @@ */ package sbt.librarymanagement -import java.net.URL +import java.net.URI import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties import scala.collection.mutable.ListBuffer @@ -132,7 +132,7 @@ private[librarymanagement] abstract class ModuleIDExtra { * It is not included in published metadata. */ def from(url: String, allowInsecureProtocol: Boolean): ModuleID = - artifacts(Artifact(name, new URL(url), allowInsecureProtocol)) + artifacts(Artifact(name, new URI(url).toURL, allowInsecureProtocol)) /** Adds a dependency on the artifact for this module with classifier `c`. */ def classifier(c: String): ModuleID = artifacts(Artifact(name, c)) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 10dd77e8f..998e66156 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -9,6 +9,7 @@ import scala.annotation.nowarn import scala.xml.XML import org.xml.sax.SAXParseException import sbt.util.Logger +import java.net.URI final class RawRepository(val resolver: AnyRef, name: String) extends Resolver(name) { override def toString = "Raw(" + resolver.toString + ")" @@ -146,13 +147,13 @@ private[librarymanagement] abstract class ResolverFunctions { def typesafeRepo(status: String) = MavenRepository("typesafe-" + status, TypesafeRepositoryRoot + "/" + status) def typesafeIvyRepo(status: String) = - url("typesafe-ivy-" + status, new URL(TypesafeRepositoryRoot + "/ivy-" + status + "/"))( + url("typesafe-ivy-" + status, new URI(TypesafeRepositoryRoot + "/ivy-" + status + "/").toURL)( ivyStylePatterns ) def sbtIvyRepo(status: String) = - url(s"sbt-ivy-$status", new URL(s"$SbtRepositoryRoot/ivy-$status/"))(ivyStylePatterns) + url(s"sbt-ivy-$status", new URI(s"$SbtRepositoryRoot/ivy-$status/").toURL)(ivyStylePatterns) def sbtPluginRepo(status: String) = - url("sbt-plugin-" + status, new URL(SbtRepositoryRoot + "/sbt-plugin-" + status + "/"))( + url("sbt-plugin-" + status, new URI(SbtRepositoryRoot + "/sbt-plugin-" + status + "/").toURL)( ivyStylePatterns ) @deprecated( @@ -175,7 +176,7 @@ private[librarymanagement] abstract class ResolverFunctions { def bintrayRepo(owner: String, repo: String) = MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") def bintrayIvyRepo(owner: String, repo: String) = - url(s"bintray-$owner-$repo", new URL(s"https://dl.bintray.com/$owner/$repo/"))( + url(s"bintray-$owner-$repo", new URI(s"https://dl.bintray.com/$owner/$repo/").toURL)( Resolver.ivyStylePatterns ) def jcenterRepo = JCenterRepository diff --git a/core/src/test/scala/sbt/librarymanagement/ResolverTest.scala b/core/src/test/scala/sbt/librarymanagement/ResolverTest.scala index 70f7c19cd..400162766 100644 --- a/core/src/test/scala/sbt/librarymanagement/ResolverTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/ResolverTest.scala @@ -1,6 +1,6 @@ package sbt.librarymanagement -import java.net.URL +import java.net.URI import sbt.internal.librarymanagement.UnitSpec @@ -10,7 +10,7 @@ object ResolverTest extends UnitSpec { val pats = Vector("[orgPath]") val patsExpected = Vector("http://foo.com/test/[orgPath]") val patterns = Resolver - .url("test", new URL("http://foo.com/test"))( + .url("test", new URI("http://foo.com/test").toURL)( Patterns( pats, pats, diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 94e82974a..46a7b9f55 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -3,7 +3,7 @@ */ package sbt.internal.librarymanagement -import java.net.URL +import java.net.URI import java.util.Collections import org.apache.ivy.core.module.descriptor.DependencyDescriptor @@ -394,7 +394,7 @@ private[sbt] object ConvertResolver { private[this] val repo = new WarnOnOverwriteFileRepo() private[this] val progress = new RepositoryCopyProgressListener(this); override def getResource(source: String) = { - val url = new URL(source) + val url = new URI(source).toURL if (url.getProtocol == IO.FileScheme) new FileResource(repo, IO.toFile(url)) else @@ -402,7 +402,7 @@ private[sbt] object ConvertResolver { } override def put(source: File, destination: String, overwrite: Boolean): Unit = { - val url = new URL(destination) + val url = new URI(destination).toURL try { if (url.getProtocol != IO.FileScheme) super.put(source, destination, overwrite) else { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala index 794fff9e3..2edf7c872 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala @@ -1,7 +1,7 @@ package sbt import java.io.File -import java.net.URL +import java.net.URI import org.apache.ivy.core.cache.ArtifactOrigin import org.apache.ivy.core.cache.{ DefaultRepositoryCacheManager, RepositoryCacheManager } @@ -69,7 +69,7 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module ): ArtifactDownloadReport = { val report = new ArtifactDownloadReport(artifact.getArtifact) - val path = new URL(artifact.getLocation).toURI.getPath + val path = new URI(artifact.getLocation).toURL.toURI.getPath val localFile = new File(path) if (path.nonEmpty && localFile.exists) { diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala index 86cf43322..33b591b62 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala @@ -1,6 +1,6 @@ package sbt.internal.librarymanagement -import java.net.URL +import java.net.URI import java.io.File import sbt.librarymanagement._ @@ -43,7 +43,7 @@ object DMSerializationSpec extends BasicTestSuite { } test("""Artifact("foo", url("http://example.com/")) should roundtrip""") { - roundtrip(Artifact("foo", new URL("http://example.com/"))) + roundtrip(Artifact("foo", new URI("http://example.com/").toURL)) } test("""Artifact("foo").extra(("key", "value")) should roundtrip""") { diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala index 92cb9fa32..6e7816ae9 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala @@ -1,13 +1,13 @@ package sbttest -import java.net.URL +import java.net.URI import sbt.librarymanagement._ import sbt.librarymanagement.syntax._ import verify.BasicTestSuite class ResolverSpec extends BasicTestSuite { test("Resolver.url") { - Resolver.url("Test Repo", new URL("http://example.com/"))(Resolver.ivyStylePatterns) + Resolver.url("Test Repo", new URI("http://example.com/").toURL)(Resolver.ivyStylePatterns) () } From f81974ecce9fc9edf77a1d05e44c73ba508294b3 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Sun, 25 Jun 2023 09:53:06 +0900 Subject: [PATCH 30/52] add LICENSE file --- LICENSE | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..5c4a3cff9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,204 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2023, Scala Center + Copyright (c) 2011 - 2022, Lightbend, Inc. + Copyright (c) 2008 - 2010, Mark Harrah + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 9a1d836b4e79664cf6558c0f059f54e5e92410fa Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Sun, 25 Jun 2023 10:10:11 +0900 Subject: [PATCH 31/52] update scalafmt --- .scalafmt.conf | 9 +- build.sbt | 11 +- .../internal/librarymanagement/JsonUtil.scala | 55 +++-- .../SemanticSelectorExtra.scala | 8 +- .../librarymanagement/VersionRange.scala | 2 +- .../librarymanagement/VersionSchemes.scala | 3 +- .../cross/CrossVersionUtil.scala | 3 +- .../sbt/librarymanagement/Configuration.scala | 10 +- .../librarymanagement/CrossVersionExtra.scala | 6 +- .../librarymanagement/DependencyFilter.scala | 4 +- .../DependencyResolution.scala | 14 +- .../sbt/librarymanagement/EvictionError.scala | 43 ++-- .../librarymanagement/EvictionWarning.scala | 14 +- .../sbt/librarymanagement/ModuleIDExtra.scala | 12 +- .../sbt/librarymanagement/ResolverExtra.scala | 46 ++-- .../librarymanagement/RichUpdateReport.scala | 25 +- .../librarymanagement/UnresolvedWarning.scala | 28 ++- .../librarymanagement/UpdateReportExtra.scala | 33 +-- .../sbt/librarymanagement/VersionNumber.scala | 9 +- core/src/test/scala/ConfigMacroSpec.scala | 2 +- .../librarymanagement/VersionNumberSpec.scala | 13 +- .../ReplaceMavenConfigurationMappings.scala | 2 - .../librarymanagement/ComponentManager.scala | 2 +- .../librarymanagement/ConvertResolver.scala | 202 +++++++-------- .../librarymanagement/CustomPomParser.scala | 25 +- .../librarymanagement/CustomXmlParser.scala | 4 +- .../librarymanagement/FakeResolver.scala | 4 +- .../sbt/internal/librarymanagement/Ivy.scala | 30 ++- .../librarymanagement/IvyActions.scala | 117 +++++---- .../internal/librarymanagement/IvyCache.scala | 18 +- .../librarymanagement/IvyLogger.scala | 2 +- .../librarymanagement/IvyRetrieve.scala | 24 +- .../librarymanagement/IvyScalaUtil.scala | 11 +- .../librarymanagement/ResolutionCache.scala | 3 +- .../CachedResolutionResolveEngine.scala | 229 ++++++++++-------- .../ivyint/ErrorMessageAuthenticator.scala | 31 ++- .../ivyint/IvyCredentialsLookup.scala | 4 +- .../ivyint/MergeDescriptors.scala | 16 +- .../ivyint/ParallelResolveEngine.scala | 25 +- .../ivyint/SbtChainResolver.scala | 87 +++---- .../librarymanagement/ivy/Credentials.scala | 4 +- .../librarymanagement/ivy/UpdateOptions.scala | 12 +- .../ComponentManagerTest.scala | 2 +- .../librarymanagement/CredentialsSpec.scala | 14 +- .../librarymanagement/EvictionErrorSpec.scala | 20 +- .../EvictionWarningSpec.scala | 40 ++- .../InconsistentDuplicateSpec.scala | 12 +- .../librarymanagement/IvyRepoSpec.scala | 28 +-- .../MergeDescriptorSpec.scala | 27 +-- .../librarymanagement/SftpRepoSpec.scala | 2 +- project/HouseRulesPlugin.scala | 4 +- project/Util.scala | 4 +- 52 files changed, 736 insertions(+), 619 deletions(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index e98e60599..4bcacf16e 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,11 +1,12 @@ -version = 2.0.0 +version = 3.7.4 maxColumn = 100 project.git = true project.excludeFilters = [ /sbt-test/, /input_sources/, /contraband-scala/ ] # http://docs.scala-lang.org/style/scaladoc.html recommends the JavaDoc style. # scala/scala is written that way too https://github.com/scala/scala/blob/v2.12.2/src/library/scala/Predef.scala -docstrings = JavaDoc +docstrings.style = Asterisk +docstrings.wrap = no # This also seems more idiomatic to include whitespace in import x.{ yyy } spaces.inImportCurlyBraces = true @@ -16,6 +17,8 @@ align.openParenCallSite = false align.openParenDefnSite = false # For better code clarity -danglingParentheses = true +danglingParentheses.preset = true trailingCommas = preserve + +runner.dialect = Scala212Source3 diff --git a/build.sbt b/build.sbt index b44f77bdb..c4db12bb1 100644 --- a/build.sbt +++ b/build.sbt @@ -3,7 +3,7 @@ import Path._ import com.typesafe.tools.mima.core._, ProblemFilters._ val _ = { - //https://github.com/sbt/contraband/issues/122 + // https://github.com/sbt/contraband/issues/122 sys.props += ("line.separator" -> "\n") } Global / semanticdbEnabled := !(Global / insideCI).value @@ -90,11 +90,10 @@ val mimaSettings = Def settings ( "1.4.0", "1.5.0", "1.6.0", - ) map ( - version => - organization.value %% moduleName.value % version - cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) - ), + ) map (version => + organization.value %% moduleName.value % version + cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) + ), ) lazy val lmRoot = (project in file(".")) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index e7e087537..8d15a64cb 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -34,34 +34,33 @@ private[sbt] object JsonUtil { UpdateReportLite(ur.configurations map { cr => ConfigurationReportLite( cr.configuration.name, - cr.details map { - oar => - OrganizationArtifactReport( - oar.organization, - oar.name, - oar.modules map { mr => - ModuleReport( - mr.module, - mr.artifacts, - mr.missingArtifacts, - mr.status, - mr.publicationDate, - mr.resolver, - mr.artifactResolver, - mr.evicted, - mr.evictedData, - mr.evictedReason, - mr.problem, - mr.homepage, - mr.extraAttributes, - mr.isDefault, - mr.branch, - mr.configurations, - mr.licenses, - filterOutArtificialCallers(mr.callers) - ) - } - ) + cr.details map { oar => + OrganizationArtifactReport( + oar.organization, + oar.name, + oar.modules map { mr => + ModuleReport( + mr.module, + mr.artifacts, + mr.missingArtifacts, + mr.status, + mr.publicationDate, + mr.resolver, + mr.artifactResolver, + mr.evicted, + mr.evictedData, + mr.evictedReason, + mr.problem, + mr.homepage, + mr.extraAttributes, + mr.isDefault, + mr.branch, + mr.configurations, + mr.licenses, + filterOutArtificialCallers(mr.callers) + ) + } + ) } ) }) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala index 8fafce2a0..d9a7fb24f 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala @@ -58,8 +58,8 @@ private[librarymanagement] abstract class SemComparatorExtra { protected def toStringImpl: String = { val versionStr = Seq(major, minor, patch) - .collect { - case Some(v) => v.toString + .collect { case Some(v) => + v.toString } .mkString(".") val tagsStr = if (tags.nonEmpty) s"-${tags.mkString("-")}" else "" @@ -177,8 +177,8 @@ private[librarymanagement] abstract class SemComparatorFunctions { } parse( numbers - .collect { - case Some(v) => v.toString + .collect { case Some(v) => + v.toString } .mkString(".") ) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala b/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala index 74c7ff253..3bf85a9e9 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala @@ -71,7 +71,7 @@ object VersionRange { case _: NumberFormatException => // TODO - if the version doesn't meet our expectations, maybe we just issue a hard // error instead of softly ignoring the attempt to rewrite. - //sys.error(s"Could not fix version [$revision] into maven style version") + // sys.error(s"Could not fix version [$revision] into maven style version") revision } } diff --git a/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala b/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala index e214cc377..112420028 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala @@ -36,7 +36,8 @@ private[sbt] object VersionSchemes { case x => sys.error(s"unknown version scheme: $x") } - /** info.versionScheme property will be included into POM after sbt 1.4.0. + /** + * info.versionScheme property will be included into POM after sbt 1.4.0. */ def extractFromId(mid: ModuleID): Option[String] = extractFromExtraAttributes(mid.extraAttributes) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index 8f84cad47..e8e518ec8 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -27,7 +27,8 @@ object CrossVersionUtil { private[sbt] val BinCompatV = raw"""$basicVersion(-$tagPattern)?-bin(-.*)?""".r private val CandidateV = raw"""$basicVersion(-RC\d+)""".r private val MilestonV = raw"""$basicVersion(-M$tagPattern)""".r - private val NonReleaseV_n = raw"""$basicVersion((?:-$tagPattern)*)""".r // 0-n word suffixes, with leading dashes + private val NonReleaseV_n = + raw"""$basicVersion((?:-$tagPattern)*)""".r // 0-n word suffixes, with leading dashes private val NonReleaseV_1 = raw"""$basicVersion(-$tagPattern)""".r // 1 word suffix, after a dash private[sbt] val PartialVersion = raw"""($longPattern)\.($longPattern)(?:\..+)?""".r diff --git a/core/src/main/scala/sbt/librarymanagement/Configuration.scala b/core/src/main/scala/sbt/librarymanagement/Configuration.scala index e82d7513e..53c409839 100644 --- a/core/src/main/scala/sbt/librarymanagement/Configuration.scala +++ b/core/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -21,11 +21,11 @@ final class Configuration private[sbt] ( override def equals(o: Any): Boolean = o match { case x: Configuration => (this.id == x.id) && - (this.name == x.name) && - (this.description == x.description) && - (this.isPublic == x.isPublic) && - (this.extendsConfigs == x.extendsConfigs) && - (this.transitive == x.transitive) + (this.name == x.name) && + (this.description == x.description) && + (this.isPublic == x.isPublic) && + (this.extendsConfigs == x.extendsConfigs) && + (this.transitive == x.transitive) case _ => false } diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 03cd97e88..546089928 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -37,13 +37,13 @@ private[librarymanagement] abstract class CrossVersionFunctions { */ def fullWith(prefix: String, suffix: String): CrossVersion = Full(prefix, suffix) - /** Cross-versions a module with the binary version (typically the binary Scala version). */ + /** Cross-versions a module with the binary version (typically the binary Scala version). */ def binary: CrossVersion = Binary() /** Disables cross versioning for a module. */ def disabled: CrossVersion = sbt.librarymanagement.Disabled - /** Cross-versions a module with a constant string (typically the binary Scala version). */ + /** Cross-versions a module with a constant string (typically the binary Scala version). */ def constant(value: String): CrossVersion = Constant(value) /** @@ -218,7 +218,7 @@ private[librarymanagement] abstract class CrossVersionFunctions { */ def scalaApiVersion(v: String): Option[(Long, Long)] = CrossVersionUtil.scalaApiVersion(v) - /** Regular expression that extracts the major and minor components of a version into matched groups 1 and 2.*/ + /** Regular expression that extracts the major and minor components of a version into matched groups 1 and 2. */ val PartialVersion = CrossVersionUtil.PartialVersion /** Extracts the major and minor components of a version string `s` or returns `None` if the version is improperly formatted. */ diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala b/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala index 2f2adf763..3aa96f30d 100644 --- a/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala @@ -29,7 +29,9 @@ trait DependencyFilterExtra { ): ArtifactFilter = new ArtifactFilter { def apply(a: Artifact): Boolean = - name.accept(a.name) && `type`.accept(a.`type`) && extension.accept(a.extension) && classifier + name.accept(a.name) && `type`.accept(a.`type`) && extension.accept( + a.extension + ) && classifier .accept(a.classifier getOrElse "") } diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala b/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala index 500f569e5..1f2b37a2d 100644 --- a/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala @@ -189,10 +189,9 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface ((sourceArtifactTypes.toIterable map (_ -> Artifact.SourceClassifier)) :: (docArtifactTypes.toIterable map (_ -> Artifact.DocClassifier)) :: Nil).flatten.toMap Right(r.substitute { (conf, mid, artFileSeq) => - artFileSeq map { - case (art, f) => - // Deduce the classifier from the type if no classifier is present already - art.withClassifier(art.classifier orElse typeClassifierMap.get(art.`type`)) -> f + artFileSeq map { case (art, f) => + // Deduce the classifier from the type if no classifier is present already + art.withClassifier(art.classifier orElse typeClassifierMap.get(art.`type`)) -> f } }) case Left(w) => Left(w) @@ -200,10 +199,9 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface } protected def directDependenciesNames(module: ModuleDescriptor): String = - (module.directDependencies map { - case mID: ModuleID => - import mID._ - s"$organization % $name % $revision" + (module.directDependencies map { case mID: ModuleID => + import mID._ + s"$organization % $name % $revision" }).mkString(", ") } diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 27333fb2f..3e73e37c7 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -157,30 +157,29 @@ final class EvictionError private[sbt] ( val out: mutable.ListBuffer[String] = mutable.ListBuffer() out += "found version conflict(s) in library dependencies; some are suspected to be binary incompatible:" out += "" - evictions.foreach({ - case (a, scheme) => - val revs = a.evicteds map { _.module.revision } - val revsStr = - if (revs.size <= 1) revs.mkString else "{" + revs.distinct.mkString(", ") + "}" - val seen: mutable.Set[ModuleID] = mutable.Set() - val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r => - val rev = r.module.revision - r.callers.toList flatMap { caller => - if (seen(caller.caller)) Nil - else { - seen += caller.caller - List(f"\t +- ${caller}%-50s (depends on $rev)") - } + evictions.foreach({ case (a, scheme) => + val revs = a.evicteds map { _.module.revision } + val revsStr = + if (revs.size <= 1) revs.mkString else "{" + revs.distinct.mkString(", ") + "}" + val seen: mutable.Set[ModuleID] = mutable.Set() + val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r => + val rev = r.module.revision + r.callers.toList flatMap { caller => + if (seen(caller.caller)) Nil + else { + seen += caller.caller + List(f"\t +- ${caller}%-50s (depends on $rev)") } } - val que = if (assumed) "?" else "" - val winnerRev = a.winner match { - case Some(r) => s":${r.module.revision} ($scheme$que) is selected over ${revsStr}" - case _ => " is evicted for all versions" - } - val title = s"\t* ${a.organization}:${a.name}$winnerRev" - val lines = title :: (if (a.showCallers) callers.reverse else Nil) ::: List("") - out ++= lines + } + val que = if (assumed) "?" else "" + val winnerRev = a.winner match { + case Some(r) => s":${r.module.revision} ($scheme$que) is selected over ${revsStr}" + case _ => " is evicted for all versions" + } + val title = s"\t* ${a.organization}:${a.name}$winnerRev" + val lines = title :: (if (a.showCallers) callers.reverse else Nil) ::: List("") + out ++= lines }) out.toList } diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index ae6c95638..df70eeffa 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -196,7 +196,7 @@ final class EvictionPair private[sbt] ( override def equals(o: Any): Boolean = o match { case o: EvictionPair => (this.organization == o.organization) && - (this.name == o.name) + (this.name == o.name) case _ => false } override def hashCode: Int = { @@ -279,10 +279,12 @@ object EvictionWarning { } confs flatMap { confReport => confReport.details map { detail => - if ((detail.modules exists { _.evicted }) && - !(buffer exists { x => - (x.organization == detail.organization) && (x.name == detail.name) - })) { + if ( + (detail.modules exists { _.evicted }) && + !(buffer exists { x => + (x.organization == detail.organization) && (x.name == detail.name) + }) + ) { buffer += detail } } @@ -298,7 +300,7 @@ object EvictionWarning { module.scalaModuleInfo match { case Some(s) => organization == s.scalaOrganization && - (name == LibraryID) || (name == CompilerID) + (name == LibraryID) || (name == CompilerID) case _ => false } diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index cb68eaf78..022d919de 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -37,10 +37,10 @@ private[librarymanagement] abstract class ModuleIDExtra { protected def toStringImpl: String = s"""$organization:$name:$revision""" + (configurations match { case Some(s) => ":" + s; case None => "" }) + { - val attr = attributeString - if (attr == "") "" - else " " + attr - } + + val attr = attributeString + if (attr == "") "" + else " " + attr + } + (if (extraAttributes.isEmpty) "" else " " + extraString) protected def attributeString: String = { @@ -95,10 +95,10 @@ private[librarymanagement] abstract class ModuleIDExtra { }) // () required for chaining - /** Do not follow dependencies of this module. Synonym for `intransitive`.*/ + /** Do not follow dependencies of this module. Synonym for `intransitive`. */ def notTransitive(): ModuleID = intransitive() - /** Do not follow dependencies of this module. Synonym for `notTransitive`.*/ + /** Do not follow dependencies of this module. Synonym for `notTransitive`. */ def intransitive(): ModuleID = withIsTransitive(false) /** diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 10dd77e8f..2f87d5d1e 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -185,7 +185,7 @@ private[librarymanagement] abstract class ResolverFunctions { "https://repository.apache.org/content/repositories/snapshots/" ) - /** Add the local and Maven Central repositories to the user repositories. */ + /** Add the local and Maven Central repositories to the user repositories. */ def combineDefaultResolvers(userResolvers: Vector[Resolver]): Vector[Resolver] = combineDefaultResolvers(userResolvers, mavenCentral = true) @@ -232,7 +232,10 @@ private[librarymanagement] abstract class ResolverFunctions { single(JCenterRepository, jcenter) ++ (xs.partition(_ == DefaultMavenRepository) match { case (_, xs) => - single(DefaultMavenRepository, mavenCentral) ++ xs // TODO - Do we need to filter out duplicates? + single( + DefaultMavenRepository, + mavenCentral + ) ++ xs // TODO - Do we need to filter out duplicates? }) }) } @@ -240,7 +243,7 @@ private[librarymanagement] abstract class ResolverFunctions { private def single[T](value: T, nonEmpty: Boolean): Vector[T] = if (nonEmpty) Vector(value) else Vector.empty - /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ + /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ sealed abstract class Define[RepositoryType <: SshBasedRepository] { /** Subclasses should implement this method to */ @@ -269,8 +272,8 @@ private[librarymanagement] abstract class ResolverFunctions { * patterns will be resolved. `basePatterns` are the initial patterns to use. * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ - def apply(name: String, hostname: String, basePath: String)( - implicit basePatterns: Patterns + def apply(name: String, hostname: String, basePath: String)(implicit + basePatterns: Patterns ): RepositoryType = apply(name, Some(hostname), None, Some(basePath)) @@ -278,8 +281,8 @@ private[librarymanagement] abstract class ResolverFunctions { * Constructs this repository type with the given `name`, `hostname`, and `port`. `basePatterns` are the initial patterns to use. * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ - def apply(name: String, hostname: String, port: Int)( - implicit basePatterns: Patterns + def apply(name: String, hostname: String, port: Int)(implicit + basePatterns: Patterns ): RepositoryType = apply(name, Some(hostname), Some(port), None) @@ -288,8 +291,8 @@ private[librarymanagement] abstract class ResolverFunctions { * patterns will be resolved. `basePatterns` are the initial patterns to use. * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ - def apply(name: String, hostname: String, port: Int, basePath: String)( - implicit basePatterns: Patterns + def apply(name: String, hostname: String, port: Int, basePath: String)(implicit + basePatterns: Patterns ): RepositoryType = apply(name, Some(hostname), Some(port), Some(basePath)) @@ -304,13 +307,13 @@ private[librarymanagement] abstract class ResolverFunctions { construct(name, SshConnection(None, hostname, port), resolvePatterns(basePath, basePatterns)) } - /** A factory to construct an interface to an Ivy SSH resolver.*/ + /** A factory to construct an interface to an Ivy SSH resolver. */ object ssh extends Define[SshRepository] { protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SshRepository(name, connection, patterns, None) } - /** A factory to construct an interface to an Ivy SFTP resolver.*/ + /** A factory to construct an interface to an Ivy SFTP resolver. */ object sftp extends Define[SftpRepository] { protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SftpRepository(name, connection, patterns) @@ -348,8 +351,8 @@ private[librarymanagement] abstract class ResolverFunctions { def apply(name: String, baseURL: URL)(implicit basePatterns: Patterns): URLRepository = baseRepository(baseURL.toURI.normalize.toString)(URLRepository(name, _)) } - private def baseRepository[T](base: String)(construct: Patterns => T)( - implicit basePatterns: Patterns + private def baseRepository[T](base: String)(construct: Patterns => T)(implicit + basePatterns: Patterns ): T = construct(resolvePatterns(base, basePatterns)) @@ -381,7 +384,7 @@ private[librarymanagement] abstract class ResolverFunctions { } def defaultFileConfiguration = FileConfiguration(true, None) def mavenStylePatterns = Patterns().withArtifactPatterns(Vector(mavenStyleBasePattern)) - def ivyStylePatterns = defaultIvyPatterns //Patterns(Nil, Nil, false) + def ivyStylePatterns = defaultIvyPatterns // Patterns(Nil, Nil, false) def defaultPatterns = mavenStylePatterns def mavenStyleBasePattern = @@ -397,10 +400,13 @@ private[librarymanagement] abstract class ResolverFunctions { val findQuoted = "\\$\\{([^\\}]*)\\}".r val env = "env\\.(.*)".r - findQuoted.replaceAllIn(str, _.group(1) match { - case env(variable) => sys.env.getOrElse(variable, "") - case property => sys.props.getOrElse(property, "") - }) + findQuoted.replaceAllIn( + str, + _.group(1) match { + case env(variable) => sys.env.getOrElse(variable, "") + case property => sys.props.getOrElse(property, "") + } + ) } private[this] def mavenLocalDir: File = { def loadHomeFromSettings(f: () => File): Option[File] = @@ -423,7 +429,9 @@ private[librarymanagement] abstract class ResolverFunctions { } sys.props.get("maven.repo.local").map(new File(_)) orElse loadHomeFromSettings(() => new File(sbt.io.Path.userHome, ".m2/settings.xml")) orElse - loadHomeFromSettings(() => new File(new File(System.getenv("M2_HOME")), "conf/settings.xml")) getOrElse + loadHomeFromSettings(() => + new File(new File(System.getenv("M2_HOME")), "conf/settings.xml") + ) getOrElse new File(sbt.io.Path.userHome, ".m2/repository") } // TODO - should this just be the *exact* same as mavenLocal? probably... diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index f66440bbb..9060f14b6 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -12,16 +12,15 @@ final class RichUpdateReport(report: UpdateReport) { private[sbt] def recomputeStamps(): UpdateReport = { val files = report.cachedDescriptor +: allFiles val stamps = files - .map( - f => - ( - f, - // TODO: The list of files may also contain some odd files that do not actually exist like: - // "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml". - // IO.getModifiedTimeOrZero() will just return zero, but the list of files should not contain such - // files to begin with, in principle. - IO.getModifiedTimeOrZero(f) - ) + .map(f => + ( + f, + // TODO: The list of files may also contain some odd files that do not actually exist like: + // "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml". + // IO.getModifiedTimeOrZero() will just return zero, but the list of files should not contain such + // files to begin with, in principle. + IO.getModifiedTimeOrZero(f) + ) ) .toMap UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) @@ -65,13 +64,13 @@ final class RichUpdateReport(report: UpdateReport) { file } - /** Constructs a new report that only contains files matching the specified filter.*/ + /** Constructs a new report that only contains files matching the specified filter. */ def filter(f: DependencyFilter): UpdateReport = moduleReportMap { (configuration, modReport) => modReport .withArtifacts( - modReport.artifacts filter { - case (art, _) => f(configuration, modReport.module, art) + modReport.artifacts filter { case (art, _) => + f(configuration, modReport.module, art) } ) .withMissingArtifacts( diff --git a/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala b/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala index d871caa83..6f4aa832d 100644 --- a/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala @@ -10,9 +10,13 @@ final class ResolveException( val failedPaths: Map[ModuleID, Seq[ModuleID]] ) extends RuntimeException(messages.mkString("\n")) { def this(messages: Seq[String], failed: Seq[ModuleID]) = - this(messages, failed, Map(failed map { m => - m -> Nil - }: _*)) + this( + messages, + failed, + Map(failed map { m => + m -> Nil + }: _*) + ) } /** @@ -30,13 +34,12 @@ object UnresolvedWarning { config: UnresolvedWarningConfiguration ): UnresolvedWarning = { def modulePosition(m0: ModuleID): Option[SourcePosition] = - config.modulePositions.find { - case (m, _) => - (m.organization == m0.organization) && - (m0.name startsWith m.name) && - (m.revision == m0.revision) - } map { - case (_, p) => p + config.modulePositions.find { case (m, _) => + (m.organization == m0.organization) && + (m0.name startsWith m.name) && + (m.revision == m0.revision) + } map { case (_, p) => + p } val failedPaths = err.failed map { (x: ModuleID) => err.failedPaths(x).toList.reverse map { id => @@ -67,9 +70,8 @@ object UnresolvedWarning { if (path.nonEmpty) { val head = path.head buffer += "\t\t" + head._1.toString + sourcePosStr(head._2) - path.tail foreach { - case (m, pos) => - buffer += "\t\t +- " + m.toString + sourcePosStr(pos) + path.tail foreach { case (m, pos) => + buffer += "\t\t +- " + m.toString + sourcePosStr(pos) } } } diff --git a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index 1ffba5008..910827703 100644 --- a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -29,9 +29,13 @@ private[librarymanagement] abstract class ConfigurationReportExtra { } def retrieve(f: (ConfigRef, ModuleID, Artifact, File) => File): ConfigurationReport = - ConfigurationReport(configuration, modules map { - _.retrieve((mid, art, file) => f(configuration, mid, art, file)) - }, details) + ConfigurationReport( + configuration, + modules map { + _.retrieve((mid, art, file) => f(configuration, mid, art, file)) + }, + details + ) } private[librarymanagement] abstract class ModuleReportExtra { @@ -124,24 +128,23 @@ private[librarymanagement] abstract class UpdateReportExtra { /** All resolved modules in all configurations. */ def allModules: Vector[ModuleID] = { val key = (m: ModuleID) => (m.organization, m.name, m.revision) - configurations.flatMap(_.allModules).groupBy(key).toVector map { - case (_, v) => - v reduceLeft { (agg, x) => - agg.withConfigurations( - (agg.configurations, x.configurations) match { - case (None, _) => x.configurations - case (Some(ac), None) => Some(ac) - case (Some(ac), Some(xc)) => Some(s"$ac;$xc") - } - ) - } + configurations.flatMap(_.allModules).groupBy(key).toVector map { case (_, v) => + v reduceLeft { (agg, x) => + agg.withConfigurations( + (agg.configurations, x.configurations) match { + case (None, _) => x.configurations + case (Some(ac), None) => Some(ac) + case (Some(ac), Some(xc)) => Some(s"$ac;$xc") + } + ) + } } } def retrieve(f: (ConfigRef, ModuleID, Artifact, File) => File): UpdateReport = UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps) - /** Gets the report for the given configuration, or `None` if the configuration was not resolved.*/ + /** Gets the report for the given configuration, or `None` if the configuration was not resolved. */ def configuration(s: ConfigRef) = configurations.find(_.configuration == s) /** Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */ diff --git a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala index 8ce15c72d..1da91342e 100644 --- a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -162,7 +162,8 @@ object VersionNumber { } } - /** A variant of SemVar that seems to be common among the Scala libraries. + /** + * A variant of SemVar that seems to be common among the Scala libraries. * The second segment (y in x.y.z) increments breaks the binary compatibility even when x > 0. * Also API compatibility is expected even when the first segment is zero. */ @@ -172,7 +173,8 @@ object VersionNumber { PackVer.isCompatible(v1, v2) } - /** A variant of SemVar that seems to be common among the Scala libraries. + /** + * A variant of SemVar that seems to be common among the Scala libraries. * The second segment (y in x.y.z) increments breaks the binary compatibility even when x > 0. * Also API compatibility is expected even when the first segment is zero. */ @@ -193,7 +195,8 @@ object VersionNumber { } } - /** A variant of SemVar that enforces API compatibility when the first segment is zero. + /** + * A variant of SemVar that enforces API compatibility when the first segment is zero. */ object EarlySemVer extends VersionNumberCompatibility { import SemVer._ diff --git a/core/src/test/scala/ConfigMacroSpec.scala b/core/src/test/scala/ConfigMacroSpec.scala index c35ab104b..ea409efa7 100644 --- a/core/src/test/scala/ConfigMacroSpec.scala +++ b/core/src/test/scala/ConfigMacroSpec.scala @@ -56,6 +56,6 @@ object ConfigMacroSpec extends Properties("ConfigMacroSpec") { s"Actual isPublic: ${c.isPublic}" |: (c.id == id) && (c.name == name) && - (c.isPublic == isPublic) + (c.isPublic == isPublic) } } diff --git a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala index 9f240f432..bf3465cce 100644 --- a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala @@ -148,13 +148,12 @@ class VersionNumberSpec extends AnyFreeSpec with Matchers with Inside { ts: Seq[String], es: Seq[String] ): Unit = - s"should parse to ($ns, $ts, $es)" in inside(v.value) { - case VersionNumber(ns1, ts1, es1) => - (ns1 shouldBe ns) - (ts1 shouldBe ts) - (es1 shouldBe es) - (VersionNumber(ns, ts, es).toString shouldBe v.value) - (VersionNumber(ns, ts, es) shouldBe VersionNumber(ns, ts, es)) + s"should parse to ($ns, $ts, $es)" in inside(v.value) { case VersionNumber(ns1, ts1, es1) => + (ns1 shouldBe ns) + (ts1 shouldBe ts) + (es1 shouldBe es) + (VersionNumber(ns, ts, es).toString shouldBe v.value) + (VersionNumber(ns, ts, es) shouldBe VersionNumber(ns, ts, es)) } private[this] def assertParsesToError(v: VersionString): Unit = diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala index 410bdcfb7..fb0b889d6 100644 --- a/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala +++ b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala @@ -21,8 +21,6 @@ import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor; * * Also see: http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html * and: http://svn.apache.org/repos/asf/ant/ivy/core/tags/2.3.0/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java - * - * */ object ReplaceMavenConfigurationMappings { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala index ed42cd14c..710c120de 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala @@ -56,7 +56,7 @@ class ComponentManager( /** This is used to lock the local cache in project/boot/. By checking the local cache first, we can avoid grabbing a global lock. */ private def lockLocalCache[T](action: => T): T = lock(provider.lockFile)(action) - /** This is used to ensure atomic access to components in the global Ivy cache.*/ + /** This is used to ensure atomic access to components in the global Ivy cache. */ private def lockGlobalCache[T](action: => T): T = lock(ivyCache.lockFile)(action) private def lock[T](file: File)(action: => T): T = globalLock(file, new Callable[T] { def call = action }) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 94e82974a..2009fd2a8 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -157,109 +157,108 @@ private[sbt] object ConvertResolver { (updateOptions.resolverConverter orElse defaultConvert)((r, settings, log)) /** The default implementation of converter. */ - lazy val defaultConvert: ResolverConverter = { - case (r, settings, log) => - val managedChecksums = Option(settings.getVariable(ManagedChecksums)) match { - case Some(x) => x.toBoolean - case _ => false - } - r match { - case repo: MavenRepository => { - val pattern = Collections.singletonList( - Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern) - ) - final class PluginCapableResolver - extends IBiblioResolver - with ChecksumFriendlyURLResolver - with DescriptorRequired { - override val managedChecksumsEnabled: Boolean = managedChecksums - override def getResource(resource: Resource, dest: File): Long = get(resource, dest) - def setPatterns(): Unit = { - // done this way for access to protected methods. - setArtifactPatterns(pattern) - setIvyPatterns(pattern) - } - override protected def findResourceUsingPattern( - mrid: ModuleRevisionId, - pattern: String, - artifact: IArtifact, - rmdparser: ResourceMDParser, - date: Date - ): ResolvedResource = { - val extraAttributes = - mrid.getExtraAttributes.asScala.toMap.asInstanceOf[Map[String, String]] - getSbtPluginCrossVersion(extraAttributes) match { - case Some(sbtCrossVersion) => - // if the module is an sbt plugin - // we first try to resolve the artifact with the sbt cross version suffix - // and we fallback to the one without the suffix - val newArtifact = DefaultArtifact.cloneWithAnotherName( - artifact, - artifact.getName + sbtCrossVersion - ) - val resolved = - super.findResourceUsingPattern(mrid, pattern, newArtifact, rmdparser, date) - if (resolved != null) resolved - else super.findResourceUsingPattern(mrid, pattern, artifact, rmdparser, date) - case None => - super.findResourceUsingPattern(mrid, pattern, artifact, rmdparser, date) - } + lazy val defaultConvert: ResolverConverter = { case (r, settings, log) => + val managedChecksums = Option(settings.getVariable(ManagedChecksums)) match { + case Some(x) => x.toBoolean + case _ => false + } + r match { + case repo: MavenRepository => { + val pattern = Collections.singletonList( + Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern) + ) + final class PluginCapableResolver + extends IBiblioResolver + with ChecksumFriendlyURLResolver + with DescriptorRequired { + override val managedChecksumsEnabled: Boolean = managedChecksums + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) + def setPatterns(): Unit = { + // done this way for access to protected methods. + setArtifactPatterns(pattern) + setIvyPatterns(pattern) + } + override protected def findResourceUsingPattern( + mrid: ModuleRevisionId, + pattern: String, + artifact: IArtifact, + rmdparser: ResourceMDParser, + date: Date + ): ResolvedResource = { + val extraAttributes = + mrid.getExtraAttributes.asScala.toMap.asInstanceOf[Map[String, String]] + getSbtPluginCrossVersion(extraAttributes) match { + case Some(sbtCrossVersion) => + // if the module is an sbt plugin + // we first try to resolve the artifact with the sbt cross version suffix + // and we fallback to the one without the suffix + val newArtifact = DefaultArtifact.cloneWithAnotherName( + artifact, + artifact.getName + sbtCrossVersion + ) + val resolved = + super.findResourceUsingPattern(mrid, pattern, newArtifact, rmdparser, date) + if (resolved != null) resolved + else super.findResourceUsingPattern(mrid, pattern, artifact, rmdparser, date) + case None => + super.findResourceUsingPattern(mrid, pattern, artifact, rmdparser, date) } } - val resolver = new PluginCapableResolver - if (repo.localIfFile) resolver.setRepository(new LocalIfFileRepo) - initializeMavenStyle(resolver, repo.name, repo.root) - resolver - .setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns - resolver } - case repo: SshRepository => { - val resolver = new SshResolver with DescriptorRequired with ThreadSafeSshBasedResolver { - override val managedChecksumsEnabled: Boolean = managedChecksums - override def getResource(resource: Resource, dest: File): Long = get(resource, dest) - } - initializeSSHResolver(resolver, repo, settings) - repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) - resolver - } - case repo: SftpRepository => { - val resolver = new SFTPResolver with ThreadSafeSshBasedResolver - initializeSSHResolver(resolver, repo, settings) - resolver - } - case repo: FileRepository => { - val resolver = new FileSystemResolver with DescriptorRequired { - // Workaround for #1156 - // Temporarily in sbt 0.13.x we deprecate overwriting - // in local files for non-changing revisions. - // This will be fully enforced in sbt 1.0. - setRepository(new WarnOnOverwriteFileRepo()) - override val managedChecksumsEnabled: Boolean = managedChecksums - override def getResource(resource: Resource, dest: File): Long = get(resource, dest) - } - resolver.setName(repo.name) - initializePatterns(resolver, repo.patterns, settings) - import repo.configuration.{ isLocal, isTransactional } - resolver.setLocal(isLocal) - isTransactional.foreach(value => resolver.setTransactional(value.toString)) - resolver - } - case repo: URLRepository => { - val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired { - override val managedChecksumsEnabled: Boolean = managedChecksums - override def getResource(resource: Resource, dest: File): Long = get(resource, dest) - } - resolver.setName(repo.name) - initializePatterns(resolver, repo.patterns, settings) - resolver - } - case repo: ChainedResolver => - IvySbt.resolverChain(repo.name, repo.resolvers, settings, log) - case repo: RawRepository => - repo.resolver match { - case r: DependencyResolver => r - } + val resolver = new PluginCapableResolver + if (repo.localIfFile) resolver.setRepository(new LocalIfFileRepo) + initializeMavenStyle(resolver, repo.name, repo.root) + resolver + .setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns + resolver } + case repo: SshRepository => { + val resolver = new SshResolver with DescriptorRequired with ThreadSafeSshBasedResolver { + override val managedChecksumsEnabled: Boolean = managedChecksums + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) + } + initializeSSHResolver(resolver, repo, settings) + repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) + resolver + } + case repo: SftpRepository => { + val resolver = new SFTPResolver with ThreadSafeSshBasedResolver + initializeSSHResolver(resolver, repo, settings) + resolver + } + case repo: FileRepository => { + val resolver = new FileSystemResolver with DescriptorRequired { + // Workaround for #1156 + // Temporarily in sbt 0.13.x we deprecate overwriting + // in local files for non-changing revisions. + // This will be fully enforced in sbt 1.0. + setRepository(new WarnOnOverwriteFileRepo()) + override val managedChecksumsEnabled: Boolean = managedChecksums + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) + } + resolver.setName(repo.name) + initializePatterns(resolver, repo.patterns, settings) + import repo.configuration.{ isLocal, isTransactional } + resolver.setLocal(isLocal) + isTransactional.foreach(value => resolver.setTransactional(value.toString)) + resolver + } + case repo: URLRepository => { + val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired { + override val managedChecksumsEnabled: Boolean = managedChecksums + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) + } + resolver.setName(repo.name) + initializePatterns(resolver, repo.patterns, settings) + resolver + } + case repo: ChainedResolver => + IvySbt.resolverChain(repo.name, repo.resolvers, settings, log) + case repo: RawRepository => + repo.resolver match { + case r: DependencyResolver => r + } + } } private def getSbtPluginCrossVersion(extraAttributes: Map[String, String]): Option[String] = { @@ -329,8 +328,9 @@ private[sbt] object ConvertResolver { override def getDependency(dd: DependencyDescriptor, data: ResolveData) = { val prev = descriptorString(isAllownomd) setDescriptor(descriptorString(hasExplicitURL(dd))) - val t = try super.getDependency(dd, data) - finally setDescriptor(prev) + val t = + try super.getDependency(dd, data) + finally setDescriptor(prev) t } def descriptorString(optional: Boolean) = diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index 3ec3282f6..eb9378880 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -64,7 +64,7 @@ object CustomPomParser { // Evil hackery to override the default maven pom mappings. ReplaceMavenConfigurationMappings.init() - /** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution.*/ + /** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution. */ val InfoKeyPrefix = SbtPomExtraProperties.POM_INFO_KEY_PREFIX val ApiURLKey = SbtPomExtraProperties.POM_API_KEY val VersionSchemeKey = SbtPomExtraProperties.VERSION_SCHEME_KEY @@ -75,7 +75,8 @@ object CustomPomParser { private[this] val unqualifiedKeys = Set(SbtVersionKey, ScalaVersionKey, ExtraAttributesKey, ApiURLKey, VersionSchemeKey) - /** In the new POM format of sbt plugins, the dependency to an sbt plugin + /** + * In the new POM format of sbt plugins, the dependency to an sbt plugin * contains the sbt cross-version _2.12_1.0. The reason is we want Maven to be able * to resolve the dependency using the pattern: * /_2.12_1.0//_2.12_1.0-.pom @@ -134,7 +135,9 @@ object CustomPomParser { val MyHash = MakeTransformHash(md) // sbt 0.13.1 used "sbtTransformHash" instead of "e:sbtTransformHash" until #1192 so read both Option(extraInfo).isDefined && - ((Option(extraInfo get TransformedHashKey) orElse Option(extraInfo get oldTransformedHashKey)) match { + ((Option(extraInfo get TransformedHashKey) orElse Option( + extraInfo get oldTransformedHashKey + )) match { case Some(MyHash) => true case _ => false }) @@ -297,17 +300,23 @@ object CustomPomParser { for (l <- md.getLicenses) dmd.addLicense(l) for ((key, value) <- md.getExtraInfo.asInstanceOf[java.util.Map[String, String]].asScala) dmd.addExtraInfo(key, value) - dmd.addExtraInfo(TransformedHashKey, MakeTransformHash(md)) // mark as transformed by this version, so we don't need to do it again - for ((key, value) <- md.getExtraAttributesNamespaces - .asInstanceOf[java.util.Map[String, String]] - .asScala) dmd.addExtraAttributeNamespace(key, value) + dmd.addExtraInfo( + TransformedHashKey, + MakeTransformHash(md) + ) // mark as transformed by this version, so we don't need to do it again + for ( + (key, value) <- md.getExtraAttributesNamespaces + .asInstanceOf[java.util.Map[String, String]] + .asScala + ) dmd.addExtraAttributeNamespace(key, value) IvySbt.addExtraNamespace(dmd) val withExtra = md.getDependencies map { dd => addExtra(dd, dependencyExtra) } val withVersionRangeMod: Seq[DependencyDescriptor] = - if (LMSysProp.modifyVersionRange) withExtra map { stripVersionRange } else withExtra + if (LMSysProp.modifyVersionRange) withExtra map { stripVersionRange } + else withExtra val unique = IvySbt.mergeDuplicateDefinitions(withVersionRangeMod) unique foreach dmd.addDependency diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala index 0498828be..a72a65339 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala @@ -15,7 +15,7 @@ import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser import org.apache.ivy.plugins.repository.Resource import org.apache.ivy.plugins.repository.url.URLResource -/** Subclasses the default Ivy file parser in order to provide access to protected methods.*/ +/** Subclasses the default Ivy file parser in order to provide access to protected methods. */ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser { import XmlModuleDescriptorParser.Parser class CustomParser(settings: IvySettings, defaultConfig: Option[String]) @@ -26,7 +26,7 @@ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser { } def setInput(bytes: Array[Byte]): Unit = setInput(new ByteArrayInputStream(bytes)) - /** Overridden because the super implementation overwrites the module descriptor.*/ + /** Overridden because the super implementation overwrites the module descriptor. */ override def setResource(res: Resource): Unit = () override def setMd(md: DefaultModuleDescriptor) = { super.setMd(md) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala index 794fff9e3..df4a7d66b 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala @@ -178,8 +178,8 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module val artifact = for { artifacts <- modules get ((moduleOrganisation, moduleName, moduleRevision)) - artifact <- artifacts find ( - a => a.name == art.getName && a.tpe == art.getType && a.ext == art.getExt + artifact <- artifacts find (a => + a.name == art.getName && a.tpe == art.getType && a.ext == art.getExt ) } yield new ArtifactOrigin(art, /* isLocal = */ true, artifact.file.toURI.toURL.toString) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 270d08546..4fbdbce4a 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -135,7 +135,8 @@ final class IvySbt( is } - /** Defines a parallel [[CachedResolutionResolveEngine]]. + /** + * Defines a parallel [[CachedResolutionResolveEngine]]. * * This is defined here because it needs access to [[mkIvy]]. */ @@ -154,8 +155,10 @@ final class IvySbt( } } - /** Provides a default ivy implementation that decides which resolution - * engine to use depending on the passed ivy configuration options. */ + /** + * Provides a default ivy implementation that decides which resolution + * engine to use depending on the passed ivy configuration options. + */ private class IvyImplementation extends Ivy { private val loggerEngine = new SbtMessageLoggerEngine override def getLoggerEngine: SbtMessageLoggerEngine = loggerEngine @@ -195,7 +198,7 @@ final class IvySbt( // ========== End Configuration/Setup ============ - /** Uses the configured Ivy instance within a safe context.*/ + /** Uses the configured Ivy instance within a safe context. */ def withIvy[T](log: Logger)(f: Ivy => T): T = withIvy(new IvyLoggerInterface(log))(f) @@ -333,7 +336,7 @@ final class IvySbt( mod } - /** Parses the Maven pom 'pomFile' from the given `PomConfiguration`.*/ + /** Parses the Maven pom 'pomFile' from the given `PomConfiguration`. */ private def configurePom(pc: PomConfiguration) = { val md = CustomPomParser.default.parseDescriptor(settings, toURL(pc.file), pc.validate) val dmd = IvySbt.toDefaultModuleDescriptor(md) @@ -347,7 +350,7 @@ final class IvySbt( (dmd, defaultConf) } - /** Parses the Ivy file 'ivyFile' from the given `IvyFileConfiguration`.*/ + /** Parses the Ivy file 'ivyFile' from the given `IvyFileConfiguration`. */ private def configureIvyFile(ifc: IvyFileConfiguration) = { val parser = new CustomXmlParser.CustomParser(settings, None) parser.setValidate(ifc.validate) @@ -703,7 +706,7 @@ private[sbt] object IvySbt { moduleID.addConflictManager(mid, matcher, manager) } - /** Converts the given sbt module id into an Ivy ModuleRevisionId.*/ + /** Converts the given sbt module id into an Ivy ModuleRevisionId. */ def toID(m: ModuleID) = { import m._ ModuleRevisionId.newInstance( @@ -783,7 +786,8 @@ private[sbt] object IvySbt { } private[sbt] def javaMap(m: Map[String, String], unqualify: Boolean = false) = { import scala.collection.JavaConverters._ - val map = if (unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } else m + val map = if (unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } + else m if (map.isEmpty) null else map.asJava } @@ -814,8 +818,8 @@ private[sbt] object IvySbt { elem: scala.xml.Elem, extra: Map[String, String] ): scala.xml.Elem = - extra.foldLeft(elem) { - case (e, (key, value)) => e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) + extra.foldLeft(elem) { case (e, (key, value)) => + e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) } private def hasInfo(module: ModuleID, x: scala.xml.NodeSeq) = { val info = {x} \ "info" @@ -943,7 +947,7 @@ private[sbt] object IvySbt { } } - /** Transforms an sbt ModuleID into an Ivy DefaultDependencyDescriptor.*/ + /** Transforms an sbt ModuleID into an Ivy DefaultDependencyDescriptor. */ def convertDependency( moduleID: DefaultModuleDescriptor, dependency: ModuleID, @@ -961,7 +965,9 @@ private[sbt] object IvySbt { dependency.configurations match { case None => // The configuration for this dependency was not explicitly specified, so use the default parser.parseDepsConfs(parser.getDefaultConf, dependencyDescriptor) - case Some(confs) => // The configuration mapping (looks like: test->default) was specified for this dependency + case Some( + confs + ) => // The configuration mapping (looks like: test->default) was specified for this dependency parser.parseDepsConfs(confs, dependencyDescriptor) } for (artifact <- dependency.explicitArtifacts) { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 6d223287c..42a0eed7f 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -29,7 +29,7 @@ import sbt.internal.librarymanagement.IvyUtil.TransientNetworkException object IvyActions { - /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/ + /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'. */ def install(module: IvySbt#Module, from: String, to: String, log: Logger): Unit = { module.withModule(log) { (ivy, md, _) => for (dependency <- md.getDependencies) { @@ -57,7 +57,7 @@ object IvyActions { module.owner.cleanCachedResolutionCache() } - /** Creates a Maven pom from the given Ivy configuration*/ + /** Creates a Maven pom from the given Ivy configuration */ def makePomFile(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger): File = { import configuration.{ allRepositories, @@ -91,13 +91,12 @@ object IvyActions { val deliverIvyPattern = configuration.deliverIvyPattern .getOrElse(sys.error("deliverIvyPattern must be specified.")) val status = getDeliverStatus(configuration.status) - module.withModule(log) { - case (ivy, md, _) => - val revID = md.getModuleRevisionId - val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) - options.setConfs(getConfigurations(md, configuration.configurations)) - ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) - deliveredFile(ivy, deliverIvyPattern, md) + module.withModule(log) { case (ivy, md, _) => + val revID = md.getModuleRevisionId + val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) + options.setConfs(getConfigurations(md, configuration.configurations)) + ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) + deliveredFile(ivy, deliverIvyPattern, md) } } @@ -130,18 +129,17 @@ object IvyActions { val artifacts = Map(configuration.artifacts: _*) val checksums = configuration.checksums - module.withModule(log) { - case (ivy, md, _) => - val resolver = ivy.getSettings.getResolver(resolverName) - if (resolver eq null) sys.error("Undefined resolver '" + resolverName + "'") - val ivyArtifact = ivyFile map { file => - (MDArtifact.newIvyArtifact(md), file) - } - val cross = crossVersionMap(module.moduleSettings) - val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList - withChecksums(resolver, checksums) { - publish(md, as, resolver, overwrite = configuration.overwrite) - } + module.withModule(log) { case (ivy, md, _) => + val resolver = ivy.getSettings.getResolver(resolverName) + if (resolver eq null) sys.error("Undefined resolver '" + resolverName + "'") + val ivyArtifact = ivyFile map { file => + (MDArtifact.newIvyArtifact(md), file) + } + val cross = crossVersionMap(module.moduleSettings) + val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList + withChecksums(resolver, checksums) { + publish(md, as, resolver, overwrite = configuration.overwrite) + } } } private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Vector[String])( @@ -193,35 +191,36 @@ object IvyActions { uwconfig: UnresolvedWarningConfiguration, log: Logger ): Either[UnresolvedWarning, UpdateReport] = { - module.withModule(log) { - case (ivy, moduleDescriptor, _) => - // Warn about duplicated and inconsistent dependencies - val iw = IvySbt.inconsistentDuplicateWarning(moduleDescriptor) - iw.foreach(log.warn(_)) + module.withModule(log) { case (ivy, moduleDescriptor, _) => + // Warn about duplicated and inconsistent dependencies + val iw = IvySbt.inconsistentDuplicateWarning(moduleDescriptor) + iw.foreach(log.warn(_)) - val metadataDirectory = configuration.metadataDirectory + val metadataDirectory = configuration.metadataDirectory - // Create inputs, resolve and retrieve the module descriptor - val inputs = ResolutionInputs(ivy, moduleDescriptor, configuration, log) - val resolutionResult: Either[ResolveException, UpdateReport] = { - if (module.owner.configuration.updateOptions.cachedResolution && metadataDirectory.isDefined) { - val cache = - metadataDirectory.getOrElse(sys.error("Missing directory for cached resolution.")) - cachedResolveAndRetrieve(inputs, cache) - } else resolveAndRetrieve(inputs) - } + // Create inputs, resolve and retrieve the module descriptor + val inputs = ResolutionInputs(ivy, moduleDescriptor, configuration, log) + val resolutionResult: Either[ResolveException, UpdateReport] = { + if ( + module.owner.configuration.updateOptions.cachedResolution && metadataDirectory.isDefined + ) { + val cache = + metadataDirectory.getOrElse(sys.error("Missing directory for cached resolution.")) + cachedResolveAndRetrieve(inputs, cache) + } else resolveAndRetrieve(inputs) + } - // Convert to unresolved warning or retrieve update report - resolutionResult.fold( - exception => Left(UnresolvedWarning(exception, uwconfig)), - ur0 => { - val ur = configuration.retrieveManaged match { - case Some(retrieveConf) => retrieve(log, ivy, ur0, retrieveConf) - case _ => ur0 - } - Right(ur) + // Convert to unresolved warning or retrieve update report + resolutionResult.fold( + exception => Left(UnresolvedWarning(exception, uwconfig)), + ur0 => { + val ur = configuration.retrieveManaged match { + case Some(retrieveConf) => retrieve(log, ivy, ur0, retrieveConf) + case _ => ur0 } - ) + Right(ur) + } + ) } } @@ -252,11 +251,10 @@ object IvyActions { exclude.getOrElse(restrictedCopy(id, false), Set.empty[String]) def extractExcludes(report: UpdateReport): Map[ModuleID, Set[String]] = - report.allMissing flatMap { - case (_, mod, art) => - art.classifier.map { c => - (restrictedCopy(mod, false), c) - } + report.allMissing flatMap { case (_, mod, art) => + art.classifier.map { c => + (restrictedCopy(mod, false), c) + } } groupBy (_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } /** @@ -275,8 +273,8 @@ object IvyActions { ) implicit def toIvyFilter(f: ArtifactTypeFilter): IvyFilter = new IvyFilter { - override def accept(o: Object): Boolean = Option(o) exists { - case a: IArtifact => applyFilter(a) + override def accept(o: Object): Boolean = Option(o) exists { case a: IArtifact => + applyFilter(a) } def applyFilter(a: IArtifact): Boolean = @@ -498,13 +496,12 @@ object IvyActions { checkFilesPresent(artifacts) try { resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite); - artifacts.foreach { - case (artifact, file) => - IvyUtil.retryWithBackoff( - resolver.publish(artifact, file, overwrite), - TransientNetworkException.apply, - maxAttempts = LMSysProp.maxPublishAttempts - ) + artifacts.foreach { case (artifact, file) => + IvyUtil.retryWithBackoff( + resolver.publish(artifact, file, overwrite), + TransientNetworkException.apply, + maxAttempts = LMSysProp.maxPublishAttempts + ) } resolver.commitPublishTransaction() } catch { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index f5ae6d8fb..756fb0686 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -31,11 +31,11 @@ private object NotInCache { } } -/** Provides methods for working at the level of a single jar file with the default Ivy cache.*/ +/** Provides methods for working at the level of a single jar file with the default Ivy cache. */ class IvyCache(val ivyHome: Option[File]) { def lockFile = new File(ivyHome getOrElse Path.userHome, ".sbt.cache.lock") - /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ + /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID. */ def cacheJar( moduleID: ModuleID, file: File, @@ -52,7 +52,7 @@ class IvyCache(val ivyHome: Option[File]) { } } - /** Clears the cache of the jar for the given ID.*/ + /** Clears the cache of the jar for the given ID. */ def clearCachedJar(id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger): Unit = { try { withCachedJar(id, lock, log)(_.delete); () @@ -61,7 +61,7 @@ class IvyCache(val ivyHome: Option[File]) { } } - /** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown.*/ + /** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown. */ def retrieveCachedJar( id: ModuleID, toDirectory: File, @@ -74,7 +74,7 @@ class IvyCache(val ivyHome: Option[File]) { copyTo } - /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown .*/ + /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown . */ def withCachedJar[T](id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger)( f: File => T ): T = { @@ -89,7 +89,7 @@ class IvyCache(val ivyHome: Option[File]) { if (cachedFile.exists) f(cachedFile) else throw new NotInCache(id) } - /** Calls the given function with the default Ivy cache.*/ + /** Calls the given function with the default Ivy cache. */ def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: Logger)( f: DefaultRepositoryCacheManager => T ): T = { @@ -103,7 +103,7 @@ class IvyCache(val ivyHome: Option[File]) { } private def unknownOrigin(artifact: IvyArtifact) = ArtifactOrigin.unkwnown(artifact) - /** A minimal Ivy setup with only a local resolver and the current directory as the base directory.*/ + /** A minimal Ivy setup with only a local resolver and the current directory as the base directory. */ private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: Logger) = { val local = Resolver.defaultLocal val paths = IvyPaths(new File("."), ivyHome) @@ -115,12 +115,12 @@ class IvyCache(val ivyHome: Option[File]) { (new IvySbt(conf), local) } - /** Creates a default jar artifact based on the given ID.*/ + /** Creates a default jar artifact based on the given ID. */ private def defaultArtifact(moduleID: ModuleID): IvyArtifact = new DefaultArtifact(IvySbt.toID(moduleID), null, moduleID.name, "jar", "jar") } -/** Required by Ivy for copying to the cache.*/ +/** Required by Ivy for copying to the cache. */ private class FileDownloader extends ResourceDownloader { def download(artifact: IvyArtifact, resource: Resource, dest: File): Unit = { if (dest.exists()) dest.delete() diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala index 29f61222a..dd0416399 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala @@ -19,7 +19,7 @@ private[sbt] final class IvyLoggerInterface(logger: Logger) extends MessageLogge case MSG_ERR => error(msg) } } - //DEBUG level messages are very verbose and rarely useful to users. + // DEBUG level messages are very verbose and rarely useful to users. // TODO: provide access to this information some other way def debug(msg: String): Unit = () def verbose(msg: String): Unit = logger.verbose(msg) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index a6d2604ce..3e1d5f32f 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -54,14 +54,18 @@ object IvyRetrieve { private[sbt] def organizationArtifactReports( confReport: ConfigurationResolveReport ): Vector[OrganizationArtifactReport] = { - val moduleIds = confReport.getModuleIds.toArray.toVector collect { - case mId: IvyModuleId => mId + val moduleIds = confReport.getModuleIds.toArray.toVector collect { case mId: IvyModuleId => + mId } def organizationArtifact(mid: IvyModuleId): OrganizationArtifactReport = { val deps = confReport.getNodes(mid).toArray.toVector collect { case node: IvyNode => node } - OrganizationArtifactReport(mid.getOrganisation, mid.getName, deps map { - moduleRevisionDetail(confReport, _) - }) + OrganizationArtifactReport( + mid.getOrganisation, + mid.getName, + deps map { + moduleRevisionDetail(confReport, _) + } + ) } moduleIds map { organizationArtifact } } @@ -141,9 +145,13 @@ object IvyRetrieve { val edOpt = Option(dep.getEvictedData(confReport.getConfiguration)) edOpt match { case Some(ed) => - (true, nonEmptyString(Option(ed.getConflictManager) map { _.toString } getOrElse { - "transitive" - }), nonEmptyString(ed.getDetail)) + ( + true, + nonEmptyString(Option(ed.getConflictManager) map { _.toString } getOrElse { + "transitive" + }), + nonEmptyString(ed.getDetail) + ) case None => (true, None, None) } case _ => (false, None, None) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala index 3ea763301..bb2701818 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala @@ -67,9 +67,11 @@ object IvyScalaUtil { new NamespaceTransformer { def transform(mrid: ModuleRevisionId): ModuleRevisionId = { if (mrid == null) mrid - else if ((isScala2Artifact(mrid.getName) || isScala3Artifact(mrid.getName)) && - configQualifies && - dependeeQualifies) { + else if ( + (isScala2Artifact(mrid.getName) || isScala3Artifact(mrid.getName)) && + configQualifies && + dependeeQualifies + ) { // do not override the binary incompatible Scala version because: // - the artifacts compiled with Scala 3 depends on the Scala 2.13 scala-library // - the Scala 2 TASTy reader can consume the Scala 3 artifacts @@ -152,7 +154,8 @@ object IvyScalaUtil { .forall(bv => bv.startsWith("3") || bv.startsWith("2.13")) def matchesOneOfTheConfigs = dep.getModuleConfigurations exists { scalaVersionConfigs } - val mismatched = isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs + val mismatched = + isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs if (mismatched) Some( "Binary version (" + depBinaryVersion + ") for dependency " + id + diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala index c6d3da447..5c381913a 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala @@ -102,5 +102,6 @@ private[sbt] object ResolutionCache { private val Name = "sbt-resolution-cache" // use sbt-specific extra attributes so that resolved xml files do not get overwritten when using different Scala/sbt versions - private val ResolvedPattern = "[organisation]/[module]/" + Resolver.PluginPattern + "([branch]/)[revision]/[artifact].[ext]" + private val ResolvedPattern = + "[organisation]/[module]/" + Resolver.PluginPattern + "([branch]/)[revision]/[artifact].[ext]" } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 7d94bca6d..7dc600e13 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -105,7 +105,7 @@ private[sbt] class CachedResolutionResolveCache { s"""Include(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" def artifactString(dad: DependencyArtifactDescriptor): String = s"""Artifact(${dad.getName},${dad.getType},${dad.getExt},${dad.getUrl},${dad.getConfigurations - .mkString(",")},${dad.getExtraAttributes})""" + .mkString(",")},${dad.getExtraAttributes})""" val mrid = dd.getDependencyRevisionId val confMap = (dd.getModuleConfigurations map { conf => conf + "->(" + dd.getDependencyConfigurations(conf).mkString(",") + ")" @@ -127,9 +127,13 @@ private[sbt] class CachedResolutionResolveCache { val mesStr = (mes map excludeRuleString).mkString(",") val os = extractOverrides(parent) val moduleLevel = s"""dependencyOverrides=${os.mkString(",")};moduleExclusions=$mesStr""" - val depsString = s"""$mrid;${confMap.mkString(",")};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" + - s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};explicitArtifacts=${explicitArtifacts - .mkString(",")};$moduleLevel;""" + val depsString = s"""$mrid;${confMap.mkString( + "," + )};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" + + s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString( + "," + )};explicitArtifacts=${explicitArtifacts + .mkString(",")};$moduleLevel;""" val sha1 = Hash.toHex( Hash(s"""graphVersion=${CachedResolutionResolveCache.graphVersion};$depsString""") ) @@ -158,15 +162,14 @@ private[sbt] class CachedResolutionResolveCache { md0.getAllDependencyDescriptorMediators.getAllRules.asScala.toSeq.toVector sortBy { case (k, _) => k.toString - } collect { - case (k: MapMatcher, v: OverrideDependencyDescriptorMediator) => - val attr: Map[Any, Any] = k.getAttributes.asScala.toMap - val module = IvyModuleId.newInstance( - attr(IvyPatternHelper.ORGANISATION_KEY).toString, - attr(IvyPatternHelper.MODULE_KEY).toString - ) - val pm = k.getPatternMatcher - IvyOverride(module, pm, v) + } collect { case (k: MapMatcher, v: OverrideDependencyDescriptorMediator) => + val attr: Map[Any, Any] = k.getAttributes.asScala.toMap + val module = IvyModuleId.newInstance( + attr(IvyPatternHelper.ORGANISATION_KEY).toString, + attr(IvyPatternHelper.MODULE_KEY).toString + ) + val pm = k.getPatternMatcher + IvyOverride(module, pm, v) } } def getOrElseUpdateMiniGraph( @@ -200,8 +203,10 @@ private[sbt] class CachedResolutionResolveCache { } val staticGraphDirectory = miniGraphPath / "static" val dynamicGraphDirectory = miniGraphPath / "dynamic" - val staticGraphPath = staticGraphDirectory / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json" - val dynamicGraphPath = dynamicGraphDirectory / todayStr / logicalClock.toString / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json" + val staticGraphPath = + staticGraphDirectory / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json" + val dynamicGraphPath = + dynamicGraphDirectory / todayStr / logicalClock.toString / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json" def cleanDynamicGraph(): Unit = { val list = IO.listFiles(dynamicGraphDirectory, DirectoryFilter).toList list filterNot { d => @@ -282,9 +287,12 @@ private[sbt] class CachedResolutionResolveCache { val moduleIdMap = Map(conflicts map { x => x.module -> x }: _*) - (surviving map moduleIdMap, evicted map moduleIdMap map { - _.withEvicted(true).withEvictedReason(Some(mgr.toString)) - }) + ( + surviving map moduleIdMap, + evicted map moduleIdMap map { + _.withEvicted(true).withEvictedReason(Some(mgr.toString)) + } + ) } (conflictCache get ((cf0, cf1))) match { case Some((surviving, evicted, mgr)) => reconstructReports(surviving, evicted, mgr) @@ -410,59 +418,58 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { Left(new ResolveException(messages, failed, failedPaths)) } } - val (internal, external) = mds.partition { - case (_, _, dd) => cache.internalDependency(dd, projectResolver).isDefined + val (internal, external) = mds.partition { case (_, _, dd) => + cache.internalDependency(dd, projectResolver).isDefined } - val internalResults = internal map { - case (md, changing, dd) => - cache.getOrElseUpdateMiniGraph( - md, - changing, - logicalClock, - miniGraphPath, - cachedDescriptor, - log - ) { - doWork(md, dd) - } + val internalResults = internal map { case (md, changing, dd) => + cache.getOrElseUpdateMiniGraph( + md, + changing, + logicalClock, + miniGraphPath, + cachedDescriptor, + log + ) { + doWork(md, dd) + } } - val externalResults = external map { - case (md0, changing, dd) => - val configurationsInInternal = internalResults flatMap { - case Right(ur) => - ur.allModules.flatMap { - case md => - val sameName = md.name == dd.getDependencyId.getName - val sameOrg = md.organization == dd.getDependencyId.getOrganisation - if (sameName && sameOrg) md.configurations - else None + val externalResults = external map { case (md0, changing, dd) => + val configurationsInInternal = internalResults flatMap { + case Right(ur) => + ur.allModules.flatMap { case md => + val sameName = md.name == dd.getDependencyId.getName + val sameOrg = md.organization == dd.getDependencyId.getOrganisation + if (sameName && sameOrg) md.configurations + else None + } + case _ => Nil + } + + dd match { + case d: DefaultDependencyDescriptor => + configurationsInInternal foreach { c => + val configurations = c.split(";").map(_.split("->")) + configurations foreach { conf => + try d.addDependencyConfiguration(conf(0), conf(1)) + catch { + case _: Throwable => () + } // An exception will be thrown if `conf(0)` doesn't exist. } - case _ => Nil - } + } - dd match { - case d: DefaultDependencyDescriptor => - configurationsInInternal foreach { c => - val configurations = c.split(";").map(_.split("->")) - configurations foreach { conf => - try d.addDependencyConfiguration(conf(0), conf(1)) - catch { case _: Throwable => () } // An exception will be thrown if `conf(0)` doesn't exist. - } - } + case _ => () + } - case _ => () - } - - cache.getOrElseUpdateMiniGraph( - md0, - changing, - logicalClock, - miniGraphPath, - cachedDescriptor, - log - ) { - doWork(md0, dd) - } + cache.getOrElseUpdateMiniGraph( + md0, + changing, + logicalClock, + miniGraphPath, + cachedDescriptor, + log + ) { + doWork(md0, dd) + } } val results = internalResults ++ externalResults val uReport = @@ -485,21 +492,20 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { log: Logger ): Either[ResolveException, UpdateReport] = if (!missingOk && (results exists { _.isLeft })) - Left(mergeErrors(md0, results collect { case Left(re) => re })) + Left(mergeErrors(md0, results collect { case Left(re) => re })) else Right(mergeReports(md0, results collect { case Right(ur) => ur }, resolveTime, os, log)) def mergeErrors(md0: ModuleDescriptor, errors: Vector[ResolveException]): ResolveException = { val messages = errors flatMap { _.messages } val failed = errors flatMap { _.failed } val failedPaths = errors flatMap { - _.failedPaths.toList map { - case (failed, paths) => - if (paths.isEmpty) (failed, paths) - else - ( - failed, - List(IvyRetrieve.toModuleID(md0.getResolvedModuleRevisionId)) ::: paths.toList.tail - ) + _.failedPaths.toList map { case (failed, paths) => + if (paths.isEmpty) (failed, paths) + else + ( + failed, + List(IvyRetrieve.toModuleID(md0.getResolvedModuleRevisionId)) ::: paths.toList.tail + ) } } new ResolveException(messages, failed, ListMap(failedPaths: _*)) @@ -579,12 +585,11 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { // this might take up some memory, but it's limited to a single val reports1 = reports0 flatMap { filterReports } val allModules0: Map[(String, String), Vector[OrganizationArtifactReport]] = - Map(orgNamePairs map { - case (organization, name) => - val xs = reports1 filter { oar => - oar.organization == organization && oar.name == name - } - ((organization, name), xs) + Map(orgNamePairs map { case (organization, name) => + val xs = reports1 filter { oar => + oar.organization == organization && oar.name == name + } + ((organization, name), xs) }: _*) // this returns a List of Lists of (org, name). should be deterministic def detectLoops( @@ -766,8 +771,8 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val completelyEvicted = xs forall { _.evicted } val allCallers = xs flatMap { _.callers } // Caller info is often repeated across the subprojects. We only need ModuleID info for later, so xs.head is ok. - val distinctByModuleId = allCallers.groupBy({ _.caller }).toVector map { - case (_, xs) => xs.head + val distinctByModuleId = allCallers.groupBy({ _.caller }).toVector map { case (_, xs) => + xs.head } val allArtifacts = (xs flatMap { _.artifacts }).distinct xs.head @@ -777,10 +782,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) - }).toSeq.toVector flatMap { - case (_, xs) => - if (xs.size < 2) xs - else Vector(mergeModuleReports(xs)) + }).toSeq.toVector flatMap { case (_, xs) => + if (xs.size < 2) xs + else Vector(mergeModuleReports(xs)) } val conflicts = merged filter { m => !m.evicted && m.problem.isEmpty @@ -789,9 +793,12 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { else resolveConflict(rootModuleConf, conflicts, os, log) match { case (survivor, evicted) => - (survivor ++ (merged filter { m => - m.evicted || m.problem.isDefined - }), evicted) + ( + survivor ++ (merged filter { m => + m.evicted || m.problem.isDefined + }), + evicted + ) } } @@ -869,9 +876,13 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { }) match { case Some(m) => log.debug(s"- directly forced dependency: $m ${m.callers}") - (Vector(m), conflicts filterNot { _ == m } map { - _.withEvicted(true).withEvictedReason(Some("direct-force")) - }, "direct-force") + ( + Vector(m), + conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some("direct-force")) + }, + "direct-force" + ) case None => (conflicts find { m => m.callers.exists { _.isForceDependency } @@ -879,18 +890,26 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { // Ivy translates pom.xml dependencies to forced="true", so transitive force is broken. case Some(m) if !ignoreTransitiveForce => log.debug(s"- transitively forced dependency: $m ${m.callers}") - (Vector(m), conflicts filterNot { _ == m } map { - _.withEvicted(true).withEvictedReason(Some("transitive-force")) - }, "transitive-force") + ( + Vector(m), + conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some("transitive-force")) + }, + "transitive-force" + ) case _ => val strategy = lcm.getStrategy val infos = conflicts map { ModuleReportArtifactInfo(_) } log.debug(s"- Using $strategy with $infos") Option(strategy.findLatest(infos.toArray, None.orNull)) match { case Some(ModuleReportArtifactInfo(m)) => - (Vector(m), conflicts filterNot { _ == m } map { - _.withEvicted(true).withEvictedReason(Some(lcm.toString)) - }, lcm.toString) + ( + Vector(m), + conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some(lcm.toString)) + }, + lcm.toString + ) case _ => (conflicts, Vector(), lcm.toString) } } @@ -905,9 +924,13 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { mr.module.revision == ovrVersion } match { case Some(m) => - (Vector(m), conflicts filterNot { _ == m } map { - _.withEvicted(true).withEvictedReason(Some("override")) - }, "override") + ( + Vector(m), + conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some("override")) + }, + "override" + ) case None => sys.error( s"override dependency specifies $ovrVersion but no candidates were found: " + (conflicts map { @@ -925,7 +948,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { }).mkString("(", ", ", ")")) ) case lcm: LatestConflictManager => useLatest(lcm) - case conflictManager => sys.error(s"Unsupported conflict manager $conflictManager") + case conflictManager => sys.error(s"Unsupported conflict manager $conflictManager") } } if (conflicts.size == 2 && os.isEmpty) { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala index 2ba03b741..478462e8d 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala @@ -64,10 +64,14 @@ object ErrorMessageAuthenticator { ivyOriginalField.set(ivy, newOriginal) } - try Option(ivyOriginalField.get(ivy).asInstanceOf[Authenticator]) match { - case Some(_: ErrorMessageAuthenticator) => // We're already installed, no need to do the work again. - case originalOpt => installIntoIvyImpl(originalOpt) - } catch { + try + Option(ivyOriginalField.get(ivy).asInstanceOf[Authenticator]) match { + case Some( + _: ErrorMessageAuthenticator + ) => // We're already installed, no need to do the work again. + case originalOpt => installIntoIvyImpl(originalOpt) + } + catch { case t: Throwable => Message.debug( "Error occurred while trying to install debug messages into Ivy Authentication" + t.getMessage @@ -135,16 +139,17 @@ private[sbt] final class ErrorMessageAuthenticator(original: Option[Authenticato // Grabs the authentication that would have been provided had we not been installed... def originalAuthentication: Option[PasswordAuthentication] = { Authenticator.setDefault(original.orNull) - try Option( - Authenticator.requestPasswordAuthentication( - getRequestingHost, - getRequestingSite, - getRequestingPort, - getRequestingProtocol, - getRequestingPrompt, - getRequestingScheme + try + Option( + Authenticator.requestPasswordAuthentication( + getRequestingHost, + getRequestingSite, + getRequestingPort, + getRequestingProtocol, + getRequestingPrompt, + getRequestingScheme + ) ) - ) finally Authenticator.setDefault(this) } originalAuthentication.orNull diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala index 4d1e92420..9d8148323 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala @@ -56,8 +56,8 @@ private[sbt] object IvyCredentialsLookup { * A mapping of host -> realms in the ivy credentials store. */ def realmsForHost: Map[String, Set[String]] = - (keyringKeys collect { - case x: Realm => x + (keyringKeys collect { case x: Realm => + x } groupBy { realm => realm.host } mapValues { realms => diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala index 1c9f2e7de..765360d90 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala @@ -13,14 +13,14 @@ private[sbt] object MergeDescriptors { a.isTransitive == b.isTransitive && a.getParentRevisionId == b.getParentRevisionId && a.getNamespace == b.getNamespace && { - val amrid = a.getDependencyRevisionId - val bmrid = b.getDependencyRevisionId - amrid == bmrid - } && { - val adyn = a.getDynamicConstraintDependencyRevisionId - val bdyn = b.getDynamicConstraintDependencyRevisionId - adyn == bdyn - } + val amrid = a.getDependencyRevisionId + val bmrid = b.getDependencyRevisionId + amrid == bmrid + } && { + val adyn = a.getDynamicConstraintDependencyRevisionId + val bdyn = b.getDynamicConstraintDependencyRevisionId + adyn == bdyn + } def apply(a: DependencyDescriptor, b: DependencyDescriptor): DependencyDescriptor = { assert(mergeable(a, b)) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala index 9af7ef6cb..711e03225 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala @@ -48,17 +48,18 @@ private[sbt] class ParallelResolveEngine( } // Farm out the dependencies for parallel download implicit val ec = ParallelResolveEngine.resolveExecutionContext - val allDownloadsFuture = Future.traverse(report.getDependencies.asScala) { - case dep: IvyNode => - Future { - if (!(dep.isCompletelyEvicted || dep.hasProblem) && - dep.getModuleRevision != null) { - Some(downloadNodeArtifacts(dep, artifactFilter, options)) - } else None - } + val allDownloadsFuture = Future.traverse(report.getDependencies.asScala) { case dep: IvyNode => + Future { + if ( + !(dep.isCompletelyEvicted || dep.hasProblem) && + dep.getModuleRevision != null + ) { + Some(downloadNodeArtifacts(dep, artifactFilter, options)) + } else None + } } val allDownloads = Await.result(allDownloadsFuture, Duration.Inf) - //compute total downloaded size + // compute total downloaded size val totalSize = allDownloads.foldLeft(0L) { case (size, Some(download)) => val dependency = download.dep @@ -67,8 +68,10 @@ private[sbt] class ParallelResolveEngine( val configurationReport = report.getConfigurationReport(configuration) // Take into account artifacts required by the given configuration - if (dependency.isEvicted(configuration) || - dependency.isBlacklisted(configuration)) { + if ( + dependency.isEvicted(configuration) || + dependency.isBlacklisted(configuration) + ) { configurationReport.addDependency(dependency) } else configurationReport.addDependency(dependency, download.report) } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index 2314838ef..9dfd3b83f 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -37,9 +37,9 @@ private[sbt] case class SbtChainResolver( override def equals(o: Any): Boolean = o match { case o: SbtChainResolver => this.name == o.name && - this.resolvers == o.resolvers && - this.settings == o.settings && - this.updateOptions == o.updateOptions + this.resolvers == o.resolvers && + this.settings == o.settings && + this.updateOptions == o.updateOptions case _ => false } @@ -124,7 +124,8 @@ private[sbt] case class SbtChainResolver( /** If None, module was not found. Otherwise, hit. */ type TriedResolution = Option[(ResolvedModuleRevision, DependencyResolver)] - /** Attempts to resolve the artifact from each of the resolvers in the chain. + /** + * Attempts to resolve the artifact from each of the resolvers in the chain. * * Contract: * 1. It doesn't resolve anything when there is a resolved module, `isReturnFirst` is @@ -155,8 +156,8 @@ private[sbt] case class SbtChainResolver( currentlyResolved = Option(resolver.getDependency(descriptor, data)) if (currentlyResolved eq previouslyResolved) None else if (useLatest) { - currentlyResolved.map( - x => (reparseModuleDescriptor(descriptor, data, resolver, x), resolver) + currentlyResolved.map(x => + (reparseModuleDescriptor(descriptor, data, resolver, x), resolver) ) } else currentlyResolved.map(x => (forcedRevision(x), resolver)) } @@ -174,7 +175,8 @@ private[sbt] case class SbtChainResolver( val oldLatest: Option[LatestStrategy] = setLatestIfRequired(resolver, Option(getLatestStrategy)) try Right(performResolution(resolver)) - catch { case NonFatal(t) => reportError(t, resolver); Left(t) } finally { + catch { case NonFatal(t) => reportError(t, resolver); Left(t) } + finally { oldLatest.foreach(_ => doSetLatestStrategy(resolver, oldLatest)) checkInterrupted() } @@ -189,34 +191,33 @@ private[sbt] case class SbtChainResolver( data: ResolveData ): Option[ResolvedModuleRevision] = { - val sortedRevisions = foundRevisions.sortBy { - case (rmr, resolver) => - val publicationDate = rmr.getPublicationDate - val descriptorDate = rmr.getDescriptor.getPublicationDate - Message.warn(s"Sorting results from $rmr, using $publicationDate and $descriptorDate.") - // Just issue warning about issues with publication date, and fake one on it for now - val chosenPublicationDate = Option(publicationDate).orElse(Option(descriptorDate)) - chosenPublicationDate match { - case Some(date) => date.getTime - case None => - val id = rmr.getId - val resolvedResource = (resolver.findIvyFileRef(descriptor, data), rmr.getDescriptor) - resolvedResource match { - case (res: ResolvedResource, dmd: DefaultModuleDescriptor) => - val resolvedPublicationDate = new java.util.Date(res.getLastModified) - Message.debug(s"No publication date from resolver $resolver for $id.") - Message.debug(s"Setting publication date to: $resolvedPublicationDate.") - dmd.setPublicationDate(resolvedPublicationDate) - res.getLastModified - case (ivf, dmd) => - // The dependency is specified by a direct URL or some sort of non-ivy file - if (ivf == null && descriptor.isChanging) - Message.warn(s"$prefix: changing dependency $id with no ivy/pom file!") - if (dmd == null) - Message.warn(s"$prefix: no publication date from resolver $resolver for $id") - 0L - } - } + val sortedRevisions = foundRevisions.sortBy { case (rmr, resolver) => + val publicationDate = rmr.getPublicationDate + val descriptorDate = rmr.getDescriptor.getPublicationDate + Message.warn(s"Sorting results from $rmr, using $publicationDate and $descriptorDate.") + // Just issue warning about issues with publication date, and fake one on it for now + val chosenPublicationDate = Option(publicationDate).orElse(Option(descriptorDate)) + chosenPublicationDate match { + case Some(date) => date.getTime + case None => + val id = rmr.getId + val resolvedResource = (resolver.findIvyFileRef(descriptor, data), rmr.getDescriptor) + resolvedResource match { + case (res: ResolvedResource, dmd: DefaultModuleDescriptor) => + val resolvedPublicationDate = new java.util.Date(res.getLastModified) + Message.debug(s"No publication date from resolver $resolver for $id.") + Message.debug(s"Setting publication date to: $resolvedPublicationDate.") + dmd.setPublicationDate(resolvedPublicationDate) + res.getLastModified + case (ivf, dmd) => + // The dependency is specified by a direct URL or some sort of non-ivy file + if (ivf == null && descriptor.isChanging) + Message.warn(s"$prefix: changing dependency $id with no ivy/pom file!") + if (dmd == null) + Message.warn(s"$prefix: no publication date from resolver $resolver for $id") + 0L + } + } } val firstHit = sortedRevisions.reverse.headOption @@ -233,7 +234,7 @@ private[sbt] case class SbtChainResolver( val (module, resolver) = h Message.info( s"Out of ${sortedRevisions.size} candidates we found for ${module.getId} in ${resolvers - .mkString(" and ")}, we are choosing ${resolver}." + .mkString(" and ")}, we are choosing ${resolver}." ) }) } else { @@ -277,12 +278,11 @@ private[sbt] case class SbtChainResolver( } /** Cleans unnecessary module id information not provided by [[IvyRetrieve.toModuleID()]]. */ - private final val moduleResolvers = updateOptions.moduleResolvers.map { - case (key, value) => - val cleanKey = ModuleID(key.organization, key.name, key.revision) - .withExtraAttributes(key.extraAttributes) - .withBranchName(key.branchName) - cleanKey -> value + private final val moduleResolvers = updateOptions.moduleResolvers.map { case (key, value) => + val cleanKey = ModuleID(key.organization, key.name, key.revision) + .withExtraAttributes(key.extraAttributes) + .withBranchName(key.branchName) + cleanKey -> value } /** @@ -309,7 +309,8 @@ private[sbt] case class SbtChainResolver( def findInterProjectResolver(resolvers: Seq[DependencyResolver]): Option[DependencyResolver] = resolvers.find(_.getName == ProjectResolver.InterProject) - /** Gets the dependency for a given descriptor with the pertinent resolve data. + /** + * Gets the dependency for a given descriptor with the pertinent resolve data. * * This is a custom sbt chain operation that produces better error output and deals with * cases that the conventional ivy resolver does not. It accumulates the resolution of diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala index 458972409..6d65f72f3 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala @@ -16,11 +16,11 @@ object Credentials { def apply(file: File): Credentials = new FileCredentials(file) - /** Add the provided credentials to Ivy's credentials cache.*/ + /** Add the provided credentials to Ivy's credentials cache. */ def add(realm: String, host: String, userName: String, passwd: String): Unit = CredentialsStore.INSTANCE.addCredentials(realm, host, userName, passwd) - /** Load credentials from the given file into Ivy's credentials cache.*/ + /** Load credentials from the given file into Ivy's credentials cache. */ def add(path: File, log: Logger): Unit = loadCredentials(path) match { case Left(err) => log.warn(err) diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala index 0a41509bb..1fa856d0e 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala @@ -79,12 +79,12 @@ 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.gigahorse == o.gigahorse && - this.resolverConverter == o.resolverConverter && - this.moduleResolvers == o.moduleResolvers + this.interProjectFirst == o.interProjectFirst && + this.latestSnapshots == o.latestSnapshots && + this.cachedResolution == o.cachedResolution && + this.gigahorse == o.gigahorse && + this.resolverConverter == o.resolverConverter && + this.moduleResolvers == o.moduleResolvers case _ => false } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala index dc2947e26..15a68f70e 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala @@ -121,7 +121,7 @@ object ComponentManagerTest extends BasicTestSuite { TestLogger { logger => withTemporaryDirectory { temp => // The actual classes we'll use at runtime. - //val mgr = new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), Some(ivyHome), logger) + // val mgr = new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), Some(ivyHome), logger) // A stub component manager object provider extends ComponentProvider { diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala index e546f9758..13189de5b 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala @@ -28,12 +28,22 @@ class CredentialsSpec extends AnyFunSuite { test("DirectCredentials.toString") { assert( - Credentials(realm = null, host = "example.org", userName = "username", passwd = "password").toString == + Credentials( + realm = null, + host = "example.org", + userName = "username", + passwd = "password" + ).toString == """DirectCredentials(null, "example.org", "username", ****)""" ) assert( - Credentials(realm = "realm", host = "example.org", userName = "username", passwd = "password").toString == + Credentials( + realm = "realm", + host = "example.org", + userName = "username", + passwd = "password" + ).toString == """DirectCredentials("realm", "example.org", "username", ****)""" ) } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala index f4b2c53e2..2d02e2896 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala @@ -118,11 +118,17 @@ object EvictionErrorSpec extends BaseIvySpecification { def oldAkkaPvp = List("com.typesafe.akka" % "*" % "pvp") lazy val `akkaActor2.1.4` = - ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary lazy val `akkaActor2.3.0` = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations( + Some("compile") + ) cross CrossVersion.binary lazy val `akkaActor2.6.0` = - ModuleID("com.typesafe.akka", "akka-actor", "2.6.0").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.6.0").withConfigurations( + Some("compile") + ) cross CrossVersion.binary lazy val `scala2.10.4` = ModuleID("org.scala-lang", "scala-library", "2.10.4").withConfigurations(Some("compile")) lazy val `scala2.12.17` = @@ -130,9 +136,13 @@ object EvictionErrorSpec extends BaseIvySpecification { lazy val `scala2.13.3` = ModuleID("org.scala-lang", "scala-library", "2.13.3").withConfigurations(Some("compile")) lazy val `bananaSesame0.4` = - ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.1.4 + ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses akka-actor 2.1.4 lazy val `akkaRemote2.3.4` = - ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 + ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses akka-actor 2.3.4 lazy val `http4s0.21.11` = ("org.http4s" %% "http4s-blaze-server" % "0.21.11").withConfigurations(Some("compile")) // https://repo1.maven.org/maven2/org/typelevel/cats-effect_2.13/3.0.0-M4/cats-effect_2.13-3.0.0-M4.pom diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index 09975ba5f..4f8ded23f 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -20,7 +20,11 @@ object EvictionWarningSpec extends BaseIvySpecification { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) assert( - EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions.size == 0 + EvictionWarning( + m, + fullOptions.withWarnScalaVersionEviction(false), + report + ).scalaEvictions.size == 0 ) } @@ -79,7 +83,11 @@ object EvictionWarningSpec extends BaseIvySpecification { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) assert( - EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions.size == 0 + EvictionWarning( + m, + fullOptions.withWarnScalaVersionEviction(false), + report + ).scalaEvictions.size == 0 ) } @@ -302,11 +310,17 @@ object EvictionWarningSpec extends BaseIvySpecification { } def akkaActor214 = - ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def akkaActor230 = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def akkaActor234 = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def scala2102 = ModuleID("org.scala-lang", "scala-library", "2.10.2").withConfigurations(Some("compile")) def scala2103 = @@ -317,13 +331,21 @@ object EvictionWarningSpec extends BaseIvySpecification { def commonsIo14 = ModuleID("commons-io", "commons-io", "1.4").withConfigurations(Some("compile")) def commonsIo24 = ModuleID("commons-io", "commons-io", "2.4").withConfigurations(Some("compile")) def bnfparser10 = - ModuleID("ca.gobits.bnf", "bnfparser", "1.0").withConfigurations(Some("compile")) // uses commons-io 2.4 + ModuleID("ca.gobits.bnf", "bnfparser", "1.0").withConfigurations( + Some("compile") + ) // uses commons-io 2.4 def unfilteredUploads080 = - ModuleID("net.databinder", "unfiltered-uploads", "0.8.0").withConfigurations(Some("compile")) cross CrossVersion.binary // uses commons-io 1.4 + ModuleID("net.databinder", "unfiltered-uploads", "0.8.0").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses commons-io 1.4 def bananaSesame04 = - ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.1.4 + ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses akka-actor 2.1.4 def akkaRemote234 = - ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 + ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses akka-actor 2.3.4 def fullOptions = EvictionWarningOptions.full def javaLibDirectDeps = Vector(commonsIo14, commonsIo24) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala index db9344070..46e830c04 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala @@ -24,9 +24,15 @@ object InconsistentDuplicateSpec extends BasicTestSuite { } def akkaActor214 = - ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def akkaActor230 = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def akkaActor230Test = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("test")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations( + Some("test") + ) cross CrossVersion.binary } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala index 97515d9ef..c3235b934 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -17,7 +17,7 @@ object IvyRepoSpec extends BaseIvySpecification { module( ourModuleID, Vector(dep), - None //, UpdateOptions().withCachedResolution(true) + None // , UpdateOptions().withCachedResolution(true) ) } @@ -31,13 +31,11 @@ object IvyRepoSpec extends BaseIvySpecification { val report = ivyUpdate(m) import Inside._ - inside(report.configuration(ConfigRef("compile")).map(_.modules)) { - case Some(Seq(mr)) => - inside(mr.artifacts) { - case Seq((ar, _)) => - assert(ar.`type` == "jar") - assert(ar.extension == "jar") - } + inside(report.configuration(ConfigRef("compile")).map(_.modules)) { case Some(Seq(mr)) => + inside(mr.artifacts) { case Seq((ar, _)) => + assert(ar.`type` == "jar") + assert(ar.extension == "jar") + } } } @@ -90,14 +88,12 @@ object IvyRepoSpec extends BaseIvySpecification { .get import Inside._ - inside(report2.configuration(ConfigRef("compile")).map(_.modules)) { - case Some(Seq(mr)) => - inside(mr.artifacts) { - case Seq((ar, _)) => - assert(ar.name == "libmodule-source") - assert(ar.`type` == "src") - assert(ar.extension == "jar") - } + inside(report2.configuration(ConfigRef("compile")).map(_.modules)) { case Some(Seq(mr)) => + inside(mr.artifacts) { case Seq((ar, _)) => + assert(ar.name == "libmodule-source") + assert(ar.`type` == "src") + assert(ar.extension == "jar") + } } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala index 898402224..780613096 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala @@ -14,20 +14,19 @@ object MergeDescriptorSpec extends BaseIvySpecification { None, UpdateOptions() ) - m.withModule(log) { - case (_, md, _) => - val deps = md.getDependencies - assert(deps.size == 1) - deps.headOption.getOrElse(sys.error("Dependencies not found")) match { - case dd @ MergedDescriptors(_, _) => - val arts = dd.getAllDependencyArtifacts - val a0: DependencyArtifactDescriptor = arts.toList(0) - val a1: DependencyArtifactDescriptor = arts.toList(1) - val configs0 = a0.getConfigurations.toList - val configs1 = a1.getConfigurations.toList - assert(configs0 == List("compile")) - assert(configs1 == List("test")) - } + m.withModule(log) { case (_, md, _) => + val deps = md.getDependencies + assert(deps.size == 1) + deps.headOption.getOrElse(sys.error("Dependencies not found")) match { + case dd @ MergedDescriptors(_, _) => + val arts = dd.getAllDependencyArtifacts + val a0: DependencyArtifactDescriptor = arts.toList(0) + val a1: DependencyArtifactDescriptor = arts.toList(1) + val configs0 = a0.getConfigurations.toList + val configs1 = a1.getConfigurations.toList + assert(configs0 == List("compile")) + assert(configs1 == List("test")) + } } } def guavaTest = diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala index 2bf13668d..c131e2900 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala @@ -13,7 +13,7 @@ import java.nio.file.Paths object SftpRepoSpec extends BaseIvySpecification { val repo: Option[String] = None // val repo: Option[String] = Some("some repo") - //a dependency which depends on another in the repo + // a dependency which depends on another in the repo def org(repo: String) = s"com.${repo}" def module(org: String) = org % "some-lib" % "version" diff --git a/project/HouseRulesPlugin.scala b/project/HouseRulesPlugin.scala index 4921e09fe..3d29c00d1 100644 --- a/project/HouseRulesPlugin.scala +++ b/project/HouseRulesPlugin.scala @@ -31,8 +31,8 @@ object HouseRulesPlugin extends AutoPlugin { scalacOptions += "-Ywarn-numeric-widen", scalacOptions += "-Ywarn-value-discard", scalacOptions ++= "-Ywarn-unused-import".ifScala(v => 11 <= v && v <= 12).value.toList - ) ++ Seq(Compile, Test).flatMap( - c => (c / console / scalacOptions) --= Seq("-Ywarn-unused-import", "-Xlint") + ) ++ Seq(Compile, Test).flatMap(c => + (c / console / scalacOptions) --= Seq("-Ywarn-unused-import", "-Xlint") ) private def scalaPartV = Def setting (CrossVersion partialVersion scalaVersion.value) diff --git a/project/Util.scala b/project/Util.scala index 172b36423..88517e668 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -30,7 +30,9 @@ object Util { val f = dir / "xsbt.version.properties" // TODO: replace lastModified() with sbt.io.IO.getModifiedTimeOrZero(), once the build // has been upgraded to a version of sbt that includes that call. - if (!f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, version)) { + if ( + !f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, version) + ) { s.log.info("Writing version information to " + f + " :\n" + content) IO.write(f, content) } From 1dd9c5c0e7bf099447e958f045b50d768cad8fc4 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 25 Jun 2023 21:01:05 -0400 Subject: [PATCH 32/52] Util 1.9.1 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index cd168495a..ae2fb420e 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -9,8 +9,8 @@ object Dependencies { def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.9.0") - private val utilVersion = nightlyVersion.getOrElse("1.9.0") + private val ioVersion = nightlyVersion.getOrElse("1.9.1") + private val utilVersion = nightlyVersion.getOrElse("1.9.1") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From f12bd96ff1cbf6069f92e1ca95dc503663162a06 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 25 Jun 2023 21:02:59 -0400 Subject: [PATCH 33/52] CLA --- .github/workflows/cla.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/cla.yml diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml new file mode 100644 index 000000000..abbf9f3ba --- /dev/null +++ b/.github/workflows/cla.yml @@ -0,0 +1,24 @@ +name: Scala CLA +on: [pull_request] +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Check CLA + env: + AUTHOR: ${{ github.event.pull_request.user.login }} + run: | + echo "Pull request submitted by $AUTHOR"; + signed=$(curl -s "https://www.lightbend.com/contribute/cla/scala/check/$AUTHOR" | jq -r ".signed"); + if [ "$signed" = "true" ] ; then + echo "CLA check for $AUTHOR successful"; + else + echo "CLA check for $AUTHOR failed"; + echo "Please sign the Scala CLA to contribute to the Scala compiler."; + echo "Go to https://www.lightbend.com/contribute/cla/scala and then"; + echo "comment on the pull request to ask for a new check."; + echo ""; + echo "Check if CLA is signed: https://www.lightbend.com/contribute/cla/scala/check/$AUTHOR"; + exit 1; + fi; From 10a79d6001a6c43a9cdf66a7c5c96748222c8f61 Mon Sep 17 00:00:00 2001 From: Matthew de Detrich Date: Thu, 27 Jul 2023 10:15:14 +0200 Subject: [PATCH 34/52] Add Apache staging repo --- .../src/main/scala/sbt/librarymanagement/ResolverExtra.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index a070c049c..ca980b7e8 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -186,6 +186,11 @@ private[librarymanagement] abstract class ResolverFunctions { "https://repository.apache.org/content/repositories/snapshots/" ) + val ApacheMavenStagingRepo = MavenRepository( + "apache-staging", + "https://repository.apache.org/content/groups/staging/" + ) + /** Add the local and Maven Central repositories to the user repositories. */ def combineDefaultResolvers(userResolvers: Vector[Resolver]): Vector[Resolver] = combineDefaultResolvers(userResolvers, mavenCentral = true) From 824cca75d23fb2aab7108450fe44a907beddf96c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 24 Aug 2023 10:36:27 -0400 Subject: [PATCH 35/52] Bump to Ivy 2.3.0-sbt-396a783bba347016e7fe30dacc60d355be607fe2 --- build.sbt | 2 +- project/Dependencies.scala | 2 +- project/build.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index c4db12bb1..70ffc1741 100644 --- a/build.sbt +++ b/build.sbt @@ -7,7 +7,7 @@ val _ = { sys.props += ("line.separator" -> "\n") } Global / semanticdbEnabled := !(Global / insideCI).value -// Global / semanticdbVersion := "4.5.9" +Global / semanticdbVersion := "4.7.8" ThisBuild / version := { val old = (ThisBuild / version).value nightlyVersion match { diff --git a/project/Dependencies.scala b/project/Dependencies.scala index ae2fb420e..f44188027 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -43,7 +43,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-a8f9eb5bf09d0539ea3658a2c2d4e09755b5133e" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-396a783bba347016e7fe30dacc60d355be607fe2" val sbtV = "1.0" val scalaV = "2.12" diff --git a/project/build.properties b/project/build.properties index 46e43a97e..52413ab79 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.8.2 +sbt.version=1.9.3 From cf5fc207b0e6db1ad12577a54b7caff029ff5b3c Mon Sep 17 00:00:00 2001 From: Kunal Date: Wed, 30 Aug 2023 18:36:44 +0530 Subject: [PATCH 36/52] Update CrossVersionUtil.scala (#426) --- .../librarymanagement/cross/CrossVersionUtil.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index e8e518ec8..eef2d1a23 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -64,10 +64,10 @@ object CrossVersionUtil { * Compatible versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. */ private[sbt] def scalaApiVersion(v: String): Option[(Long, Long)] = v match { - case ReleaseV(x, y, _, _) => Some((x.toLong, y.toLong)) - case BinCompatV(x, y, _, _, _) => Some((x.toLong, y.toLong)) - case NonReleaseV_1(x, y, z, _) if z.toInt > 0 => Some((x.toLong, y.toLong)) - case _ => None + case ReleaseV(x, y, _, _) => Some((x.toLong, y.toLong)) + case BinCompatV(x, y, _, _, _) => Some((x.toLong, y.toLong)) + case NonReleaseV_1(x, y, z, _) if z.toLong > 0 => Some((x.toLong, y.toLong)) + case _ => None } private[sbt] def partialVersion(s: String): Option[(Long, Long)] = From fd3b33b4727779af6702ee7648319aa7e82b1f12 Mon Sep 17 00:00:00 2001 From: Matthew de Detrich Date: Mon, 11 Sep 2023 00:50:13 +0200 Subject: [PATCH 37/52] Add allModuleReports to UpdateReport --- .../librarymanagement/UpdateReportExtra.scala | 20 +++++++++++++++++-- .../FakeResolverSpecification.scala | 2 ++ .../librarymanagement/FrozenModeSpec.scala | 9 +++++++++ .../librarymanagement/InclExclSpec.scala | 12 +++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index 910827703..b54058e8c 100644 --- a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -125,10 +125,11 @@ private[librarymanagement] abstract class UpdateReportExtra { def stats: UpdateStats private[sbt] def stamps: Map[File, Long] + private[sbt] def moduleKey(m: ModuleID) = (m.organization, m.name, m.revision) + /** All resolved modules in all configurations. */ def allModules: Vector[ModuleID] = { - val key = (m: ModuleID) => (m.organization, m.name, m.revision) - configurations.flatMap(_.allModules).groupBy(key).toVector map { case (_, v) => + configurations.flatMap(_.allModules).groupBy(moduleKey).toVector map { case (_, v) => v reduceLeft { (agg, x) => agg.withConfigurations( (agg.configurations, x.configurations) match { @@ -141,6 +142,21 @@ private[librarymanagement] abstract class UpdateReportExtra { } } + def allModuleReports: Vector[ModuleReport] = { + configurations.flatMap(_.modules).groupBy(mR => moduleKey(mR.module)).toVector map { + case (_, v) => + v reduceLeft { (agg, x) => + agg.withConfigurations( + (agg.configurations, x.configurations) match { + case (v, _) if v.isEmpty => x.configurations + case (ac, v) if v.isEmpty => ac + case (ac, xc) => ac ++ xc + } + ) + } + } + } + def retrieve(f: (ConfigRef, ModuleID, Artifact, File) => File): UpdateReport = UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala index 89095a51c..6ed8f1d7a 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala @@ -23,6 +23,7 @@ object FakeResolverSpecification extends BaseIvySpecification { val allFiles = getAllFiles(report) assert(report.allModules.length == 1) + assert(report.allModuleReports.length == 1) assert(report.configurations.length == 3) assert(allFiles.toSet.size == 1) assert(allFiles(1).getName == "artifact1-0.0.1-SNAPSHOT.jar") @@ -34,6 +35,7 @@ object FakeResolverSpecification extends BaseIvySpecification { val allFiles = getAllFiles(report).toSet assert(report.allModules.length == 1) + assert(report.allModuleReports.length == 1) assert(report.configurations.length == 3) assert(allFiles.toSet.size == 2) assert(allFiles.map(_.getName) == Set("artifact1-1.0.0.jar", "artifact2-1.0.0.txt")) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala index cae7b3f48..ab6a93c90 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala @@ -35,6 +35,7 @@ object FrozenModeSpec extends BaseIvySpecification { val onlineResolution = update(toResolve, onlineConf) assert(onlineResolution.isRight) val numberResolved = onlineResolution.right.get.allModules.size + val numberReportsResolved = onlineResolution.right.get.allModuleReports.size cleanIvyCache() val singleFrozenResolution = update(toResolve, frozenConf) @@ -43,6 +44,10 @@ object FrozenModeSpec extends BaseIvySpecification { singleFrozenResolution.right.get.allModules.size == 1, s"The number of explicit modules in frozen mode should 1" ) + assert( + singleFrozenResolution.right.get.allModuleReports.size == 1, + s"The number of explicit module reports in frozen mode should 1" + ) cleanIvyCache() // This relies on the fact that stoml has 5 transitive dependencies @@ -53,5 +58,9 @@ object FrozenModeSpec extends BaseIvySpecification { frozenResolution.right.get.allModules.size == numberResolved, s"The number of explicit modules in frozen mode should be equal than $numberResolved" ) + assert( + frozenResolution.right.get.allModuleReports.size == numberReportsResolved, + s"The number of explicit module reports in frozen mode should be equal than $numberReportsResolved" + ) } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala index d05f115ef..7305a2ddc 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala @@ -68,6 +68,10 @@ object InclExclSpec extends BaseIvySpecification { !report.allModules.exists(_.name.contains("lift-json")), "lift-json has not been excluded." ) + assert( + !report.allModuleReports.exists(_.module.name.contains("lift-json")), + "lift-json has not been excluded." + ) } def testScalaLibraryIsMissing(report: UpdateReport): Unit = { @@ -75,6 +79,10 @@ object InclExclSpec extends BaseIvySpecification { !report.allModules.exists(_.name.contains("scala-library")), "scala-library has not been excluded." ) + assert( + !report.allModuleReports.exists(_.module.name.contains("scala-library")), + "scala-library has not been excluded." + ) } def testScalahostIsMissing(report: UpdateReport): Unit = { @@ -82,5 +90,9 @@ object InclExclSpec extends BaseIvySpecification { !report.allModules.exists(_.name.contains("scalahost")), "scalahost has not been excluded." ) + assert( + !report.allModuleReports.exists(_.module.name.contains("scalahost")), + "scalahost has not been excluded." + ) } } From 9919feb8a1f70482069a779efd9a1a8e96ae89b1 Mon Sep 17 00:00:00 2001 From: Matthew de Detrich Date: Mon, 11 Sep 2023 11:11:55 +0200 Subject: [PATCH 38/52] Add JDK 17 to CI --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6ef1c3dab..4d4ad94d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,9 @@ jobs: - os: ubuntu-latest java: 11 jobtype: 1 + - os: ubuntu-latest + java: 17 + jobtype: 1 runs-on: ${{ matrix.os }} env: # define Java options for both official sbt and sbt-extras From 96220355e25a5e030ee0976861287300c748d093 Mon Sep 17 00:00:00 2001 From: Matthew de Detrich Date: Mon, 11 Sep 2023 11:12:59 +0200 Subject: [PATCH 39/52] Update github checkout action --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6ef1c3dab..95b392301 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: JVM_OPTS: -Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup JDK uses: actions/setup-java@v3 with: From 47bdf1bcde9a43a246a1a8013b7efb18c4b20c2f Mon Sep 17 00:00:00 2001 From: Matthew de Detrich Date: Mon, 11 Sep 2023 12:02:37 +0200 Subject: [PATCH 40/52] Update Scala 2.13 version --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index f44188027..47ebbe2b5 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -4,7 +4,7 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala212 = "2.12.18" - val scala213 = "2.13.10" + val scala213 = "2.13.12" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") From fdb519b9e2a7aca05b72786ef29b8c4778b89659 Mon Sep 17 00:00:00 2001 From: Roberto Tyley Date: Sat, 16 Sep 2023 13:09:07 +0100 Subject: [PATCH 41/52] Avoid repeating versions in Eviction warning message As with https://github.com/sbt/librarymanagement/pull/386, which dealt with Eviction *errors*, this fixes the way Eviction *warnings* report the list of evicted versions - removing duplicate versions - and does a refactor so that both `EvictionError` & `EvictionWarning` are using the same logic to generate the revision string. The logic for the revisions string is moved to the new field `EvictionPair.evictedRevs`. Without this fix, we see Eviction warnings like this: ``` * org.scala-lang.modules:scala-java8-compat_2.13:1.0.2 is selected over {1.0.0, 1.0.0} ``` --- .../main/scala/sbt/librarymanagement/EvictionError.scala | 5 +---- .../scala/sbt/librarymanagement/EvictionWarning.scala | 9 ++++++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 3e73e37c7..3662127be 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -158,9 +158,6 @@ final class EvictionError private[sbt] ( out += "found version conflict(s) in library dependencies; some are suspected to be binary incompatible:" out += "" evictions.foreach({ case (a, scheme) => - val revs = a.evicteds map { _.module.revision } - val revsStr = - if (revs.size <= 1) revs.mkString else "{" + revs.distinct.mkString(", ") + "}" val seen: mutable.Set[ModuleID] = mutable.Set() val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r => val rev = r.module.revision @@ -174,7 +171,7 @@ final class EvictionError private[sbt] ( } val que = if (assumed) "?" else "" val winnerRev = a.winner match { - case Some(r) => s":${r.module.revision} ($scheme$que) is selected over ${revsStr}" + case Some(r) => s":${r.module.revision} ($scheme$que) is selected over ${a.evictedRevs}" case _ => " is evicted for all versions" } val title = s"\t* ${a.organization}:${a.name}$winnerRev" diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index df70eeffa..a7179c30c 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -191,6 +191,11 @@ final class EvictionPair private[sbt] ( val includesDirect: Boolean, val showCallers: Boolean ) { + val evictedRevs: String = { + val revs = evicteds map { _.module.revision } + if (revs.size <= 1) revs.mkString else revs.distinct.mkString("{", ", ", "}") + } + override def toString: String = EvictionPair.evictionPairLines.showLines(this).mkString override def equals(o: Any): Boolean = o match { @@ -209,8 +214,6 @@ final class EvictionPair private[sbt] ( object EvictionPair { implicit val evictionPairLines: ShowLines[EvictionPair] = ShowLines { (a: EvictionPair) => - val revs = a.evicteds map { _.module.revision } - val revsStr = if (revs.size <= 1) revs.mkString else "{" + revs.mkString(", ") + "}" val seen: mutable.Set[ModuleID] = mutable.Set() val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r => val rev = r.module.revision @@ -223,7 +226,7 @@ object EvictionPair { } } val winnerRev = a.winner match { - case Some(r) => s":${r.module.revision} is selected over ${revsStr}" + case Some(r) => s":${r.module.revision} is selected over ${a.evictedRevs}" case _ => " is evicted for all versions" } val title = s"\t* ${a.organization}:${a.name}$winnerRev" From 999b881ee7c61300ee8527177db108b61fb6f839 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Mon, 9 Oct 2023 07:51:32 +0900 Subject: [PATCH 42/52] fix warnings. Resolver.sonatypeRepo => Resolver.sonatypeOssRepos --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 70ffc1741..ef3d2f672 100644 --- a/build.sbt +++ b/build.sbt @@ -44,14 +44,14 @@ def commonSettings: Seq[Setting[_]] = Def.settings( scalaVersion := scala212, // publishArtifact in packageDoc := false, resolvers += Resolver.typesafeIvyRepo("releases"), - resolvers += Resolver.sonatypeRepo("snapshots"), + resolvers ++= Resolver.sonatypeOssRepos("snapshots"), resolvers += Resolver.sbtPluginRepo("releases"), testFrameworks += new TestFramework("verify.runner.Framework"), // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), compile / javacOptions ++= Seq("-Xlint", "-Xlint:-serial"), crossScalaVersions := Seq(scala212, scala213), - resolvers += Resolver.sonatypeRepo("public"), + resolvers ++= Resolver.sonatypeOssRepos("public"), scalacOptions := { val old = scalacOptions.value scalaVersion.value match { From 3156ac253a1a8e84cc12ff922f208b9dc7c06a22 Mon Sep 17 00:00:00 2001 From: Alex Zolotko Date: Sat, 30 Mar 2024 17:30:57 +0100 Subject: [PATCH 43/52] Update jsch to 0.2.17 (the com.github.mwiede fork) --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 47ebbe2b5..e9e6735fc 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -48,7 +48,7 @@ object Dependencies { val sbtV = "1.0" val scalaV = "2.12" - val jsch = "com.jcraft" % "jsch" % "0.1.54" intransitive () + val jsch = "com.github.mwiede" % "jsch" % "0.2.17" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "2.1.0" From 04fcad6d9a79e8fc1b077c2a213ed6c6807c2f91 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 8 Apr 2024 22:06:49 -0400 Subject: [PATCH 44/52] Use 2 for binarySbtVersion in 2.x --- build.sbt | 9 ++++--- .../cross/CrossVersionUtil.scala | 8 +++++- .../librarymanagement/CrossVersionTest.scala | 27 +++++++++---------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/build.sbt b/build.sbt index ef3d2f672..c4e1a1608 100644 --- a/build.sbt +++ b/build.sbt @@ -55,11 +55,12 @@ def commonSettings: Seq[Setting[_]] = Def.settings( scalacOptions := { val old = scalacOptions.value scalaVersion.value match { - case sv if sv.startsWith("2.10") => - old diff List("-Xfuture", "-Ywarn-unused", "-Ywarn-unused-import") - case sv if sv.startsWith("2.11") => old ++ List("-Ywarn-unused", "-Ywarn-unused-import") case sv if sv.startsWith("2.12") => - old ++ List("-Ywarn-unused", "-Ywarn-unused-import", "-YdisableFlatCpCaching") + old ++ List( + "-Ywarn-unused", + "-Ywarn-unused-import", + "-Ywarn-unused:-nowarn", + ) case _ => old } }, diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index eef2d1a23..f2d467133 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -117,7 +117,13 @@ object CrossVersionUtil { } def binarySbtVersion(full: String): String = - binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) + sbtApiVersion(full) match { + case Some((0, minor)) if minor < 12 => full + case Some((0, minor)) => s"0.$minor" + case Some((1, minor)) => s"1.$minor" + case Some((major, _)) => major.toString + case _ => full + } private[this] def isNewer(major: Long, minor: Long, minMajor: Long, minMinor: Long): Boolean = major > minMajor || (major == minMajor && minor >= minMinor) diff --git a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala index 96b3d164f..c273653a0 100644 --- a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala @@ -96,23 +96,23 @@ class CrossVersionTest extends UnitSpec { "binarySbtVersion" should "for 0.11.3 return 0.11.3" in { binarySbtVersion("0.11.3") shouldBe "0.11.3" } - it should "for 0.12.0-M1 return 0.12.0-M1" in { - binarySbtVersion("0.12.0-M1") shouldBe "0.12.0-M1" + it should "for 2.0.0 return 2" in { + binarySbtVersion("2.0.0") shouldBe "2" } - it should "for 0.12.0-RC1 return 0.12" in { - binarySbtVersion("0.12.0-RC1") shouldBe "0.12" + it should "for 2.0.0-M1 return 2.0.0-M1" in { + binarySbtVersion("2.0.0-M1") shouldBe "2.0.0-M1" } - it should "for 0.12.0 return 0.12" in { - binarySbtVersion("0.12.0") shouldBe "0.12" + it should "for 2.0.0-RC1 return 2" in { + binarySbtVersion("2.0.0-RC1") shouldBe "2" } - it should "for 0.12.1-SNAPSHOT return 0.12" in { - binarySbtVersion("0.12.1-SNAPSHOT") shouldBe "0.12" + it should "for 2.1.0-M1 return 2" in { + binarySbtVersion("2.1.0-M1") shouldBe "2" } - it should "for 0.12.1-RC1 return 0.12" in { - binarySbtVersion("0.12.1-RC1") shouldBe "0.12" + it should "for 2.1.0 return 2" in { + binarySbtVersion("2.1.0") shouldBe "2" } - it should "for 0.12.1 return 0.12" in { - binarySbtVersion("0.12.1") shouldBe "0.12" + it should "for 0.13.1 return 0.13" in { + binarySbtVersion("0.13.1") shouldBe "0.13" } it should "for 1.0.0-M6 return 1.0.0-M6" in { binarySbtVersion("1.0.0-M6") shouldBe "1.0.0-M6" @@ -144,9 +144,6 @@ class CrossVersionTest extends UnitSpec { it should "for 1.10.0 return 1.0" in { binarySbtVersion("1.10.0") shouldBe "1.0" } - it should "for 2.0.0 return 2.0" in { - binarySbtVersion("2.0.0") shouldBe "2.0" - } "scalaApiVersion" should "for xyz return None" in { scalaApiVersion("xyz") shouldBe None From 6ab6c2baa95b1031ea7d465dbd6c708eaf7c7cef Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 8 Apr 2024 22:36:44 -0400 Subject: [PATCH 45/52] Util 1.10.0-RC1 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index e9e6735fc..b68ef80e2 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -9,8 +9,8 @@ object Dependencies { def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.9.1") - private val utilVersion = nightlyVersion.getOrElse("1.9.1") + private val ioVersion = nightlyVersion.getOrElse("1.9.9") + private val utilVersion = nightlyVersion.getOrElse("1.10.0-RC1") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From dc460527b40a19424bdd0166b6865c1707547aae Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 5 May 2024 17:53:08 -0400 Subject: [PATCH 46/52] Util 1.10.0 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b68ef80e2..43e8550be 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -9,8 +9,8 @@ object Dependencies { def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.9.9") - private val utilVersion = nightlyVersion.getOrElse("1.10.0-RC1") + private val ioVersion = nightlyVersion.getOrElse("1.10.0") + private val utilVersion = nightlyVersion.getOrElse("1.10.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From b3edb6a405a10787839b2eef04d124b002b84202 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 23 May 2024 17:04:26 +0200 Subject: [PATCH 47/52] Fix merge --- .scalafmt.conf | 2 -- .../ivyint/ErrorMessageAuthenticator.scala | 14 ++++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index 36996af92..dfdd36b0b 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -22,5 +22,3 @@ align.openParenDefnSite = false danglingParentheses.preset = true trailingCommas = preserve - -runner.dialect = Scala212Source3 diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala index f9f6ec04e..478462e8d 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala @@ -64,12 +64,14 @@ object ErrorMessageAuthenticator { ivyOriginalField.set(ivy, newOriginal) } - try Option(ivyOriginalField.get(ivy).asInstanceOf[Authenticator]) match { - case Some( - _: ErrorMessageAuthenticator - ) => // We're already installed, no need to do the work again. - case originalOpt => installIntoIvyImpl(originalOpt) - } catch { + try + Option(ivyOriginalField.get(ivy).asInstanceOf[Authenticator]) match { + case Some( + _: ErrorMessageAuthenticator + ) => // We're already installed, no need to do the work again. + case originalOpt => installIntoIvyImpl(originalOpt) + } + catch { case t: Throwable => Message.debug( "Error occurred while trying to install debug messages into Ivy Authentication" + t.getMessage From f8ce2cdef698d31206defbe6b45ae1a15772cced Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 23 May 2024 17:04:38 +0200 Subject: [PATCH 48/52] Update to Scala 3.3 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 4424008b0..d6e28cf91 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,7 +5,7 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala212 = "2.12.18" val scala213 = "2.13.12" - val scala3 = "3.2.1" + val scala3 = "3.3.3" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") @@ -63,5 +63,5 @@ object Dependencies { val sjsonnewScalaJson = Def.setting { "com.eed3si9n" %% "sjson-new-scalajson" % sjsonNewVersion } - val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-apache-http" % "0.7.0" + val gigahorseApacheHttp = "com.eed3si9n" %% "gigahorse-apache-http" % "0.7.0" } From 28b5db1465cdfb6d076a9e9306595775fd74df60 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 23 May 2024 17:09:12 +0200 Subject: [PATCH 49/52] fix Scala 3 compilation --- .../test/scala/sbt/librarymanagement/ResolverExtraTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala b/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala index 10cad9012..6aba7ec05 100644 --- a/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala @@ -36,7 +36,7 @@ object ResolverExtraTest extends BasicTestSuite { // - Helper functions ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------- def assertExpansion(input: String, expected: String) = - assert(Resolver.expandMavenSettings(input) == s"$expected") + assert(Resolver.expandMavenSettings(input) == expected) def env(name: String) = sys.env.getOrElse(name, "") def prop(name: String) = sys.props.getOrElse(name, "") From e140c8066730efb8170e87f7c944145af37f2408 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 28 May 2024 11:11:44 +0200 Subject: [PATCH 50/52] Bump sjson-new --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index d6e28cf91..824ae9b54 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -56,7 +56,7 @@ object Dependencies { val scalaTest = "org.scalatest" %% "scalatest" % "3.2.10" val scalaVerify = "com.eed3si9n.verify" %% "verify" % "1.0.0" val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.15.3" - val sjsonNewVersion = "0.13.0" + val sjsonNewVersion = "0.14.0-M1" val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % sjsonNewVersion } From 1b3d5324bb4bd730d8a729e5e71be3bbb1015756 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 29 May 2024 10:35:34 +0200 Subject: [PATCH 51/52] Use String instead of File as key of stamps - regenerate contraband --- .../ChainedResolverFormats.scala | 15 +-------------- .../ConfigurationReportFormats.scala | 18 +----------------- .../ModuleConfigurationFormats.scala | 16 +--------------- .../PatternsBasedRepositoryFormats.scala | 12 +----------- .../PublishConfigurationFormats.scala | 8 +------- .../librarymanagement/ResolverFormats.scala | 15 +-------------- .../SftpRepositoryFormats.scala | 7 +------ .../SshBasedRepositoryFormats.scala | 9 +-------- .../SshConnectionFormats.scala | 5 +---- .../SshRepositoryFormats.scala | 7 +------ .../sbt/librarymanagement/UpdateReport.scala | 8 ++++---- .../UpdateReportFormats.scala | 2 +- .../src/main/contraband/librarymanagement.json | 2 +- .../librarymanagement/RichUpdateReport.scala | 2 +- .../librarymanagement/UpdateReportExtra.scala | 2 +- .../DMSerializationSpec.scala | 2 +- 16 files changed, 19 insertions(+), 111 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala index 25792d684..61cf796da 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala @@ -5,20 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ChainedResolverFormats { self: sbt.librarymanagement.ResolverFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.MavenRepoFormats with - sbt.librarymanagement.MavenCacheFormats with - sbt.librarymanagement.PatternsFormats with - sbt.librarymanagement.FileConfigurationFormats with - sbt.librarymanagement.FileRepositoryFormats with - sbt.librarymanagement.URLRepositoryFormats with - sbt.librarymanagement.SshConnectionFormats with - sbt.librarymanagement.SshAuthenticationFormats with - sbt.librarymanagement.SshRepositoryFormats with - sbt.librarymanagement.SftpRepositoryFormats with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait ChainedResolverFormats { self: sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ChainedResolverFormat: JsonFormat[sbt.librarymanagement.ChainedResolver] = new JsonFormat[sbt.librarymanagement.ChainedResolver] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ChainedResolver = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala index 282877526..c8090c6e1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala @@ -5,23 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ConfigurationReportFormats { self: sbt.librarymanagement.ConfigRefFormats with - sbt.librarymanagement.ModuleReportFormats with - sbt.librarymanagement.ModuleIDFormats with - sbt.librarymanagement.ArtifactFormats with - sbt.librarymanagement.ChecksumFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.InclExclRuleFormats with - sbt.librarymanagement.CrossVersionFormats with - sbt.librarymanagement.DisabledFormats with - sbt.librarymanagement.BinaryFormats with - sbt.librarymanagement.ConstantFormats with - sbt.librarymanagement.PatchFormats with - sbt.librarymanagement.FullFormats with - sbt.librarymanagement.For3Use2_13Formats with - sbt.librarymanagement.For2_13Use3Formats with - sbt.librarymanagement.CallerFormats with - sbt.librarymanagement.OrganizationArtifactReportFormats => +trait ConfigurationReportFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ModuleReportFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sbt.librarymanagement.CallerFormats with sbt.librarymanagement.OrganizationArtifactReportFormats => implicit lazy val ConfigurationReportFormat: JsonFormat[sbt.librarymanagement.ConfigurationReport] = new JsonFormat[sbt.librarymanagement.ConfigurationReport] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConfigurationReport = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala index f562f1bb4..1f34ab28f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala @@ -5,21 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ModuleConfigurationFormats { self: sbt.librarymanagement.ResolverFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.ChainedResolverFormats with - sbt.librarymanagement.MavenRepoFormats with - sbt.librarymanagement.MavenCacheFormats with - sbt.librarymanagement.PatternsFormats with - sbt.librarymanagement.FileConfigurationFormats with - sbt.librarymanagement.FileRepositoryFormats with - sbt.librarymanagement.URLRepositoryFormats with - sbt.librarymanagement.SshConnectionFormats with - sbt.librarymanagement.SshAuthenticationFormats with - sbt.librarymanagement.SshRepositoryFormats with - sbt.librarymanagement.SftpRepositoryFormats with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait ModuleConfigurationFormats { self: sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ModuleConfigurationFormat: JsonFormat[sbt.librarymanagement.ModuleConfiguration] = new JsonFormat[sbt.librarymanagement.ModuleConfiguration] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleConfiguration = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala index f49f0f9c6..843e70f3d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala @@ -6,16 +6,6 @@ package sbt.librarymanagement import _root_.sjsonnew.JsonFormat -trait PatternsBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.FileConfigurationFormats with - sbt.librarymanagement.FileRepositoryFormats with - sbt.librarymanagement.URLRepositoryFormats with - sbt.librarymanagement.SshConnectionFormats with - sbt.librarymanagement.SshAuthenticationFormats with - sbt.librarymanagement.SshRepositoryFormats with - sbt.librarymanagement.SftpRepositoryFormats with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait PatternsBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.FileConfigurationFormats with sbt.librarymanagement.FileRepositoryFormats with sbt.librarymanagement.URLRepositoryFormats with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => implicit lazy val PatternsBasedRepositoryFormat: JsonFormat[sbt.librarymanagement.PatternsBasedRepository] = flatUnionFormat4[sbt.librarymanagement.PatternsBasedRepository, sbt.librarymanagement.FileRepository, sbt.librarymanagement.URLRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala index 8b2842ad8..d1fde3d18 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala @@ -5,13 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait PublishConfigurationFormats { self: sbt.librarymanagement.ConfigRefFormats with - sbt.librarymanagement.ArtifactFormats with - sbt.librarymanagement.UpdateLoggingFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats with - sbt.librarymanagement.ChecksumFormats => +trait PublishConfigurationFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.UpdateLoggingFormats with sjsonnew.BasicJsonProtocol => implicit lazy val PublishConfigurationFormat: JsonFormat[sbt.librarymanagement.PublishConfiguration] = new JsonFormat[sbt.librarymanagement.PublishConfiguration] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.PublishConfiguration = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala index 3f0a73150..5569ef568 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala @@ -6,19 +6,6 @@ package sbt.librarymanagement import _root_.sjsonnew.JsonFormat -trait ResolverFormats { self: sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.ChainedResolverFormats with - sbt.librarymanagement.MavenRepoFormats with - sbt.librarymanagement.MavenCacheFormats with - sbt.librarymanagement.PatternsFormats with - sbt.librarymanagement.FileConfigurationFormats with - sbt.librarymanagement.FileRepositoryFormats with - sbt.librarymanagement.URLRepositoryFormats with - sbt.librarymanagement.SshConnectionFormats with - sbt.librarymanagement.SshAuthenticationFormats with - sbt.librarymanagement.SshRepositoryFormats with - sbt.librarymanagement.SftpRepositoryFormats with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait ResolverFormats { self: sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ChainedResolverFormats with sbt.librarymanagement.MavenRepoFormats with sbt.librarymanagement.MavenCacheFormats with sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.FileConfigurationFormats with sbt.librarymanagement.FileRepositoryFormats with sbt.librarymanagement.URLRepositoryFormats with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => implicit lazy val ResolverFormat: JsonFormat[sbt.librarymanagement.Resolver] = flatUnionFormat7[sbt.librarymanagement.Resolver, sbt.librarymanagement.ChainedResolver, sbt.librarymanagement.MavenRepo, sbt.librarymanagement.MavenCache, sbt.librarymanagement.FileRepository, sbt.librarymanagement.URLRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala index 2a2f49073..9441ada31 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala @@ -5,12 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait SftpRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.SshConnectionFormats with - sbt.librarymanagement.SshAuthenticationFormats with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait SftpRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats => implicit lazy val SftpRepositoryFormat: JsonFormat[sbt.librarymanagement.SftpRepository] = new JsonFormat[sbt.librarymanagement.SftpRepository] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SftpRepository = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala index b16f32821..8143d7239 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala @@ -6,13 +6,6 @@ package sbt.librarymanagement import _root_.sjsonnew.JsonFormat -trait SshBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.SshConnectionFormats with - sbt.librarymanagement.SshAuthenticationFormats with - sbt.librarymanagement.SshRepositoryFormats with - sbt.librarymanagement.SftpRepositoryFormats with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait SshBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => implicit lazy val SshBasedRepositoryFormat: JsonFormat[sbt.librarymanagement.SshBasedRepository] = flatUnionFormat2[sbt.librarymanagement.SshBasedRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala index db4ea41e5..9daea2940 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala @@ -5,10 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait SshConnectionFormats { self: sbt.librarymanagement.SshAuthenticationFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait SshConnectionFormats { self: sbt.librarymanagement.SshAuthenticationFormats with sjsonnew.BasicJsonProtocol => implicit lazy val SshConnectionFormat: JsonFormat[sbt.librarymanagement.SshConnection] = new JsonFormat[sbt.librarymanagement.SshConnection] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SshConnection = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala index 2b3c4893b..861d359b1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala @@ -5,12 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait SshRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.SshConnectionFormats with - sbt.librarymanagement.SshAuthenticationFormats with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait SshRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats => implicit lazy val SshRepositoryFormat: JsonFormat[sbt.librarymanagement.SshRepository] = new JsonFormat[sbt.librarymanagement.SshRepository] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SshRepository = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala index 0e3c68f1a..3e8bcbe1a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala @@ -16,7 +16,7 @@ final class UpdateReport private ( val cachedDescriptor: java.io.File, val configurations: Vector[sbt.librarymanagement.ConfigurationReport], val stats: sbt.librarymanagement.UpdateStats, - val stamps: Map[java.io.File, Long]) extends sbt.librarymanagement.UpdateReportExtra with Serializable { + val stamps: Map[String, Long]) extends sbt.librarymanagement.UpdateReportExtra with Serializable { @@ -30,7 +30,7 @@ final class UpdateReport private ( override def toString: String = { "Update report:\n\t" + stats + "\n" + configurations.mkString } - private[this] def copy(cachedDescriptor: java.io.File = cachedDescriptor, configurations: Vector[sbt.librarymanagement.ConfigurationReport] = configurations, stats: sbt.librarymanagement.UpdateStats = stats, stamps: Map[java.io.File, Long] = stamps): UpdateReport = { + private[this] def copy(cachedDescriptor: java.io.File = cachedDescriptor, configurations: Vector[sbt.librarymanagement.ConfigurationReport] = configurations, stats: sbt.librarymanagement.UpdateStats = stats, stamps: Map[String, Long] = stamps): UpdateReport = { new UpdateReport(cachedDescriptor, configurations, stats, stamps) } def withCachedDescriptor(cachedDescriptor: java.io.File): UpdateReport = { @@ -42,11 +42,11 @@ final class UpdateReport private ( def withStats(stats: sbt.librarymanagement.UpdateStats): UpdateReport = { copy(stats = stats) } - def withStamps(stamps: Map[java.io.File, Long]): UpdateReport = { + def withStamps(stamps: Map[String, Long]): UpdateReport = { copy(stamps = stamps) } } object UpdateReport { - def apply(cachedDescriptor: java.io.File, configurations: Vector[sbt.librarymanagement.ConfigurationReport], stats: sbt.librarymanagement.UpdateStats, stamps: Map[java.io.File, Long]): UpdateReport = new UpdateReport(cachedDescriptor, configurations, stats, stamps) + def apply(cachedDescriptor: java.io.File, configurations: Vector[sbt.librarymanagement.ConfigurationReport], stats: sbt.librarymanagement.UpdateStats, stamps: Map[String, Long]): UpdateReport = new UpdateReport(cachedDescriptor, configurations, stats, stamps) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala index 41951020d..36ea7c27a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala @@ -14,7 +14,7 @@ implicit lazy val UpdateReportFormat: JsonFormat[sbt.librarymanagement.UpdateRep val cachedDescriptor = unbuilder.readField[java.io.File]("cachedDescriptor") val configurations = unbuilder.readField[Vector[sbt.librarymanagement.ConfigurationReport]]("configurations") val stats = unbuilder.readField[sbt.librarymanagement.UpdateStats]("stats") - val stamps = unbuilder.readField[Map[java.io.File, Long]]("stamps") + val stamps = unbuilder.readField[Map[String, Long]]("stamps") unbuilder.endObject() sbt.librarymanagement.UpdateReport(cachedDescriptor, configurations, stats, stamps) case None => diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 6b210d34c..89d20007d 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -814,7 +814,7 @@ "type": "sbt.librarymanagement.UpdateStats", "doc": [ "stats information about the update that produced this report" ] }, - { "name": "stamps", "type": "Map[java.io.File, Long]" } + { "name": "stamps", "type": "Map[String, Long]" } ], "toString": "\"Update report:\\n\\t\" + stats + \"\\n\" + configurations.mkString" }, diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index 9060f14b6..321790def 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -14,7 +14,7 @@ final class RichUpdateReport(report: UpdateReport) { val stamps = files .map(f => ( - f, + f.toString, // TODO: The list of files may also contain some odd files that do not actually exist like: // "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml". // IO.getModifiedTimeOrZero() will just return zero, but the list of files should not contain such diff --git a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index b54058e8c..c8b3ac69c 100644 --- a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -123,7 +123,7 @@ private[librarymanagement] abstract class UpdateReportExtra { def cachedDescriptor: File def configurations: Vector[ConfigurationReport] def stats: UpdateStats - private[sbt] def stamps: Map[File, Long] + private[sbt] def stamps: Map[String, Long] private[sbt] def moduleKey(m: ModuleID) = (m.organization, m.name, m.revision) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala index 7487252d1..bc035efa1 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala @@ -75,7 +75,7 @@ object DMSerializationSpec extends BasicTestSuite { new File("./foo"), Vector(configurationReportExample), UpdateStats(0, 0, 0, false), - Map(new File("./foo") -> 0) + Map("./foo" -> 0) ) lazy val configurationReportExample = ConfigurationReport( From 4251aa3ba00382ba4fb4005e6370ee1ce2c7b000 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 29 May 2024 13:39:22 +0200 Subject: [PATCH 52/52] Add lmIvy dependency to sjsonnew --- build.sbt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.sbt b/build.sbt index e947018be..a877f64f2 100644 --- a/build.sbt +++ b/build.sbt @@ -282,6 +282,8 @@ lazy val lmIvy = (project in file("ivy")) contrabandSjsonNewVersion := sjsonNewVersion, libraryDependencies ++= Seq( ivy, + sjsonnewScalaJson.value, + sjsonnew.value, scalaTest % Test, scalaCheck % Test, scalaVerify % Test,