Skip to content

Commit 319eb45

Browse files
committed
Force baseProjectName in InputsComposer
1 parent 4372de2 commit 319eb45

File tree

4 files changed

+93
-70
lines changed

4 files changed

+93
-70
lines changed

modules/build/src/main/scala/scala/build/input/InputsComposer.scala

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,80 +27,83 @@ object InputsComposer {
2727

2828
// TODO Check for module dependencies that do not exist
2929
private[input] def readAllModules(modules: Option[Value])
30-
: Either[BuildException, Seq[ModuleDefinition]] = modules match {
30+
: Either[BuildException, Seq[ModuleDefinition]] = modules match {
3131
case Some(Tbl(values)) => EitherSequence.sequence {
32-
values.toSeq.map(readModule)
33-
}.left.map(CompositeBuildException.apply)
32+
values.toSeq.map(readModule)
33+
}.left.map(CompositeBuildException.apply)
3434
case _ => Left(ModuleConfigurationError(s"$modules must exist and must be a table"))
3535
}
3636

3737
private def readModule(
3838
key: String,
3939
value: Value
40-
): Either[ModuleConfigurationError, ModuleDefinition] = {
40+
): Either[ModuleConfigurationError, ModuleDefinition] =
4141
value match
4242
case Tbl(values) =>
4343
val maybeRoots = values.get(Keys.roots).map {
44-
case Str(value) => Right(Seq(value))
45-
case Arr(values) => EitherSequence.sequence {
44+
case Str(value) => Right(Seq(value))
45+
case Arr(values) => EitherSequence.sequence {
4646
values.map {
4747
case Str(value) => Right(value)
48-
case _ => Left(())
48+
case _ => Left(())
4949
}
5050
}.left.map(_ => ())
51-
case _ => Left(())
52-
}.getOrElse(Right(Seq(key)))
51+
case _ => Left(())
52+
}.getOrElse(Right(Seq(key)))
5353
.left.map(_ =>
5454
ModuleConfigurationError(
5555
s"${Keys.modules}.$key.${Keys.roots} must be a string or a list of strings"
5656
)
5757
)
5858

5959
val maybeDependsOn = values.get(Keys.dependsOn).map {
60-
case Arr(values) =>
61-
EitherSequence.sequence {
62-
values.map {
63-
case Str(value) => Right(value)
64-
case _ => Left(())
65-
}
66-
}.left.map(_ => ())
67-
case _ => Left(())
68-
}.getOrElse(Right(Nil))
60+
case Arr(values) =>
61+
EitherSequence.sequence {
62+
values.map {
63+
case Str(value) => Right(value)
64+
case _ => Left(())
65+
}
66+
}.left.map(_ => ())
67+
case _ => Left(())
68+
}.getOrElse(Right(Nil))
6969
.left.map(_ =>
7070
ModuleConfigurationError(
7171
s"${Keys.modules}.$key.${Keys.dependsOn} must be a list of strings"
7272
)
7373
)
7474

7575
for {
76-
roots <- maybeRoots
76+
roots <- maybeRoots
7777
dependsOn <- maybeDependsOn
7878
} yield ModuleDefinition(key, roots, dependsOn)
7979

8080
case _ => Left(ModuleConfigurationError(s"${Keys.modules}.$key must be a table"))
81-
}
8281
}
8382

