Repository: scala-steward-org/scala-steward
Pull request #2852 (2022-12-22 21:09:46)

Add sbt plugins locally and not globally
`StewardPlugin.scala` is the sbt plugin that outputs all relevant information from a build for consumption by Scala Steward. That plugin has been installed so far globally at the start of Scala Steward into sbt's home directory. With this PR, that plugin is now installed into the local `project/` directories as long as it is needed to run `sbt stewardDependencies`.

This change is motivated by #2847 - i.e. only sbt >= 1.3.0 can currently load our sbt plugin. With this change we would be able to use different plugins dependending on a repo's sbt version.

closes: #1624


Patch:
diff --git a/README.md b/README.md
index 5f1a29fc..5ace9d1b 100644
--- a/README.md
+++ b/README.md
@@ -192,7 +192,6 @@ Consider creating PR to add your company to the list and join the community.
 * [Tupl](https://www.tupl.com)
 * [VirtusLab](https://virtuslab.com/)
 * [wehkamp](https://www.wehkamp.nl/)
-* [Wiringbits](https://wiringbits.net)
 * [Zalando](https://en.zalando.de/)
 
 ## Participation
diff --git a/modules/core/src/main/scala/org/scalasteward/core/application/StewardAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/application/StewardAlg.scala
index 94944ed7..2fc2e50e 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/application/StewardAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/application/StewardAlg.scala
@@ -20,7 +20,6 @@ import better.files.File
 import cats.effect.{ExitCode, Sync}
 import cats.syntax.all._
 import fs2.Stream
-import org.scalasteward.core.buildtool.sbt.SbtAlg
 import org.scalasteward.core.git.GitAlg
 import org.scalasteward.core.io.{FileAlg, WorkspaceAlg}
 import org.scalasteward.core.nurture.NurtureAlg
@@ -44,7 +43,6 @@ final class StewardAlg[F[_]](config: Config)(implicit
     nurtureAlg: NurtureAlg[F],
     pruningAlg: PruningAlg[F],
     repoCacheAlg: RepoCacheAlg[F],
-    sbtAlg: SbtAlg[F],
     selfCheckAlg: SelfCheckAlg[F],
     workspaceAlg: WorkspaceAlg[F],
     F: Sync[F]
@@ -95,7 +93,7 @@ final class StewardAlg[F[_]](config: Config)(implicit
       for {
         _ <- selfCheckAlg.checkAll
         _ <- workspaceAlg.cleanWorkspace
-        exitCode <- sbtAlg.addGlobalPlugins.surround {
+        exitCode <-
           (config.githubApp.map(getGitHubAppRepos).getOrElse(Stream.empty) ++
             readRepos(config.reposFile))
             .evalMap(steward)
@@ -109,7 +107,6 @@ final class StewardAlg[F[_]](config: Config)(implicit
                   s"""The format is "- $$owner/$$repo" or "- $$owner/$$repo:$$branch"."""
                 logger.warn(msg).as(ExitCode.Success)
             }
-        }
       } yield exitCode
     }
 }
diff --git a/modules/core/src/main/scala/org/scalasteward/core/buildtool/sbt/SbtAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/buildtool/sbt/SbtAlg.scala
index c7e5ddce..244d371c 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/buildtool/sbt/SbtAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/buildtool/sbt/SbtAlg.scala
@@ -25,16 +25,14 @@ import org.scalasteward.core.buildtool.BuildToolAlg
 import org.scalasteward.core.buildtool.sbt.command._
 import org.scalasteward.core.buildtool.sbt.data.SbtVersion
 import org.scalasteward.core.coursier.VersionsCache
-import org.scalasteward.core.data.{Dependency, Scope}
+import org.scalasteward.core.data.{Dependency, Scope, Version}
 import org.scalasteward.core.edit.scalafix.{ScalafixCli, ScalafixMigration}
-import org.scalasteward.core.io.{FileAlg, FileData, ProcessAlg, WorkspaceAlg}
+import org.scalasteward.core.io.{FileAlg, ProcessAlg, WorkspaceAlg}
 import org.scalasteward.core.util.Nel
 import org.scalasteward.core.vcs.data.BuildRoot
-import org.typelevel.log4cats.Logger
 
 final class SbtAlg[F[_]](config: Config)(implicit
     fileAlg: FileAlg[F],
-    logger: Logger[F],
     processAlg: ProcessAlg[F],
     scalafixCli: ScalafixCli[F],
     workspaceAlg: WorkspaceAlg[F],
@@ -44,17 +42,6 @@ final class SbtAlg[F[_]](config: Config)(implicit
   private def getSbtDependency(buildRoot: BuildRoot): F[Option[Dependency]] =
     OptionT(getSbtVersion(buildRoot)).subflatMap(sbtDependency).value
 
-  private def addGlobalPluginTemporarily(plugin: FileData): Resource[F, Unit] =
-    Resource.eval(sbtDir).flatMap { dir =>
-      List("0.13", "1.0").traverse_ { version =>
-        fileAlg.createTemporarily(dir / version / "plugins" / plugin.name, plugin.content)
-      }
-    }
-
-  def addGlobalPlugins: Resource[F, Unit] =
-    Resource.eval(logger.info("Add global sbt plugins")) >>
-      Resource.eval(stewardPlugin).flatMap(addGlobalPluginTemporarily)
-
   override def containsBuild(buildRoot: BuildRoot): F[Boolean] =
     workspaceAlg
       .buildRootDir(buildRoot)
@@ -63,18 +50,28 @@ final class SbtAlg[F[_]](config: Config)(implicit
   private def getSbtVersion(buildRoot: BuildRoot): F[Option[SbtVersion]] =
     for {
       buildRootDir <- workspaceAlg.buildRootDir(buildRoot)
-      maybeProperties <- fileAlg.readFile(buildRootDir / "project" / "build.properties")
+      maybeProperties <- fileAlg.readFile(buildRootDir / project / "build.properties")
       version = maybeProperties.flatMap(parser.parseBuildProperties)
     } yield version
 
   override def getDependencies(buildRoot: BuildRoot): F[List[Scope.Dependencies]] =
+    addStewardPluginTemporarily(buildRoot).surround {
+      for {
+        buildRootDir <- workspaceAlg.buildRootDir(buildRoot)
+        commands = Nel.of(crossStewardDependencies, reloadPlugins, stewardDependencies)
+        lines <- sbt(commands, buildRootDir)
+        dependencies = parser.parseDependencies(lines)
+        additionalDependencies <- getAdditionalDependencies(buildRoot)
+      } yield additionalDependencies ::: dependencies
+    }
+
+  private def addStewardPluginTemporarily(buildRoot: BuildRoot): Resource[F, Unit] =
     for {
-      buildRootDir <- workspaceAlg.buildRootDir(buildRoot)
-      commands = Nel.of(crossStewardDependencies, reloadPlugins, stewardDependencies)
-      lines <- sbt(commands, buildRootDir)
-      dependencies = parser.parseDependencies(lines)
-      additionalDependencies <- getAdditionalDependencies(buildRoot)
-    } yield additionalDependencies ::: dependencies
+      buildRootDir <- Resource.eval(workspaceAlg.buildRootDir(buildRoot))
+      plugin <- Resource.eval(stewardPlugin[F])
+      _ <- fileAlg.createTemporarily(buildRootDir / project, plugin)
+      _ <- fileAlg.createTemporarily(buildRootDir / project / project, plugin)
+    } yield ()
 
   override def runMigration(buildRoot: BuildRoot, migration: ScalafixMigration): F[Unit] =
     migration.targetOrDefault match {
@@ -83,31 +80,29 @@ final class SbtAlg[F[_]](config: Config)(implicit
     }
 
   private def runSourcesMigration(buildRoot: BuildRoot, migration: ScalafixMigration): F[Unit] =
-    sbtScalaFixPluginVersion.foreachF { pluginVersion =>
-      addGlobalPluginTemporarily(scalaStewardScalafixSbt(pluginVersion)).surround {
-        workspaceAlg.buildRootDir(buildRoot).flatMap { buildRootDir =>
-          val withScalacOptions =
-            migration.scalacOptions.fold(Resource.unit[F]) { opts =>
-              val file = scalaStewardScalafixOptions(opts.toList)
-              fileAlg.createTemporarily(buildRootDir / file.name, file.content)
-            }
+    OptionT(latestSbtScalafixVersion).foreachF { pluginVersion =>
+      workspaceAlg.buildRootDir(buildRoot).flatMap { buildRootDir =>
+        val plugin = scalaStewardSbtScalafix(pluginVersion)
+        fileAlg.createTemporarily(buildRootDir / project, plugin).surround {
+          val withScalacOptions = migration.scalacOptions.fold(Resource.unit[F]) { opts =>
+            val options = scalaStewardScalafixOptions(opts.toList)
+            fileAlg.createTemporarily(buildRootDir, options)
+          }
           val scalafixCmds = migration.rewriteRules.map(rule => s"$scalafixAll $rule").toList
           withScalacOptions.surround(sbt(Nel(scalafixEnable, scalafixCmds), buildRootDir).void)
         }
       }
     }
 
-  private def sbtScalaFixPluginVersion: OptionT[F, String] =
-    OptionT(
-      versionsCache
-        .getVersions(Scope(sbtScalaFixDependency, List(config.defaultResolver)), None)
-        .map(_.lastOption.map(_.value))
-    )
+  private def latestSbtScalafixVersion: F[Option[Version]] =
+    versionsCache
+      .getVersions(Scope(sbtScalafixDependency, List(config.defaultResolver)), None)
+      .map(_.lastOption)
 
   private def runBuildMigration(buildRoot: BuildRoot, migration: ScalafixMigration): F[Unit] =
     for {
       buildRootDir <- workspaceAlg.buildRootDir(buildRoot)
-      projectDir = buildRootDir / "project"
+      projectDir = buildRootDir / project
       files0 <- (
         fileAlg.walk(buildRootDir, 1).filter(_.extension.contains(".sbt")) ++
           fileAlg.walk(projectDir, 3).filter(_.extension.exists(Set(".sbt", ".scala")))
@@ -117,9 +112,6 @@ final class SbtAlg[F[_]](config: Config)(implicit
       }
     } yield ()
 
-  private val sbtDir: F[File] =
-    fileAlg.home.map(_ / ".sbt")
-
   private def sbt(sbtCommands: Nel[String], repoDir: File): F[List[String]] =
     maybeIgnoreOptsFiles(repoDir).surround {
       val command =
@@ -133,7 +125,7 @@ final class SbtAlg[F[_]](config: Config)(implicit
       processAlg.execSandboxed(command, repoDir)
     }
 
-  private def maybeIgnoreOptsFiles[A](dir: File): Resource[F, Unit] =
+  private def maybeIgnoreOptsFiles(dir: File): Resource[F, Unit] =
     if (config.ignoreOptsFiles) ignoreOptsFiles(dir) else Resource.unit[F]
 
   private def ignoreOptsFiles(dir: File): Resource[F, Unit] =
@@ -142,4 +134,6 @@ final class SbtAlg[F[_]](config: Config)(implicit
   private def getAdditionalDependencies(buildRoot: BuildRoot): F[List[Scope.Dependencies]] =
     getSbtDependency(buildRoot)
       .map(_.map(dep => Scope(List(dep), List(config.defaultResolver))).toList)
+
+  private val project = "project"
 }
diff --git a/modules/core/src/main/scala/org/scalasteward/core/buildtool/sbt/package.scala b/modules/core/src/main/scala/org/scalasteward/core/buildtool/sbt/package.scala
index 2aa3a9dd..7a15c3d5 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/buildtool/sbt/package.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/buildtool/sbt/package.scala
@@ -35,23 +35,24 @@ package object sbt {
     Option.when(version >= Version("1.0.0"))(Dependency(sbtGroupId, sbtArtifactId, version))
   }
 
-  val sbtScalaFixGroupId = GroupId("ch.epfl.scala")
-  val sbtScalaFixArtifactId = ArtifactId("sbt-scalafix")
+  val sbtScalafixGroupId: GroupId = GroupId("ch.epfl.scala")
 
-  val sbtScalaFixDependency: Dependency =
+  val sbtScalafixArtifactId: ArtifactId = ArtifactId("sbt-scalafix")
+
+  val sbtScalafixDependency: Dependency =
     Dependency(
-      sbtScalaFixGroupId,
-      sbtScalaFixArtifactId,
+      sbtScalafixGroupId,
+      sbtScalafixArtifactId,
       Version(""),
       Some(SbtVersion("1.0")),
       Some(ScalaVersion("2.12"))
     )
 
-  def scalaStewardScalafixSbt(version: String): FileData =
-    FileData(
-      "scala-steward-scalafix.sbt",
-      s"""addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "$version")"""
-    )
+  def scalaStewardSbtScalafix(version: Version): FileData = {
+    val content =
+      s"""addSbtPlugin("${sbtScalafixGroupId.value}" % "${sbtScalafixArtifactId.name}" % "$version")"""
+    FileData("scala-steward-sbt-scalafix.sbt", content)
+  }
 
   def scalaStewardScalafixOptions(scalacOptions: List[String]): FileData = {
     val args = scalacOptions.map(s => s""""$s"""").mkString(", ")
@@ -63,6 +64,6 @@ package object sbt {
     val name = "StewardPlugin.scala"
     fileAlg
       .readResource(s"${pkg.replace('.', '/')}/$name")
-      .map(FileData(name, _))
+      .map(FileData(s"scala-steward-$name", _))
   }
 }
diff --git a/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/HookExecutor.scala b/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/HookExecutor.scala
index 01de4fae..4396def2 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/HookExecutor.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/HookExecutor.scala
@@ -22,8 +22,8 @@ import cats.syntax.all._
 import org.scalasteward.core.buildtool.sbt.{
   sbtArtifactId,
   sbtGroupId,
-  sbtScalaFixArtifactId,
-  sbtScalaFixGroupId
+  sbtScalafixArtifactId,
+  sbtScalafixGroupId
 }
 import org.scalasteward.core.data._
 import org.scalasteward.core.edit.EditAttempt
@@ -123,7 +123,7 @@ object HookExecutor {
 
   // Modules that most likely require the workflow to be regenerated if updated.
   private val conditionalSbtGitHubWorkflowGenerateModules =
-    (sbtGroupId, sbtArtifactId) :: (sbtScalaFixGroupId, sbtScalaFixArtifactId) :: scalaLangModules
+    (sbtGroupId, sbtArtifactId) :: (sbtScalafixGroupId, sbtScalafixArtifactId) :: scalaLangModules
 
   private def sbtGithubWorkflowGenerateHook(
       groupId: GroupId,
diff --git a/modules/core/src/main/scala/org/scalasteward/core/io/FileAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/io/FileAlg.scala
index ad7975e3..8d228f1b 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/io/FileAlg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/io/FileAlg.scala
@@ -32,8 +32,6 @@ trait FileAlg[F[_]] {
 
   def ensureExists(dir: File): F[File]
 
-  def home: F[File]
-
   def isDirectory(file: File): F[Boolean]
 
   def isRegularFile(file: File): F[Boolean]
@@ -58,6 +56,11 @@ trait FileAlg[F[_]] {
     Resource.make(create)(_ => delete)
   }
 
+  final def createTemporarily[E](dir: File, data: FileData)(implicit
+      F: ApplicativeError[F, E]
+  ): Resource[F, Unit] =
+    createTemporarily(dir / data.name, data.content)
+
   final def editFile(file: File, edit: String => Option[String])(implicit
       F: MonadThrow[F]
   ): F[Boolean] =
@@ -99,9 +102,6 @@ object FileAlg {
           dir
         }
 
-      override def home: F[File] =
-        F.delay(File.home)
-
       override def isDirectory(file: File): F[Boolean] =
         F.blocking(file.isDirectory(File.LinkOptions.noFollow))
 


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/buildtool/BuildToolDispatcherTest.scala b/modules/core/src/test/scala/org/scalasteward/core/buildtool/BuildToolDispatcherTest.scala
index d3b057b7..fc5c42dd 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/buildtool/BuildToolDispatcherTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/buildtool/BuildToolDispatcherTest.scala
@@ -33,6 +33,9 @@ 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("read", "classpath:org/scalasteward/sbt/plugin/StewardPlugin.scala"),
+        Cmd("write", s"$repoDir/project/scala-steward-StewardPlugin.scala"),
+        Cmd("write", s"$repoDir/project/project/scala-steward-StewardPlugin.scala"),
         Cmd(
           repoDir.toString,
           "firejail",
@@ -47,6 +50,8 @@ class BuildToolDispatcherTest extends FunSuite {
           s";$crossStewardDependencies;$reloadPlugins;$stewardDependencies"
         ),
         Cmd("read", s"$repoDir/project/build.properties"),
+        Cmd("rm", "-rf", s"$repoDir/project/project/scala-steward-StewardPlugin.scala"),
+        Cmd("rm", "-rf", s"$repoDir/project/scala-steward-StewardPlugin.scala"),
         Cmd("read", s"$repoDir/$scalafmtConfName")
       )
     )
diff --git a/modules/core/src/test/scala/org/scalasteward/core/buildtool/sbt/SbtAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/buildtool/sbt/SbtAlgTest.scala
index da6d6f1b..b808af72 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/buildtool/sbt/SbtAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/buildtool/sbt/SbtAlgTest.scala
@@ -1,6 +1,5 @@
 package org.scalasteward.core.buildtool.sbt
 
-import cats.data.Kleisli
 import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.scalasteward.core.buildtool.sbt.command._
@@ -9,30 +8,11 @@ import org.scalasteward.core.edit.scalafix.ScalafixMigration
 import org.scalasteward.core.mock.MockConfig.{config, mockRoot}
 import org.scalasteward.core.mock.MockContext.context.sbtAlg
 import org.scalasteward.core.mock.MockState
-import org.scalasteward.core.mock.MockState.TraceEntry.{Cmd, Log}
+import org.scalasteward.core.mock.MockState.TraceEntry.Cmd
 import org.scalasteward.core.util.Nel
 import org.scalasteward.core.vcs.data.{BuildRoot, Repo}
 
 class SbtAlgTest extends FunSuite {
-  test("addGlobalPlugins") {
-    val obtained = sbtAlg.addGlobalPlugins
-      .surround(Kleisli(_.update(_.exec(List("fa")))))
-      .runS(MockState.empty)
-      .unsafeRunSync()
-    val expected = MockState.empty.copy(
-      trace = Vector(
-        Log("Add global sbt plugins"),
-        Cmd("read", "classpath:org/scalasteward/sbt/plugin/StewardPlugin.scala"),
-        Cmd("write", s"$mockRoot/.sbt/0.13/plugins/StewardPlugin.scala"),
-        Cmd("write", s"$mockRoot/.sbt/1.0/plugins/StewardPlugin.scala"),
-        Cmd("fa"),
-        Cmd("rm", "-rf", s"$mockRoot/.sbt/1.0/plugins/StewardPlugin.scala"),
-        Cmd("rm", "-rf", s"$mockRoot/.sbt/0.13/plugins/StewardPlugin.scala")
-      )
-    )
-    assertEquals(obtained, expected)
-  }
-
   test("getDependencies") {
     val repo = Repo("typelevel", "cats")
     val buildRoot = BuildRoot(repo, ".")
@@ -42,6 +22,9 @@ class SbtAlgTest extends FunSuite {
     val state = sbtAlg.getDependencies(buildRoot).runS(initial).unsafeRunSync()
     val expected = initial.copy(
       trace = Vector(
+        Cmd("read", "classpath:org/scalasteward/sbt/plugin/StewardPlugin.scala"),
+        Cmd("write", s"$repoDir/project/scala-steward-StewardPlugin.scala"),
+        Cmd("write", s"$repoDir/project/project/scala-steward-StewardPlugin.scala"),
         Cmd(
           repoDir.toString,
           "firejail",
@@ -55,7 +38,9 @@ class SbtAlgTest extends FunSuite {
           "-Dsbt.supershell=false",
           s";$crossStewardDependencies;$reloadPlugins;$stewardDependencies"
         ),
-        Cmd("read", s"$repoDir/project/build.properties")
+        Cmd("read", s"$repoDir/project/build.properties"),
+        Cmd("rm", "-rf", s"$repoDir/project/project/scala-steward-StewardPlugin.scala"),
+        Cmd("rm", "-rf", s"$repoDir/project/scala-steward-StewardPlugin.scala")
       )
     )
     assertEquals(state, expected)
@@ -83,8 +68,7 @@ class SbtAlgTest extends FunSuite {
           "read",
           s"$mockRoot/workspace/store/versions/v2/https/repo1.maven.org/maven2/ch/epfl/scala/sbt-scalafix_2.12_1.0/versions.json"
         ),
-        Cmd("write", s"$mockRoot/.sbt/0.13/plugins/scala-steward-scalafix.sbt"),
-        Cmd("write", s"$mockRoot/.sbt/1.0/plugins/scala-steward-scalafix.sbt"),
+        Cmd("write", s"$repoDir/project/scala-steward-sbt-scalafix.sbt"),
         Cmd(
           repoDir.toString,
           "firejail",
@@ -98,8 +82,7 @@ class SbtAlgTest extends FunSuite {
           "-Dsbt.supershell=false",
           s";$scalafixEnable;$scalafixAll github:functional-streams-for-scala/fs2/v1?sha=v1.0.5"
         ),
-        Cmd("rm", "-rf", s"$mockRoot/.sbt/1.0/plugins/scala-steward-scalafix.sbt"),
-        Cmd("rm", "-rf", s"$mockRoot/.sbt/0.13/plugins/scala-steward-scalafix.sbt")
+        Cmd("rm", "-rf", s"$repoDir/project/scala-steward-sbt-scalafix.sbt")
       )
     )
     assertEquals(state, expected)
@@ -128,8 +111,7 @@ class SbtAlgTest extends FunSuite {
           "read",
           s"$mockRoot/workspace/store/versions/v2/https/repo1.maven.org/maven2/ch/epfl/scala/sbt-scalafix_2.12_1.0/versions.json"
         ),
-        Cmd("write", s"$mockRoot/.sbt/0.13/plugins/scala-steward-scalafix.sbt"),
-        Cmd("write", s"$mockRoot/.sbt/1.0/plugins/scala-steward-scalafix.sbt"),
+        Cmd("write", s"$repoDir/project/scala-steward-sbt-scalafix.sbt"),
         Cmd("write", s"$repoDir/scala-steward-scalafix-options.sbt"),
         Cmd(
           repoDir.toString,
@@ -145,14 +127,13 @@ class SbtAlgTest extends FunSuite {
           s";$scalafixEnable;$scalafixAll github:cb372/cats/Cats_v2_2_0?sha=235bd7c92e431ab1902db174cf4665b05e08f2f1"
         ),
         Cmd("rm", "-rf", s"$repoDir/scala-steward-scalafix-options.sbt"),
-        Cmd("rm", "-rf", s"$mockRoot/.sbt/1.0/plugins/scala-steward-scalafix.sbt"),
-        Cmd("rm", "-rf", s"$mockRoot/.sbt/0.13/plugins/scala-steward-scalafix.sbt")
+        Cmd("rm", "-rf", s"$repoDir/project/scala-steward-sbt-scalafix.sbt")
       )
     )
     assertEquals(state, expected)
   }
 
-  private val sbtScalafixVersionJson =
+  private def sbtScalafixVersionJson =
     s"""|{
         |  "updatedAt" : 9999999999999,
         |  "versions" : [
diff --git a/modules/core/src/test/scala/org/scalasteward/core/io/FileAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/io/FileAlgTest.scala
index 2a834fb1..cd535539 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/io/FileAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/io/FileAlgTest.scala
@@ -51,18 +51,18 @@ class FileAlgTest extends FunSuite {
   }
 
   test("removeTemporarily: nonexistent file") {
-    val file = mockRoot / "does-not-exists.txt"
+    val file = mockRoot / "does-not-exist.txt"
     assertEquals(ioFileAlg.removeTemporarily(file).surround(IO.pure(42)).unsafeRunSync(), 42)
   }
 
   test("editFile: nonexistent file") {
-    val (state, edited) = (for {
-      home <- fileAlg.home
-      edited <- fileAlg.editFile(home / "does-not-exists.txt", Some.apply)
-    } yield edited).runSA(MockState.empty).unsafeRunSync()
+    val (state, edited) = fileAlg
+      .editFile(mockRoot / "does-not-exist.txt", Some.apply)
+      .runSA(MockState.empty)
+      .unsafeRunSync()
 
     val expected =
-      MockState.empty.copy(trace = Vector(Cmd("read", s"$mockRoot/does-not-exists.txt")))
+      MockState.empty.copy(trace = Vector(Cmd("read", s"$mockRoot/does-not-exist.txt")))
     assertEquals(state, expected)
     assert(!edited)
   }
diff --git a/modules/core/src/test/scala/org/scalasteward/core/io/MockFileAlg.scala b/modules/core/src/test/scala/org/scalasteward/core/io/MockFileAlg.scala
index f4567550..091a6cc6 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/io/MockFileAlg.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/io/MockFileAlg.scala
@@ -15,9 +15,6 @@ class MockFileAlg extends FileAlg[MockEff] {
   override def ensureExists(dir: File): MockEff[File] =
     Kleisli(_.update(_.exec(List("mkdir", "-p", dir.pathAsString))) >> ioFileAlg.ensureExists(dir))
 
-  override def home: MockEff[File] =
-    Kleisli.pure(MockConfig.mockRoot)
-
   override def isDirectory(file: File): MockEff[Boolean] =
     Kleisli(_.update(_.exec(List("test", "-d", file.pathAsString))) >> ioFileAlg.isDirectory(file))