Skip to content

Commit bf941ea

Browse files
authored
Extract dependencies from scala-cli via sbt export (#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
1 parent 6787260 commit bf941ea

File tree

9 files changed

+167
-5
lines changed

9 files changed

+167
-5
lines changed

build.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ lazy val dockerSettings = Def.settings(
348348
Cmd("RUN", "apk --no-cache add bash git ca-certificates curl maven openssh nodejs npm"),
349349
Cmd("RUN", s"wget $sbtUrl && tar -xf $sbtTgz && rm -f $sbtTgz"),
350350
Cmd("RUN", s"curl -L $millUrl > $millBin && chmod +x $millBin"),
351+
Cmd("RUN", "curl -sSLf https://virtuslab.github.io/scala-cli-packages/scala-setup.sh | sh"),
351352
Cmd("RUN", s"curl -L https://git.io/coursier-cli > $coursierBin && chmod +x $coursierBin"),
352353
Cmd("RUN", s"$coursierBin install --install-dir $binDir scalafix scalafmt"),
353354
Cmd("RUN", "npm install --global yarn")

modules/core/src/main/scala/org/scalasteward/core/application/Context.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import org.scalasteward.core.buildtool.BuildToolDispatcher
3030
import org.scalasteward.core.buildtool.maven.MavenAlg
3131
import org.scalasteward.core.buildtool.mill.MillAlg
3232
import org.scalasteward.core.buildtool.sbt.SbtAlg
33+
import org.scalasteward.core.buildtool.scalacli.ScalaCliAlg
3334
import org.scalasteward.core.client.ClientConfiguration
3435
import org.scalasteward.core.coursier.{CoursierAlg, VersionsCache}
3536
import org.scalasteward.core.data.Repo
@@ -75,6 +76,7 @@ final class Context[F[_]](implicit
7576
val repoCacheAlg: RepoCacheAlg[F],
7677
val repoConfigAlg: RepoConfigAlg[F],
7778
val sbtAlg: SbtAlg[F],
79+
val scalaCliAlg: ScalaCliAlg[F],
7880
val scalafixMigrationsFinder: ScalafixMigrationsFinder,
7981
val scalafixMigrationsLoader: ScalafixMigrationsLoader[F],
8082
val scalafmtAlg: ScalafmtAlg[F],
@@ -221,6 +223,7 @@ object Context {
221223
implicit val updateAlg: UpdateAlg[F] = new UpdateAlg[F]
222224
implicit val mavenAlg: MavenAlg[F] = new MavenAlg[F](config)
223225
implicit val sbtAlg: SbtAlg[F] = new SbtAlg[F](config)
226+
implicit val scalaCliAlg: ScalaCliAlg[F] = new ScalaCliAlg[F]
224227
implicit val millAlg: MillAlg[F] = new MillAlg[F]
225228
implicit val buildToolDispatcher: BuildToolDispatcher[F] = new BuildToolDispatcher[F]
226229
implicit val refreshErrorAlg: RefreshErrorAlg[F] =

modules/core/src/main/scala/org/scalasteward/core/buildtool/BuildToolDispatcher.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import cats.syntax.all._
2121
import org.scalasteward.core.buildtool.maven.MavenAlg
2222
import org.scalasteward.core.buildtool.mill.MillAlg
2323
import org.scalasteward.core.buildtool.sbt.SbtAlg
24+
import org.scalasteward.core.buildtool.scalacli.ScalaCliAlg
2425
import org.scalasteward.core.data.{Repo, Scope}
2526
import org.scalasteward.core.edit.scalafix.ScalafixMigration
2627
import org.scalasteward.core.repoconfig.RepoConfig
@@ -32,6 +33,7 @@ final class BuildToolDispatcher[F[_]](implicit
3233
mavenAlg: MavenAlg[F],
3334
millAlg: MillAlg[F],
3435
sbtAlg: SbtAlg[F],
36+
scalaCliAlg: ScalaCliAlg[F],
3537
scalafmtAlg: ScalafmtAlg[F],
3638
F: Monad[F]
3739
) {
@@ -54,7 +56,7 @@ final class BuildToolDispatcher[F[_]](implicit
5456
private def getBuildRoots(repo: Repo, repoConfig: RepoConfig): List[BuildRoot] =
5557
repoConfig.buildRootsOrDefault.map(buildRootCfg => BuildRoot(repo, buildRootCfg.relativePath))
5658

57-
private val allBuildTools = List(mavenAlg, millAlg, sbtAlg)
59+
private val allBuildTools = List(mavenAlg, millAlg, sbtAlg, scalaCliAlg)
5860
private val fallbackBuildTool = List(sbtAlg)
5961

6062
private def findBuildTools(buildRoot: BuildRoot): F[(BuildRoot, List[BuildToolAlg[F]])] =

modules/core/src/main/scala/org/scalasteward/core/buildtool/maven/MavenAlg.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ final class MavenAlg[F[_]](config: Config)(implicit
5858

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

6464
private def exec(command: Nel[String], repoDir: File): F[List[String]] =

modules/core/src/main/scala/org/scalasteward/core/buildtool/mill/MillAlg.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import cats.effect.MonadCancelThrow
2121
import cats.syntax.all._
2222
import org.scalasteward.core.buildtool.mill.MillAlg._
2323
import org.scalasteward.core.buildtool.{BuildRoot, BuildToolAlg}
24-
import org.scalasteward.core.data.Scope.Dependencies
2524
import org.scalasteward.core.data._
2625
import org.scalasteward.core.edit.scalafix.ScalafixMigration
2726
import org.scalasteward.core.io.{FileAlg, ProcessAlg, WorkspaceAlg}
@@ -42,7 +41,7 @@ final class MillAlg[F[_]](implicit
4241
.buildRootDir(buildRoot)
4342
.flatMap(buildRootDir => fileAlg.isRegularFile(buildRootDir / "build.sc"))
4443

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

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

7271
private def getMillVersion(buildRootDir: File): F[Option[Version]] =
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2018-2023 Scala Steward contributors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.scalasteward.core.buildtool.scalacli
18+
19+
import cats.Monad
20+
import cats.syntax.all._
21+
import org.scalasteward.core.buildtool.sbt.SbtAlg
22+
import org.scalasteward.core.buildtool.{BuildRoot, BuildToolAlg}
23+
import org.scalasteward.core.data.Scope
24+
import org.scalasteward.core.edit.scalafix.ScalafixMigration
25+
import org.scalasteward.core.git.GitAlg
26+
import org.scalasteward.core.io.{FileAlg, ProcessAlg, WorkspaceAlg}
27+
import org.scalasteward.core.util.Nel
28+
import org.typelevel.log4cats.Logger
29+
30+
final class ScalaCliAlg[F[_]](implicit
31+
fileAlg: FileAlg[F],
32+
gitAlg: GitAlg[F],
33+
logger: Logger[F],
34+
processAlg: ProcessAlg[F],
35+
sbtAlg: SbtAlg[F],
36+
workspaceAlg: WorkspaceAlg[F],
37+
F: Monad[F]
38+
) extends BuildToolAlg[F] {
39+
override def name: String = "Scala CLI"
40+
41+
override def containsBuild(buildRoot: BuildRoot): F[Boolean] = {
42+
val buildRootPath = buildRoot.relativePath.dropWhile(Set('.', '/'))
43+
gitAlg
44+
.findFilesContaining(buildRoot.repo, "//> using lib ")
45+
.map(_.exists(_.startsWith(buildRootPath)))
46+
}
47+
48+
override def getDependencies(buildRoot: BuildRoot): F[List[Scope.Dependencies]] =
49+
for {
50+
buildRootDir <- workspaceAlg.buildRootDir(buildRoot)
51+
exportDir = "tmp-sbt-build-for-scala-steward"
52+
exportCmd =
53+
Nel.of("scala-cli", "export", "--sbt", "--output", exportDir, buildRootDir.pathAsString)
54+
_ <- processAlg.execSandboxed(exportCmd, buildRootDir)
55+
exportBuildRoot = buildRoot.copy(relativePath = buildRoot.relativePath + s"/$exportDir")
56+
dependencies <- sbtAlg.getDependencies(exportBuildRoot)
57+
_ <- fileAlg.deleteForce(buildRootDir / exportDir)
58+
} yield dependencies
59+
60+
override def runMigration(buildRoot: BuildRoot, migration: ScalafixMigration): F[Unit] =
61+
logger.warn(
62+
s"Scalafix migrations are currently not supported in $name projects, see https://github.com/VirtusLab/scala-cli/issues/647 for details"
63+
)
64+
}

modules/core/src/test/scala/org/scalasteward/core/buildtool/BuildToolDispatcherTest.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import cats.effect.unsafe.implicits.global
44
import munit.FunSuite
55
import org.scalasteward.core.buildtool.sbt.command._
66
import org.scalasteward.core.data._
7+
import org.scalasteward.core.mock.MockConfig.gitCmd
78
import org.scalasteward.core.mock.MockContext.context._
89
import org.scalasteward.core.mock.MockState
910
import org.scalasteward.core.mock.MockState.TraceEntry.{Cmd, Log}
@@ -33,9 +34,25 @@ class BuildToolDispatcherTest extends FunSuite {
3334
Cmd("test", "-f", s"$repoDir/pom.xml"),
3435
Cmd("test", "-f", s"$repoDir/build.sc"),
3536
Cmd("test", "-f", s"$repoDir/build.sbt"),
37+
Cmd(
38+
gitCmd(repoDir),
39+
"grep",
40+
"-I",
41+
"--fixed-strings",
42+
"--files-with-matches",
43+
"//> using lib "
44+
),
3645
Cmd("test", "-f", s"$repoDir/mvn-build/pom.xml"),
3746
Cmd("test", "-f", s"$repoDir/mvn-build/build.sc"),
3847
Cmd("test", "-f", s"$repoDir/mvn-build/build.sbt"),
48+
Cmd(
49+
gitCmd(repoDir),
50+
"grep",
51+
"-I",
52+
"--fixed-strings",
53+
"--files-with-matches",
54+
"//> using lib "
55+
),
3956
Log("Get dependencies in . from sbt"),
4057
Cmd("read", s"$repoDir/project/build.properties"),
4158
Cmd("read", "classpath:StewardPlugin_1_0_0.scala"),
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package org.scalasteward.core.buildtool.scalacli
2+
3+
import munit.CatsEffectSuite
4+
import org.scalasteward.core.buildtool.BuildRoot
5+
import org.scalasteward.core.buildtool.sbt.command._
6+
import org.scalasteward.core.data.{GroupId, Repo, Version}
7+
import org.scalasteward.core.edit.scalafix.ScalafixMigration
8+
import org.scalasteward.core.mock.MockContext.context._
9+
import org.scalasteward.core.mock.MockState
10+
import org.scalasteward.core.mock.MockState.TraceEntry.{Cmd, Log}
11+
import org.scalasteward.core.util.Nel
12+
13+
class ScalaCliAlgTest extends CatsEffectSuite {
14+
test("getDependencies") {
15+
val repo = Repo("user", "repo")
16+
val buildRoot = BuildRoot(repo, ".")
17+
val repoDir = workspaceAlg.repoDir(repo).unsafeRunSync()
18+
val sbtBuildDir = repoDir / "tmp-sbt-build-for-scala-steward"
19+
20+
val obtained = scalaCliAlg.getDependencies(buildRoot).runS(MockState.empty)
21+
val expected = MockState.empty.copy(trace =
22+
Vector(
23+
Cmd(
24+
repoDir.toString,
25+
"firejail",
26+
"--quiet",
27+
s"--whitelist=$repoDir",
28+
"--env=VAR1=val1",
29+
"--env=VAR2=val2",
30+
"scala-cli",
31+
"export",
32+
"--sbt",
33+
"--output",
34+
"tmp-sbt-build-for-scala-steward",
35+
repoDir.toString
36+
),
37+
Cmd("read", s"$sbtBuildDir/project/build.properties"),
38+
Cmd("read", "classpath:StewardPlugin_1_3_11.scala"),
39+
Cmd("write", s"$sbtBuildDir/project/scala-steward-StewardPlugin_1_3_11.scala"),
40+
Cmd("write", s"$sbtBuildDir/project/project/scala-steward-StewardPlugin_1_3_11.scala"),
41+
Cmd(
42+
sbtBuildDir.toString,
43+
"firejail",
44+
"--quiet",
45+
s"--whitelist=$sbtBuildDir",
46+
"--env=VAR1=val1",
47+
"--env=VAR2=val2",
48+
"sbt",
49+
"-Dsbt.color=false",
50+
"-Dsbt.log.noformat=true",
51+
"-Dsbt.supershell=false",
52+
s";$crossStewardDependencies;$reloadPlugins;$stewardDependencies"
53+
),
54+
Cmd("rm", "-rf", s"$sbtBuildDir/project/project/scala-steward-StewardPlugin_1_3_11.scala"),
55+
Cmd("rm", "-rf", s"$sbtBuildDir/project/scala-steward-StewardPlugin_1_3_11.scala"),
56+
Cmd("rm", "-rf", s"$sbtBuildDir")
57+
)
58+
)
59+
60+
assertIO(obtained, expected)
61+
}
62+
63+
test("runMigration") {
64+
val repo = Repo("user", "repo")
65+
val buildRoot = BuildRoot(repo, ".")
66+
val migration = ScalafixMigration(
67+
GroupId("co.fs2"),
68+
Nel.of("fs2-core"),
69+
Version("1.0.0"),
70+
Nel.of("github:functional-streams-for-scala/fs2/v1?sha=v1.0.5")
71+
)
72+
val obtained = scalaCliAlg.runMigration(buildRoot, migration).runS(MockState.empty)
73+
assertIO(obtained.map(_.trace.collect { case Log(_) => () }.size), 1)
74+
}
75+
}

repos.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ All lines that do not start with a hyphen and space are ignored.
1010
- scala-steward-org/sbt-plugin
1111
- scala-steward-org/scala-steward
1212
- scala-steward-org/test-repo-1
13+
- scala-steward-org/test-repo-1:scala-cli-test
1314
- scala-steward-org/test-repo-2

0 commit comments

Comments
 (0)