Repository: flyingcircusio/batou

Issue:
batou.lib.file.Directory: Allow to explicitly overwrite target directory
`batou.lib.file.Directory` should get a flag to either append or overwrite (-> rsync --delete) the contents of a target directory based on given source folder.

Usecase: 

When syncing sourcecode via something like 

```
        self += Directory(
            "docroot",
            source=os.path.join(self.root.defdir, "..", "..", "docroot"),
            exclude=["/docroot/wp-config.php", "/docroot/.htaccess"],
        )
```

it might happen that deleted files are not gone after. On the other hand making deletion a default would be dangerous 

Discussion:

Patch:
diff --git a/src/batou/lib/file.py b/src/batou/lib/file.py
index 329a7038..980e3c59 100644
--- a/src/batou/lib/file.py
+++ b/src/batou/lib/file.py
@@ -244,13 +244,22 @@ class Directory(Component):
     source = None
     exclude = ()
 
+    verify_opts = None
+    sync_opts = None
+
     def configure(self):
         self.path = self.map(self.path)
         if self.source:
             # XXX The ordering is wrong. SyncDirectory should run *after*.
-            self += SyncDirectory(
-                self.path, source=self.source, exclude=self.exclude
-            )
+            args = {
+                "source": self.source,
+                "exclude": self.exclude,
+            }
+            if self.verify_opts:
+                args["verify_opts"] = self.verify_opts
+            if self.sync_opts:
+                args["sync_opts"] = self.sync_opts
+            self += SyncDirectory(self.path, **args)
 
     def verify(self):
         assert os.path.isdir(self.path)


Test patch:
diff --git a/src/batou/lib/tests/test_file.py b/src/batou/lib/tests/test_file.py
index 9d35bd15..841611b6 100644
--- a/src/batou/lib/tests/test_file.py
+++ b/src/batou/lib/tests/test_file.py
@@ -1153,3 +1153,14 @@ def test_syncdirectory_needs_update_on_nonexisting_target(root):
     with pytest.raises(batou.UpdateNeeded):
         sd = SyncDirectory("non_existing_dir", source="existing_dir")
         sd.verify()
+
+
+def test_directory_passes_args_to_syncdirectory(root):
+    d = Directory(
+        "target", source="source", verify_opts="-abc", sync_opts="-xyz"
+    )
+    d.prepare(root.component)
+    sd = d._
+    assert isinstance(sd, SyncDirectory)
+    assert sd.verify_opts == "-abc"
+    assert sd.sync_opts == "-xyz"