Skip to content

Commit 18ac25d

Browse files
Merge pull request #1087 from alexarchambault/tweaking
Tweaking
2 parents e46b73b + b98ea7c commit 18ac25d

File tree

24 files changed

+215
-101
lines changed

24 files changed

+215
-101
lines changed

build.sc

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,9 @@ object integration extends CliIntegration {
109109
PathRef(T.dest / "working-dir")
110110
}
111111
def forkEnv = super.forkEnv() ++ Seq(
112-
"SCALA_CLI_TMP" -> tmpDirBase().path.toString,
113-
"SCALA_CLI_IMAGE" -> "scala-cli",
114-
"CI" -> "1",
115-
"ACTUAL_CI" -> (if (System.getenv("CI") == null) "" else "1")
112+
"SCALA_CLI_TMP" -> tmpDirBase().path.toString,
113+
"SCALA_CLI_IMAGE" -> "scala-cli",
114+
"SCALA_CLI_PRINT_STACK_TRACES" -> "1"
116115
)
117116
}
118117
}
@@ -125,10 +124,9 @@ object integration extends CliIntegration {
125124
PathRef(T.dest / "working-dir")
126125
}
127126
def forkEnv = super.forkEnv() ++ Seq(
128-
"SCALA_CLI_TMP" -> tmpDirBase().path.toString,
129-
"SCALA_CLI_IMAGE" -> "scala-cli-slim",
130-
"CI" -> "1",
131-
"ACTUAL_CI" -> (if (System.getenv("CI") == null) "" else "1")
127+
"SCALA_CLI_TMP" -> tmpDirBase().path.toString,
128+
"SCALA_CLI_IMAGE" -> "scala-cli-slim",
129+
"SCALA_CLI_PRINT_STACK_TRACES" -> "1"
132130
)
133131
}
134132
}
@@ -632,15 +630,27 @@ trait Cli extends SbtModule with ProtoBuildModule with CliLaunchers
632630

