Skip to content

Commit 025beec

Browse files
committed
Merge branch 'workspace-warning'
2 parents ee0775f + 24fcd22 commit 025beec

File tree

5 files changed

+67
-23
lines changed

5 files changed

+67
-23
lines changed

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ import cats.syntax.all._
2121
import org.scalasteward.core.edit.scalafix.ScalafixCli
2222
import org.scalasteward.core.edit.scalafix.ScalafixCli.scalafixBinary
2323
import org.scalasteward.core.git.GitAlg
24+
import org.scalasteward.core.io.FileAlg
2425
import org.scalasteward.core.scalafmt.{scalafmtBinary, ScalafmtAlg}
2526
import org.scalasteward.core.util.UrlChecker
2627
import org.scalasteward.core.util.logger.LoggerOps
2728
import org.typelevel.log4cats.Logger
2829

2930
final class SelfCheckAlg[F[_]](config: Config)(implicit
31+
fileAlg: FileAlg[F],
3032
gitAlg: GitAlg[F],
3133
logger: Logger[F],
3234
scalafixCli: ScalafixCli[F],
@@ -37,12 +39,28 @@ final class SelfCheckAlg[F[_]](config: Config)(implicit
3739
def checkAll: F[Unit] =
3840
for {
3941
_ <- logger.info("Run self checks")
42+
_ <- checkWorkspaceDirectory
4043
_ <- checkGitBinary
4144
_ <- checkScalafixBinary
4245
_ <- checkScalafmtBinary
4346
_ <- checkUrlChecker
4447
} yield ()
4548

49+
private def checkWorkspaceDirectory: F[Unit] =
50+
fileAlg
51+
.isNonEmptyDirectory(config.workspace)
52+
.ifM(
53+
F.unit,
54+
logger.warn(
55+
s"""
56+
|The workspace directory is empty: '${config.workspace}'
57+
|This is expected if this is your first Scala Steward run.
58+
|Make sure to preserve the workspace between runs for all features to work as expected.
59+
|https://github.com/scala-steward-org/scala-steward/blob/main/docs/faq.md#why-doesnt-self-hosted-scala-steward-close-obsolete-prs
60+
|""".stripMargin
61+
)
62+
)
63+
4664
private def checkGitBinary: F[Unit] =
4765
logger.attemptWarn.log_(execFailedMessage("git")) {
4866
gitAlg.version.flatMap(output => logger.info(s"Using $output"))

modules/core/src/main/scala/org/scalasteward/core/io/FileAlg.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ trait FileAlg[F[_]] {
3434

3535
def isDirectory(file: File): F[Boolean]
3636

37+
def isNonEmptyDirectory(dir: File): F[Boolean]
38+
3739
def isRegularFile(file: File): F[Boolean]
3840

3941
def removeTemporarily(file: File): Resource[F, Unit]
@@ -101,6 +103,9 @@ object FileAlg {
101103
override def isDirectory(file: File): F[Boolean] =
102104
F.blocking(file.isDirectory(File.LinkOptions.noFollow))
103105

106+
override def isNonEmptyDirectory(dir: File): F[Boolean] =
107+
F.blocking(dir.isDirectory(File.LinkOptions.noFollow) && dir.nonEmpty)
108+
104109
override def isRegularFile(file: File): F[Boolean] =
105110
F.blocking(file.isRegularFile(File.LinkOptions.noFollow))
106111

modules/core/src/test/scala/org/scalasteward/core/application/StewardAlgTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ import org.scalasteward.core.mock.MockState
88
class StewardAlgTest extends CatsEffectSuite {
99
test("runF") {
1010
val exitCode = stewardAlg.runF.runA(MockState.empty)
11-
exitCode.map(assertEquals(_, ExitCode.Success))
11+
assertIO(exitCode, ExitCode.Success)
1212
}
1313
}

modules/core/src/test/scala/org/scalasteward/core/io/FileAlgTest.scala

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ package org.scalasteward.core.io
22

33
import better.files.File
44
import cats.effect.IO
5-
import cats.effect.unsafe.implicits.global
6-
import munit.FunSuite
5+
import munit.CatsEffectSuite
76
import org.http4s.Uri
87
import org.scalacheck.Arbitrary
98
import org.scalasteward.core.TestInstances.ioLogger
@@ -13,65 +12,65 @@ import org.scalasteward.core.mock.MockContext.context.fileAlg
1312
import org.scalasteward.core.mock.MockState
1413
import org.scalasteward.core.mock.MockState.TraceEntry.Cmd
1514

16-
class FileAlgTest extends FunSuite {
15+
class FileAlgTest extends CatsEffectSuite {
1716
test("createTemporarily") {
1817
val file = mockRoot / "test-scala-steward3.tmp"
1918
val content = Arbitrary.arbitrary[String].sample.getOrElse("")
2019

21-
val p = for {
20+
val obtained = for {
2221
before <- ioFileAlg.readFile(file)
2322
during <- ioFileAlg.createTemporarily(file, content).surround(ioFileAlg.readFile(file))
2423
after <- ioFileAlg.readFile(file)
2524
} yield (before, during, after)
2625

27-
assertEquals(p.unsafeRunSync(), (None, Some(content), None))
26+
assertIO(obtained, (None, Some(content), None))
2827
}
2928

3029
test("writeFile *> readFile <* deleteForce") {
3130
val file = mockRoot / "test-scala-steward1.tmp"
3231
val content = Arbitrary.arbitrary[String].sample.getOrElse("")
33-
val read = ioFileAlg.writeFile(file, content) *>
32+
val obtained = ioFileAlg.writeFile(file, content) *>
3433
ioFileAlg.readFile(file).map(_.getOrElse("")) <*
3534
ioFileAlg.deleteForce(file)
36-
assertEquals(read.unsafeRunSync(), content)
35+
assertIO(obtained, content)
3736
}
3837

3938
test("removeTemporarily") {
4039
val file = mockRoot / "test-scala-steward2.tmp"
4140
val content = Arbitrary.arbitrary[String].sample.getOrElse("")
4241

43-
val p = for {
42+
val obtained = for {
4443
_ <- ioFileAlg.writeFile(file, content)
4544
before <- ioFileAlg.readFile(file)
4645
during <- ioFileAlg.removeTemporarily(file).surround(ioFileAlg.readFile(file))
4746
after <- ioFileAlg.readFile(file)
4847
} yield (before, during, after)
4948

50-
assertEquals(p.unsafeRunSync(), (Some(content), None, Some(content)))
49+
assertIO(obtained, (Some(content), None, Some(content)))
5150
}
5251

5352
test("removeTemporarily: nonexistent file") {
5453
val file = mockRoot / "does-not-exist.txt"
55-
assertEquals(ioFileAlg.removeTemporarily(file).surround(IO.pure(42)).unsafeRunSync(), 42)
54+
val obtained = ioFileAlg.removeTemporarily(file).surround(IO.pure(42))
55+
assertIO(obtained, 42)
5656
}
5757

5858
test("editFile: nonexistent file") {
59-
val state = fileAlg
59+
val obtained = fileAlg
6060
.editFile(mockRoot / "does-not-exist.txt", identity)
6161
.runS(MockState.empty)
62-
.unsafeRunSync()
6362

6463
val expected =
6564
MockState.empty.copy(trace = Vector(Cmd("read", s"$mockRoot/does-not-exist.txt")))
66-
assertEquals(state, expected)
65+
assertIO(obtained, expected)
6766
}
6867

6968
test("editFile: existent file") {
7069
val file = mockRoot / "steward" / "test1.sbt"
71-
val state = (for {
70+
val obtained = (for {
7271
_ <- fileAlg.writeFile(file, "123")
7372
_ <- fileAlg.editFile(file, _.replace("2", "4"))
74-
} yield ()).runS(MockState.empty).unsafeRunSync()
73+
} yield ()).runS(MockState.empty)
7574

7675
val expected = MockState.empty.copy(
7776
trace = Vector(
@@ -81,15 +80,15 @@ class FileAlgTest extends FunSuite {
8180
),
8281
files = Map(file -> "143")
8382
)
84-
assertEquals(state, expected)
83+
assertIO(obtained, expected)
8584
}
8685

8786
test("deleteForce removes dangling symlink in subdirectory") {
8887
val dir = mockRoot / "steward-symlink"
8988
val sub = dir / "sub"
9089
val regular = dir / "regular"
9190
val symlink = sub / "symlink"
92-
val p = for {
91+
val obtained = for {
9392
_ <- IO(dir.delete(swallowIOExceptions = true))
9493
_ <- ioFileAlg.writeFile(regular, "I'm a regular file")
9594
_ <- IO(sub.createDirectory())
@@ -98,29 +97,45 @@ class FileAlgTest extends FunSuite {
9897
_ <- ioFileAlg.deleteForce(dir)
9998
symlinkExists <- IO(symlink.exists(File.LinkOptions.noFollow))
10099
} yield symlinkExists
101-
assertEquals(p.unsafeRunSync(), false)
100+
assertIO(obtained, false)
102101
}
103102

104103
test("readUri: local file without scheme") {
105104
val file = mockRoot / "steward" / "readUri.txt"
106105
val content = "42"
107-
val p = for {
106+
val obtained = for {
108107
_ <- ioFileAlg.writeFile(file, content)
109108
read <- ioFileAlg.readUri(Uri.unsafeFromString(file.toString))
110109
} yield read
111-
assertEquals(p.unsafeRunSync(), content)
110+
assertIO(obtained, content)
112111
}
113112

114113
test("isRegularFile") {
115114
val dir = mockRoot / "steward" / "regular"
116115
val file = dir / "file.txt"
117-
val p = for {
116+
val obtained = for {
118117
_ <- ioFileAlg.deleteForce(dir)
119118
r1 <- ioFileAlg.isRegularFile(file)
120119
_ <- ioFileAlg.writeFile(file, "content")
121120
r2 <- ioFileAlg.isRegularFile(file)
122121
} yield (r1, r2)
123-
assertEquals(p.unsafeRunSync(), (false, true))
122+
assertIO(obtained, (false, true))
123+
}
124+
125+
test("isNonEmptyDirectory: empty") {
126+
val dir = mockRoot / "workspace2"
127+
val obtained = ioFileAlg.isNonEmptyDirectory(dir)
128+
assertIO(obtained, false)
129+
}
130+
131+
test("isNonEmptyDirectory: non empty") {
132+
val dir = mockRoot / "workspace1"
133+
val file = dir / "file.txt"
134+
val obtained = for {
135+
_ <- ioFileAlg.writeFile(file, "42")
136+
read <- ioFileAlg.isNonEmptyDirectory(dir)
137+
} yield read
138+
assertIO(obtained, true)
124139
}
125140
}
126141

modules/core/src/test/scala/org/scalasteward/core/io/MockFileAlg.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ class MockFileAlg extends FileAlg[MockEff] {
1818
override def isDirectory(file: File): MockEff[Boolean] =
1919
Kleisli(_.update(_.exec(List("test", "-d", file.pathAsString))) >> ioFileAlg.isDirectory(file))
2020

21+
override def isNonEmptyDirectory(dir: File): MockEff[Boolean] =
22+
Kleisli(
23+
_.update(_.exec(List("find", dir.pathAsString, "-type", "d", "-not", "-empty"))) >> ioFileAlg
24+
.isNonEmptyDirectory(dir)
25+
)
26+
2127
override def isRegularFile(file: File): MockEff[Boolean] =
2228
Kleisli {
2329
_.update(_.exec(List("test", "-f", file.pathAsString))) >> ioFileAlg.isRegularFile(file)

0 commit comments

Comments
 (0)