Skip to content

Commit 71e118a

Browse files
authored
Support the --test flag with the doc sub-command (#3539)
1 parent dff00a6 commit 71e118a

File tree

13 files changed

+158
-106
lines changed

13 files changed

+158
-106
lines changed

modules/build/src/main/scala/scala/build/Build.scala

+6-1
Original file line numberDiff line numberDiff line change
@@ -385,9 +385,14 @@ object Build {
385385
)
386386
)
387387
val testOptions0 = extraTestOptions.orElse(testOptions)
388+
val isScala2 =
389+
value(testOptions0.scalaParams).exists(_.scalaVersion.startsWith("2."))
390+
val finalSources = if doc && isScala2 then
391+
testSources.withExtraSources(mainSources)
392+
else testSources
388393
doBuildScope(
389394
testOptions0,
390-
testSources,
395+
finalSources,
391396
Scope.Test,
392397
actualCompiler = actualCompiler
393398
)

modules/build/src/main/scala/scala/build/Sources.scala

+7
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ final case class Sources(
1919
buildOptions: BuildOptions
2020
) {
2121

22+
def withExtraSources(other: Sources): Sources =
23+
copy(
24+
paths = paths ++ other.paths,
25+
inMemory = inMemory ++ other.inMemory,
26+
resourceDirs = resourceDirs ++ other.resourceDirs
27+
)
28+
2229
def withVirtualDir(inputs: Inputs, scope: Scope, options: BuildOptions): Sources = {
2330

2431
val srcRootPath = inputs.generatedSrcRoot(scope)

modules/cli/src/main/scala/scala/cli/commands/doc/Doc.scala

+35-31
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import scala.build.compiler.{ScalaCompilerMaker, SimpleScalaCompilerMaker}
1212
import scala.build.errors.BuildException
1313
import scala.build.interactive.InteractiveFileOps
1414
import scala.build.internal.{Constants, Runner}
15-
import scala.build.options.BuildOptions
15+
import scala.build.options.{BuildOptions, Scope}
1616
import scala.cli.CurrentParams
1717
import scala.cli.commands.publish.ConfigUtil.*
1818
import scala.cli.commands.shared.{HelpCommandGroup, HelpGroup, SharedOptions}
@@ -52,33 +52,34 @@ object Doc extends ScalaCommand[DocOptions] {
5252
configDb.get(Keys.actions).getOrElse(None)
5353
)
5454

55-
val builds =
56-
Build.build(
57-
inputs,
58-
initialBuildOptions,
59-
compilerMaker,
60-
docCompilerMakerOpt,
61-
logger,
62-
crossBuilds = false,
63-
buildTests = false,
64-
partial = None,
65-
actionableDiagnostics = actionableDiagnostics
66-
)
67-
.orExit(logger)
68-
builds.main match {
69-
case s: Build.Successful =>
55+
val withTestScope = options.scope.test
56+
Build.build(
57+
inputs,
58+
initialBuildOptions,
59+
compilerMaker,
60+
docCompilerMakerOpt,
61+
logger,
62+
crossBuilds = false,
63+
buildTests = withTestScope,
64+
partial = None,
65+
actionableDiagnostics = actionableDiagnostics
66+
)
67+
.orExit(logger).docBuilds match {
68+
case b if b.forall(_.success) =>
69+
val successfulBuilds = b.collect { case s: Build.Successful => s }
7070
val res0 = doDoc(
7171
logger,
7272
options.output.filter(_.nonEmpty),
7373
options.force,
74-
s,
75-
args.unparsed
74+
successfulBuilds,
75+
args.unparsed,
76+
withTestScope
7677
)
7778
res0.orExit(logger)
78-
case _: Build.Failed =>
79+
case b if b.exists(bb => !bb.success && !bb.cancelled) =>
7980
System.err.println("Compilation failed")
8081
sys.exit(1)
81-
case _: Build.Cancelled =>
82+
case _ =>
8283
System.err.println("Build cancelled")
8384
sys.exit(1)
8485
}
@@ -88,8 +89,9 @@ object Doc extends ScalaCommand[DocOptions] {
8889
logger: Logger,
8990
outputOpt: Option[String],
9091
force: Boolean,
91-
build: Build.Successful,
92-
extraArgs: Seq[String]
92+
builds: Seq[Build.Successful],
93+
extraArgs: Seq[String],
94+
withTestScope: Boolean
9395
): Either[BuildException, Unit] = either {
9496

9597
def defaultName = "scala-doc"
@@ -101,7 +103,7 @@ object Doc extends ScalaCommand[DocOptions] {
101103
def alreadyExistsCheck(): Either[BuildException, Unit] = {
102104
val alreadyExists = !force && os.exists(destPath)
103105
if (alreadyExists)
104-
build.options.interactive.map { interactive =>
106+
builds.head.options.interactive.map { interactive =>
105107
InteractiveFileOps.erasingPath(interactive, printableDest, destPath) { () =>
106108
val msg = s"$printableDest already exists"
107109
System.err.println(s"Error: $msg. Pass -f or --force to force erasing it.")
@@ -114,10 +116,9 @@ object Doc extends ScalaCommand[DocOptions] {
114116

115117
value(alreadyExistsCheck())
116118

117-
val docJarPath = value(generateScaladocDirPath(Seq(build), logger, extraArgs))
119+
val docJarPath = value(generateScaladocDirPath(builds, logger, extraArgs, withTestScope))
118120
value(alreadyExistsCheck())
119-
if (force) os.copy.over(docJarPath, destPath)
120-
else os.copy(docJarPath, destPath)
121+
if force then os.copy.over(docJarPath, destPath) else os.copy(docJarPath, destPath)
121122

122123
val printableOutput = CommandUtils.printablePath(destPath)
123124

@@ -138,12 +139,15 @@ object Doc extends ScalaCommand[DocOptions] {
138139
def generateScaladocDirPath(
139140
builds: Seq[Build.Successful],
140141
logger: Logger,
141-
extraArgs: Seq[String]
142+
extraArgs: Seq[String],
143+
withTestScope: Boolean
142144
): Either[BuildException, os.Path] = either {
143-
val docContentDir = builds.head.scalaParams match {
144-
case Some(scalaParams) if scalaParams.scalaVersion.startsWith("2.") =>
145-
builds.head.project.scaladocDir
146-
case Some(scalaParams) =>
145+
val docContentDir = builds.head.scalaParams
146+
.map(sp => sp -> sp.scalaVersion.startsWith("2.")) match {
147+
case Some((_, true)) if withTestScope =>
148+
builds.find(_.scope == Scope.Test).getOrElse(builds.head).project.scaladocDir
149+
case Some((_, true)) => builds.head.project.scaladocDir
150+
case Some((scalaParams, _)) =>
147151
val res = value {
148152
Artifacts.fetchAnyDependencies(
149153
Seq(Positioned.none(dep"org.scala-lang::scaladoc:${scalaParams.scalaVersion}")),

modules/cli/src/main/scala/scala/cli/commands/doc/DocOptions.scala

+9-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ import caseapp.*
44
import caseapp.core.help.Help
55

66
import scala.cli.ScalaCli.fullRunnerName
7-
import scala.cli.commands.shared.{HasSharedOptions, HelpGroup, HelpMessages, SharedOptions}
7+
import scala.cli.commands.shared.{
8+
HasSharedOptions,
9+
HelpGroup,
10+
HelpMessages,
11+
ScopeOptions,
12+
SharedOptions
13+
}
814
import scala.cli.commands.tags
915

1016
// format: off
@@ -27,6 +33,8 @@ final case class DocOptions(
2733
@Tag(tags.should)
2834
@ExtraName("defaultScaladocOpts")
2935
defaultScaladocOptions: Option[Boolean] = None,
36+
@Recurse
37+
scope: ScopeOptions = ScopeOptions()
3038
) extends HasSharedOptions
3139
// format: on
3240

modules/cli/src/main/scala/scala/cli/commands/package0/Package.scala

+14-9
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
8787
configDb.get(Keys.actions).getOrElse(None)
8888
)
8989

90-
if (options.watch.watchMode) {
90+
val withTestScope = options.scope.test
91+
if options.watch.watchMode then {
9192
var expectedModifyEpochSecondOpt = Option.empty[Long]
9293
val watcher = Build.watch(
9394
inputs,
@@ -96,7 +97,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
9697
docCompilerMakerOpt,
9798
logger,
9899
crossBuilds = cross,
99-
buildTests = options.scope.test,
100+
buildTests = withTestScope,
100101
partial = None,
101102
actionableDiagnostics = actionableDiagnostics,
102103
postAction = () => WatchUtil.printWatchMessage()
@@ -114,7 +115,8 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
114115
extraArgs = args.unparsed,
115116
expectedModifyEpochSecondOpt = expectedModifyEpochSecondOpt,
116117
allowTerminate = !options.watch.watchMode,
117-
mainClassOptions = options.mainClass
118+
mainClassOptions = options.mainClass,
119+
withTestScope = withTestScope
118120
)
119121
.orReport(logger)
120122
for (valueOpt <- mtimeDestPath)
@@ -135,7 +137,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
135137
docCompilerMakerOpt,
136138
logger,
137139
crossBuilds = cross,
138-
buildTests = options.scope.test,
140+
buildTests = withTestScope,
139141
partial = None,
140142
actionableDiagnostics = actionableDiagnostics
141143
)
@@ -153,7 +155,8 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
153155
extraArgs = args.unparsed,
154156
expectedModifyEpochSecondOpt = None,
155157
allowTerminate = !options.watch.watchMode,
156-
mainClassOptions = options.mainClass
158+
mainClassOptions = options.mainClass,
159+
withTestScope = withTestScope
157160
)
158161
res0.orExit(logger)
159162
case b if b.exists(bb => !bb.success && !bb.cancelled) =>
@@ -189,7 +192,8 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
189192
extraArgs: Seq[String],
190193
expectedModifyEpochSecondOpt: Option[Long],
191194
allowTerminate: Boolean,
192-
mainClassOptions: MainClassOptions
195+
mainClassOptions: MainClassOptions,
196+
withTestScope: Boolean
193197
): Either[BuildException, Option[Long]] = either {
194198
if mainClassOptions.mainClassLs.contains(true) then
195199
value {
@@ -349,7 +353,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
349353
else os.write(destPath, content, createFolders = true)
350354
destPath
351355
case PackageType.DocJar =>
352-
val docJarPath = value(docJar(builds, logger, extraArgs))
356+
val docJarPath = value(docJar(builds, logger, extraArgs, withTestScope))
353357
value(alreadyExistsCheck())
354358
if force then os.copy.over(docJarPath, destPath, createFolders = true)
355359
else os.copy(docJarPath, destPath, createFolders = true)
@@ -547,7 +551,8 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
547551
def docJar(
548552
builds: Seq[Build.Successful],
549553
logger: Logger,
550-
extraArgs: Seq[String]
554+
extraArgs: Seq[String],
555+
withTestScope: Boolean
551556
): Either[BuildException, os.Path] = either {
552557

553558
val workDir = builds.head.inputs.docJarWorkDir
@@ -562,7 +567,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
562567

563568
if cacheData.changed then {
564569

565-
val contentDir = value(Doc.generateScaladocDirPath(builds, logger, extraArgs))
570+
val contentDir = value(Doc.generateScaladocDirPath(builds, logger, extraArgs, withTestScope))
566571

567572
var outputStream: OutputStream = null
568573
try {

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

+7-2
Original file line numberDiff line numberDiff line change
@@ -585,8 +585,13 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
585585
docBuildOpt match {
586586
case None => None
587587
case Some(docBuild) =>
588-
val docJarPath = value(PackageCmd.docJar(Seq(docBuild), logger, Nil))
589-
val docJar = workingDir / org / s"$moduleName-$ver-javadoc.jar"
588+
val docJarPath = value(PackageCmd.docJar(
589+
builds = Seq(docBuild),
590+
logger = logger,
591+
extraArgs = Nil,
592+
withTestScope = false
593+
))
594+
val docJar = workingDir / org / s"$moduleName-$ver-javadoc.jar"
590595
os.copy.over(docJarPath, docJar, createFolders = true)
591596
Some(docJar)
592597
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package scala.build.errors
2+
3+
final class NoDocBuildError extends BuildException(
4+
"Doc build not present. It may have been cancelled."
5+
)

0 commit comments

Comments
 (0)