84-
/** Creates [[ModuleInputs]] given the initial arguments passed to the command,
85-
* Looks for module config .toml file and if found composes module inputs according to the defined config,
86-
* otherwise if module config is not found or if [[allowForbiddenFeatures]] is not set, returns only one basic module created from initial args (see [[basicInputs]])
87-
*
88-
* @param args - initial args passed to command
89-
* @param cwd - working directory
90-
* @param inputsFromArgs - function that proceeds with the whole [[ModuleInputs]] creation flow (validating elements, etc.) this takes into account options passed from CLI
91-
* like in SharedOptions
92-
* @param allowForbiddenFeatures
93-
*/
83+
/** Creates [[ModuleInputs]] given the initial arguments passed to the command, Looks for module
84+
* config .toml file and if found composes module inputs according to the defined config, otherwise
85+
* if module config is not found or if [[allowForbiddenFeatures]] is not set, returns only one
86+
* basic module created from initial args (see [[basicInputs]])
87+
*
88+
* @param args
89+
* initial args passed to command
90+
* @param cwd
91+
* working directory
92+
* @param inputsFromArgs
93+
* function that proceeds with the whole [[ModuleInputs]] creation flow (validating elements,
94+
* etc.) this takes into account options passed from CLI like in SharedOptions
95+
* @param allowForbiddenFeatures
96+
*/
9497
final case class InputsComposer(
9598
args: Seq[String],
9699
cwd: os.Path,
97-
inputsFromArgs: Seq[String] => Either[BuildException, ModuleInputs],
100+
inputsFromArgs: (Seq[String], Option[ProjectName]) => Either[BuildException, ModuleInputs],
98101
allowForbiddenFeatures: Boolean
99102
) {
100103
import InputsComposer.*
101104

102105
/** Inputs with no dependencies coming only from args */
103-
def basicInputs = for (inputs <- inputsFromArgs(args)) yield Seq(inputs)
106+
def basicInputs = for (inputs <- inputsFromArgs(args, None)) yield Seq(inputs)
104107

105108
def getModuleInputs: Either[BuildException, Seq[ModuleInputs]] =
106109
if allowForbiddenFeatures then
@@ -192,7 +195,11 @@ final case class InputsComposer(
192195
modules: Seq[ModuleDefinition],
193196
moduleConfigPath: os.Path
194197
): Either[BuildException, Seq[ModuleInputs]] = either {
195-
val moduleInputsInfo = modules.map(m => m -> value(inputsFromArgs(m.roots)))
198+
val moduleInputsInfo = modules.map { m =>
199+
val moduleName = ProjectName(m.name)
200+
val moduleInputs = inputsFromArgs(m.roots, Some(moduleName))
201+
m -> value(moduleInputs)
202+
}
196203

197204
val projectNameMap: Map[String, ProjectName] =
198205
moduleInputsInfo.map((moduleDef, inputs) => moduleDef.name -> inputs.projectName).toMap

modules/build/src/main/scala/scala/build/input/ModuleInputs.scala

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ object ModuleInputs {
141141
workspaceOrigin: WorkspaceOrigin,
142142
enableMarkdown: Boolean,
143143
allowRestrictedFeatures: Boolean,
144-
extraClasspathWasPassed: Boolean
144+
extraClasspathWasPassed: Boolean,
145+
forcedProjectName: Option[ProjectName]
145146
): ModuleInputs = {
146147
assert(extraClasspathWasPassed || validElems.nonEmpty)
147148
val allDirs = validElems.collect { case d: Directory => d.path }
@@ -159,7 +160,7 @@ object ModuleInputs {
159160
updatedElems,
160161
defaultMainClassElemOpt,
161162
workspace,
162-
baseName(workspace),
163+
forcedProjectName.fold(baseName(workspace))(_.name),
163164
mayAppendHash = needsHash,
164165
workspaceOrigin = Some(workspaceOrigin),
165166
enableMarkdown = enableMarkdown,
@@ -336,7 +337,8 @@ object ModuleInputs {
336337
forcedWorkspace: Option[os.Path],
337338
enableMarkdown: Boolean,
338339
allowRestrictedFeatures: Boolean,
339-
extraClasspathWasPassed: Boolean
340+
extraClasspathWasPassed: Boolean,
341+
forcedProjectName: Option[ProjectName]
340342
)(using invokeData: ScalaCliInvokeData): Either[BuildException, ModuleInputs] = {
341343
val validatedArgs: Seq[Either[String, Seq[Element]]] =
342344
validateArgs(
@@ -419,7 +421,8 @@ object ModuleInputs {
419421
workspaceOrigin0,
420422
enableMarkdown,
421423
allowRestrictedFeatures,
422-
extraClasspathWasPassed
424+
extraClasspathWasPassed,
425+
forcedProjectName
423426
))
424427
}
425428
else
@@ -440,7 +443,8 @@ object ModuleInputs {
440443
forcedWorkspace: Option[os.Path] = None,
441444
enableMarkdown: Boolean = false,
442445
allowRestrictedFeatures: Boolean,
443-
extraClasspathWasPassed: Boolean
446+
extraClasspathWasPassed: Boolean,
447+
forcedProjectName: Option[ProjectName] = None
444448
)(using ScalaCliInvokeData): Either[BuildException, ModuleInputs] =
445449
if (
446450
args.isEmpty && scriptSnippetList.isEmpty && scalaSnippetList.isEmpty && javaSnippetList.isEmpty &&
@@ -463,7 +467,8 @@ object ModuleInputs {
463467
forcedWorkspace,
464468
enableMarkdown,
465469
allowRestrictedFeatures,
466-
extraClasspathWasPassed
470+
extraClasspathWasPassed,
471+
forcedProjectName
467472
)
468473

469474
def default(): Option[ModuleInputs] = None

modules/build/src/test/scala/scala/build/input/InputsComposerTest.scala

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package scala.build.input
22

33
import scala.build.Build
4+
import scala.build.bsp.buildtargets.ProjectName
45
import scala.build.errors.BuildException
56
import scala.build.internal.Constants
67
import scala.build.options.BuildOptions
@@ -10,16 +11,16 @@ class InputsComposerTest extends TestUtil.ScalaCliBuildSuite {
1011

1112
test("read simple module config") {
1213
val configText =
13-
"""[modules.webpage]
14-
|dependsOn = ["core"]
15-
|
16-
|[modules.core]
17-
|roots = ["Core.scala", "Utils.scala"]
18-
|""".stripMargin
14+
"""[modules.webpage]
15+
|dependsOn = ["core"]
16+
|
17+
|[modules.core]
18+
|roots = ["Core.scala", "Utils.scala"]
19+
|""".stripMargin
1920

2021
val parsedModules = {
2122
for {
22-
table <- toml.Toml.parse(configText)
23+
table <- toml.Toml.parse(configText)
2324
modules <- InputsComposer.readAllModules(table.values.get(InputsComposer.Keys.modules))
2425
} yield modules
2526
}.toSeq.flatten
@@ -40,29 +41,34 @@ class InputsComposerTest extends TestUtil.ScalaCliBuildSuite {
4041
test("compose module inputs from module config") {
4142
val testInputs = TestInputs(
4243
os.rel / Constants.moduleConfigFileName ->
43-
"""[modules.webpage]
44-
|dependsOn = ["core"]
45-
|
46-
|[modules.core]
47-
|roots = ["Core.scala", "Utils.scala"]
48-
|""".stripMargin
44+
"""[modules.webpage]
45+
|dependsOn = ["core"]
46+
|
47+
|[modules.core]
48+
|roots = ["Core.scala", "Utils.scala"]
49+
|""".stripMargin
4950
)
5051

5152
testInputs.fromRoot { root =>
52-
val argsToInputs: Seq[String] => Either[BuildException, ModuleInputs] = args => {
53-
val emptyInputs = ModuleInputs.empty(args.head)
54-
Right(Build.updateInputs(emptyInputs, BuildOptions()))
55-
}
53+
val argsToInputs: (Seq[String], Option[ProjectName]) => Either[BuildException, ModuleInputs] =
54+
(args, projectNameOpt) => {
55+
assert(projectNameOpt.isDefined)
56+
val emptyInputs = ModuleInputs.empty(projectNameOpt.get.name)
57+
Right(Build.updateInputs(emptyInputs, BuildOptions()))
58+
}
5659
val modules = InputsComposer(Seq(root.toString), root, argsToInputs, true)
5760
.getModuleInputs
5861
.toSeq
5962
.flatten
6063

6164
assert(modules.nonEmpty)
62-
assert(modules.head.baseProjectName.startsWith("webpage"), clue = modules.head.baseProjectName)
65+
assert(
66+
modules.head.baseProjectName.startsWith("webpage"),
67+
clue = modules.head.baseProjectName
68+
)
6369

64-
val websiteModule = modules.head
65-
val coreModule = modules.last
70+
val websiteModule = modules.head
71+
val coreModule = modules.last
6672
val coreProjectName = coreModule.projectName
6773

6874
assert(websiteModule.moduleDependencies.toSet == Set(coreProjectName))

modules/cli/src/main/scala/scala/cli/commands/shared/SharedOptions.scala

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ import dependency.parser.DependencyParser
1616
import java.io.{File, InputStream}
1717
import java.nio.file.Paths
1818
import java.util.concurrent.atomic.AtomicBoolean
19-
2019
import scala.build.EitherCps.{either, value}
2120
import scala.build.Ops.EitherOptOps
2221
import scala.build.*
22+
import scala.build.bsp.buildtargets.ProjectName
2323
import scala.build.compiler.{BloopCompilerMaker, ScalaCompilerMaker, SimpleScalaCompilerMaker}
2424
import scala.build.directives.DirectiveDescription
2525
import scala.build.errors.{AmbiguousPlatformError, BuildException, ConfigDbException, Severity}
@@ -631,6 +631,7 @@ final case class SharedOptions(
631631

632632
private def moduleInputsFromArgs(
633633
args: Seq[String],
634+
forcedProjectName: Option[ProjectName],
634635
defaultInputs: () => Option[ModuleInputs] = () => ModuleInputs.default()
635636
)(using ScalaCliInvokeData) = SharedOptions.inputs(
636637
args,
@@ -647,19 +648,21 @@ final case class SharedOptions(
647648
javaSnippetList = allJavaSnippets,
648649
markdownSnippetList = allMarkdownSnippets,
649650
enableMarkdown = markdown.enableMarkdown,
650-
extraClasspathWasPassed = extraClasspathWasPassed
651+
extraClasspathWasPassed = extraClasspathWasPassed,
652+
forcedProjectName = forcedProjectName
651653
)
652654

653655
def composeInputs(
654656
args: Seq[String],
655657
defaultInputs: () => Option[ModuleInputs] = () => ModuleInputs.default()
656658
)(using ScalaCliInvokeData): Either[BuildException, Seq[ModuleInputs]] = {
657-
val updatedModuleInputsFromArgs = { (args: Seq[String]) =>
658-
for {
659-
moduleInputs <- moduleInputsFromArgs(args, defaultInputs)
660-
options <- buildOptions()
661-
} yield Build.updateInputs(moduleInputs, options)
662-
}
659+
val updatedModuleInputsFromArgs
660+
: (Seq[String], Option[ProjectName]) => Either[BuildException, ModuleInputs] =
661+
(args, projectNameOpt) =>
662+
for {
663+
moduleInputs <- moduleInputsFromArgs(args, projectNameOpt, defaultInputs)
664+
options <- buildOptions()
665+
} yield Build.updateInputs(moduleInputs, options)
663666

664667
InputsComposer(
665668
args,
@@ -672,7 +675,7 @@ final case class SharedOptions(
672675
def inputs(
673676
args: Seq[String],
674677
defaultInputs: () => Option[ModuleInputs] = () => ModuleInputs.default()
675-
)(using ScalaCliInvokeData) = moduleInputsFromArgs(args, defaultInputs)
678+
)(using ScalaCliInvokeData) = moduleInputsFromArgs(args, forcedProjectName = None, defaultInputs)
676679

677680
def allScriptSnippets: List[String] = snippet.scriptSnippet ++ snippet.executeScript
678681
def allScalaSnippets: List[String] = snippet.scalaSnippet ++ snippet.executeScala
@@ -731,7 +734,8 @@ object SharedOptions {
731734
javaSnippetList: List[String],
732735
markdownSnippetList: List[String],
733736
enableMarkdown: Boolean = false,
734-
extraClasspathWasPassed: Boolean = false
737+
extraClasspathWasPassed: Boolean = false,
738+
forcedProjectName: Option[ProjectName] = None
735739
)(using ScalaCliInvokeData): Either[BuildException, ModuleInputs] = {
736740
val resourceInputs = resourceDirs
737741
.map(os.Path(_, Os.pwd))
@@ -756,7 +760,8 @@ object SharedOptions {
756760
forcedWorkspace = forcedWorkspaceOpt,
757761
enableMarkdown = enableMarkdown,
758762
allowRestrictedFeatures = ScalaCli.allowRestrictedFeatures,
759-
extraClasspathWasPassed = extraClasspathWasPassed
763+
extraClasspathWasPassed = extraClasspathWasPassed,
764+
forcedProjectName = forcedProjectName
760765
)
761766

762767
maybeInputs.map { inputs =>

0 commit comments

Comments
 (0)