 
   WARNING: This function moves and deletes your source files!  Make
   sure you have a backup or version control."
-  [old-sym new-sym source-path dest-path]
-  ;; TBD: Add dry run option
+  [old-sym new-sym source-path dest-path opts]
   (let [old-file (io/file source-path (#'move/ns-file-name old-sym))
         new-file (io/file dest-path (#'move/ns-file-name new-sym))]
-    (.mkdirs (.getParentFile new-file))
-    (io/copy old-file new-file)
-    (.delete old-file)
-    (loop [dir (.getParentFile old-file)]
-      (when (empty? (.listFiles dir))
-        (.delete dir)
-        (recur (.getParentFile dir))))))
+    (when (:print? opts)
+      (println (format "mkdir %s"
+                       (abbreviate-path (str (.getParentFile new-file))
+                                        dest-path (:dest-path-abbrev opts)))))
+    (when-not (:dry-run? opts)
+      (.mkdirs (.getParentFile new-file)))
+    (when (:print? opts)
+      (println (format "copy %s %s"
+                       (abbreviate-path (str old-file)
+                                        source-path (:source-path-abbrev opts))
+                       (abbreviate-path (str new-file)
+                                        dest-path (:dest-path-abbrev opts)))))
+    (when-not (:dry-run? opts)
+      (io/copy old-file new-file))
+    (when (:print? opts)
+      (println (format "delete %s"
+                       (abbreviate-path (str old-file)
+                                        source-path (:source-path-abbrev opts)))))
+    (when-not (:dry-run? opts)
+      (.delete old-file))
+    (when (:print? opts)
+      (println (format "delete old dir %s if empty"
+                       (abbreviate-path (str (.getParentFile old-file))
+                                        source-path (:source-path-abbrev opts)))))
+    (when-not (:dry-run? opts)
+      (loop [dir (.getParentFile old-file)]
+        (when (empty? (.listFiles dir))
+          (.delete dir)
+          (recur (.getParentFile dir)))))))
 
 
 (defn replace-ns-symbol

(require '[dolly.clone :as c])
(def tns-path "/Users/jafinger/clj/dolly/copy-deps/tools.namespace/src/main/clojure")
(def staging-path "/Users/jafinger/clj/dolly/staging")
(def o1 (c/update-file (str tns-path "/clojure/tools/namespace.clj")
                       {:dry-run? true}
                       c/replace-ns-symbol 
                       'clojure.tools.namespace
                       'eastwood.copieddeps.tns.clojure.tools.namespace))
(def o1 (c/update-file (str tns-path "/clojure/tools/namespace.clj") {:dry-run? true} c/replace-ns-symbol 'clojure.tools.namespace 'eastwood.copieddeps.tns.clojure.tools.namespace))
(pprint o1)
(def o2 (c/copy-namespaces-unmodified tns-path 'clojure.tools.namespace.dir staging-path true))
(print (apply str (:dry-run-msgs o2)))
)



For example, if source-path is /source/path and it contains a file
/source/path/one/two.clj, it will be an error if the namespace inside
is anything other than 'one.two'."
  [source-path ns-sym dest-path opts]
  (let [ns-info (ns/namespaces-in-dirs {:paths [source-path]})]
    (if (:err ns-info)
      ns-info
      (do
        (when (:print? opts)
          (println (format "Copy Clojure source files in namespace %s unmodified\n  from source path S='%s'\n  to dest path D='%s'"
                           ns-sym source-path dest-path)))
        (doseq [[file ns] (:clojure.tools.namespace.file/filemap ns-info)]
          (if (namespace-to-copy? ns ns-sym)
            (copy-ns-file source-path ns dest-path
                          (merge opts {:source-path-abbrev "S"
                                       :dest-path-abbrev "D"}))
            (when (:print? opts)
              (println (format "Don't copy namespace %s from S since it is not a 'sub-namespace' of %s"
                               ns ns-sym)))))))))


(comment
(require '[dolly.clone :as c])
(def tns-path "/Users/jafinger/clj/dolly/copy-deps/tools.namespace/src/main/clojure")
(def staging-path "/Users/jafinger/clj/dolly/staging")
(def o1 (c/copy-namespaces-unmodified tns-path 'clojure.tools.namespace staging-path {:dry-run? true :print? true}))
;;(print (apply str (:dry-run-msgs o1)))
(def o2 (c/copy-namespaces-unmodified tns-path 'clojure.tools.namespace.dir staging-path {:dry-run? true :print? true}))
;;(print (apply str (:dry-run-msgs o2)))
)


