summaryrefslogtreecommitdiff
path: root/src/Propellor/Property/Rsync.hs
diff options
context:
space:
mode:
authorJoey Hess2015-09-04 10:38:36 -0700
committerJoey Hess2015-09-04 11:15:43 -0700
commit9d546f04c640c0eb1ded6e585c99e2cd11fb1847 (patch)
treec636ca6b8e5c0658dac808a7ac6feb5289c604ba /src/Propellor/Property/Rsync.hs
parent2c94926558850cb702fd8e844ccbe768937af110 (diff)
Added Propellor.Property.Rsync.
Diffstat (limited to 'src/Propellor/Property/Rsync.hs')
-rw-r--r--src/Propellor/Property/Rsync.hs58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/Propellor/Property/Rsync.hs b/src/Propellor/Property/Rsync.hs
new file mode 100644
index 00000000..064d129f
--- /dev/null
+++ b/src/Propellor/Property/Rsync.hs
@@ -0,0 +1,58 @@
+module Propellor.Property.Rsync where
+
+import Propellor
+import qualified Propellor.Property.Apt as Apt
+
+type Src = FilePath
+type Dest = FilePath
+
+class RsyncParam p where
+ toRsync :: p -> String
+
+-- | Rsync checks each name to be transferred against its list of Filter
+-- rules, and the first matching one is acted on. If no matching rule
+-- is found, the file is processed.
+data Filter
+ = Include Pattern
+ | Exclude Pattern
+
+instance RsyncParam Filter where
+ toRsync (Include (Pattern p)) = "--include=" ++ p
+ toRsync (Exclude (Pattern p)) = "--exclude=" ++ p
+
+-- | A pattern to match against files that rsync is going to transfer.
+--
+-- See "INCLUDE/EXCLUDE PATTERN RULES" in the rsync(1) man page.
+--
+-- For example, Pattern "/foo/*" matches all files under the "foo"
+-- directory, relative to the 'Src' that rsync is acting on.
+newtype Pattern = Pattern String
+
+-- | A pattern that matches all files under a directory, but does not
+-- match the directory itself.
+filesUnder :: FilePath -> Pattern
+filesUnder d = Pattern (d ++ "/*")
+
+-- | Ensures that the Dest directory exists and has identical contents as
+-- the Src directory.
+syncDir :: Src -> Dest -> Property NoInfo
+syncDir = syncDirFiltered []
+
+-- | Like syncDir, but avoids copying anything that the filter list
+-- excludes. Anything that's filtered out will be deleted from Dest.
+syncDirFiltered :: [Filter] -> Src -> Dest -> Property NoInfo
+syncDirFiltered filters src dest = rsync $
+ [ "-av"
+ -- Add trailing '/' to get rsync to sync the Dest directory,
+ -- rather than a subdir inside it, which it will do without a
+ -- trailing '/'.
+ , addTrailingPathSeparator src
+ , addTrailingPathSeparator dest
+ , "--delete"
+ , "--delete-exluded"
+ , "--quiet"
+ ] ++ map toRsync filters
+
+rsync :: [String] -> Property NoInfo
+rsync ps = cmdProperty "rsync" ps
+ `requires` Apt.installed ["rsync"]