@@ -267,7 +267,8 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
267267 isCi = options.publishParams.isCi,
268268 () => configDb,
269269 options.mainClass,
270- dummy = options.sharedPublish.dummy
270+ dummy = options.sharedPublish.dummy,
271+ buildTests = options.sharedPublish.scope.test
271272 )
272273 }
273274
@@ -289,25 +290,26 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
289290 isCi : Boolean ,
290291 configDb : () => ConfigDb ,
291292 mainClassOptions : MainClassOptions ,
292- dummy : Boolean
293+ dummy : Boolean ,
294+ buildTests : Boolean
293295 ): Unit = {
294296
295297 val actionableDiagnostics = configDb().get(Keys .actions).getOrElse(None )
296298
297- if ( watch) {
299+ if watch then {
298300 val watcher = Build .watch(
299301 inputs,
300302 initialBuildOptions,
301303 compilerMaker,
302304 docCompilerMaker,
303305 logger,
304306 crossBuilds = cross,
305- buildTests = false ,
307+ buildTests = buildTests ,
306308 partial = None ,
307309 actionableDiagnostics = actionableDiagnostics,
308310 postAction = () => WatchUtil .printWatchMessage()
309- ) { res =>
310- res .orReport(logger).foreach { builds =>
311+ ) {
312+ _ .orReport(logger).foreach { builds =>
311313 maybePublish(
312314 builds,
313315 workingDir,
@@ -336,7 +338,7 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
336338 docCompilerMaker,
337339 logger,
338340 crossBuilds = cross,
339- buildTests = false ,
341+ buildTests = buildTests ,
340342 partial = None ,
341343 actionableDiagnostics = actionableDiagnostics
342344 ).orExit(logger)
@@ -384,14 +386,14 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
384386 name
385387 }
386388
387- def defaultComputeVersion (mayDefaultToGitTag : Boolean ): Option [ComputeVersion ] =
389+ private def defaultComputeVersion (mayDefaultToGitTag : Boolean ): Option [ComputeVersion ] =
388390 if (mayDefaultToGitTag) Some (ComputeVersion .GitTag (os.rel, dynVer = false , positions = Nil ))
389391 else None
390392
391- def defaultVersionError =
393+ private def defaultVersionError =
392394 new MissingPublishOptionError (" version" , " --project-version" , " publish.version" )
393395
394- def defaultVersion : Either [BuildException , String ] =
396+ private def defaultVersion : Either [BuildException , String ] =
395397 Left (defaultVersionError)
396398
397399 /** Check if all builds are successful and proceed with preparing files to be uploaded OR print
@@ -422,17 +424,20 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
422424 case _ : Build .Cancelled => true
423425 case _ : Build .Failed => false
424426 }
425- if ( allOk && allDocsOk) {
427+ if allOk && allDocsOk then {
426428 val builds0 = builds.all.collect {
427429 case s : Build .Successful => s
428430 }
429431 val docBuilds0 = builds.allDoc.collect {
430432 case s : Build .Successful => s
431433 }
432434 val res : Either [BuildException , Unit ] =
433- builds.main match {
434- case s : Build .Successful if mainClassOptions.mainClassLs.contains(true ) =>
435- mainClassOptions.maybePrintMainClasses(s.foundMainClasses(), shouldExit = allowExit)
435+ builds.builds match {
436+ case b if b.forall(_.success) && mainClassOptions.mainClassLs.contains(true ) =>
437+ mainClassOptions.maybePrintMainClasses(
438+ builds0.flatMap(_.foundMainClasses()).distinct,
439+ shouldExit = allowExit
440+ )
436441 case _ => prepareFilesAndUpload(
437442 builds0,
438443 docBuilds0,
@@ -447,16 +452,12 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
447452 dummy
448453 )
449454 }
450- if (allowExit)
451- res.orExit(logger)
452- else
453- res.orReport(logger)
455+ if allowExit then res.orExit(logger) else res.orReport(logger)
454456 }
455457 else {
456- val msg = if ( allOk) " Scaladoc generation failed" else " Compilation failed"
458+ val msg = if allOk then " Scaladoc generation failed" else " Compilation failed"
457459 System .err.println(msg)
458- if (allowExit)
459- sys.exit(1 )
460+ if allowExit then sys.exit(1 )
460461 }
461462 }
462463
@@ -529,8 +530,8 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
529530 }
530531
531532 private def buildFileSet (
532- build : Build .Successful ,
533- docBuildOpt : Option [Build .Successful ],
533+ builds : Seq [ Build .Successful ] ,
534+ docBuilds : Seq [Build .Successful ],
534535 workingDir : os.Path ,
535536 now : Instant ,
536537 isIvy2LocalLike : Boolean ,
@@ -539,41 +540,56 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
539540 logger : Logger
540541 ): Either [BuildException , (FileSet , (coursier.core.Module , String ))] = either {
541542
542- logger.debug(s " Preparing project ${build .project.projectName}" )
543+ logger.debug(s " Preparing project ${builds.head .project.projectName}" )
543544
544- val publishOptions = build .options.notForBloopOptions.publishOptions
545+ val publishOptions = builds.head .options.notForBloopOptions.publishOptions
545546
546547 val (org, moduleName, ver) = value {
547548 orgNameVersion(
548549 publishOptions,
549- build .inputs.workspace,
550+ builds.head .inputs.workspace,
550551 logger,
551- build .artifacts.scalaOpt,
552+ builds.head .artifacts.scalaOpt,
552553 isCi
553554 )
554555 }
555556
556557 logger.message(s " Publishing $org: $moduleName: $ver" )
557558
558559 val mainJar = {
559- val mainClassOpt = build.options.mainClass.orElse {
560- build.retainedMainClass(logger) match {
561- case Left (_ : NoMainClassFoundError ) => None
562- case Left (err) =>
563- logger.debug(s " Error while looking for main class: $err" )
564- None
565- case Right (cls) => Some (cls)
566- }
567- }
568- val libraryJar = Library .libraryJar(Seq (build), mainClassOpt)
560+ val mainClassOpt : Option [String ] =
561+ (builds.head.options.mainClass.filter(_.nonEmpty) match {
562+ case Some (cls) => Right (cls)
563+ case None =>
564+ val potentialMainClasses = builds.flatMap(_.foundMainClasses()).distinct
565+ builds
566+ .map { build =>
567+ build.retainedMainClass(logger, potentialMainClasses)
568+ .map(mainClass => build.scope -> mainClass)
569+ }
570+ .sequence
571+ .left
572+ .map(CompositeBuildException (_))
573+ .map(_.toMap)
574+ .map { retainedMainClassesByScope =>
575+ if retainedMainClassesByScope.size == 1 then retainedMainClassesByScope.head._2
576+ else
577+ retainedMainClassesByScope
578+ .get(Scope .Main )
579+ .orElse(retainedMainClassesByScope.get(Scope .Test ))
580+ .get
581+ }
582+
583+ }).toOption
584+ val libraryJar = Library .libraryJar(builds, mainClassOpt)
569585 val dest = workingDir / org / s " $moduleName- $ver.jar "
570586 os.copy.over(libraryJar, dest, createFolders = true )
571587 dest
572588 }
573589
574590 val sourceJarOpt =
575591 if publishOptions.contextual(isCi).sourceJar.getOrElse(true ) then {
576- val content = PackageCmd .sourceJar(Seq (build) , now.toEpochMilli)
592+ val content = PackageCmd .sourceJar(builds , now.toEpochMilli)
577593 val sourceJar = workingDir / org / s " $moduleName- $ver-sources.jar "
578594 os.write.over(sourceJar, content, createFolders = true )
579595 Some (sourceJar)
@@ -582,25 +598,27 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
582598
583599 val docJarOpt =
584600 if publishOptions.contextual(isCi).docJar.getOrElse(true ) then
585- docBuildOpt match {
586- case None => None
587- case Some (docBuild) =>
588- val docJarPath = value(PackageCmd .docJar(Seq (docBuild) , logger, Nil ))
601+ docBuilds match {
602+ case Nil => None
603+ case docBuilds =>
604+ val docJarPath = value(PackageCmd .docJar(docBuilds , logger, Nil ))
589605 val docJar = workingDir / org / s " $moduleName- $ver-javadoc.jar "
590606 os.copy.over(docJarPath, docJar, createFolders = true )
591607 Some (docJar)
592608 }
593609 else None
594610
595- val dependencies = build. artifacts.userDependencies
596- .map(_.toCs(build .artifacts.scalaOpt.map(_.params)))
611+ val dependencies = builds.flatMap(_. artifacts.userDependencies)
612+ .map(_.toCs(builds.head .artifacts.scalaOpt.map(_.params)))
597613 .sequence
598614 .left.map(CompositeBuildException (_))
599615 .orExit(logger)
600616 .map { dep0 =>
601617 val config =
602- if (build.scope == Scope .Main ) None
603- else Some (Configuration (build.scope.name))
618+ builds -> builds.length match {
619+ case (b, 1 ) if b.head.scope != Scope .Main => Some (Configuration (b.head.scope.name))
620+ case _ => None
621+ }
604622 (dep0.module.organization, dep0.module.name, dep0.version, config, dep0.minimizedExclusions)
605623 }
606624 val url = publishOptions.url.map(_.value)
@@ -629,20 +647,20 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
629647 developers = developers
630648 )
631649
632- if ( isSonatype) {
633- if ( url.isEmpty)
650+ if isSonatype then {
651+ if url.isEmpty then
634652 logger.diagnostic(
635653 " Publishing to Sonatype, but project URL is empty (set it with the '//> using publish.url' directive)."
636654 )
637- if ( license.isEmpty)
655+ if license.isEmpty then
638656 logger.diagnostic(
639657 " Publishing to Sonatype, but license is empty (set it with the '//> using publish.license' directive)."
640658 )
641- if ( scm.isEmpty)
659+ if scm.isEmpty then
642660 logger.diagnostic(
643661 " Publishing to Sonatype, but SCM details are empty (set them with the '//> using publish.scm' directive)."
644662 )
645- if ( developers.isEmpty)
663+ if developers.isEmpty then
646664 logger.diagnostic(
647665 " Publishing to Sonatype, but developer details are empty (set them with the '//> using publish.developer' directive)."
648666 )
@@ -754,10 +772,7 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
754772
755773 assert(docBuilds.isEmpty || docBuilds.length == builds.length)
756774
757- val it = builds.iterator.zip {
758- if (docBuilds.isEmpty) Iterator .continually(None )
759- else docBuilds.iterator.map(Some (_))
760- }
775+ val it = Iterator (builds -> docBuilds)
761776
762777 val publishOptions = ConfigMonoid .sum(
763778 builds.map(_.options.notForBloopOptions.publishOptions)
@@ -815,8 +830,7 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
815830 lazy val es =
816831 Executors .newSingleThreadScheduledExecutor(Util .daemonThreadFactory(" publish-retry" ))
817832
818- if (publishLocal)
819- RepoParams .ivy2Local(ivy2HomeOpt)
833+ if publishLocal then RepoParams .ivy2Local(ivy2HomeOpt)
820834 else
821835 value {
822836 publishOptions.contextual(isCi).repository match {
@@ -854,13 +868,11 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
854868 val now = Instant .now()
855869 val (fileSet0, modVersionOpt) = value {
856870 it
857- // TODO Allow to add test JARs to the main build artifacts
858- .filter(_._1.scope != Scope .Test )
859871 .map {
860- case (build, docBuildOpt ) =>
872+ case (builds, docBuilds ) =>
861873 buildFileSet(
862- build ,
863- docBuildOpt ,
874+ builds ,
875+ docBuilds ,
864876 workingDir,
865877 now,
866878 isIvy2LocalLike = repoParams.isIvy2LocalLike,
@@ -1170,17 +1182,13 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
11701182 }
11711183 else url
11721184 }
1173- if (dummy)
1174- println(" \n \ud83d\udc40 You could have checked results at" )
1175- else
1176- println(" \n \ud83d\udc40 Check results at" )
1185+ if dummy then println(" \n \ud83d\udc40 You could have checked results at" )
1186+ else println(" \n \ud83d\udc40 Check results at" )
11771187 println(s " $path" )
11781188 for (targetRepo <- repoParams.targetRepoOpt if ! isSnapshot0) {
11791189 val url = targetRepo.stripSuffix(" /" ) + relPath
1180- if (dummy)
1181- println(" before they would have landed at" )
1182- else
1183- println(" before they land at" )
1190+ if dummy then println(" before they would have landed at" )
1191+ else println(" before they land at" )
11841192 println(s " $url" )
11851193 }
11861194 }
0 commit comments