Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure create directory hierarchy - but not in a procedural way

Tags:

clojure

Let's say I need to create the following directory structure in Clojure:

a
\--b
|   \--b1
|   \--b2
\--c
   \-c1

Instead of doing procedural things like the following:

(def a (File. "a"))
(.mkdir a)
(def b (File. a "b"))
(.mkdir b)
;; ...

... is there a clever way to somehow represent the above actions as data, declaratively, and then create the hierarchy in one fell swoop?

like image 389
Marcus Junius Brutus Avatar asked Feb 12 '13 19:02

Marcus Junius Brutus


2 Answers

Another option if you want to easily handle creating recursive directories is to use .mkdirs

user> (require '[clojure.java.io :as io]')
user> (.mkdirs (io/file "a/b/c/d"))

You can use absolute path eg. /a/b/c/d or else it will be created relative to the path you initiated the repl from.

Also handy to check if given path is not an existing directory

user> (.isDirectory (io/file "a/b/c/d"))
like image 195
foomip Avatar answered Oct 04 '22 07:10

foomip


a quick and simple approach would be to make a vector of dirs to create and map mkdir on to it:

user> (map #(.mkdir (java.io.File. %)) ["a", "a/b" "a/b/c"])
(true true true)

or you can specify your dir structure as a tree and use zippers to walk it making the dirs on the way:

(def dirs ["a" ["b" ["b1" "b2"]] ["c" ["c1"]]])
(defn make-dir-tree [original]
  (loop [loc (zip/vector-zip original)]
    (if (zip/end? loc)
      (zip/root loc)
      (recur (zip/next
              (do (if (not (vector? (zip/node loc)))
                    (let [path (apply str (interpose "/" (butlast (map first (zip/path loc)))))
                          name (zip/node loc)]
                      (if (empty? path)
                        (.mkdir (java.io.File. name))
                        (.mkdir (java.io.File. (str path "/" name))))))
                  loc))))))
(make-dir-tree dirs)

.

arthur@a:~/hello$ find a
a
a/c
a/c/c1
a/b
a/b/c
a/b/b2
a/b/b1

If you are doing a lot of general systems administration then something heavier may be in order. The pallet project is a library for doing system administration of all sorts on physical and cloud hosted systems (though it tends to lean towards the cloudy stuff). Specifically the directory

like image 44
Arthur Ulfeldt Avatar answered Oct 04 '22 07:10

Arthur Ulfeldt