633631
def defaultFilesResources = T.persistent {
634632
val dir = T.dest / "resources"
635-
val resources = Seq(
636-
"https://raw.githubusercontent.com/scala-cli/default-workflow/main/.github/workflows/ci.yml" -> (os.sub / "workflows" / "default.yml"),
637-
"https://raw.githubusercontent.com/scala-cli/default-workflow/main/.gitignore" -> (os.sub / "gitignore")
633+
def transformWorkflow(content: Array[Byte]): Array[Byte] =
634+
new String(content, "UTF-8")
635+
.replaceAll(" ./scala-cli", " scala-cli")
636+
.getBytes("UTF-8")
637+
val resources = Seq[(String, os.SubPath, Array[Byte] => Array[Byte])](
638+
(
639+
"https://raw.githubusercontent.com/scala-cli/default-workflow/main/.github/workflows/ci.yml",
640+
os.sub / "workflows" / "default.yml",
641+
transformWorkflow _
642+
),
643+
(
644+
"https://raw.githubusercontent.com/scala-cli/default-workflow/main/.gitignore",
645+
os.sub / "gitignore",
646+
identity
647+
)
638648
)
639-
for ((srcUrl, destRelPath) <- resources) {
649+
for ((srcUrl, destRelPath, transform) <- resources) {
640650
val dest = dir / defaultFilesResourcePath / destRelPath
641651
if (!os.isFile(dest)) {
642652
val content = Using.resource(new URL(srcUrl).openStream())(_.readAllBytes())
643-
os.write(dest, content, createFolders = true)
653+
os.write(dest, transform(content), createFolders = true)
644654
}
645655
}
646656
PathRef(dir)
@@ -766,9 +776,8 @@ trait CliIntegration extends SbtModule with ScalaCliPublishModule with HasTests
766776
Deps.jsoniterMacros
767777
)
768778
def forkEnv = super.forkEnv() ++ Seq(
769-
"SCALA_CLI_TMP" -> tmpDirBase().path.toString,
770-
"CI" -> "1",
771-
"ACTUAL_CI" -> (if (System.getenv("CI") == null) "" else "1")
779+
"SCALA_CLI_TMP" -> tmpDirBase().path.toString,
780+
"SCALA_CLI_PRINT_STACK_TRACES" -> "1"
772781
)
773782
private def updateRef(name: String, ref: PathRef): PathRef = {
774783
val rawPath = ref.path.toString.replace(

modules/build/src/test/scala/scala/build/tests/TestUtil.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ import munit.Assertions.assertEquals
66

77
object TestUtil {
88

9-
val isCI = Option(System.getenv("ACTUAL_CI")) match {
10-
case None => System.getenv("CI") != null
11-
case Some(value) => value.nonEmpty
12-
}
9+
val isCI = System.getenv("CI") != null
1310

1411
implicit class TestBuildOps(private val build: Build) extends AnyVal {
1512
private def successfulBuild: Build.Successful =

modules/cli-options/src/main/scala/scala/cli/commands/config/ConfigOptions.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ final case class ConfigOptions(
2424
@HelpMessage("If the entry is a password, print the password value rather than how to get the password")
2525
password: Boolean = false,
2626
@Group("Config")
27+
@HelpMessage("If the entry is a password, save the password value rather than how to get the password")
28+
passwordValue: Boolean = false,
29+
@Group("Config")
2730
@HelpMessage("Remove an entry from config")
2831
unset: Boolean = false
2932
)

modules/cli-options/src/main/scala/scala/cli/commands/publish/PublishOptions.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@ package scala.cli.commands.publish
22

33
import caseapp._
44

5-
import scala.cli.commands.{CompileCrossOptions, MainClassOptions, SharedOptions, SharedWatchOptions}
5+
import scala.cli.commands.{
6+
CompileCrossOptions,
7+
MainClassOptions,
8+
SharedDirectoriesOptions,
9+
SharedOptions,
10+
SharedWatchOptions
11+
}
612

713
// format: off
814
final case class PublishOptions(

modules/cli-options/src/main/scala/scala/cli/commands/publish/PublishParamsOptions.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ final case class PublishParamsOptions(
4242
developer: List[String] = Nil,
4343

4444
@Group("Publishing")
45-
@HelpMessage("Secret key to use to sign artifacts with BouncyCastle")
45+
@HelpMessage("Secret key to use to sign artifacts with Bouncy Castle")
4646
secretKey: Option[PasswordOption] = None,
4747

4848
@Group("Publishing")
49-
@HelpMessage("Password of secret key to use to sign artifacts with BouncyCastle")
49+
@HelpMessage("Password of secret key to use to sign artifacts with Bouncy Castle")
5050
@ValueDescription("value:…")
5151
@ExtraName("secretKeyPass")
5252
secretKeyPassword: Option[PasswordOption] = None

modules/cli/src/main/scala/scala/cli/ScalaCli.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import sun.misc.{Signal, SignalHandler}
55

66
import java.io.{ByteArrayOutputStream, File, PrintStream}
77
import java.nio.charset.StandardCharsets
8+
import java.util.Locale
89

910
import scala.build.blooprifle.FailedToStartServerException
1011
import scala.build.internal.Constants
@@ -57,6 +58,12 @@ object ScalaCli {
5758
}
5859

5960
private def isCI = System.getenv("CI") != null
61+
private def printStackTraces = Option(System.getenv("SCALA_CLI_PRINT_STACK_TRACES"))
62+
.map(_.toLowerCase(Locale.ROOT))
63+
.exists {
64+
case "true" | "1" => true
65+
case _ => false
66+
}
6067

6168
private def ignoreSigpipe(): Unit =
6269
Signal.handle(new Signal("PIPE"), SignalHandler.SIG_IGN)
@@ -73,7 +80,7 @@ object ScalaCli {
7380
def main(args: Array[String]): Unit =
7481
try main0(args)
7582
catch {
76-
case e: Throwable if !isCI =>
83+
case e: Throwable if !isCI && !printStackTraces =>
7784
val workspace = CurrentParams.workspaceOpt.getOrElse(os.pwd)
7885
val dir = workspace / Constants.workspaceDirName / "stacktraces"
7986
os.makeDir.all(dir)

modules/cli/src/main/scala/scala/cli/commands/config/Config.scala

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,21 @@ object Config extends ScalaCommand[ConfigOptions] {
9191
}
9292
}
9393
else {
94-
db.setFromString(entry, values).orExit(logger)
94+
val finalValues =
95+
if (options.passwordValue && entry.isPasswordOption)
96+
values.map { input =>
97+
PasswordOption.parse(input) match {
98+
case Left(err) =>
99+
System.err.println(err)
100+
sys.exit(1)
101+
case Right(passwordOption) =>
102+
PasswordOption.Value(passwordOption.get()).asString.value
103+
}
104+
}
105+
else
106+
values
107+
108+
db.setFromString(entry, finalValues).orExit(logger)
95109
db.save(directories)
96110
}
97111
}

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

Lines changed: 68 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import scala.build.options.{BuildOptions, ConfigMonoid, Scope}
3434
import scala.cli.CurrentParams
3535
import scala.cli.commands.pgp.PgpExternalCommand
3636
import scala.cli.commands.publish.{PublishParamsOptions, PublishRepositoryOptions}
37+
import scala.cli.commands.util.CommonOps.SharedDirectoriesOptionsOps
3738
import scala.cli.commands.util.ScalaCliSttpBackend
3839
import scala.cli.commands.util.SharedOptionsUtil._
3940
import scala.cli.commands.{
@@ -43,6 +44,7 @@ import scala.cli.commands.{
4344
SharedOptions,
4445
WatchUtil
4546
}
47+
import scala.cli.config.{ConfigDb, Keys}
4648
import scala.cli.errors.{
4749
FailedToSignFileError,
4850
MalformedChecksumsError,
@@ -162,6 +164,9 @@ object Publish extends ScalaCommand[PublishOptions] {
162164

163165
val cross = options.compileCross.cross.getOrElse(false)
164166

167+
lazy val configDb = ConfigDb.open(options.shared.directories.directories)
168+
.orExit(logger)
169+
165170
lazy val workingDir = options.sharedPublish.workingDir
166171
.filter(_.trim.nonEmpty)
167172
.map(os.Path(_, os.pwd))
@@ -188,7 +193,8 @@ object Publish extends ScalaCommand[PublishOptions] {
188193
publishLocal = false,
189194
forceSigningBinary = options.sharedPublish.forceSigningBinary,
190195
parallelUpload = options.parallelUpload.getOrElse(true),
191-
options.watch.watch
196+
options.watch.watch,
197+
() => configDb
192198
)
193199
}
194200

@@ -204,7 +210,8 @@ object Publish extends ScalaCommand[PublishOptions] {
204210
publishLocal: Boolean,
205211
forceSigningBinary: Boolean,
206212
parallelUpload: Boolean,
207-
watch: Boolean
213+
watch: Boolean,
214+
configDb: () => ConfigDb
208215
): Unit = {
209216

210217
if (watch) {
@@ -228,7 +235,8 @@ object Publish extends ScalaCommand[PublishOptions] {
228235
logger,
229236
allowExit = false,
230237
forceSigningBinary = forceSigningBinary,
231-
parallelUpload = parallelUpload
238+
parallelUpload = parallelUpload,
239+
configDb
232240
)
233241
}
234242
}
@@ -255,7 +263,8 @@ object Publish extends ScalaCommand[PublishOptions] {
255263
logger,
256264
allowExit = true,
257265
forceSigningBinary = forceSigningBinary,
258-
parallelUpload = parallelUpload
266+
parallelUpload = parallelUpload,
267+
configDb
259268
)
260269
}
261270
}
@@ -275,7 +284,8 @@ object Publish extends ScalaCommand[PublishOptions] {
275284
logger: Logger,
276285
allowExit: Boolean,
277286
forceSigningBinary: Boolean,
278-
parallelUpload: Boolean
287+
parallelUpload: Boolean,
288+
configDb: () => ConfigDb
279289
): Unit = {
280290

281291
val allOk = builds.all.forall {
@@ -303,7 +313,8 @@ object Publish extends ScalaCommand[PublishOptions] {
303313
publishLocal,
304314
logger,
305315
forceSigningBinary,
306-
parallelUpload
316+
parallelUpload,
317+
configDb
307318
)
308319
if (allowExit)
309320
res.orExit(logger)
@@ -544,7 +555,8 @@ object Publish extends ScalaCommand[PublishOptions] {
544555
publishLocal: Boolean,
545556
logger: Logger,
546557
forceSigningBinary: Boolean,
547-
parallelUpload: Boolean
558+
parallelUpload: Boolean,
559+
configDb: () => ConfigDb
548560
): Either[BuildException, Unit] = either {
549561

550562
assert(docBuilds.isEmpty || docBuilds.length == builds.length)
@@ -565,23 +577,45 @@ object Publish extends ScalaCommand[PublishOptions] {
565577
lazy val es =
566578
Executors.newSingleThreadScheduledExecutor(Util.daemonThreadFactory("publish-retry"))
567579

568-
lazy val authOpt = {
569-
val passwordOpt = publishOptions.repoPassword.map(_.get())
570-
passwordOpt.map { password =>
571-
val userOpt = publishOptions.repoUser
572-
val realmOpt = publishOptions.repoRealm
573-
val auth = Authentication(userOpt.fold("")(_.get().value), password.value)
574-
realmOpt.fold(auth)(auth.withRealm)
580+
def authOpt(repo: String): Either[BuildException, Option[Authentication]] = either {
581+
val hostOpt = {
582+
val uri = new URI(repo)
583+
if (uri.getScheme == "https") Some(uri.getHost)
584+
else None
585+
}
586+
val isSonatype =
587+
hostOpt.exists(host => host == "oss.sonatype.org" || host.endsWith(".oss.sonatype.org"))
588+
val passwordOpt = publishOptions.repoPassword match {
589+
case None if isSonatype =>
590+
value(configDb().get(Keys.sonatypePassword))
591+
case other => other
592+
}
593+
passwordOpt.map(_.get()) match {
594+
case None => None
595+
case Some(password) =>
596+
val userOpt = publishOptions.repoUser match {
597+
case None if isSonatype =>
598+
value(configDb().get(Keys.sonatypeUser))
599+
case other => other
600+
}
601+
val realmOpt = publishOptions.repoRealm match {
602+
case None if isSonatype =>
603+
Some("Sonatype Nexus Repository Manager")
604+
case other => other
605+
}
606+
val auth = Authentication(userOpt.fold("")(_.get().value), password.value)
607+
Some(realmOpt.fold(auth)(auth.withRealm))
575608
}
576609
}
577610

578-
def centralRepo(base: String) = {
611+
def centralRepo(base: String) = either {
612+
val authOpt0 = value(authOpt(base))
579613
val repo0 = {
580614
val r = PublishRepository.Sonatype(MavenRepository(base))
581-
authOpt.fold(r)(r.withAuthentication)
615+
authOpt0.fold(r)(r.withAuthentication)
582616
}
583617
val backend = ScalaCliSttpBackend.httpURLConnection(logger)
584-
val api = SonatypeApi(backend, base + "/service/local", authOpt, logger.verbosity)
618+
val api = SonatypeApi(backend, base + "/service/local", authOpt0, logger.verbosity)
585619
val hooks0 = Hooks.sonatype(
586620
repo0,
587621
api,
@@ -618,22 +652,25 @@ object Publish extends ScalaCommand[PublishOptions] {
618652
case Some("ivy2-local") =>
619653
ivy2Local
620654
case Some("central" | "maven-central" | "mvn-central") =>
621-
centralRepo("https://oss.sonatype.org")
655+
value(centralRepo("https://oss.sonatype.org"))
622656
case Some("central-s01" | "maven-central-s01" | "mvn-central-s01") =>
623-
centralRepo("https://s01.oss.sonatype.org")
657+
value(centralRepo("https://s01.oss.sonatype.org"))
624658
case Some(repoStr) =>
625-
val repo0 = RepositoryParser.repositoryOpt(repoStr)
626-
.collect {
627-
case m: MavenRepository =>
628-
m
629-
}
630-
.getOrElse {
631-
val url =
632-
if (repoStr.contains("://")) repoStr
633-
else os.Path(repoStr, Os.pwd).toNIO.toUri.toASCIIString
634-
MavenRepository(url)
635-
}
636-
.withAuthentication(authOpt)
659+
val repo0 = {
660+
val r = RepositoryParser.repositoryOpt(repoStr)
661+
.collect {
662+
case m: MavenRepository =>
663+
m
664+
}
665+
.getOrElse {
666+
val url =
667+
if (repoStr.contains("://")) repoStr
668+
else os.Path(repoStr, Os.pwd).toNIO.toUri.toASCIIString
669+
MavenRepository(url)
670+
}
671+
r.withAuthentication(value(authOpt(r.root)))
672+
}
673+
637674
(
638675
PublishRepository.Simple(repo0),
639676
None,

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import scala.build.BuildThreads
66
import scala.cli.CurrentParams
77
import scala.cli.commands.ScalaCommand
88
import scala.cli.commands.util.SharedOptionsUtil._
9+
import scala.cli.config.ConfigDb
910

1011
object PublishLocal extends ScalaCommand[PublishLocalOptions] {
1112

@@ -67,7 +68,8 @@ object PublishLocal extends ScalaCommand[PublishLocalOptions] {
6768
publishLocal = true,
6869
forceSigningBinary = options.sharedPublish.forceSigningBinary,
6970
parallelUpload = true,
70-
options.watch.watch
71+
options.watch.watch,
72+
() => ConfigDb.empty // shouldn't be used, no need of repo credentials here
7173
)
7274
}
7375
}

0 commit comments

Comments
 (0)