Skip to content
Merged
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
4 changes: 3 additions & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = "3.0.0"
version = "3.0.3"

align.preset = more
maxColumn = 100
Expand All @@ -12,6 +12,8 @@ newlines.beforeMultiline = keep
newlines.afterCurlyLambdaParams = keep
newlines.alwaysBeforeElseAfterCurlyIf = true

runner.dialect = scala213

fileOverride {
"glob:**/scala-3-stable/**" {
runner.dialect = scala3
Expand Down
18 changes: 15 additions & 3 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,23 @@ object `generate-reference-doc` extends SbtModule {
}

object dummy extends Module {
// dummy project to get scala steward updates for Ammonite, whose
// version is used in the repl command, and ensure Ammonite is available
// for all Scala versions we support
// dummy projects to get scala steward updates for Ammonite and scalafmt, whose
// versions are used in the fmt and repl commands, and ensure Ammonite is available
// for all Scala versions we support.
object amm extends Cross[Amm](Scala.listAll: _*)
class Amm(val crossScalaVersion: String) extends CrossScalaModule with Bloop.Module {
def skipBloop = true
def ivyDeps = Agg(
Deps.ammonite
)
}
object scalafmt extends ScalaModule with Bloop.Module {
def skipBloop = true
def scalaVersion = Scala.defaultInternal
def ivyDeps = Agg(
Deps.scalafmtCli
)
}
}

class BuildMacros(val crossScalaVersion: String) extends CrossSbtModule with ScalaCliPublishModule {
Expand All @@ -134,6 +141,9 @@ class Build(val crossScalaVersion: String)
def repositories = super.repositories ++ Seq(
coursier.Repositories.sonatype("snapshots")
)
def compileIvyDeps = super.compileIvyDeps() ++ Agg(
Deps.svm
)
def ivyDeps = super.ivyDeps() ++ Agg(
Deps.asm,
Deps.bloopConfig,
Expand Down Expand Up @@ -218,6 +228,8 @@ class Build(val crossScalaVersion: String)
|
| def ammoniteVersion = "${Deps.ammonite.dep.version}"
|
| def defaultScalafmtVersion = "${Deps.scalafmtCli.dep.version}"
|
| def defaultScalaVersion = "${Scala.defaultUser}"
|}
|""".stripMargin
Expand Down
11 changes: 11 additions & 0 deletions examples/cross-build/Hello.js.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// using scala 2.13
// require scala-js

import scala.scalajs.js

object Test {
def main(args: Array[String]): Unit = {
val console = js.Dynamic.global.console
console.log("Hello from Scala.JS")
}
}
14 changes: 14 additions & 0 deletions examples/cross-build/Hello.native.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// using scala 2.13
// require scala-native

import scala.scalanative.libc._
import scala.scalanative.unsafe._

object Test {
def main(args: Array[String]): Unit = {
val message = "Hello from Scala Native\n"
Zone { implicit z =>
stdio.printf(toCString(message))
}
}
}
6 changes: 0 additions & 6 deletions examples/cross-build/Hello.scala

This file was deleted.

15 changes: 15 additions & 0 deletions modules/build/src/main/java/scala/build/internal/Chdir.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package scala.build.internal;

import coursier.jvm.ErrnoException;

public final class Chdir {

public static boolean available() {
return false;
}

public static void chdir(String path) throws ErrnoException {
// Not supported on the JVM, returning immediately
}

}
37 changes: 37 additions & 0 deletions modules/build/src/main/java/scala/build/internal/ChdirGraalvm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package scala.build.internal;

import java.io.FileNotFoundException;

import com.oracle.svm.core.CErrorNumber;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
import coursier.jvm.ErrnoException;
import coursier.jvm.GraalvmErrnoExtras;
import org.graalvm.nativeimage.c.type.CTypeConversion;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

@TargetClass(className = "scala.build.internal.Chdir")
@Platforms({Platform.LINUX.class, Platform.DARWIN.class})
final class ChdirGraalvm {

@Substitute
public static boolean available() {
return true;
}

@Substitute
public static void chdir(String path) throws ErrnoException {
CTypeConversion.CCharPointerHolder path0 = CTypeConversion.toCString(path);
int ret = GraalvmUnistdExtras.chdir(path0.get());

if (ret != 0) {
int n = CErrorNumber.getCErrorNumber();
Throwable cause = null;
if (n == GraalvmErrnoExtras.ENOENT() || n == GraalvmErrnoExtras.ENOTDIR())
cause = new FileNotFoundException(path);
throw new ErrnoException(n, cause);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package scala.build.internal;

import com.oracle.svm.core.posix.headers.PosixDirectives;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.nativeimage.c.CContext;
import org.graalvm.nativeimage.c.function.CFunction;
import org.graalvm.nativeimage.c.type.CCharPointer;
import org.graalvm.nativeimage.c.type.CCharPointerPointer;

@CContext(PosixDirectives.class)
@Platforms({Platform.LINUX.class, Platform.DARWIN.class})
public class GraalvmUnistdExtras {

@CFunction
public static native int chdir(CCharPointer path);

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import scala.util.Properties

object OsLibc {

private lazy val isMusl: Option[Boolean] = {
lazy val isMusl: Option[Boolean] = {

def tryRun(cmd: String*): Option[os.CommandResult] =
try {
Expand Down
17 changes: 12 additions & 5 deletions modules/build/src/main/scala/scala/build/internal/Runner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ object Runner {
commandName: String,
command: Seq[String],
logger: Logger,
allowExecve: Boolean = false
allowExecve: Boolean = false,
cwd: Option[os.Path] = None
): Int = {

import logger.{log, debug}
Expand All @@ -31,18 +32,24 @@ object Runner {

if (allowExecve && Execve.available()) {
debug("execve available")

for (dir <- cwd)
Chdir.chdir(dir.toString)

Execve.execve(
findInPath(command.head).fold(command.head)(_.toString),
commandName +: command.tail.toArray,
sys.env.toArray.sorted.map { case (k, v) => s"$k=$v" }
)
sys.error("should not happen")
}
else
new ProcessBuilder(command: _*)
else {
val b = new ProcessBuilder(command: _*)
.inheritIO()
.start()
.waitFor()
for (dir <- cwd)
b.directory(dir.toIO)
b.start().waitFor()
}
}

def runJvm(
Expand Down
1 change: 1 addition & 0 deletions modules/cli/src/main/scala/scala/cli/ScalaCli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ object ScalaCli extends CommandsEntryPoint {
Compile,
Directories,
Export,
Fmt,
InstallCompletions,
Metabrowse,
Repl,
Expand Down
54 changes: 54 additions & 0 deletions modules/cli/src/main/scala/scala/cli/commands/Fmt.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package scala.cli.commands

import caseapp._

import scala.build.Inputs
import scala.build.internal.Runner
import scala.cli.internal.FetchExternalBinary

object Fmt extends ScalaCommand[FmtOptions] {
override def group = "Miscellaneous"
override def sharedOptions(options: FmtOptions) = Some(options.shared)
def run(options: FmtOptions, args: RemainingArgs): Unit = {

// TODO If no input is given, just pass '.' to scalafmt?
val (sourceFiles, workspace) =
if (args.remaining.isEmpty)
(Seq(os.pwd), os.pwd)
else {
val i = options.shared.inputsOrExit(args)
val s = i.sourceFiles().collect {
case sc: Inputs.Script => sc.path
case sc: Inputs.ScalaFile => sc.path
}
(s, i.workspace)
}

val logger = options.shared.logger
val cache = options.shared.coursierCache

if (sourceFiles.isEmpty)
logger.debug("No source files, not formatting anything")
else {

val fmtLauncher = options.scalafmtLauncher.filter(_.nonEmpty) match {
case Some(launcher) =>
os.Path(launcher, os.pwd)
case None =>
val (url, changing) = options.binaryUrl
FetchExternalBinary.fetch(url, changing, cache, logger, "scalafmt")
}

logger.debug(s"Using scalafmt launcher $fmtLauncher")

val command = Seq(fmtLauncher.toString) ++ sourceFiles.map(_.toString)
Runner.run(
"scalafmt",
command,
logger,
allowExecve = true,
cwd = Some(workspace)
)
}
}
}
41 changes: 41 additions & 0 deletions modules/cli/src/main/scala/scala/cli/commands/FmtOptions.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package scala.cli.commands

import caseapp._

import scala.build.internal.Constants
import scala.cli.internal.FetchExternalBinary
import scala.util.Properties

// format: off
@HelpMessage("Format Scala code")
final case class FmtOptions(
@Recurse
shared: SharedOptions = SharedOptions(),
@HelpMessage("Check that sources are well formatted")
check: Boolean = false,

@Hidden
osArchSuffix: Option[String] = None,
@Hidden
scalafmtTag: Option[String] = None,
@Hidden
scalafmtGitHubOrgName: Option[String] = None,
@Hidden
scalafmtExtension: Option[String] = None,
@Hidden
scalafmtLauncher: Option[String] = None
) {
// format: on

def binaryUrl: (String, Boolean) = {
val osArchSuffix0 = osArchSuffix.map(_.trim).filter(_.nonEmpty)
.getOrElse(FetchExternalBinary.platformSuffix())
val tag0 = scalafmtTag.getOrElse("v" + Constants.defaultScalafmtVersion)
val gitHubOrgName0 = scalafmtGitHubOrgName.getOrElse("alexarchambault/scalafmt-native-image")
val extension0 = if (Properties.isWin) ".zip" else ".gz"
val url =
s"https://github.com/$gitHubOrgName0/releases/download/$tag0/scalafmt-$osArchSuffix0$extension0"
(url, !tag0.startsWith("v"))
}

}
Loading