Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 94 lines (82 sloc) 3.661 kb
4470daf @stuartsierra Add 'move-ns': refactoring tool to rename a namespace (alpha)
stuartsierra authored
1 ;; Copyright (c) Stuart Sierra, 2012. All rights reserved. The use and
2 ;; distribution terms for this software are covered by the Eclipse
3 ;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4 ;; which can be found in the file epl-v10.html at the root of this
5 ;; distribution. By using this software in any fashion, you are
6 ;; agreeing to be bound by the terms of this license. You must not
7 ;; remove this notice, or any other, from this software.
8
651d086 @stuartsierra ns docstring for 'move'
stuartsierra authored
9 (ns ^{:author "Stuart Sierra"
10 :doc "Refactoring tool to move a Clojure namespace from one name/file to
5f26c53 @stuartsierra Docstrings & warnings in 'move'
stuartsierra authored
11 another, and update all references to that namespace in your other
12 Clojure source files.
13
14 WARNING: This code is ALPHA and subject to change. It also modifies
15 and deletes your source files! Make sure you have a backup or
651d086 @stuartsierra ns docstring for 'move'
stuartsierra authored
16 version control."}
17 clojure.tools.namespace.move
4470daf @stuartsierra Add 'move-ns': refactoring tool to rename a namespace (alpha)
stuartsierra authored
18 (:require [clojure.string :as str]
19 [clojure.java.io :as io])
20 (:import (java.io File)))
21
22 (defn- update-file
faa9c90 @stuartsierra Docstrings in 'move'
stuartsierra authored
23 "Reads file as a string, calls f on the string plus any args, then
24 writes out return value of f as the new contents of file."
4470daf @stuartsierra Add 'move-ns': refactoring tool to rename a namespace (alpha)
stuartsierra authored
25 [file f & args]
26 (spit file (str (apply f (slurp file) args))))
27
28 (defn- ns-file-name [sym]
29 (str (-> (name sym)
30 (str/replace #"-" "_")
31 (str/replace #"\." File/separator))
32 ".clj"))
33
34 (defn- clojure-source-files [dirs]
35 (->> dirs
36 (map io/file)
ca860fc @stuartsierra Fix reflection warnings in 'move'
stuartsierra authored
37 (filter #(.exists ^File %))
4470daf @stuartsierra Add 'move-ns': refactoring tool to rename a namespace (alpha)
stuartsierra authored
38 (mapcat file-seq)
ca860fc @stuartsierra Fix reflection warnings in 'move'
stuartsierra authored
39 (filter (fn [^File file]
40 (and (.isFile file)
41 (.endsWith (.getName file) ".clj"))))
42 (map #(.getCanonicalFile ^File %))))
4470daf @stuartsierra Add 'move-ns': refactoring tool to rename a namespace (alpha)
stuartsierra authored
43
44 (def ^:private symbol-regex
45 ;; LispReader.java uses #"[:]?([\D&&[^/]].*/)?([\D&&[^/]][^/]*)" but
46 ;; that's too broad; we don't want a whole namespace-qualified symbol,
47 ;; just each part individually.
48 #"[a-zA-Z0-9$%*+=?!<>_-]['.a-zA-Z0-9$%*+=?!<>_-]*")
49
50 (defn replace-ns-symbol
51 "ALPHA: subject to change. Given Clojure source as a string, replaces
52 all occurances of the namespace name old-sym with new-sym and
53 returns modified source as a string."
54 [source old-sym new-sym]
55 (let [old-name (name old-sym)
56 new-name (name new-sym)]
57 ;; A lossless parser would be better, but this is adequate
58 (str/replace source symbol-regex
59 (fn [match]
60 (if (= match old-name)
61 new-name
62 match)))))
63
64 (defn move-ns-file
65 "ALPHA: subject to change. Moves the .clj source file (found relative
66 to source-path) for the namespace named old-sym to a file for a
5f26c53 @stuartsierra Docstrings & warnings in 'move'
stuartsierra authored
67 namespace named new-sym.
68
69 WARNING: This function moves and deletes your source files! Make
70 sure you have a backup or version control."
4470daf @stuartsierra Add 'move-ns': refactoring tool to rename a namespace (alpha)
stuartsierra authored
71 [old-sym new-sym source-path]
72 (let [old-file (io/file source-path (ns-file-name old-sym))
73 new-file (io/file source-path (ns-file-name new-sym))]
74 (.mkdirs (.getParentFile new-file))
75 (io/copy old-file new-file)
76 (.delete old-file)
77 (loop [dir (.getParentFile old-file)]
78 (when (empty? (.listFiles dir))
79 (.delete dir)
80 (recur (.getParentFile dir))))))
81
82 (defn move-ns
83 "ALPHA: subject to change. Moves the .clj source file (found relative
faa9c90 @stuartsierra Docstrings in 'move'
stuartsierra authored
84 to source-path) for the namespace named old-sym to new-sym and
85 replace all occurances of the old name with the new name in all
5f26c53 @stuartsierra Docstrings & warnings in 'move'
stuartsierra authored
86 Clojure source files found in dirs.
87
88 WARNING: This function modifies and deletes your source files! Make
89 sure you have a backup or version control."
4470daf @stuartsierra Add 'move-ns': refactoring tool to rename a namespace (alpha)
stuartsierra authored
90 [old-sym new-sym source-path dirs]
91 (move-ns-file old-sym new-sym source-path)
92 (doseq [file (clojure-source-files dirs)]
93 (update-file file replace-ns-symbol old-sym new-sym)))
Something went wrong with that request. Please try again.