Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions modules/build/src/main/scala/scala/build/input/Element.scala
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ final case class MarkdownFile(base: os.Path, subPath: os.SubPath)
lazy val path: os.Path = base / subPath
}

final case class SbtFile(base: os.Path, subPath: os.SubPath)
extends OnDisk with SourceFile {
lazy val path: os.Path = base / subPath
}

final case class Directory(path: os.Path) extends OnDisk with Compiled

final case class ResourceDirectory(path: os.Path) extends OnDisk
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ object ElementsUtils {
case p if p.last.endsWith(".sc") =>
// TODO: hasShebang test without consuming 1st 2 bytes of Stream
Script(d.path, p.subRelativeTo(d.path), None)
case p if p.last.endsWith(".sbt") =>
SbtFile(d.path, p.subRelativeTo(d.path))
}
.toVector
.sortBy(_.subPath.segments)
Expand Down Expand Up @@ -68,6 +70,7 @@ object ElementsUtils {
case _: Script => "sc:"
case _: MarkdownFile => "md:"
case _: JarFile => "jar:"
case _: SbtFile => "sbt:"
}
Iterator(prefix, elem.path.toString, "\n").map(bytes)
case v: Virtual =>
Expand Down
2 changes: 2 additions & 0 deletions modules/build/src/main/scala/scala/build/input/Inputs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ final case class Inputs(
Seq("dir:") ++ dirInput.singleFilesFromDirectory(enableMarkdown)
.map(file => s"${file.path}:" + os.read(file.path))
case _: ResourceDirectory => Nil
case _: SbtFile => Nil
case _ => Seq(os.read(elem.path))
}
(Iterator(elem.path.toString) ++ content.iterator ++ Iterator("\n")).map(bytes)
Expand Down Expand Up @@ -282,6 +283,7 @@ object Inputs {
else if arg.endsWith(".java") then Right(Seq(JavaFile(dir, subPath)))
else if arg.endsWith(".jar") then Right(Seq(JarFile(dir, subPath)))
else if arg.endsWith(".c") || arg.endsWith(".h") then Right(Seq(CFile(dir, subPath)))
else if arg.endsWith(".sbt") then Right(Seq(SbtFile(dir, subPath)))
else if arg.endsWith(".md") then Right(Seq(MarkdownFile(dir, subPath)))
else if acceptFds && arg.startsWith("/dev/fd/") then
Right(Seq(VirtualScript(content, arg, os.sub / s"input-${idx + 1}.sc")))
Expand Down
36 changes: 29 additions & 7 deletions modules/build/src/test/scala/scala/build/tests/InputsTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,8 @@ package scala.build.tests
import bloop.rifle.BloopRifleConfig
import com.eed3si9n.expecty.Expecty.expect

import scala.build.input.*
import scala.build.input.ElementsUtils.*
import scala.build.input.{
Inputs,
ScalaCliInvokeData,
VirtualJavaFile,
VirtualScalaFile,
VirtualScript
}
import scala.build.internal.Constants
import scala.build.options.{BuildOptions, InternalOptions}
import scala.build.tests.util.BloopServer
Expand Down Expand Up @@ -127,6 +121,34 @@ class InputsTests extends TestUtil.ScalaCliBuildSuite {
}
}

test("sbt file is recognized as SbtFile when passed explicitly") {
TestInputs(os.rel / "build.sbt" -> "").fromRoot { root =>
val elements = Inputs.validateArgs(
Seq((root / "build.sbt").toString),
root,
download = _ => Right(Array.emptyByteArray),
stdinOpt = None,
acceptFds = false,
enableMarkdown = false
)(using ScalaCliInvokeData.dummy)
elements match {
case Seq(Right(Seq(f: SbtFile))) =>
assert(f.path == root / "build.sbt")
case _ => fail(s"Unexpected elements: $elements")
}
}
}

test("sbt file is picked up from directory scan") {
TestInputs(os.rel / "build.sbt" -> "").fromRoot { root =>
val dir = Directory(root)
val singles = dir.singleFilesFromDirectory(enableMarkdown = false)
val sbtFiles = singles.collect { case f: SbtFile => f }
assert(sbtFiles.nonEmpty)
assert(sbtFiles.head.path == root / "build.sbt")
}
}

