Skip to content

Commit b36b32c

Browse files
committed
React to some HTTP responses
1 parent 709a6c8 commit b36b32c

File tree

3 files changed

+66
-8
lines changed

3 files changed

+66
-8
lines changed

modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import coursier.publish.signing.logger.InteractiveSignerLogger
1212
import coursier.publish.signing.{GpgSigner, NopSigner, Signer}
1313
import coursier.publish.sonatype.SonatypeApi
1414
import coursier.publish.upload.logger.InteractiveUploadLogger
15-
import coursier.publish.upload.{DummyUpload, FileUpload, HttpURLConnectionUpload}
15+
import coursier.publish.upload.{DummyUpload, FileUpload, HttpURLConnectionUpload, Upload}
1616
import coursier.publish.{Content, Hooks, Pom, PublishRepository}
1717

1818
import java.io.{File, OutputStreamWriter}
@@ -56,13 +56,7 @@ import scala.cli.commands.shared.{
5656
import scala.cli.commands.util.{BuildCommandHelpers, ScalaCliSttpBackend}
5757
import scala.cli.commands.{ScalaCommand, SpecificationLevel, WatchUtil}
5858
import scala.cli.config.{ConfigDb, Keys, PasswordOption, PublishCredentials}
59-
import scala.cli.errors.{
60-
FailedToSignFileError,
61-
MalformedChecksumsError,
62-
MissingConfigEntryError,
63-
MissingPublishOptionError,
64-
UploadError
65-
}
59+
import scala.cli.errors._
6660
import scala.cli.packaging.Library
6761
import scala.cli.publish.BouncycastleSignerMaker
6862
import scala.cli.util.ArgHelpers.*
@@ -1040,11 +1034,30 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
10401034
val hooksDataOpt = Option.when(!dummy) {
10411035
try repoParams0.hooks.beforeUpload(finalFileSet, isSnapshot0).unsafeRun()(ec)
10421036
catch {
1037+
case NonFatal(e)
1038+
if "Failed to get .*/staging/profiles \\(http status: 403,".r.unanchored.matches(
1039+
e.getMessage
1040+
) =>
1041+
logger.exit(new WrongSonatypeServerError)
1042+
case NonFatal(e)
1043+
if "Failed to get .*/staging/profiles \\(http status: 401,".r.unanchored.matches(
1044+
e.getMessage
1045+
) =>
1046+
logger.exit(new InvalidPublishCredentials)
10431047
case NonFatal(e) =>
10441048
throw new Exception(e)
10451049
}
10461050
}
10471051

1052+
val isHttps = {
1053+
val uri = new URI(repoParams.repo.repo(isSnapshot0).root)
1054+
uri.getScheme == "https"
1055+
}
1056+
val hostOpt = Option.when(isHttps)(new URI(repoParams.repo.repo(isSnapshot0).root).getHost)
1057+
1058+
val isSonatype =
1059+
hostOpt.exists(host => host == "oss.sonatype.org" || host.endsWith(".oss.sonatype.org"))
1060+
10481061
val retainedRepo = hooksDataOpt match {
10491062
case None => // dummy mode
10501063
repoParams0.repo.repo(isSnapshot0)
@@ -1087,6 +1100,35 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
10871100
}
10881101

10891102
errors.toList match {
1103+
case (h @ (_, _, e: Upload.Error.HttpError)) :: _
1104+
if isSonatype && errors.distinctBy(_._3.getMessage()).size == 1 =>
1105+
val httpCodeRegex = "HTTP (\\d+)\n.*".r
1106+
e.getMessage() match {
1107+
case httpCodeRegex("403") =>
1108+
logger.error(
1109+
s"""
1110+
|Uploading files failed!
1111+
|Possible causes:
1112+
|- no rights to push to under this organization or organization name is misspelled
1113+
| -> have you registered your organisation yet?
1114+
|""".stripMargin
1115+
)
1116+
case _ => throw new UploadError(::(h, Nil))
1117+
}
1118+
case _ :: _ if isSonatype && errors.forall {
1119+
case (_, _, _: Upload.Error.Unauthorized) => true
1120+
case _ => false
1121+
} =>
1122+
logger.error(
1123+
s"""
1124+
|Uploading files failed!
1125+
|Possible causes:
1126+
|- incorrect Sonatype credentials
1127+
|- your Sonatype password or username may contain unsupported characters
1128+
|- incorrect Sonatype server was used (legacy or s01)
1129+
| -> consult publish subcommand documentation
1130+
|""".stripMargin
1131+
)
10901132
case h :: t =>
10911133
value(Left(new UploadError(::(h, t))))
10921134
case Nil =>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package scala.cli.errors
2+
3+
import scala.build.errors.BuildException
4+
5+
final class InvalidPublishCredentials
6+
extends BuildException(
7+
"Username or password to the publish repository is invalid"
8+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package scala.cli.errors
2+
3+
import scala.build.errors.BuildException
4+
5+
final class WrongSonatypeServerError
6+
extends BuildException(
7+
"Make sure you're publishing to the right Sonatype server: legacy 'central' or new 'central-s01'"
8+
)

0 commit comments

Comments
 (0)