Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fix command #1627

Closed
wants to merge 3 commits into from
Closed
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
8 changes: 5 additions & 3 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ import $file.project.settings, settings.{
ScalaCliTests,
localRepoResourcePath,
platformExecutableJarExtension,
workspaceDirName,
projectFileName
workspaceDirName
}
import $file.project.deps, deps.customRepositories
import $file.project.website
Expand Down Expand Up @@ -404,7 +403,8 @@ trait Core extends ScalaCliSbtModule with ScalaCliPublishModule with HasTests
| def defaultScala213Version = "${Scala.scala213}"
|
| def workspaceDirName = "$workspaceDirName"
| def projectFileName = "$projectFileName"
| def mainProjectFileName = "${deps.mainProjectFileName}"
| def testProjectFileName = "${deps.testProjectFileName}"
|
| def defaultGraalVMJavaVersion = ${deps.graalVmJavaVersion}
| def defaultGraalVMVersion = "${deps.graalVmVersion}"
Expand Down Expand Up @@ -926,6 +926,8 @@ trait CliIntegration extends SbtModule with ScalaCliPublishModule with HasTests
| def authProxyTestImage = "${Docker.authProxyTestImage}"
| def mostlyStaticDockerfile = "${mostlyStaticDockerfile.toString.replace("\\", "\\\\")}"
| def cs = "${settings.cs().replace("\\", "\\\\")}"
| def mainProjectFileName = "${deps.mainProjectFileName}"
| def testProjectFileName = "${deps.testProjectFileName}"
| def workspaceDirName = "$workspaceDirName"
| def libsodiumVersion = "${deps.libsodiumVersion}"
| def dockerArchLinuxImage = "${TestDeps.archLinuxImage}"
Expand Down
87 changes: 58 additions & 29 deletions modules/build/src/main/scala/scala/build/CrossSources.scala
Original file line number Diff line number Diff line change
Expand Up @@ -119,19 +119,26 @@ object CrossSources {
}
}

def isTestSource(path: ScopePath, inputs: Inputs): Boolean =
path.subPath.last.endsWith(".test.scala") || withinTestSubDirectory(path, inputs)