test("URLs with query parameters") {
val urlBase =
"https://gist.githubusercontent.com/USER/hash/raw/hash"
Expand Down
4 changes: 2 additions & 2 deletions modules/cli/src/main/scala/scala/cli/commands/fmt/Fmt.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import caseapp.core.help.HelpFormat
import dependency.*

import scala.build.Logger
import scala.build.input.{ProjectScalaFile, Script, SourceScalaFile}
import scala.build.input.{ProjectScalaFile, SbtFile, Script, SourceScalaFile}
import scala.build.internal.{Constants, ExternalBinaryParams, FetchExternalBinary, Runner}
import scala.build.internals.ConsoleUtils.ScalaCliConsole.warnPrefix
import scala.cli.CurrentParams
Expand Down Expand Up @@ -53,7 +53,7 @@ object Fmt extends ScalaCommand[FmtOptions] {
if args.all.isEmpty then (Seq(os.pwd), os.pwd, None)
else {
val i = options.shared.inputs(args.all).orExit(logger)
type FormattableSourceFile = Script | SourceScalaFile | ProjectScalaFile
type FormattableSourceFile = Script | SourceScalaFile | ProjectScalaFile | SbtFile
val s = i.sourceFiles().collect { case sc: FormattableSourceFile => sc.path }
(s, i.workspace, Some(i))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
case s: ScalaFile => fwd(s.path.toString)
case s: Script => fwd(s.path.toString)
case s: MarkdownFile => fwd(s.path.toString)
case _: SbtFile => ""
case s: OnDisk => fwd(s.path.toString)
case s => s.getClass.getName
}.filter(_.nonEmpty).distinct
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -972,4 +972,17 @@ abstract class CompileTestDefinitions
}
}
}

test("sbt file in directory does not break compile") {
TestInputs(
os.rel / "Main.scala" ->
"""object Main {
| def main(args: Array[String]): Unit = println("Hello")
|}
|""".stripMargin,
os.rel / "build.sbt" -> """name := "my-project""""
).fromRoot { root =>
os.proc(TestUtil.cli, "compile", extraOptions, ".").call(cwd = root)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,30 @@ abstract class FixTestDefinitions
}
}

test("sbt file in directory does not break fix") {
TestInputs(
os.rel / "Main.scala" ->
"""object Main {
| def main(args: Array[String]): Unit = println("Hello")
|}
|""".stripMargin,
os.rel / "build.sbt" -> """name := "my-project"""",
os.rel / scalafixConfFileName ->
"""rules = [
| RedundantSyntax
|]
|""".stripMargin
).fromRoot { root =>
os.proc(
TestUtil.cli,
"--power",
"fix",
".",
extraOptions
).call(cwd = root)
}
}

def filterDebugOutputs(output: String): String =
output
.linesIterator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,4 +232,35 @@ class FmtTests extends ScalaCliSuite {
expect(updatedContent == expectedSimpleInputsFormattedContent)
}
}

val sbtUnformattedContent: String =
"""val message = "hello"
|""".stripMargin
val expectedSbtFormattedContent: String = noCrLf {
"""val message = "hello"
|""".stripMargin
}
val sbtInputs: TestInputs = TestInputs(
os.rel / confFileName ->
s"""|version = "${Constants.defaultScalafmtVersion}"
|runner.dialect = scala213
|""".stripMargin,
os.rel / "build.sbt" -> sbtUnformattedContent
)

test("sbt file is formatted when passed explicitly") {
sbtInputs.fromRoot { root =>
os.proc(TestUtil.cli, "fmt", "build.sbt").call(cwd = root)
val updatedContent = noCrLf(os.read(root / "build.sbt"))
expect(updatedContent == expectedSbtFormattedContent)
}
}

test("sbt file is formatted when directory is passed") {
sbtInputs.fromRoot { root =>
os.proc(TestUtil.cli, "fmt", ".").call(cwd = root)
val updatedContent = noCrLf(os.read(root / "build.sbt"))
expect(updatedContent == expectedSbtFormattedContent)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1601,4 +1601,26 @@ abstract class PackageTestDefinitions extends ScalaCliSuite with TestScalaVersio
}
}
}

test("sbt file in directory does not break package") {
val message = "Hello from package"
TestInputs(
os.rel / "Main.scala" ->
s"""object Main {
| def main(args: Array[String]): Unit = println("$message")
|}
|""".stripMargin,
os.rel / "build.sbt" -> """name := "my-project""""
).fromRoot { root =>
os.proc(TestUtil.cli, "--power", "package", extraOptions, ".").call(
cwd = root,
stdin = os.Inherit,
stdout = os.Inherit
)
val launcher = root / (if Properties.isWin then "Main.bat" else "Main")
expect(os.isFile(launcher))
val output = TestUtil.maybeUseBash(launcher)(cwd = root).out.trim()
expect(output == message)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2510,4 +2510,19 @@ abstract class RunTestDefinitions
processes.foreach { case (p, _) => expect(p.exitCode() == 0) }
}
}

test("sbt file in directory does not break run") {
val message = "Hello from run"
TestInputs(
os.rel / "Main.scala" ->
s"""object Main {
| def main(args: Array[String]): Unit = println("$message")
|}
|""".stripMargin,
os.rel / "build.sbt" -> """name := "my-project""""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we also run scalafmt on build.sbt in that case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we apparently do.
I wasn't aware, either.

).fromRoot { root =>
val output = os.proc(TestUtil.cli, extraOptions, ".").call(cwd = root).out.trim()
expect(output == message)
}
}
}