Skip to content

Commit

Permalink
Extract dependencies from scala-cli via sbt export (scala-steward-org…
Browse files Browse the repository at this point in the history
…#2933)

* Extract dependencies from scala-cli via sbt export

* Fix BuildToolDispatcherTest

* Install scala-cli in Docker container

* Warn about missing Scalafix support in Scala CLI projects

* Use Scope.Dependencies in all BuildToolAlg implementations

* Remove unused import

* Remove the export directory after calling sbtAlg

* Do not install scala-cli with coursier

Use the command from https://scala-cli.virtuslab.org/install instead.

* Require a space after "using lib"

* Use less vertical space

* Ensure that using directives are in files below buildRoot

* Add test

* Test runMigration

* Link to the Scala CLI issue about Scalafix support

* Check that runMigration only logs
  • Loading branch information
fthomas authored Jan 19, 2023
1 parent 6787260 commit bf941ea
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 5 deletions.
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ lazy val dockerSettings = Def.settings(
Cmd("RUN", "apk --no-cache add bash git ca-certificates curl maven openssh nodejs npm"),
Cmd("RUN", s"wget $sbtUrl && tar -xf $sbtTgz && rm -f $sbtTgz"),
Cmd("RUN", s"curl -L $millUrl > $millBin && chmod +x $millBin"),
Cmd("RUN", "curl -sSLf https://virtuslab.github.io/scala-cli-packages/scala-setup.sh | sh"),
Cmd("RUN", s"curl -L https://git.io/coursier-cli > $coursierBin && chmod +x $coursierBin"),
Cmd("RUN", s"$coursierBin install --install-dir $binDir scalafix scalafmt"),
Cmd("RUN", "npm install --global yarn")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import org.scalasteward.core.buildtool.BuildToolDispatcher
import org.scalasteward.core.buildtool.maven.MavenAlg
import org.scalasteward.core.buildtool.mill.MillAlg
import org.scalasteward.core.buildtool.sbt.SbtAlg
import org.scalasteward.core.buildtool.scalacli.ScalaCliAlg
import org.scalasteward.core.client.ClientConfiguration
import org.scalasteward.core.coursier.{CoursierAlg, VersionsCache}
import org.scalasteward.core.data.Repo
Expand Down Expand Up @@ -75,6 +76,7 @@ final class Context[F[_]](implicit
val repoCacheAlg: RepoCacheAlg[F],
val repoConfigAlg: RepoConfigAlg[F],
val sbtAlg: SbtAlg[F],
val scalaCliAlg: ScalaCliAlg[F],
val scalafixMigrationsFinder: ScalafixMigrationsFinder,
val scalafixMigrationsLoader: ScalafixMigrationsLoader[F],
val scalafmtAlg: ScalafmtAlg[F],
Expand Down Expand Up @@ -221,6 +223,7 @@ object Context {
implicit val updateAlg: UpdateAlg[F] = new UpdateAlg[F]
implicit val mavenAlg: MavenAlg[F] = new MavenAlg[F](config)
implicit val sbtAlg: SbtAlg[F] = new SbtAlg[F](config)
implicit val scalaCliAlg: ScalaCliAlg[F] = new ScalaCliAlg[F]
implicit val millAlg: MillAlg[F] = new MillAlg[F]
implicit val buildToolDispatcher: BuildToolDispatcher[F] = new BuildToolDispatcher[F]
implicit val refreshErrorAlg: RefreshErrorAlg[F] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import cats.syntax.all._
import org.scalasteward.core.buildtool.maven.MavenAlg
import org.scalasteward.core.buildtool.mill.MillAlg
import org.scalasteward.core.buildtool.sbt.SbtAlg
import org.scalasteward.core.buildtool.scalacli.ScalaCliAlg
import org.scalasteward.core.data.{Repo, Scope}
import org.scalasteward.core.edit.scalafix.ScalafixMigration
import org.scalasteward.core.repoconfig.RepoConfig
Expand All @@ -32,6 +33,7 @@ final class BuildToolDispatcher[F[_]](implicit
mavenAlg: MavenAlg[F],
millAlg: MillAlg[F],
sbtAlg: SbtAlg[F],
scalaCliAlg: ScalaCliAlg[F],
scalafmtAlg: ScalafmtAlg[F],
F: Monad[F]
) {
Expand All @@ -54,7 +56,7 @@ final class BuildToolDispatcher[F[_]](implicit
private def getBuildRoots(repo: Repo, repoConfig: RepoConfig): List[BuildRoot] =
repoConfig.buildRootsOrDefault.map(buildRootCfg => BuildRoot(repo, buildRootCfg.relativePath))

private val allBuildTools = List(mavenAlg, millAlg, sbtAlg)
private val allBuildTools = List(mavenAlg, millAlg, sbtAlg, scalaCliAlg)
private val fallbackBuildTool = List(sbtAlg)

private def findBuildTools(buildRoot: BuildRoot): F[(BuildRoot, List[BuildToolAlg[F]])] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ final class MavenAlg[F[_]](config: Config)(implicit

override def runMigration(buildRoot: BuildRoot, migration: ScalafixMigration): F[Unit] =
logger.warn(
"Scalafix migrations are currently not supported in Maven projects, see https://github.com/scala-steward-org/scala-steward/issues/2839 for details"
s"Scalafix migrations are currently not supported in $name projects, see https://github.com/scala-steward-org/scala-steward/issues/2839 for details"
)

private def exec(command: Nel[String], repoDir: File): F[List[String]] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import cats.effect.MonadCancelThrow
import cats.syntax.all._
import org.scalasteward.core.buildtool.mill.MillAlg._
import org.scalasteward.core.buildtool.{BuildRoot, BuildToolAlg}
import org.scalasteward.core.data.Scope.Dependencies
import org.scalasteward.core.data._
import org.scalasteward.core.edit.scalafix.ScalafixMigration
import org.scalasteward.core.io.{FileAlg, ProcessAlg, WorkspaceAlg}
Expand All @@ -42,7 +41,7 @@ final class MillAlg[F[_]](implicit
.buildRootDir(buildRoot)
.flatMap(buildRootDir => fileAlg.isRegularFile(buildRootDir / "build.sc"))

override def getDependencies(buildRoot: BuildRoot): F[List[Dependencies]] =
override def getDependencies(buildRoot: BuildRoot): F[List[Scope.Dependencies]] =
for {
buildRootDir <- workspaceAlg.buildRootDir(buildRoot)
predef = buildRootDir / "scala-steward.sc"
Expand All @@ -66,7 +65,7 @@ final class MillAlg[F[_]](implicit

override def runMigration(buildRoot: BuildRoot, migration: ScalafixMigration): F[Unit] =
logger.warn(
"Scalafix migrations are currently not supported in Mill projects, see https://github.com/scala-steward-org/scala-steward/issues/2838 for details"
s"Scalafix migrations are currently not supported in $name projects, see https://github.com/scala-steward-org/scala-steward/issues/2838 for details"
)

private def getMillVersion(buildRootDir: File): F[Option[Version]] =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2018-2023 Scala Steward contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.scalasteward.core.buildtool.scalacli

import cats.Monad
import cats.syntax.all._
import org.scalasteward.core.buildtool.sbt.SbtAlg
import org.scalasteward.core.buildtool.{BuildRoot, BuildToolAlg}
import org.scalasteward.core.data.Scope
import org.scalasteward.core.edit.scalafix.ScalafixMigration
import org.scalasteward.core.git.GitAlg
import org.scalasteward.core.io.{FileAlg, ProcessAlg, WorkspaceAlg}
import org.scalasteward.core.util.Nel
import org.typelevel.log4cats.Logger

final class ScalaCliAlg[F[_]](implicit
fileAlg: FileAlg[F],
gitAlg: GitAlg[F],
logger: Logger[F],
processAlg: ProcessAlg[F],
sbtAlg: SbtAlg[F],
workspaceAlg: WorkspaceAlg[F],
F: Monad[F]
) extends BuildToolAlg[F] {
override def name: String = "Scala CLI"

override def containsBuild(buildRoot: BuildRoot): F[Boolean] = {
val buildRootPath = buildRoot.relativePath.dropWhile(Set('.', '/'))
gitAlg
.findFilesContaining(buildRoot.repo, "//> using lib ")
.map(_.exists(_.startsWith(buildRootPath)))
}

override def getDependencies(buildRoot: BuildRoot): F[List[Scope.Dependencies]] =
for {
buildRootDir <- workspaceAlg.buildRootDir(buildRoot)
exportDir = "tmp-sbt-build-for-scala-steward"
exportCmd =
Nel.of("scala-cli", "export", "--sbt", "--output", exportDir, buildRootDir.pathAsString)
_ <- processAlg.execSandboxed(exportCmd, buildRootDir)
exportBuildRoot = buildRoot.copy(relativePath = buildRoot.relativePath + s"/$exportDir")
dependencies <- sbtAlg.getDependencies(exportBuildRoot)
_ <- fileAlg.deleteForce(buildRootDir / exportDir)
} yield dependencies

override def runMigration(buildRoot: BuildRoot, migration: ScalafixMigration): F[Unit] =
logger.warn(
s"Scalafix migrations are currently not supported in $name projects, see https://github.com/VirtusLab/scala-cli/issues/647 for details"
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import cats.effect.unsafe.implicits.global
import munit.FunSuite
import org.scalasteward.core.buildtool.sbt.command._
import org.scalasteward.core.data._
import org.scalasteward.core.mock.MockConfig.gitCmd
import org.scalasteward.core.mock.MockContext.context._
import org.scalasteward.core.mock.MockState
import org.scalasteward.core.mock.MockState.TraceEntry.{Cmd, Log}
Expand Down Expand Up @@ -33,9 +34,25 @@ class BuildToolDispatcherTest extends FunSuite {
Cmd("test", "-f", s"$repoDir/pom.xml"),
Cmd("test", "-f", s"$repoDir/build.sc"),
Cmd("test", "-f", s"$repoDir/build.sbt"),
Cmd(
gitCmd(repoDir),
"grep",
"-I",
"--fixed-strings",
"--files-with-matches",
"//> using lib "
),
Cmd("test", "-f", s"$repoDir/mvn-build/pom.xml"),
Cmd("test", "-f", s"$repoDir/mvn-build/build.sc"),
Cmd("test", "-f", s"$repoDir/mvn-build/build.sbt"),
Cmd(
gitCmd(repoDir),
"grep",
"-I",
"--fixed-strings",
"--files-with-matches",
"//> using lib "
),
Log("Get dependencies in . from sbt"),
Cmd("read", s"$repoDir/project/build.properties"),
Cmd("read", "classpath:StewardPlugin_1_0_0.scala"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package org.scalasteward.core.buildtool.scalacli

import munit.CatsEffectSuite
import org.scalasteward.core.buildtool.BuildRoot
import org.scalasteward.core.buildtool.sbt.command._
import org.scalasteward.core.data.{GroupId, Repo, Version}
import org.scalasteward.core.edit.scalafix.ScalafixMigration
import org.scalasteward.core.mock.MockContext.context._
import org.scalasteward.core.mock.MockState
import org.scalasteward.core.mock.MockState.TraceEntry.{Cmd, Log}
import org.scalasteward.core.util.Nel

class ScalaCliAlgTest extends CatsEffectSuite {
test("getDependencies") {
val repo = Repo("user", "repo")
val buildRoot = BuildRoot(repo, ".")
val repoDir = workspaceAlg.repoDir(repo).unsafeRunSync()
val sbtBuildDir = repoDir / "tmp-sbt-build-for-scala-steward"

val obtained = scalaCliAlg.getDependencies(buildRoot).runS(MockState.empty)
val expected = MockState.empty.copy(trace =
Vector(
Cmd(
repoDir.toString,
"firejail",
"--quiet",
s"--whitelist=$repoDir",
"--env=VAR1=val1",
"--env=VAR2=val2",
"scala-cli",
"export",
"--sbt",
"--output",
"tmp-sbt-build-for-scala-steward",
repoDir.toString
),
Cmd("read", s"$sbtBuildDir/project/build.properties"),
Cmd("read", "classpath:StewardPlugin_1_3_11.scala"),
Cmd("write", s"$sbtBuildDir/project/scala-steward-StewardPlugin_1_3_11.scala"),
Cmd("write", s"$sbtBuildDir/project/project/scala-steward-StewardPlugin_1_3_11.scala"),
Cmd(
sbtBuildDir.toString,
"firejail",
"--quiet",
s"--whitelist=$sbtBuildDir",
"--env=VAR1=val1",
"--env=VAR2=val2",
"sbt",
"-Dsbt.color=false",
"-Dsbt.log.noformat=true",
"-Dsbt.supershell=false",
s";$crossStewardDependencies;$reloadPlugins;$stewardDependencies"
),
Cmd("rm", "-rf", s"$sbtBuildDir/project/project/scala-steward-StewardPlugin_1_3_11.scala"),
Cmd("rm", "-rf", s"$sbtBuildDir/project/scala-steward-StewardPlugin_1_3_11.scala"),
Cmd("rm", "-rf", s"$sbtBuildDir")
)
)

assertIO(obtained, expected)
}

test("runMigration") {
val repo = Repo("user", "repo")
val buildRoot = BuildRoot(repo, ".")
val migration = ScalafixMigration(
GroupId("co.fs2"),
Nel.of("fs2-core"),
Version("1.0.0"),
Nel.of("github:functional-streams-for-scala/fs2/v1?sha=v1.0.5")
)
val obtained = scalaCliAlg.runMigration(buildRoot, migration).runS(MockState.empty)
assertIO(obtained.map(_.trace.collect { case Log(_) => () }.size), 1)
}
}
1 change: 1 addition & 0 deletions repos.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ All lines that do not start with a hyphen and space are ignored.
- scala-steward-org/sbt-plugin
- scala-steward-org/scala-steward
- scala-steward-org/test-repo-1
- scala-steward-org/test-repo-1:scala-cli-test
- scala-steward-org/test-repo-2

0 comments on commit bf941ea

Please sign in to comment.