Skip to content

Commit

Permalink
Add error for ammonite scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
MaciejG604 committed Jan 17, 2023
1 parent 049d5d8 commit 45ff80c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import dependency.AnyDependency
import dependency.parser.DependencyParser

import java.nio.charset.StandardCharsets

import scala.build.EitherCps.{either, value}
import scala.build.Ops.*
import scala.build.actionable.ActionableDiagnostic.ActionableAmmoniteImportUpdateDiagnostic
Expand Down Expand Up @@ -233,24 +234,21 @@ case object ScalaPreprocessor extends Preprocessor {
allowRestrictedFeatures
))

val afterProcessImports: Option[SpecialImportsProcessingOutput] = value {
value {
processSpecialImports(
afterStrictUsing.strippedContent.getOrElse(content0),
path,
logger
)
}

if (afterStrictUsing.isEmpty && afterProcessImports.isEmpty) None
if (afterStrictUsing.isEmpty) None
else {
val allRequirements = afterProcessImports.map(_.reqs).toSeq :+ afterStrictUsing.globalReqs
val allRequirements = Seq(afterStrictUsing.globalReqs)
val summedRequirements = allRequirements.foldLeft(BuildRequirements())(_ orElse _)
val allOptions = afterStrictUsing.globalUsings +:
afterProcessImports.map(_.opts).toSeq
val summedOptions = allOptions.foldLeft(BuildOptions())(_ orElse _)
val lastContentOpt = afterProcessImports
.map(_.content)
.orElse(afterStrictUsing.strippedContent)
val allOptions = Seq(afterStrictUsing.globalUsings)
val summedOptions = allOptions.foldLeft(BuildOptions())(_ orElse _)
val lastContentOpt = afterStrictUsing.strippedContent
.orElse(if (isSheBang) Some(content0) else None)
val directivesPositions = afterStrictUsing.directivesPositions

Expand All @@ -269,7 +267,7 @@ case object ScalaPreprocessor extends Preprocessor {
content: String,
path: Either[String, os.Path],
logger: Logger
): Either[BuildException, Option[SpecialImportsProcessingOutput]] = either {
): Either[BuildException, Unit] = {

import fastparse.*

Expand Down Expand Up @@ -310,58 +308,28 @@ case object ScalaPreprocessor extends Preprocessor {
}
.toVector


val dependencyTrees = importTrees.filter { case (_, t) =>
val firstSegmentOpt = t.prefix.headOption
(firstSegmentOpt.contains("$ivy") || firstSegmentOpt.contains("$dep")) &&
t.prefix.lengthCompare(1) > 0
}

if (dependencyTrees.isEmpty) None
else {
if (dependencyTrees.nonEmpty) {
val toFilePos = Position.Raw.filePos(path, content)
val msg = "Switch to 'using lib' directive, Ammonite imports using \"$ivy\" and \"$dep\" are no longer supported"
val msg =
"Switch to 'using lib' directive, Ammonite imports using \"$ivy\" and \"$dep\" are no longer supported"
val diagnostics = dependencyTrees.map { case (importStart, t) =>
val pos = toFilePos(Position.Raw(importStart, t.end))
val pos = toFilePos(Position.Raw(importStart, t.end))
val importText = t.prefix.mkString(".")
val suggestion = t.prefix.drop(1).mkString(".")
ActionableAmmoniteImportUpdateDiagnostic(msg, Seq(pos), importText, suggestion)
}

logger.log(diagnostics)

// replace statements like
// import $ivy.`foo`,
// by
// import $ivy.A ,
// Ideally, we should just wipe those statements, and take care of keeping 'import' and ','
// for standard imports.
val buf = content.toCharArray
for ((_, t) <- dependencyTrees) {
val substitute = (t.prefix.head + ".A").padTo(t.end - t.start, ' ')
assert(substitute.length == (t.end - t.start))
System.arraycopy(substitute.toArray, 0, buf, t.start, substitute.length)
}
val newCode = new String(buf)
//val toFilePos = Position.Raw.filePos(path, content)
val deps = value {
dependencyTrees
.map { case (_, t) => // skip ivy ($ivy.`) or dep syntax ($dep.`)
val pos = toFilePos(Position.Raw(t.start + "$ivy.`".length, t.end))
val strDep = t.prefix.drop(1).mkString(".")
val maybeDep = parseDependency(strDep, pos)
maybeDep.map(dep => Positioned(Seq(pos), dep))
}
.sequence
.left.map(CompositeBuildException(_))
}
val options = BuildOptions(
classPathOptions = ClassPathOptions(
extraDependencies = ShadowingSeq.from(deps)
)
)
Some(SpecialImportsProcessingOutput(BuildRequirements(), options, newCode))
Left(new UnsupportedAmmoniteImportError(diagnostics.flatMap(_.positions)))
}
else Right(())
}

private def processStrictUsing(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package scala.build.errors

import scala.build.Position

final class UnsupportedAmmoniteImportError(positions: Seq[Position])
extends BuildException(
"Ammonite imports using \"$ivy\" and \"$dep\" are no longer supported, switch to 'using lib' directive",
positions
)

0 comments on commit 45ff80c

Please sign in to comment.