Skip to content

Commit

Permalink
support inlining .cljc files
Browse files Browse the repository at this point in the history
- inlines clojure.tools.namespace.move as mranderson.move with an added
  patch to support .cljc files (improved version for c.t.n 0.3.x was
  submitted to c.t.n)
  • Loading branch information
benedekfazekas committed Sep 8, 2015
1 parent e4b0293 commit 70dbe9f
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 15 deletions.
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ function check_result {
fi
}

lein do clean, source-deps :skip-javaclass-repackage true :project-prefix mranderson045
lein do clean, source-deps :skip-javaclass-repackage true :project-prefix mranderson046
check_result
lein with-profile plugin.mranderson/config "$@"
9 changes: 5 additions & 4 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
(defproject thomasa/mranderson "0.4.5"
(defproject thomasa/mranderson "0.4.6"
:description "Leiningen plugin to download and use some dependencies as source."
:url "https://github.com/benedekfazekas/mranderson"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:eval-in :leiningen
:plugins [[thomasa/mranderson "0.4.0"]]
:plugins [[thomasa/mranderson "0.4.5"]]
:java-source-paths ["java-src"]
:javac-options ["-target" "1.6" "-source" "1.6"]
:filespecs [{:type :bytes :path "mranderson/project.clj" :bytes ~(slurp "project.clj")}]
:dependencies [^:source-dep [com.cemerick/pomegranate "0.3.0"]
^:source-dep [org.clojure/tools.namespace "0.2.7"]
^:source-dep [org.clojure/tools.namespace "0.2.11"]
^:source-dep [me.raynes/fs "1.4.6"]
[com.googlecode.jarjar/jarjar "1.3"]])
[com.googlecode.jarjar/jarjar "1.3"]]
:profiles {:dev {:dependencies [[org.clojure/clojure "1.7.0"]]}})
17 changes: 9 additions & 8 deletions src/leiningen/source_deps.clj
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
(ns leiningen.source-deps
(:require [mranderson.util :refer :all]
[mranderson.move :as move]
[cemerick.pomegranate.aether :as aether]
[me.raynes.fs :as fs]
[clojure.string :as str]
[clojure.java.io :as io]
[clojure.tools.namespace.move :refer [move-ns]]
[clojure.tools.namespace.file :refer [read-file-ns-decl]]
[clojure.pprint :as pp]
[leiningen.core.main :refer [info debug]]
Expand Down Expand Up @@ -33,7 +33,7 @@
(->> entries
(filter #(not (.isDirectory ^java.util.zip.ZipEntry %)))
(map #(.getName %))
(filter #(.endsWith % ".clj"))))))
(filter #(or (.endsWith % ".clj") (.endsWith % ".cljc")))))))

(defn- cljfile->prefix [clj-file]
(->> (str/split clj-file #"/")
Expand All @@ -60,10 +60,11 @@
(str/join "."))))

(defn- replacement [prefix postfix underscorize?]
(->> (if underscorize? (-> postfix
str
(str/replace "-" "_"))
postfix)
(->> (if underscorize?
(-> postfix
str
(str/replace "-" "_"))
postfix)
vector
(concat [prefix])
(str/join "." )
Expand Down Expand Up @@ -245,7 +246,7 @@
(if-let [old-ns (->> clj-file (fs/file srcdeps) read-file-ns-decl second)]
(let [import (find-orig-import imports clj-file)
new-ns (replacement repl-prefix old-ns nil)
new-deftype (replacement repl-prefix old-ns true)]
new-deftype (replacement (str/replace repl-prefix "-" "_") old-ns true)]
(debug " new ns:" new-ns)
;; garble imports
(when-not (str/blank? import)
Expand All @@ -255,7 +256,7 @@
(doseq [file (clojure-source-files [srcdeps])]
(update-deftypes file old-ns new-deftype)))
;; move actual ns-s
(move-ns old-ns new-ns srcdeps [srcdeps]))
(move/move-ns old-ns new-ns srcdeps [srcdeps]))
;; a clj file without ns
(when-not (= "project.clj" clj-file)
(let [old-path (str "target/srcdeps/" clj-file)
Expand Down
122 changes: 122 additions & 0 deletions src/mranderson/move.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
;; Copyright (c) Stuart Sierra, 2012. All rights reserved. The use and
;; distribution terms for this software are covered by the Eclipse
;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file epl-v10.html at the root of this
;; distribution. By using this software in any fashion, you are
;; agreeing to be bound by the terms of this license. You must not
;; remove this notice, or any other, from this software.

(ns ^{:author "Stuart Sierra"
:doc "Refactoring tool to move a Clojure namespace from one name/file to
another, and update all references to that namespace in your other
Clojure source files.
WARNING: This code is ALPHA and subject to change. It also modifies
and deletes your source files! Make sure you have a backup or
version control.
DISCLAIMER
This is patched version of Stuart Siearra's original to handle cljc files
"}
mranderson.move
(:require [clojure.string :as str]
[clojure.java.io :as io])
(:import (java.io File FileNotFoundException)))

(defn- update-file
"Reads file as a string, calls f on the string plus any args, then
writes out return value of f as the new contents of file. Does not
modify file if the content is unchanged."
[file f & args]
(let [old (slurp file)
new (str (apply f old args))]
(when-not (= old new)
(spit file new))))

(defn- sym->file-name
[sym]
(-> (name sym)
(str/replace "-" "_")
(str/replace "." File/separator)))

(defn- find-file-for-sym [path sym]
(->> [".clj" ".cljc"]
(map #(io/file path (str (sym->file-name sym) %)))
(filter #(.exists %))
first))

(defn- sym->file
[path sym extension]
(io/file path (str (sym->file-name sym) extension)))

(defn- clojure-source-files [dirs]
(->> dirs
(map io/file)
(filter #(.exists ^File %))
(mapcat file-seq)
(filter (fn [^File file]
(and (.isFile file)
(or
(.endsWith (.getName file) ".clj")
(.endsWith (.getName file) ".cljc")))))
(map #(.getCanonicalFile ^File %))))

(def ^:private symbol-regex
;; LispReader.java uses #"[:]?([\D&&[^/]].*/)?([\D&&[^/]][^/]*)" but
;; that's too broad; we don't want a whole namespace-qualified symbol,
;; just each part individually.
#"[a-zA-Z0-9$%*+=?!<>_-]['.a-zA-Z0-9$%*+=?!<>_-]*")

(defn replace-ns-symbol
"ALPHA: subject to change. Given Clojure source as a string, replaces
all occurrences of the namespace name old-sym with new-sym and
returns modified source as a string."
[source old-sym new-sym]
(let [old-name (name old-sym)
new-name (name new-sym)]
;; A lossless parser would be better, but this is adequate
(str/replace source symbol-regex
(fn [match]
(if (= match old-name)
new-name
match)))))

(defn- file->extension
[file]
(re-find #"\.cljc?$" (str file)))

(defn move-ns-file
"ALPHA: subject to change. Moves the .clj or .cljc source file (found relative
to source-path) for the namespace named old-sym to a file for a
namespace named new-sym.
WARNING: This function moves and deletes your source files! Make
sure you have a backup or version control."
[old-sym new-sym source-path]
(if-let [old-file (find-file-for-sym source-path old-sym)]
(let [new-file (sym->file source-path new-sym (file->extension old-file))]
(.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)))))
(throw FileNotFoundException (format "file for %s not found in %s" old-sym source-path))))

(defn move-ns
"ALPHA: subject to change. Moves the .clj or .cljc source file (found relative
to source-path) for the namespace named old-sym to new-sym and
replace all occurrences of the old name with the new name in all
Clojure source files found in dirs.
This is a purely textual transformation. It does not work on
namespaces require'd or use'd from a prefix list.
WARNING: This function modifies and deletes your source files! Make
sure you have a backup or version control."
[old-sym new-sym source-path dirs]
(move-ns-file old-sym new-sym source-path)
(doseq [file (clojure-source-files dirs)]
(update-file file replace-ns-symbol old-sym new-sym)))
7 changes: 5 additions & 2 deletions src/mranderson/util.clj
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
(remove (fn [file]
(some #(.startsWith (str file) %) excl-dirs) ))
(filter (fn [^File file]
(and (.isFile file)
(.endsWith (.getName file) ".clj")))))))
(let [file-name (.getName file)]
(and (.isFile file)
(or
(.endsWith file-name ".cljc")
(.endsWith file-name ".clj")))))))))
([dirs]
(clojure-source-files-relative dirs nil)))

Expand Down

0 comments on commit 70dbe9f

Please sign in to comment.