From bf8ba5a9ca386ef96ffd6adcaf9ed6db3ce0c246 Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Fri, 3 Apr 2026 15:21:02 +0200 Subject: [PATCH 1/2] Respect settings.xml mirror repository definition --- .../scala/sbtpomreader/MavenPomResolver.scala | 34 +++++++++++++++---- .../MavenUserSettingsHelper.scala | 23 +++++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/main/scala/sbtpomreader/MavenPomResolver.scala b/src/main/scala/sbtpomreader/MavenPomResolver.scala index aeeee64..635e0d6 100644 --- a/src/main/scala/sbtpomreader/MavenPomResolver.scala +++ b/src/main/scala/sbtpomreader/MavenPomResolver.scala @@ -14,23 +14,45 @@ import org.apache.maven.model.building.{ } import org.apache.maven.model.resolution.ModelResolver import org.eclipse.aether.RepositorySystem -import org.eclipse.aether.repository.RemoteRepository +import org.eclipse.aether.repository.{ MirrorSelector, RemoteRepository } object MavenPomResolver { val system = newRepositorySystemImpl require(system != null, "Repository system failed to initialize") + + private[sbtpomreader] lazy val mirrorSelector: Option[MirrorSelector] = { + val settingsFile = new File( + sys.props("user.home") + File.separator + ".m2" + File.separator + "settings.xml" + ) + MavenUserSettingsHelper.loadUserSettings(settingsFile, Seq.empty).flatMap { settings => + val selector = MavenUserSettingsHelper.buildMirrorSelector(settings) + if (settings.getMirrors.isEmpty) None else Some(selector) + } + } + def apply(localRepo: File) = new MavenPomResolver(system, localRepo) } class MavenPomResolver(system: RepositorySystem, localRepo: File) { - val session = newSessionImpl(system, localRepo) + val session = { + val s = newSessionImpl(system, localRepo) + MavenPomResolver.mirrorSelector.foreach(s.setMirrorSelector) + s + } private val modelBuilder = (new DefaultModelBuilderFactory).newInstance - private val defaultRepositories: Seq[RemoteRepository] = - Seq( - new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2").build() - ) + private val defaultRepositories: Seq[RemoteRepository] = { + val central = new RemoteRepository.Builder( + "central", "default", "https://repo.maven.apache.org/maven2" + ).build() + MavenPomResolver.mirrorSelector match { + case Some(selector) => + Seq(Option(selector.getMirror(central)).getOrElse(central)) + case None => + Seq(central) + } + } // TODO - Add repositories from the pom... val modelResolver: ModelResolver = { diff --git a/src/main/scala/sbtpomreader/MavenUserSettingsHelper.scala b/src/main/scala/sbtpomreader/MavenUserSettingsHelper.scala index 95d8879..1bd885f 100644 --- a/src/main/scala/sbtpomreader/MavenUserSettingsHelper.scala +++ b/src/main/scala/sbtpomreader/MavenUserSettingsHelper.scala @@ -7,6 +7,8 @@ import scala.collection.JavaConverters._ import org.apache.maven.model.{ Model => PomModel, Repository => PomRepository } import org.apache.maven.settings.{ Settings => MavenSettings } import org.apache.maven.settings.building.{ DefaultSettingsBuilderFactory, DefaultSettingsBuildingRequest } +import org.eclipse.aether.repository.MirrorSelector +import org.eclipse.aether.util.repository.DefaultMirrorSelector /** * Helper object with functions to extract settings from the user's Maven settings file (typically ~/.m2/settings.xml) @@ -44,6 +46,27 @@ object MavenUserSettingsHelper { s <- settings.getServers.asScala } yield ServerCredentials(s.getId, s.getUsername, s.getPassword) + /** + * Build a MirrorSelector from the mirrors defined in Maven settings. + * The returned selector applies the same mirror matching rules as Maven itself + * (supporting `*`, `central`, `external:*`, negations like `*,!repo1`, etc.). + */ + def buildMirrorSelector(settings: MavenSettings): MirrorSelector = { + val selector = new DefaultMirrorSelector() + for (mirror <- settings.getMirrors.asScala) { + selector.add( + mirror.getId, + mirror.getUrl, + Option(mirror.getLayout).getOrElse("default"), + false, + mirror.isBlocked, + mirror.getMirrorOf, + mirror.getMirrorOfLayouts + ) + } + selector + } + /** Associates server credentials defined in the settings with repositories referenced in the POM. */ // TODO - Grab authentication realm... def matchCredentialsWithServers( From 68d763432ba0263f74089ed4a6b3aaf731253745 Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Mon, 6 Apr 2026 12:29:18 +0300 Subject: [PATCH 2/2] Respect settingsLocation and added scripted-test --- src/main/scala/sbtpomreader/MavenHelper.scala | 3 +- .../scala/sbtpomreader/MavenPomResolver.scala | 15 ++++--- src/main/scala/sbtpomreader/package.scala | 5 ++- .../can-read-settings-mirrors/build.sbt | 13 ++++++ .../override-settings.xml | 12 ++++++ .../can-read-settings-mirrors/pom.xml | 42 +++++++++++++++++++ .../project/plugin.sbt | 1 + .../simple-pom/can-read-settings-mirrors/test | 1 + 8 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 src/sbt-test/simple-pom/can-read-settings-mirrors/build.sbt create mode 100644 src/sbt-test/simple-pom/can-read-settings-mirrors/override-settings.xml create mode 100644 src/sbt-test/simple-pom/can-read-settings-mirrors/pom.xml create mode 100644 src/sbt-test/simple-pom/can-read-settings-mirrors/project/plugin.sbt create mode 100644 src/sbt-test/simple-pom/can-read-settings-mirrors/test diff --git a/src/main/scala/sbtpomreader/MavenHelper.scala b/src/main/scala/sbtpomreader/MavenHelper.scala index 70e5a41..9d37587 100644 --- a/src/main/scala/sbtpomreader/MavenHelper.scala +++ b/src/main/scala/sbtpomreader/MavenHelper.scala @@ -34,7 +34,8 @@ object MavenHelper { pomLocation.value, mvnLocalRepository.value, profiles.value, - mavenUserProperties.value + mavenUserProperties.value, + settingsLocation.value ), effectiveSettings := loadUserSettings(settingsLocation.value, profiles.value), showEffectivePom := showPom(pomLocation.value, effectivePom.value, streams.value), diff --git a/src/main/scala/sbtpomreader/MavenPomResolver.scala b/src/main/scala/sbtpomreader/MavenPomResolver.scala index 635e0d6..9851b6c 100644 --- a/src/main/scala/sbtpomreader/MavenPomResolver.scala +++ b/src/main/scala/sbtpomreader/MavenPomResolver.scala @@ -20,23 +20,22 @@ object MavenPomResolver { val system = newRepositorySystemImpl require(system != null, "Repository system failed to initialize") - private[sbtpomreader] lazy val mirrorSelector: Option[MirrorSelector] = { - val settingsFile = new File( - sys.props("user.home") + File.separator + ".m2" + File.separator + "settings.xml" - ) + private[sbtpomreader] def mirrorSelector(settingsFile: File): Option[MirrorSelector] = { MavenUserSettingsHelper.loadUserSettings(settingsFile, Seq.empty).flatMap { settings => val selector = MavenUserSettingsHelper.buildMirrorSelector(settings) if (settings.getMirrors.isEmpty) None else Some(selector) } } - def apply(localRepo: File) = new MavenPomResolver(system, localRepo) + def apply(localRepo: File, settingsFile: File) = new MavenPomResolver(system, localRepo, settingsFile) } -class MavenPomResolver(system: RepositorySystem, localRepo: File) { +class MavenPomResolver(system: RepositorySystem, localRepo: File, settingsFile: File) { + private val mirrors = MavenPomResolver.mirrorSelector(settingsFile) + val session = { val s = newSessionImpl(system, localRepo) - MavenPomResolver.mirrorSelector.foreach(s.setMirrorSelector) + mirrors.foreach(s.setMirrorSelector) s } @@ -46,7 +45,7 @@ class MavenPomResolver(system: RepositorySystem, localRepo: File) { val central = new RemoteRepository.Builder( "central", "default", "https://repo.maven.apache.org/maven2" ).build() - MavenPomResolver.mirrorSelector match { + mirrors match { case Some(selector) => Seq(Option(selector.getMirror(central)).getOrElse(central)) case None => diff --git a/src/main/scala/sbtpomreader/package.scala b/src/main/scala/sbtpomreader/package.scala index fac1e37..eb0c2b4 100644 --- a/src/main/scala/sbtpomreader/package.scala +++ b/src/main/scala/sbtpomreader/package.scala @@ -26,7 +26,8 @@ package object sbtpomreader { pom: File, localRepo: File = defaultLocalRepo, profiles: Seq[String], - userProps: Map[String, String] + userProps: Map[String, String], + settingsFile: File = new File(sys.props("user.home"), ".m2/settings.xml") ) = - MavenPomResolver(localRepo).loadEffectivePom(pom, Seq.empty, profiles, userProps) + MavenPomResolver(localRepo, settingsFile).loadEffectivePom(pom, Seq.empty, profiles, userProps) } diff --git a/src/sbt-test/simple-pom/can-read-settings-mirrors/build.sbt b/src/sbt-test/simple-pom/can-read-settings-mirrors/build.sbt new file mode 100644 index 0000000..6215c49 --- /dev/null +++ b/src/sbt-test/simple-pom/can-read-settings-mirrors/build.sbt @@ -0,0 +1,13 @@ + +settingsLocation := baseDirectory.value / "override-settings.xml" + +TaskKey[Unit]("checkMirrors") := { + val settings = effectiveSettings.value + assert(settings.isDefined, "Expected effective settings to be defined") + val mirrors = settings.get.getMirrors + assert(mirrors.size == 1, s"Expected 1 mirror, got ${mirrors.size}") + val mirror = mirrors.get(0) + assert(mirror.getId == "my-mirror", s"Expected mirror id 'my-mirror', got '${mirror.getId}'") + assert(mirror.getMirrorOf == "central", s"Expected mirrorOf 'central', got '${mirror.getMirrorOf}'") + assert(mirror.getUrl == "https://mirror.example.com/maven2", s"Expected mirror url 'https://mirror.example.com/maven2', got '${mirror.getUrl}'") +} diff --git a/src/sbt-test/simple-pom/can-read-settings-mirrors/override-settings.xml b/src/sbt-test/simple-pom/can-read-settings-mirrors/override-settings.xml new file mode 100644 index 0000000..38b435b --- /dev/null +++ b/src/sbt-test/simple-pom/can-read-settings-mirrors/override-settings.xml @@ -0,0 +1,12 @@ + + + + my-mirror + central + https://mirror.example.com/maven2 + + + diff --git a/src/sbt-test/simple-pom/can-read-settings-mirrors/pom.xml b/src/sbt-test/simple-pom/can-read-settings-mirrors/pom.xml new file mode 100644 index 0000000..25c9727 --- /dev/null +++ b/src/sbt-test/simple-pom/can-read-settings-mirrors/pom.xml @@ -0,0 +1,42 @@ + + 4.0.0 + com.jsuereth.junk + test-project + 1.0-SNAPSHOT + jar + + + 2.13.13 + UTF-8 + ${encoding} + + + + + org.scala-lang + scala-library + ${scala.version} + + + + + + + net.alchim31.maven + scala-maven-plugin + 3.1.0 + + + + compile + testCompile + + + + + ${scala.version} + + + + + diff --git a/src/sbt-test/simple-pom/can-read-settings-mirrors/project/plugin.sbt b/src/sbt-test/simple-pom/can-read-settings-mirrors/project/plugin.sbt new file mode 100644 index 0000000..b1b1130 --- /dev/null +++ b/src/sbt-test/simple-pom/can-read-settings-mirrors/project/plugin.sbt @@ -0,0 +1 @@ +addSbtPlugin("com.github.sbt" % "sbt-pom-reader" % sys.props("project.version")) diff --git a/src/sbt-test/simple-pom/can-read-settings-mirrors/test b/src/sbt-test/simple-pom/can-read-settings-mirrors/test new file mode 100644 index 0000000..173612e --- /dev/null +++ b/src/sbt-test/simple-pom/can-read-settings-mirrors/test @@ -0,0 +1 @@ +> checkMirrors \ No newline at end of file