@@ -48,7 +48,7 @@ import scala.cli.commands.{
48
48
SharedPythonOptions ,
49
49
WatchUtil
50
50
}
51
- import scala .cli .config .{ConfigDb , Keys }
51
+ import scala .cli .config .{ConfigDb , Keys , PublishCredentials }
52
52
import scala .cli .errors .{
53
53
FailedToSignFileError ,
54
54
MalformedChecksumsError ,
@@ -661,16 +661,6 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
661
661
(fileSet, (mod, ver))
662
662
}
663
663
664
- private final case class RepoParams (
665
- repo : PublishRepository ,
666
- targetRepoOpt : Option [String ],
667
- hooks : Hooks ,
668
- isIvy2LocalLike : Boolean ,
669
- defaultParallelUpload : Boolean ,
670
- supportsSig : Boolean ,
671
- acceptsChecksums : Boolean
672
- )
673
-
674
664
private def doPublish (
675
665
builds : Seq [Build .Successful ],
676
666
docBuilds : Seq [Build .Successful ],
@@ -697,150 +687,79 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
697
687
698
688
val ec = builds.head.options.finalCache.ec
699
689
700
- val repoParams = {
701
-
702
- lazy val es =
703
- Executors .newSingleThreadScheduledExecutor(Util .daemonThreadFactory(" publish-retry" ))
704
-
705
- def authOpt (repo : String ): Either [BuildException , Option [Authentication ]] = either {
706
- val hostOpt = {
707
- val uri = new URI (repo)
708
- if (uri.getScheme == " https" ) Some (uri.getHost)
709
- else None
710
- }
711
- val isSonatype =
712
- hostOpt.exists(host => host == " oss.sonatype.org" || host.endsWith(" .oss.sonatype.org" ))
713
- val passwordOpt = publishOptions.contextual(isCi).repoPassword match {
714
- case None if isSonatype =>
715
- value(configDb().get(Keys .sonatypePassword).wrapConfigException)
716
- case other => other.map(_.toConfig)
717
- }
718
- passwordOpt.map(_.get()) match {
719
- case None => None
720
- case Some (password) =>
721
- val userOpt = publishOptions.contextual(isCi).repoUser match {
722
- case None if isSonatype =>
723
- value(configDb().get(Keys .sonatypeUser).wrapConfigException)
724
- case other => other.map(_.toConfig)
725
- }
726
- val realmOpt = publishOptions.contextual(isCi).repoRealm match {
727
- case None if isSonatype =>
728
- Some (" Sonatype Nexus Repository Manager" )
729
- case other => other
690
+ def authOpt (repo : String ): Either [BuildException , Option [Authentication ]] = either {
691
+ val isHttps = {
692
+ val uri = new URI (repo)
693
+ uri.getScheme == " https"
694
+ }
695
+ val hostOpt = Option .when(isHttps)(new URI (repo).getHost)
696
+ val maybeCredentials : Either [BuildException , Option [PublishCredentials ]] = hostOpt match {
697
+ case None => Right (None )
698
+ case Some (host) =>
699
+ configDb().get(Keys .publishCredentials).wrapConfigException.map { credListOpt =>
700
+ credListOpt.flatMap { credList =>
701
+ credList.find { cred =>
702
+ cred.host == host &&
703
+ (isHttps || cred.httpsOnly.contains(false ))
704
+ }
730
705
}
731
- val auth = Authentication (userOpt.fold(" " )(_.get().value), password.value)
732
- Some (realmOpt.fold(auth)(auth.withRealm))
733
- }
706
+ }
734
707
}
735
-
736
- def centralRepo (base : String ) = either {
737
- val authOpt0 = value(authOpt(base))
738
- val repo0 = {
739
- val r = PublishRepository .Sonatype (MavenRepository (base))
740
- authOpt0.fold(r)(r.withAuthentication)
741
- }
742
- val backend = ScalaCliSttpBackend .httpURLConnection(logger)
743
- val api = SonatypeApi (backend, base + " /service/local" , authOpt0, logger.verbosity)
744
- val hooks0 = Hooks .sonatype(
745
- repo0,
746
- api,
747
- logger.compilerOutputStream, // meh
748
- logger.verbosity,
749
- batch = coursier.paths.Util .useAnsiOutput(), // FIXME Get via logger
750
- es
751
- )
752
- RepoParams (repo0, Some (" https://repo1.maven.org/maven2" ), hooks0, false , true , true , true )
708
+ val isSonatype =
709
+ hostOpt.exists(host => host == " oss.sonatype.org" || host.endsWith(" .oss.sonatype.org" ))
710
+ val passwordOpt = publishOptions.contextual(isCi).repoPassword match {
711
+ case None => value(maybeCredentials).flatMap(_.password)
712
+ case other => other.map(_.toConfig)
753
713
}
754
-
755
- def gitHubRepoFor (org : String , name : String ) =
756
- RepoParams (
757
- PublishRepository .Simple (MavenRepository (s " https://maven.pkg.github.com/ $org/ $name" )),
758
- None ,
759
- Hooks .dummy,
760
- false ,
761
- false ,
762
- false ,
763
- false
764
- )
765
-
766
- def gitHubRepo = either {
767
- val orgNameFromVcsOpt = publishOptions.versionControl
768
- .map(_.url)
769
- .flatMap(url => GitRepo .maybeGhOrgName(url))
770
-
771
- val (org, name) = orgNameFromVcsOpt match {
772
- case Some (orgName) => orgName
773
- case None =>
774
- value(GitRepo .ghRepoOrgName(builds.head.inputs.workspace, logger))
775
- }
776
-
777
- gitHubRepoFor(org, name)
714
+ passwordOpt.map(_.get()) match {
715
+ case None => None
716
+ case Some (password) =>
717
+ val userOpt = publishOptions.contextual(isCi).repoUser match {
718
+ case None => value(maybeCredentials).flatMap(_.user)
719
+ case other => other.map(_.toConfig)
720
+ }
721
+ val realmOpt = publishOptions.contextual(isCi).repoRealm match {
722
+ case None =>
723
+ value(maybeCredentials)
724
+ .flatMap(_.realm)
725
+ .orElse {
726
+ if (isSonatype) Some (" Sonatype Nexus Repository Manager" )
727
+ else None
728
+ }
729
+ case other => other
730
+ }
731
+ val auth = Authentication (userOpt.fold(" " )(_.get().value), password.value)
732
+ Some (realmOpt.fold(auth)(auth.withRealm))
778
733
}
734
+ }
779
735
780
- def ivy2Local = {
781
- val home = ivy2HomeOpt.getOrElse(os.home / " .ivy2" )
782
- val base = home / " local"
783
- // not really a Maven repo…
784
- RepoParams (
785
- PublishRepository .Simple (MavenRepository (base.toNIO.toUri.toASCIIString)),
786
- None ,
787
- Hooks .dummy,
788
- true ,
789
- true ,
790
- true ,
791
- true
792
- )
793
- }
736
+ val repoParams = {
737
+
738
+ lazy val es =
739
+ Executors .newSingleThreadScheduledExecutor(Util .daemonThreadFactory(" publish-retry" ))
794
740
795
741
if (publishLocal)
796
- ivy2Local
742
+ RepoParams . ivy2Local(ivy2HomeOpt)
797
743
else
798
- publishOptions.contextual(isCi).repository match {
799
- case None =>
800
- value(Left (new MissingPublishOptionError (
801
- " repository" ,
802
- " --publish-repository" ,
803
- " publish.repository"
804
- )))
805
- case Some (" ivy2-local" ) =>
806
- ivy2Local
807
- case Some (" central" | " maven-central" | " mvn-central" ) =>
808
- value(centralRepo(" https://oss.sonatype.org" ))
809
- case Some (" central-s01" | " maven-central-s01" | " mvn-central-s01" ) =>
810
- value(centralRepo(" https://s01.oss.sonatype.org" ))
811
- case Some (" github" ) =>
812
- value(gitHubRepo)
813
- case Some (repoStr) if repoStr.startsWith(" github:" ) && repoStr.count(_ == '/' ) == 1 =>
814
- val (org, name) = repoStr.stripPrefix(" github:" ).split('/' ) match {
815
- case Array (org0, name0) => (org0, name0)
816
- case other => sys.error(s " Cannot happen (' $repoStr' -> ${other.toSeq}) " )
817
- }
818
- gitHubRepoFor(org, name)
819
- case Some (repoStr) =>
820
- val repo0 = {
821
- val r = RepositoryParser .repositoryOpt(repoStr)
822
- .collect {
823
- case m : MavenRepository =>
824
- m
825
- }
826
- .getOrElse {
827
- val url =
828
- if (repoStr.contains(" ://" )) repoStr
829
- else os.Path (repoStr, Os .pwd).toNIO.toUri.toASCIIString
830
- MavenRepository (url)
831
- }
832
- r.withAuthentication(value(authOpt(r.root)))
833
- }
834
-
835
- RepoParams (
836
- PublishRepository .Simple (repo0),
837
- None ,
838
- Hooks .dummy,
839
- publishOptions.contextual(isCi).repositoryIsIvy2LocalLike.getOrElse(false ),
840
- true ,
841
- true ,
842
- true
843
- )
744
+ value {
745
+ publishOptions.contextual(isCi).repository match {
746
+ case None =>
747
+ Left (new MissingPublishOptionError (
748
+ " repository" ,
749
+ " --publish-repository" ,
750
+ " publish.repository"
751
+ ))
752
+ case Some (repo) =>
753
+ RepoParams (
754
+ repo,
755
+ publishOptions.versionControl.map(_.url),
756
+ builds.head.inputs.workspace,
757
+ ivy2HomeOpt,
758
+ publishOptions.contextual(isCi).repositoryIsIvy2LocalLike.getOrElse(false ),
759
+ es,
760
+ logger
761
+ )
762
+ }
844
763
}
845
764
}
846
765
@@ -988,10 +907,11 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
988
907
else fileSet2.order(ec).unsafeRun()(ec)
989
908
990
909
val isSnapshot0 = modVersionOpt.exists(_._2.endsWith(" SNAPSHOT" ))
991
- val hooksData = repoParams.hooks.beforeUpload(finalFileSet, isSnapshot0).unsafeRun()(ec)
910
+ val repoParams0 = repoParams.withAuth(value(authOpt(repoParams.repo.repo(isSnapshot0).root)))
911
+ val hooksData = repoParams0.hooks.beforeUpload(finalFileSet, isSnapshot0).unsafeRun()(ec)
992
912
993
- val retainedRepo = repoParams .hooks.repository(hooksData, repoParams .repo, isSnapshot0)
994
- .getOrElse(repoParams .repo.repo(isSnapshot0))
913
+ val retainedRepo = repoParams0 .hooks.repository(hooksData, repoParams0 .repo, isSnapshot0)
914
+ .getOrElse(repoParams0 .repo.repo(isSnapshot0))
995
915
996
916
val upload =
997
917
if (retainedRepo.root.startsWith(" http://" ) || retainedRepo.root.startsWith(" https://" ))
@@ -1015,9 +935,9 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
1015
935
case h :: t =>
1016
936
value(Left (new UploadError (:: (h, t))))
1017
937
case Nil =>
1018
- repoParams .hooks.afterUpload(hooksData).unsafeRun()(ec)
938
+ repoParams0 .hooks.afterUpload(hooksData).unsafeRun()(ec)
1019
939
for ((mod, version) <- modVersionOpt) {
1020
- val checkRepo = repoParams .repo.checkResultsRepo(isSnapshot0)
940
+ val checkRepo = repoParams0 .repo.checkResultsRepo(isSnapshot0)
1021
941
val relPath = {
1022
942
val elems =
1023
943
if (repoParams.isIvy2LocalLike)
0 commit comments