Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
MaciejG604 committed Oct 3, 2023
1 parent 032cda8 commit cc73322
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import scala.cli.commands.shared.{
}
import scala.cli.commands.util.{BuildCommandHelpers, ScalaCliSttpBackend}
import scala.cli.commands.{ScalaCommand, SpecificationLevel, WatchUtil}
import scala.concurrent.duration.DurationInt
import scala.cli.config.{ConfigDb, Keys, PasswordOption, PublishCredentials}
import scala.cli.errors.{
FailedToSignFileError,
Expand Down Expand Up @@ -91,6 +92,7 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
sharedPublish: SharedPublishOptions,
publishRepo: PublishRepositoryOptions,
scalaSigning: PgpScalaSigningOptions,
publishConnection: PublishConnectionOptions,
mainClass: MainClassOptions,
ivy2LocalLike: Option[Boolean]
): Either[BuildException, BuildOptions] = either {
Expand Down Expand Up @@ -122,7 +124,12 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
val input = sharedPublish.checksum.flatMap(_.split(",")).map(_.trim).filter(_.nonEmpty)
if (input.isEmpty) None
else Some(input)
}
},
connectionTimeoutRetries = publishConnection.connectionTimeoutRetries,
connectionTimeoutSeconds = publishConnection.connectionTimeoutSeconds,
responseTimeoutSeconds = publishConnection.responseTimeoutSeconds,
stagingRepoRetries = publishConnection.stagingRepoRetries,
stagingRepoWaitTimeMilis = publishConnection.stagingRepoWaitTimeMilis
)
baseOptions.copy(
mainClass = mainClass.mainClass.filter(_.nonEmpty),
Expand Down Expand Up @@ -212,6 +219,7 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
options.sharedPublish,
options.publishRepo,
options.signingCli,
options.connectionOptions,
options.mainClass,
options.ivy2LocalLike
).orExit(logger)
Expand Down Expand Up @@ -819,7 +827,11 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
ivy2HomeOpt,
publishOptions.contextual(isCi).repositoryIsIvy2LocalLike.getOrElse(false),
es,
logger
logger,
publishOptions.contextual(isCi).connectionTimeoutRetries,
publishOptions.contextual(isCi).connectionTimeoutSeconds,
publishOptions.contextual(isCi).stagingRepoRetries,
publishOptions.contextual(isCi).stagingRepoWaitTimeMilis
)
}
}
Expand Down Expand Up @@ -1043,7 +1055,12 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {

val baseUpload =
if (retainedRepo.root.startsWith("http://") || retainedRepo.root.startsWith("https://"))
HttpURLConnectionUpload.create()
HttpURLConnectionUpload.create(
publishOptions.contextual(isCi)
.connectionTimeoutSeconds.map(_.seconds.toMillis.toInt),
publishOptions.contextual(isCi)
.responseTimeoutSeconds.map(_.seconds.toMillis.toInt)
)
else
FileUpload(Paths.get(new URI(retainedRepo.root)))

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package scala.cli.commands.publish

import caseapp.*

import scala.cli.commands.shared.{HelpGroup, SharedVersionOptions}
import scala.cli.commands.tags

// format: off
final case class PublishConnectionOptions(
@Group(HelpGroup.Publishing.toString)
@HelpMessage("Connection timeout, in seconds.")
@Tag(tags.restricted)
@Hidden
connectionTimeoutSeconds: Option[Int] = None,

@Group(HelpGroup.Publishing.toString)
@HelpMessage("How many times to retry establishing the connection on timeout.")
@Tag(tags.restricted)
@Hidden
connectionTimeoutRetries: Option[Int] = None,

@Group(HelpGroup.Publishing.toString)
@HelpMessage("Waiting for response timeout, in seconds.")
@Tag(tags.restricted)
@Hidden
responseTimeoutSeconds: Option[Int] = None,

@Group(HelpGroup.Publishing.toString)
@HelpMessage("How many times to retry the staging repository operations on failure.")
@Tag(tags.restricted)
@Hidden
stagingRepoRetries: Option[Int] = None,

@Group(HelpGroup.Publishing.toString)
@HelpMessage("Time to wait between staging repository operation retries, in milliseconds.")
@Tag(tags.restricted)
@Hidden
stagingRepoWaitTimeMilis: Option[Int] = None
) {
// format: on
}

object PublishConnectionOptions {
implicit lazy val parser: Parser[PublishConnectionOptions] = Parser.derive
implicit lazy val help: Help[PublishConnectionOptions] = Help.derive
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ object PublishLocal extends ScalaCommand[PublishLocalOptions] {
options.sharedPublish,
PublishRepositoryOptions(),
options.scalaSigning,
PublishConnectionOptions(),
options.mainClass,
None
).orExit(logger)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ final case class PublishOptions(
sharedPublish: SharedPublishOptions = SharedPublishOptions(),
@Recurse
signingCli: PgpScalaSigningOptions = PgpScalaSigningOptions(),
@Recurse
connectionOptions: PublishConnectionOptions = PublishConnectionOptions(),

@Group(HelpGroup.Publishing.toString)
@Tag(tags.restricted)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package scala.cli.commands.publish
import coursier.core.Authentication
import coursier.maven.MavenRepository
import coursier.publish.sonatype.SonatypeApi
import coursier.publish.util.EmaRetryParams
import coursier.publish.{Hooks, PublishRepository}

import java.util.concurrent.ScheduledExecutorService

import scala.build.EitherCps.{either, value}
import scala.build.Logger
import scala.build.errors.BuildException
Expand Down Expand Up @@ -50,15 +50,35 @@ object RepoParams {
ivy2HomeOpt: Option[os.Path],
isIvy2LocalLike: Boolean,
es: ScheduledExecutorService,
logger: Logger
logger: Logger,
connectionTimeoutRetries: Option[Int] = None,
connectionTimeoutSeconds: Option[Int] = None,
stagingRepoRetries: Option[Int] = None,
stagingRepoWaitTimeMilis: Option[Int] = None
): Either[BuildException, RepoParams] = either {
repo match {
case "ivy2-local" =>
RepoParams.ivy2Local(ivy2HomeOpt)
case "sonatype" | "central" | "maven-central" | "mvn-central" =>
RepoParams.centralRepo("https://oss.sonatype.org", es, logger)
RepoParams.centralRepo(
"https://oss.sonatype.org",
connectionTimeoutRetries,
connectionTimeoutSeconds,
stagingRepoRetries,
stagingRepoWaitTimeMilis,
es,
logger
)
case "sonatype-s01" | "central-s01" | "maven-central-s01" | "mvn-central-s01" =>
RepoParams.centralRepo("https://s01.oss.sonatype.org", es, logger)
RepoParams.centralRepo(
"https://s01.oss.sonatype.org",
connectionTimeoutRetries,
connectionTimeoutSeconds,
stagingRepoRetries,
stagingRepoWaitTimeMilis,
es,
logger
)
case "github" =>
value(RepoParams.gitHubRepo(vcsUrlOpt, workspace, logger))
case repoStr if repoStr.startsWith("github:") && repoStr.count(_ == '/') == 1 =>
Expand Down Expand Up @@ -89,10 +109,29 @@ object RepoParams {
}
}

def centralRepo(base: String, es: ScheduledExecutorService, logger: Logger) = {
def centralRepo(
base: String,
connectionTimeoutRetries: Option[Int],
connectionTimeoutSeconds: Option[Int],
stagingRepoRetries: Option[Int],
stagingRepoWaitTimeMilis: Option[Int],
es: ScheduledExecutorService,
logger: Logger
) = {
val repo0 = PublishRepository.Sonatype(MavenRepository(base))
val backend = ScalaCliSttpBackend.httpURLConnection(logger)
val api = SonatypeApi(backend, base + "/service/local", None, logger.verbosity)
val backend = ScalaCliSttpBackend.httpURLConnection(logger, connectionTimeoutSeconds)
val api = SonatypeApi(
backend,
base + "/service/local",
None,
logger.verbosity,
retryOnTimeout = connectionTimeoutRetries.getOrElse(3),
stagingRepoRetryParams = EmaRetryParams(
stagingRepoRetries.getOrElse(3),
stagingRepoWaitTimeMilis.getOrElse(10 * 1000),
2.0f
)
)
val hooks0 = Hooks.sonatype(
repo0,
api,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package scala.cli.commands.util

import sttp.capabilities.Effect
import sttp.client3._
import sttp.client3.*
import sttp.monad.MonadError

import scala.build.Logger
import scala.concurrent.duration
import scala.concurrent.duration.FiniteDuration
import scala.util.Try

class ScalaCliSttpBackend(
Expand Down Expand Up @@ -38,9 +40,14 @@ class ScalaCliSttpBackend(
}

object ScalaCliSttpBackend {
def httpURLConnection(logger: Logger): ScalaCliSttpBackend =
def httpURLConnection(logger: Logger, timeoutSeconds: Option[Int] = None): ScalaCliSttpBackend =
new ScalaCliSttpBackend(
HttpURLConnectionBackend(),
HttpURLConnectionBackend(
options = timeoutSeconds
.fold(SttpBackendOptions.Default)(t =>
SttpBackendOptions.connectionTimeout(FiniteDuration(t, duration.SECONDS))
)
),
logger
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ final case class PublishContextualOptions(
repoPassword: Option[PasswordOption] = None,
repoRealm: Option[String] = None,
computeVersion: Option[ComputeVersion] = None,
checksums: Option[Seq[String]] = None
checksums: Option[Seq[String]] = None,
connectionTimeoutRetries: Option[Int] = None,
connectionTimeoutSeconds: Option[Int] = None,
responseTimeoutSeconds: Option[Int] = None,
stagingRepoRetries: Option[Int] = None,
stagingRepoWaitTimeMilis: Option[Int] = None
)

object PublishContextualOptions {
Expand Down
33 changes: 33 additions & 0 deletions website/docs/reference/cli-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -2092,6 +2092,39 @@ Available in commands:
### `--key`

[Internal]
### Publish connection options

Available in commands:

[`publish`](./commands.md#publish)

<!-- Automatically generated, DO NOT EDIT MANUALLY -->

### `--connection-timeout-seconds`

[Internal]
Connection timeout, in seconds.

### `--connection-timeout-retries`

[Internal]
How many times to retry establishing the connection on timeout.

### `--response-timeout-seconds`

[Internal]
Waiting for response timeout, in seconds.

### `--staging-repo-retries`

[Internal]
How many times to retry the staging repository operations on failure.

### `--staging-repo-wait-time-milis`

[Internal]
Time to wait between staging repository operation retries, in milliseconds.

### Setup IDE options

Available in commands:
Expand Down
2 changes: 1 addition & 1 deletion website/docs/reference/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ The `publish` sub-command is experimental.
Please bear in mind that non-ideal user experience should be expected.
If you encounter any bugs or have feedback to share, make sure to reach out to the maintenance team at https://github.com/VirtusLab/scala-cli

Accepts option groups: [compilation server](./cli-options.md#compilation-server-options), [coursier](./cli-options.md#coursier-options), [cross](./cli-options.md#cross-options), [debug](./cli-options.md#debug-options), [dependency](./cli-options.md#dependency-options), [global suppress warning](./cli-options.md#global-suppress-warning-options), [help group](./cli-options.md#help-group-options), [input](./cli-options.md#input-options), [jvm](./cli-options.md#jvm-options), [logging](./cli-options.md#logging-options), [main class](./cli-options.md#main-class-options), [markdown](./cli-options.md#markdown-options), [pgp scala signing](./cli-options.md#pgp-scala-signing-options), [publish](./cli-options.md#publish-options), [publish params](./cli-options.md#publish-params-options), [publish repository](./cli-options.md#publish-repository-options), [python](./cli-options.md#python-options), [Scala.js](./cli-options.md#scalajs-options), [Scala Native](./cli-options.md#scala-native-options), [scalac](./cli-options.md#scalac-options), [scalac extra](./cli-options.md#scalac-extra-options), [shared](./cli-options.md#shared-options), [snippet](./cli-options.md#snippet-options), [source generator](./cli-options.md#source-generator-options), [suppress warning](./cli-options.md#suppress-warning-options), [verbosity](./cli-options.md#verbosity-options), [version](./cli-options.md#version-options), [watch](./cli-options.md#watch-options), [workspace](./cli-options.md#workspace-options)
Accepts option groups: [compilation server](./cli-options.md#compilation-server-options), [coursier](./cli-options.md#coursier-options), [cross](./cli-options.md#cross-options), [debug](./cli-options.md#debug-options), [dependency](./cli-options.md#dependency-options), [global suppress warning](./cli-options.md#global-suppress-warning-options), [help group](./cli-options.md#help-group-options), [input](./cli-options.md#input-options), [jvm](./cli-options.md#jvm-options), [logging](./cli-options.md#logging-options), [main class](./cli-options.md#main-class-options), [markdown](./cli-options.md#markdown-options), [pgp scala signing](./cli-options.md#pgp-scala-signing-options), [publish](./cli-options.md#publish-options), [publish connection](./cli-options.md#publish-connection-options), [publish params](./cli-options.md#publish-params-options), [publish repository](./cli-options.md#publish-repository-options), [python](./cli-options.md#python-options), [Scala.js](./cli-options.md#scalajs-options), [Scala Native](./cli-options.md#scala-native-options), [scalac](./cli-options.md#scalac-options), [scalac extra](./cli-options.md#scalac-extra-options), [shared](./cli-options.md#shared-options), [snippet](./cli-options.md#snippet-options), [source generator](./cli-options.md#source-generator-options), [suppress warning](./cli-options.md#suppress-warning-options), [verbosity](./cli-options.md#verbosity-options), [version](./cli-options.md#version-options), [watch](./cli-options.md#watch-options), [workspace](./cli-options.md#workspace-options)

## publish local

Expand Down

0 comments on commit cc73322

Please sign in to comment.