/** @return
* a CrossSources and Inputs which contains element processed from using directives
* Inputs which contain elements processed from using directives and preprocessed sources
* extracted from given Inputs
*/
def forInputs(
def allInputsAndPreprocessedSources(
inputs: Inputs,
preprocessors: Seq[Preprocessor],
logger: Logger,
suppressDirectivesInMultipleFilesWarning: Option[Boolean],
maybeRecoverOnError: BuildException => Option[BuildException] = e => Some(e)
): Either[BuildException, (CrossSources, Inputs)] = either {

def preprocessSources(elems: Seq[SingleElement])
: Either[BuildException, Seq[PreprocessedSource]] =
): Either[BuildException, (Inputs, Seq[PreprocessedSource])] = either {
def preprocessSources(
elems: Seq[SingleElement],
inputs: Inputs,
preprocessors: Seq[Preprocessor],
logger: Logger,
maybeRecoverOnError: BuildException => Option[BuildException] = e => Some(e)
): Either[BuildException, Seq[PreprocessedSource]] =
elems
.map { elem =>
preprocessors
Expand All @@ -153,7 +160,13 @@ object CrossSources {
.left.map(CompositeBuildException(_))
.map(_.flatten)

val preprocessedInputFromArgs = value(preprocessSources(inputs.flattened()))
val preprocessedInputFromArgs = value(preprocessSources(
inputs.flattened(),
inputs,
preprocessors,
logger,
maybeRecoverOnError
))

val sourcesFromDirectives =
preprocessedInputFromArgs
Expand All @@ -162,34 +175,51 @@ object CrossSources {
.distinct
val inputsElemFromDirectives =
value(resolveInputsFromSources(sourcesFromDirectives, inputs.enableMarkdown))
val preprocessedSourcesFromDirectives = value(preprocessSources(inputsElemFromDirectives))
val allInputs = inputs.add(inputsElemFromDirectives)

val preprocessedSources =
val preprocessedSourcesFromDirectives = value(preprocessSources(
inputsElemFromDirectives,
inputs,
preprocessors,
logger,
maybeRecoverOnError
))

val allInputs = inputs.add(inputsElemFromDirectives)
val allPreprocessedSources =
(preprocessedInputFromArgs ++ preprocessedSourcesFromDirectives).distinct

(allInputs, allPreprocessedSources)
}

/** @return
* a CrossSources and Inputs which contains element processed from using directives
*/
def forInputs(
inputs: Inputs,
preprocessors: Seq[Preprocessor],
logger: Logger,
suppressDirectivesInMultipleFilesWarning: Option[Boolean],
maybeRecoverOnError: BuildException => Option[BuildException] = e => Some(e)
): Either[BuildException, (CrossSources, Inputs)] = either {
val (allInputs, preprocessedSources) =
value(allInputsAndPreprocessedSources(inputs, preprocessors, logger, maybeRecoverOnError))

val preprocessedWithUsingDirs = preprocessedSources.filter(_.directivesPositions.isDefined)
if (
preprocessedWithUsingDirs.length > 1 && !suppressDirectivesInMultipleFilesWarning.getOrElse(
false
)
preprocessedWithUsingDirs.length > 1 &&
!suppressDirectivesInMultipleFilesWarning.getOrElse(false)
) {
val projectFilePath = inputs.elements.projectSettingsFiles.headOption match
val projectFilePath = inputs.elements.mainProjectSettingsFiles.headOption match
case Some(s) => s.path
case _ => inputs.workspace / Constants.projectFileName
case _ => inputs.workspace / Constants.mainProjectFileName

preprocessedWithUsingDirs
.filter(_.scopePath != ScopePath.fromPath(projectFilePath))
.foreach { source =>
source.directivesPositions match
case Some(positions) =>
val pos = Seq(
positions.codeDirectives,
positions.specialCommentDirectives,
positions.plainCommentDirectives
).maxBy(p => p.endPos._1)
logger.diagnostic(
s"Using directives detected in multiple files. It is recommended to keep them centralized in the $projectFilePath file.",
positions = Seq(pos)
positions = Seq(positions.scope)
)
case _ => ()
}
Expand All @@ -207,10 +237,7 @@ object CrossSources {
// Scala CLI treats all `.test.scala` files tests as well as
// files from within `test` subdirectory from provided input directories
// If file has `using target <scope>` directive this take precendeces.
if (
fromDirectives.scope.isEmpty &&
(path.subPath.last.endsWith(".test.scala") || withinTestSubDirectory(path, allInputs))
)
if (fromDirectives.scope.isEmpty && isTestSource(path, allInputs))
fromDirectives.copy(scope = Some(BuildRequirements.ScopeRequirement(Scope.Test)))
else fromDirectives
}
Expand Down Expand Up @@ -268,8 +295,10 @@ object CrossSources {
lazy val subPath = sourcePath.subRelativeTo(dir)
if (os.isDir(sourcePath))
Right(Directory(sourcePath).singleFilesFromDirectory(enableMarkdown))
else if (sourcePath == os.sub / Constants.projectFileName)
Right(Seq(ProjectScalaFile(dir, subPath)))
else if (sourcePath == os.sub / Constants.mainProjectFileName)
Right(Seq(MainProjectScalaFile(dir, subPath)))
else if (sourcePath == os.sub / Constants.testProjectFileName)
Right(Seq(TestProjectScalaFile(dir, subPath)))
else if (sourcePath.ext == "scala") Right(Seq(SourceScalaFile(dir, subPath)))
else if (sourcePath.ext == "sc") Right(Seq(Script(dir, subPath)))
else if (sourcePath.ext == "java") Right(Seq(JavaFile(dir, subPath)))
Expand Down
5 changes: 3 additions & 2 deletions modules/build/src/main/scala/scala/build/input/Element.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ final case class Script(base: os.Path, subPath: os.SubPath)
final case class SourceScalaFile(base: os.Path, subPath: os.SubPath)
extends OnDisk with SourceFile with ScalaFile

final case class ProjectScalaFile(base: os.Path, subPath: os.SubPath)
extends OnDisk with SourceFile with ScalaFile
sealed trait ProjectScalaFile extends OnDisk with SourceFile with ScalaFile
final case class MainProjectScalaFile(base: os.Path, subPath: os.SubPath) extends ProjectScalaFile
final case class TestProjectScalaFile(base: os.Path, subPath: os.SubPath) extends ProjectScalaFile

final case class JavaFile(base: os.Path, subPath: os.SubPath)
extends OnDisk with SourceFile with AnyJavaFile {
Expand Down
18 changes: 14 additions & 4 deletions modules/build/src/main/scala/scala/build/input/ElementsUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ object ElementsUtils {
.collect {
case p if p.last.endsWith(".java") =>
JavaFile(d.path, p.subRelativeTo(d.path))
case p if p.last == Constants.projectFileName =>
ProjectScalaFile(d.path, p.subRelativeTo(d.path))
case p if p.last == Constants.mainProjectFileName =>
MainProjectScalaFile(d.path, p.subRelativeTo(d.path))
case p if p.last == Constants.testProjectFileName =>
TestProjectScalaFile(d.path, p.subRelativeTo(d.path))
case p if p.last.endsWith(".scala") =>
SourceScalaFile(d.path, p.subRelativeTo(d.path))
case p if p.last.endsWith(".sc") =>
Expand All @@ -32,8 +34,10 @@ object ElementsUtils {
}

def configFile: Seq[ProjectScalaFile] =
if (os.exists(d.path / Constants.projectFileName))
Seq(ProjectScalaFile(d.path, os.sub / Constants.projectFileName))
if (os.exists(d.path / Constants.mainProjectFileName))
Seq(MainProjectScalaFile(d.path, os.sub / Constants.mainProjectFileName))
else if (os.exists(d.path / Constants.testProjectFileName))
Seq(TestProjectScalaFile(d.path, os.sub / Constants.testProjectFileName))
else Nil
}

Expand All @@ -45,6 +49,12 @@ object ElementsUtils {
case _ => Nil
}.distinct

def mainProjectSettingsFiles: Seq[MainProjectScalaFile] =
projectSettingsFiles.collect { case a: MainProjectScalaFile => a }

def testProjectSettingsFiles: Seq[TestProjectScalaFile] =
projectSettingsFiles.collect { case a: TestProjectScalaFile => a }

def inputsHash: String = {
def bytes(s: String): Array[Byte] = s.getBytes(StandardCharsets.UTF_8)

Expand Down
10 changes: 6 additions & 4 deletions modules/build/src/main/scala/scala/build/input/Inputs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,15 @@ object Inputs {
): Inputs = {
assert(extraClasspathWasPassed || validElems.nonEmpty)
val (inferredWorkspace, inferredNeedsHash, workspaceOrigin) = {
val settingsFiles = validElems.projectSettingsFiles
val settingsFiles = validElems.mainProjectSettingsFiles
val dirsAndFiles = validElems.collect {
case d: Directory => d
case f: SourceFile => f
}
settingsFiles.headOption.map { s =>
if (settingsFiles.length > 1)
System.err.println(
s"Warning: more than one ${Constants.projectFileName} file has been found. Setting ${s.base} as the project root directory for this run."
s"Warning: more than one ${Constants.mainProjectFileName} file has been found. Setting ${s.base} as the project root directory for this run."
)
(s.base, true, WorkspaceOrigin.SourcePaths)
}.orElse {
Expand Down Expand Up @@ -307,8 +307,10 @@ object Inputs {
else List(Virtual(url, urlContent))
}
}
else if path.last == Constants.projectFileName then
Right(Seq(ProjectScalaFile(dir, subPath)))
else if path.last == Constants.mainProjectFileName then
Right(Seq(MainProjectScalaFile(dir, subPath)))
else if path.last == Constants.testProjectFileName then
Right(Seq(TestProjectScalaFile(dir, subPath)))
else if arg.endsWith(".sc") then Right(Seq(Script(dir, subPath)))
else if arg.endsWith(".scala") then Right(Seq(SourceScalaFile(dir, subPath)))
else if arg.endsWith(".java") then Right(Seq(JavaFile(dir, subPath)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ case class DirectivesPositions(
codeDirectives: Position.File,
specialCommentDirectives: Position.File,
plainCommentDirectives: Position.File
)
) {
def scope: Position.File =
Seq(codeDirectives, specialCommentDirectives, plainCommentDirectives).maxBy(p => p.endPos._1)
}

object ExtractedDirectives {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class InputsTests extends munit.FunSuite {
}

test("project file") {
val projectFileName = Constants.projectFileName
val projectFileName = Constants.mainProjectFileName
val testInputs = TestInputs(
files = Seq(
os.rel / "custom-dir" / projectFileName -> "",
Expand Down Expand Up @@ -89,7 +89,7 @@ class InputsTests extends munit.FunSuite {
}

test("passing project file and its parent directory") {
val projectFileName = Constants.projectFileName
val projectFileName = Constants.mainProjectFileName
val testInputs = TestInputs(
files = Seq(
os.rel / "foo.scala" ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class ScalaCliCommands(
directories.Directories,
doc.Doc,
export0.Export,
fix.Fix,
fmt.Fmt,
new HelpCmd(help),
installcompletions.InstallCompletions,
Expand Down
Loading