Commit a7de50a6522bffbef45b83e06570ff0985710eba

Thomas de Grivel 2018-07-10T12:46:18

file

diff --git a/unix/defs.lisp b/unix/defs.lisp
index ee07370..e3d4815 100644
--- a/unix/defs.lisp
+++ b/unix/defs.lisp
@@ -85,9 +85,12 @@
            (push `(,(sym 'probe-file-cksum- algorithm)
                     :properties (,algorithm))
                  algorithms))
-         (nreverse algorithms))))
+         (nreverse algorithms)))
+  ((op-file-ensure :properties (:ensure)))
+  ((:op-properties (:ensure :mode :uid :gid :owner :group))))
 
 (defgeneric probe-file-content (resource os))
+(defgeneric op-file-ensure (resource os &key ensure))
 
 ;;  Directory
 
diff --git a/unix/operations.lisp b/unix/operations.lisp
index 5d882aa..931fcf5 100644
--- a/unix/operations.lisp
+++ b/unix/operations.lisp
@@ -82,4 +82,26 @@
 
 (defmethod op-chmod ((res vnode) (os os-unix) &key mode
                                                 &allow-other-keys)
-  (run "chmod " (octal (mode-permissions mode)) " " (sh-quote (resource-id res))))
+  (run "chmod " (octal (mode-permissions mode)) " "
+       (sh-quote (resource-id res))))
+
+;;  File
+
+(defmethod op-file-ensure ((res file) (os os-unix) &key ensure)
+  (let* ((id (resource-id res))
+         (sh-id (sh-quote id)))
+    (ecase ensure
+      ((:absent) (run "rm " sh-id))
+      ((:present) (run "touch " sh-id))
+      ((nil)))))
+
+;;  Directory
+
+(defmethod op-directory-ensure ((res directory) (os os-unix)
+                                &key ensure)
+  (let* ((id (resource-id res))
+         (sh-id (sh-quote id)))
+    (ecase ensure
+      ((:absent) (run "rmdir " sh-id))
+      ((:present) (run "mkdir " sh-id))
+      ((nil)))))
diff --git a/unix/probes.lisp b/unix/probes.lisp
index 9d7badf..e271418 100644
--- a/unix/probes.lisp
+++ b/unix/probes.lisp
@@ -78,27 +78,30 @@
 ;;  VNode (filesystem node)
 
 (defmethod probe-vnode-using-ls ((vnode vnode) (os os-unix))
-  (let ((id (resource-id vnode)))
+  (let ((id (resource-id vnode))
+        (ensure :absent))
     (multiple-value-bind #1=(mode links owner group size mtime)
         (with-ls<1>-lT #.(cons 'name '#1#)
             (ls "-ldT" id)
           (when (string= id name)
             (setq mode (mode (mode-permissions mode))
                   owner (resource 'user owner)
-                  group (resource 'group group))
+                  group (resource 'group group)
+                  ensure :present)
             (return (values* #1#))))
-      (properties* #1#))))
+      (properties* (ensure . #1#)))))
 
 (defmethod probe-vnode-using-stat ((vnode vnode) (os os-unix))
-  (let ((id (resource-id vnode)))
+  (let ((id (resource-id vnode))
+        (ensure :absent))
     (multiple-value-bind #1=(dev ino mode links uid gid rdev size
                                  atime mtime ctime blksize blocks flags)
-        (with-stat<1>-r #.(cons 'name '#1#)
-            (stat "-r" id)
-          (when (string= id name)
-            (setq mode (mode (mode-permissions mode)))
+        (with-stat<1>-r (name . #1#) (stat "-r" id)
+          (when (and name (string= id (the string name)))
+            (setq mode (mode (mode-permissions mode))
+                  ensure :present)
             (return (values* #1#))))
-        (properties* #1#))))
+        (properties* (ensure . #1#)))))
 
 ;;  Regular file