Skip to content

Commit 7b460a8

Browse files
committed
Fix discovery of project file for exclude
pick the outermost project file, so that if an excluded directory is itself a scala-cli project then it is ignored. fixes #3546
1 parent 020e601 commit 7b460a8

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

modules/build/src/main/scala/scala/build/CrossSources.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,14 @@ object CrossSources {
190190

191191
val flattenedInputs = inputs.flattened()
192192
val allExclude = { // supports only one exclude directive in one source file, which should be the project file.
193-
val projectScalaFileOpt = flattenedInputs.collectFirst {
193+
val projectScalaFileCandidates = flattenedInputs.collect {
194194
case f: ProjectScalaFile => f
195195
}
196+
197+
// this relies upon the inferred workspace root being the outermost directory.
198+
// which is the common case when you pass a single directory.
199+
val projectScalaFileOpt =
200+
projectScalaFileCandidates.sortBy(_.subPath.segments.size).headOption
196201
val excludeFromProjectFile =
197202
value(preprocessSources(projectScalaFileOpt.toSeq))
198203
.flatMap(_.options).flatMap(_.internal.exclude)

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,4 +213,40 @@ class ExcludeTests extends TestUtil.ScalaCliBuildSuite {
213213
}
214214
}
215215

216+
test("exclude nested scala-cli project") {
217+
val testInputs = TestInputs(
218+
os.rel / "Hello.scala" -> "object Hello",
219+
// this project.scala needs to come first so that the inferred workspace is the outermost one.
220+
os.rel / "project.scala" ->
221+
"""//> using exclude */examples/*""",
222+
os.rel / "examples" / "fail.scala" ->
223+
"""val i: Int = "abc";""",
224+
os.rel / "examples" / "project.scala" ->
225+
"""val unused = 23"""
226+
)
227+
testInputs.withInputs { (root, inputs) =>
228+
val (crossSources, _) =
229+
CrossSources.forInputs(
230+
inputs,
231+
preprocessors,
232+
TestLogger(),
233+
SuppressWarningOptions()
234+
)(using ScalaCliInvokeData.dummy).orThrow
235+
val scopedSources = crossSources.scopedSources(BuildOptions())
236+
.orThrow
237+
val sources =
238+
scopedSources.sources(
239+
Scope.Main,
240+
crossSources.sharedOptions(BuildOptions()),
241+
root,
242+
TestLogger()
243+
)
244+
.orThrow
245+
246+
expect(sources.paths.nonEmpty)
247+
expect(sources.paths.length == 2)
248+
expect(sources.paths.map(_._2) == Seq(os.rel / "Hello.scala", os.rel / "project.scala"))
249+
}
250+
}
251+
216252
}

0 commit comments

Comments
 (0)