~jan0sch/smederee

Showing details for patch fd4a8df98fdcd145a2693411cbb6a2f87e3c27d3.
2022-10-19 (Wed), 2:22 PM - Jens Grassel - fd4a8df98fdcd145a2693411cbb6a2f87e3c27d3

darcs: Add applyPatch command.

- add `applyPatch` command to the `DarcsCommands`
- add test case and test patch
- refactor test to use test local and not suite local resource
Summary of changes
1 files added
  • modules/darcs/src/test/resources/test-patch.dpatch
2 files modified with 75 lines added and 29 lines removed
  • modules/darcs/src/main/scala/de/smederee/darcs/DarcsCommands.scala with 27 added and 0 removed lines
  • modules/darcs/src/test/scala/de/smederee/darcs/DarcsCommandsTest.scala with 48 added and 29 removed lines
diff -rN -u old-smederee/modules/darcs/src/main/scala/de/smederee/darcs/DarcsCommands.scala new-smederee/modules/darcs/src/main/scala/de/smederee/darcs/DarcsCommands.scala
--- old-smederee/modules/darcs/src/main/scala/de/smederee/darcs/DarcsCommands.scala	2025-02-02 00:43:16.314722520 +0000
+++ new-smederee/modules/darcs/src/main/scala/de/smederee/darcs/DarcsCommands.scala	2025-02-02 00:43:16.314722520 +0000
@@ -73,6 +73,33 @@
 final class DarcsCommands[F[_]: Sync](val darcsBinary: Path) {
   private val log = LoggerFactory.getLogger(getClass)
 
+  /** Apply a patch to a darcs repository.
+    *
+    * @param basePath
+    *   The base path under which the repository is located.
+    * @param repositoryName
+    *   The name of the repository.
+    * @param patchFile
+    *   The path to the file containing the patch. This may also be a complete email. In the latter case the email will
+    *   be parsed for a MIME attachment with a darcs patch.
+    * @param options
+    *   Additional options for the initialize command. Please note that you should not specify options which need user
+    *   interaction and also you might want to set the `--dont-allow-conflicts` options.
+    * @return
+    *   The output of the darcs command.
+    */
+  def applyPatch(basePath: Path)(repositoryName: String)(patchFile: Path)(
+      options: Chain[String]
+  ): F[DarcsCommandOutput] = {
+    log.trace(s"Execute $darcsBinary apply $patchFile for $repositoryName with $options")
+    val repositoryDirectory = basePath.resolve(repositoryName)
+    val darcsOptions        = List("apply") ::: options.toList ::: List(patchFile.toAbsolutePath().toString)
+    val externalCommand     = os.proc(darcsBinary.toString, darcsOptions)
+    for {
+      process <- Sync[F].delay(externalCommand.call(cwd = os.Path(repositoryDirectory), check = false))
+    } yield DarcsCommandOutput(process.exitCode, Chain(process.out.text()), Chain(process.err.text()))
+  }
+
   /** Clone a darcs repository from one directory into another one. This function is intended to be used for server side
     * forking or repositories.
     *
diff -rN -u old-smederee/modules/darcs/src/test/resources/test-patch.dpatch new-smederee/modules/darcs/src/test/resources/test-patch.dpatch
--- old-smederee/modules/darcs/src/test/resources/test-patch.dpatch	1970-01-01 00:00:00.000000000 +0000
+++ new-smederee/modules/darcs/src/test/resources/test-patch.dpatch	2025-02-02 00:43:16.314722520 +0000
@@ -0,0 +1,24 @@
+A test patch for unit testing stuff.
+
+patch 78a59ae0b68d69dea51165ea37e77eb10ce60657
+Author: Jens Grassel <jens@wegtam.com>
+Date:   Wed Oct 19 15:46:07 CEST 2022
+  * README: Test patch
+
+
+New patches:
+
+[README: Test patch
+Jens Grassel <jens@wegtam.com>**20221019134607
+ Ignore-this: e5223d6faa6d0d0f245f74e010ab4a327bb1c7676a00bcaf582e8af34222aaec0f2b3d9905a3a712
+] addfile ./README.md
+hunk ./README.md 1
++# Test-Repository
++
++This is a test to validate if the darcs apply command works as expected.
++
+
+Context:
+
+Patch bundle hash:
+0fda8801bdc08fb973d5a4c3920e11d7ad896d54
diff -rN -u old-smederee/modules/darcs/src/test/scala/de/smederee/darcs/DarcsCommandsTest.scala new-smederee/modules/darcs/src/test/scala/de/smederee/darcs/DarcsCommandsTest.scala
--- old-smederee/modules/darcs/src/test/scala/de/smederee/darcs/DarcsCommandsTest.scala	2025-02-02 00:43:16.314722520 +0000
+++ new-smederee/modules/darcs/src/test/scala/de/smederee/darcs/DarcsCommandsTest.scala	2025-02-02 00:43:16.314722520 +0000
@@ -28,20 +28,38 @@
 final class DarcsCommandsTest extends CatsEffectSuite with TestHelpers {
   val darcsBinary = Paths.get("darcs")
 
-  val workingDirectory = ResourceSuiteLocalFixture(
-    "working-directory",
+  val tempWorkingDirectory = ResourceFixture(
     Resource.make(IO(Files.createTempDirectory("darcs-cmd-test-").toAbsolutePath()))(path => IO(deleteDirectory(path)))
   )
 
-  override def munitFixtures = List(workingDirectory)
+  tempWorkingDirectory.test("darcs apply must apply a proper patch") { workingDirectory =>
+    val cmd               = new DarcsCommands[IO](darcsBinary)
+    val repo              = "test-apply"
+    val expectedDirectory = workingDirectory.resolve(repo)
+    val testPatch         = Paths.get(getClass().getClassLoader().getResource("test-patch.dpatch").toURI())
+    val createRepository  = cmd.initialize(workingDirectory)(repo)(Chain.empty)
+    val test = for {
+      init  <- createRepository
+      patch <- cmd.applyPatch(workingDirectory)(repo)(testPatch)(Chain.empty)
+    } yield (init, patch)
+    test.map { output =>
+      val (init, patch) = output
+      assert(init.exitValue === 0, "darcs init did not finish with exit code 0!")
+      assert(patch.exitValue === 0, "darcs apply did not finish with exit code 0!")
+      assert(
+        Files.exists(expectedDirectory.resolve("README.md")),
+        "Expected file README.md missing after applying the patch!"
+      )
+    }
+  }
 
-  test("darcs clone must create a proper copy") {
+  tempWorkingDirectory.test("darcs clone must create a proper copy") { workingDirectory =>
     val cmd    = new DarcsCommands[IO](darcsBinary)
-    val source = Paths.get(workingDirectory().toString, "source")
-    val target = Paths.get(workingDirectory().toString, "target")
+    val source = workingDirectory.resolve("source")
+    val target = workingDirectory.resolve("target")
     val test =
       for {
-        init  <- cmd.initialize(workingDirectory())("source")(Chain.empty)
+        init  <- cmd.initialize(workingDirectory)("source")(Chain.empty)
         clone <- cmd.clone(source, target)(Chain.empty)
       } yield (init, clone)
     test.map { output =>
@@ -53,10 +71,10 @@
     }
   }
 
-  test("darcs clone must fail if the source does not exist") {
+  tempWorkingDirectory.test("darcs clone must fail if the source does not exist") { workingDirectory =>
     val cmd    = new DarcsCommands[IO](darcsBinary)
-    val source = Paths.get(workingDirectory().toString, "source-should-not-exist")
-    val target = Paths.get(workingDirectory().toString, "target-should-not-be-created")
+    val source = workingDirectory.resolve("source-should-not-exist")
+    val target = workingDirectory.resolve("target-should-not-be-created")
     val test =
       for {
         clone <- cmd.clone(source, target)(Chain.empty)
@@ -68,11 +86,11 @@
     }
   }
 
-  test("darcs initialize must create a new repository") {
+  tempWorkingDirectory.test("darcs initialize must create a new repository") { workingDirectory =>
     val cmd               = new DarcsCommands[IO](darcsBinary)
     val repo              = "test-repository"
-    val expectedDirectory = Paths.get(workingDirectory().toString, repo)
-    val test              = cmd.initialize(workingDirectory())(repo)(Chain.empty)
+    val expectedDirectory = workingDirectory.resolve(repo)
+    val test              = cmd.initialize(workingDirectory)(repo)(Chain.empty)
     test.map { output =>
       assert(output.exitValue === 0, "Exit code of darcs command is expected to be 0!")
       assert(Files.exists(expectedDirectory), "Expected directory does not exist!")
@@ -82,27 +100,28 @@
     }
   }
 
-  test("darcs initialize must create a new repository in an existing directory") {
-    val cmd               = new DarcsCommands[IO](darcsBinary)
-    val repo              = "test-repository-in-directory"
-    val expectedDirectory = Paths.get(workingDirectory().toString, repo)
-    val _                 = Files.createDirectories(expectedDirectory)
-    val test              = cmd.initialize(workingDirectory())(repo)(Chain.empty)
-    test.map { output =>
-      assert(output.exitValue === 0, "Exit code of darcs command is expected to be 0!")
-      val darcsDirectory = Paths.get(expectedDirectory.toString, "_darcs")
-      assert(Files.exists(darcsDirectory), "The _darcs directory does not exist in the repository!")
-    }
+  tempWorkingDirectory.test("darcs initialize must create a new repository in an existing directory") {
+    workingDirectory =>
+      val cmd               = new DarcsCommands[IO](darcsBinary)
+      val repo              = "test-repository-in-directory"
+      val expectedDirectory = workingDirectory.resolve(repo)
+      val _                 = Files.createDirectories(expectedDirectory)
+      val test              = cmd.initialize(workingDirectory)(repo)(Chain.empty)
+      test.map { output =>
+        assert(output.exitValue === 0, "Exit code of darcs command is expected to be 0!")
+        val darcsDirectory = Paths.get(expectedDirectory.toString, "_darcs")
+        assert(Files.exists(darcsDirectory), "The _darcs directory does not exist in the repository!")
+      }
   }
 
-  test("darcs initialize must fail if the repository already exists") {
+  tempWorkingDirectory.test("darcs initialize must fail if the repository already exists") { workingDirectory =>
     val cmd               = new DarcsCommands[IO](darcsBinary)
     val repo              = "test-repository-existing"
-    val expectedDirectory = Paths.get(workingDirectory().toString, repo)
+    val expectedDirectory = workingDirectory.resolve(repo)
     val _                 = Files.createDirectories(expectedDirectory)
     val test = for {
-      _      <- cmd.initialize(workingDirectory())(repo)(Chain.empty)
-      output <- cmd.initialize(workingDirectory())(repo)(Chain.empty)
+      _      <- cmd.initialize(workingDirectory)(repo)(Chain.empty)
+      output <- cmd.initialize(workingDirectory)(repo)(Chain.empty)
     } yield output
     test.map { output =>
       assert(output.exitValue =!= 0, "The initialize command is expected to fail here!")