rlm@0
|
1 (ns coderloop.export-files
|
rlm@0
|
2 (:use clojure.java.io)
|
rlm@0
|
3 (:use [clojure.contrib [duck-streams :only [file-str]]])
|
rlm@0
|
4 (:use [rlm
|
rlm@0
|
5 [classpath-utils :only [classpath]]
|
rlm@0
|
6 [shell-write :only [sw]]])
|
rlm@0
|
7 (:require clojure.string)
|
rlm@0
|
8 (:import java.io.File)
|
rlm@0
|
9 (:import [org.apache.commons.io FileUtils])
|
rlm@0
|
10 )
|
rlm@0
|
11
|
rlm@0
|
12
|
rlm@0
|
13 (defn trans-print [x] (println x) x)
|
rlm@0
|
14
|
rlm@0
|
15 (def *nailgun* true)
|
rlm@0
|
16
|
rlm@0
|
17 ;;; put standard base-path on the classpath
|
rlm@0
|
18 (def standard-base-directory (file-str "~/.clojure-exports/"))
|
rlm@0
|
19
|
rlm@0
|
20 (defn better-export-files [namespace name]
|
rlm@0
|
21 (binding [*compile-path* (.getPath standard-base-directory)]
|
rlm@0
|
22 ;;clear out classes -- prepare temp directory
|
rlm@0
|
23 (FileUtils/forceMkdir standard-base-directory)
|
rlm@0
|
24 (FileUtils/deleteDirectory standard-base-directory)
|
rlm@0
|
25 (FileUtils/forceMkdir standard-base-directory)
|
rlm@0
|
26 ;; make classes
|
rlm@0
|
27 (compile (symbol (str namespace)))
|
rlm@0
|
28
|
rlm@0
|
29 ;; make jar
|
rlm@0
|
30 ;; (jar {:jarfile jar-name :basedir temp-class-dir})
|
rlm@0
|
31
|
rlm@0
|
32 ;; move jar
|
rlm@0
|
33 ;; (FileUtils/copyFileToDirectory jar-name target-lib-dir)
|
rlm@0
|
34 ))
|
rlm@0
|
35
|
rlm@0
|
36 (defmulti source-location class)
|
rlm@0
|
37
|
rlm@0
|
38 (defmethod source-location clojure.lang.Var [sym]
|
rlm@0
|
39 (let [source? (:file (meta sym))]
|
rlm@0
|
40 (if source?
|
rlm@0
|
41 (.getResource (clojure.lang.RT/baseLoader) source?)
|
rlm@0
|
42 nil)))
|
rlm@0
|
43
|
rlm@0
|
44 (defmethod source-location java.lang.Class [sym]
|
rlm@0
|
45 (let [source? (.getCodeSource (.getProtectionDomain sym))]
|
rlm@0
|
46 (if source?
|
rlm@0
|
47 (.getLocation source?)
|
rlm@0
|
48 nil)))
|
rlm@0
|
49
|
rlm@0
|
50 (defn all-dependent-namespaces [namespace]
|
rlm@0
|
51 (set
|
rlm@0
|
52 (concat
|
rlm@0
|
53 [namespace]
|
rlm@0
|
54 (vals (ns-aliases namespace))
|
rlm@0
|
55 (map #(.ns %)
|
rlm@0
|
56 (filter #(= (class %) clojure.lang.Var)
|
rlm@0
|
57 (concat
|
rlm@0
|
58 (vals (ns-map namespace))
|
rlm@0
|
59 (vals (ns-refers namespace))))))))
|
rlm@0
|
60
|
rlm@0
|
61 (defn deep-dependent-namespaces [namespace-set]
|
rlm@0
|
62 (let [new-namespaces (set (mapcat all-dependent-namespaces namespace-set))]
|
rlm@0
|
63 ;;(println (count new-namespaces))
|
rlm@0
|
64 (if (= new-namespaces namespace-set)
|
rlm@0
|
65 namespace-set
|
rlm@0
|
66 (recur new-namespaces))))
|
rlm@0
|
67
|
rlm@0
|
68 (defn dependencies-url
|
rlm@0
|
69 "returns all of the files necessary to succesfully run the namespace."
|
rlm@0
|
70 [namespace]
|
rlm@0
|
71 (set
|
rlm@0
|
72 (remove
|
rlm@0
|
73 nil?
|
rlm@0
|
74 (map source-location
|
rlm@0
|
75 (map second
|
rlm@0
|
76 (mapcat ns-map (deep-dependent-namespaces #{namespace})))))))
|
rlm@0
|
77
|
rlm@0
|
78 (defn dependencies-file [namespace]
|
rlm@0
|
79 (map file-str
|
rlm@0
|
80 (set
|
rlm@0
|
81 (map #(.replaceFirst % "file:" "")
|
rlm@0
|
82 (map #(if (.contains % ".jar!/")
|
rlm@0
|
83 (clojure.string/replace % #"\.jar.*" ".jar") %)
|
rlm@0
|
84 (map #(.getFile %) (dependencies-url namespace)))))))
|
rlm@0
|
85
|
rlm@0
|
86 (defn classpath-files []
|
rlm@0
|
87 (map file-str (clojure.string/split (classpath) #":")))
|
rlm@0
|
88
|
rlm@0
|
89 ;;Every file that comes back from dependencies-file is also on the classpath.
|
rlm@0
|
90 ;;In order to recreate the right project structure, we need to copy the files
|
rlm@0
|
91 ;;with the appropiate classpath nesting.
|
rlm@0
|
92
|
rlm@0
|
93 (defn bifurcate
|
rlm@0
|
94 "split a collection between f and not f"
|
rlm@0
|
95 [f coll]
|
rlm@0
|
96 (list
|
rlm@0
|
97 (filter f coll)
|
rlm@0
|
98 (filter (comp not f) coll)))
|
rlm@0
|
99
|
rlm@0
|
100 (defn jar? [#^java.io.File f]
|
rlm@0
|
101 (re-matches #".*\.jar$" (.getCanonicalPath f)))
|
rlm@0
|
102
|
rlm@0
|
103 (defn contains-file? [#^java.io.File parent #^java.io.File child]
|
rlm@0
|
104 (let [new-child (.getParentFile child)]
|
rlm@0
|
105 (cond (nil? new-child) false
|
rlm@0
|
106 (= new-child parent) true
|
rlm@0
|
107 true (recur parent new-child))))
|
rlm@0
|
108
|
rlm@0
|
109 (defn destination [base-path-list #^java.io.File current-file #^java.io.File base-destination]
|
rlm@0
|
110 (let [base-path (last (filter #(contains-file? % current-file) base-path-list))]
|
rlm@0
|
111 (file-str
|
rlm@0
|
112 (.replaceFirst (.getCanonicalPath current-file)
|
rlm@0
|
113 (.getCanonicalPath base-path)
|
rlm@0
|
114 (.getCanonicalPath base-destination)))))
|
rlm@0
|
115
|
rlm@0
|
116 (defn export-dependencies [namespace #^java.io.File target]
|
rlm@0
|
117 (let [[jars sources] (bifurcate jar? (dependencies-file namespace))
|
rlm@0
|
118 jars (if *nailgun*
|
rlm@0
|
119 (conj jars (file-str "~/roBin/nailgun-0.7.1/nailgun-0.7.1.jar"))
|
rlm@0
|
120 jars)
|
rlm@0
|
121
|
rlm@0
|
122 lib (file-str (str (.getCanonicalPath target) File/separatorChar "lib"))
|
rlm@0
|
123 src (file-str (str (.getCanonicalPath target) File/separatorChar "src"))]
|
rlm@0
|
124 (if *nailgun*
|
rlm@0
|
125 (do
|
rlm@0
|
126 (FileUtils/copyFileToDirectory (file-str "~/roBin/nailgun-0.7.1/ng") lib)
|
rlm@0
|
127 (sw (str "chmod +x " (.getCanonicalPath target) File/separatorChar "lib/ng"))))
|
rlm@0
|
128 (dorun (map #(FileUtils/copyFileToDirectory % lib) jars))
|
rlm@0
|
129 (dorun (map #(FileUtils/copyFile % (destination (classpath-files) % src)) sources))))
|
rlm@0
|
130
|
rlm@0
|
131 (defn run-script-text [namespace]
|
rlm@0
|
132
|
rlm@0
|
133 (if *nailgun*
|
rlm@0
|
134 (str
|
rlm@0
|
135
|
rlm@0
|
136 "#!/usr/bin/perl
|
rlm@0
|
137
|
rlm@0
|
138 if (`./lib/ng ng-alias 2>&1 1>/dev/null` eq \"connect: Connection refused\\n\"){
|
rlm@0
|
139
|
rlm@0
|
140 $nailgun_init =
|
rlm@0
|
141 \"java -Xmn500M -Xms2000M -Xmx2000M \" .
|
rlm@0
|
142 \"-classpath ./src/:lib/*\" . \" -server \".
|
rlm@0
|
143 \"com.martiansoftware.nailgun.NGServer \".
|
rlm@0
|
144 \" >/dev/null 2>/dev/null &\";
|
rlm@0
|
145 `$nailgun_init`;
|
rlm@0
|
146 }\n\n"
|
rlm@0
|
147
|
rlm@0
|
148
|
rlm@0
|
149 "while (`./lib/ng ng-alias 2>&1 1>/dev/null` eq \"connect: Connection refused\\n\"){
|
rlm@0
|
150 }\n\n"
|
rlm@0
|
151
|
rlm@0
|
152 "$command = "
|
rlm@0
|
153
|
rlm@0
|
154
|
rlm@0
|
155 "\"./lib/ng clojure.main "
|
rlm@0
|
156 "./src/"
|
rlm@0
|
157 (.replace (.replace (str *ns*) \. File/separatorChar) \- \_)
|
rlm@0
|
158 ".clj "
|
rlm@0
|
159 " @ARGV\";\n"
|
rlm@0
|
160
|
rlm@0
|
161 "print `$command`;\n")
|
rlm@0
|
162 (str
|
rlm@0
|
163 "#!/bin/bash\n"
|
rlm@0
|
164 "java -Xmn500M -Xms2000M -Xmx2000M -server -cp ./lib/*:./src clojure.main "
|
rlm@0
|
165 "./src/"
|
rlm@0
|
166 (.replace (.replace (str *ns*) \. File/separatorChar) \- \_)
|
rlm@0
|
167 ".clj "
|
rlm@0
|
168 " $@\n")))
|
rlm@0
|
169
|
rlm@0
|
170
|
rlm@0
|
171
|
rlm@0
|
172 (defn make-run-script [namespace base-dir name]
|
rlm@0
|
173 (let [w (clojure.java.io/writer
|
rlm@0
|
174 (str (.getCanonicalPath base-dir) File/separatorChar name))]
|
rlm@0
|
175 (.write w (run-script-text namespace))
|
rlm@0
|
176 (.close w))
|
rlm@0
|
177 (let [f (file-str (str (.getCanonicalPath base-dir) File/separatorChar name))]
|
rlm@0
|
178 (.setExecutable f true)))
|
rlm@0
|
179
|
rlm@0
|
180 (defn export-files [namespace base-dir name]
|
rlm@0
|
181 (export-dependencies namespace base-dir)
|
rlm@0
|
182 (make-run-script namespace base-dir name))
|
rlm@0
|
183
|
rlm@0
|
184 (defn bzip-folder [#^java.io.File destination #^java.io.File directory]
|
rlm@0
|
185 (apply (partial sw "tar" "-cvjf" (.getCanonicalPath destination))
|
rlm@0
|
186 (concat
|
rlm@0
|
187 (rest
|
rlm@0
|
188 (map #(.replaceFirst
|
rlm@0
|
189 %
|
rlm@0
|
190 (str (.getCanonicalPath directory) File/separatorChar ) "")
|
rlm@0
|
191 (map str (file-seq directory))))
|
rlm@0
|
192 [:dir (.getCanonicalPath directory)])))
|
rlm@0
|
193
|
rlm@0
|
194 (defn bzip-export-files [directory target-dir name]
|
rlm@0
|
195 (apply (partial sw "tar" "-cvjf"
|
rlm@0
|
196 (str (.getCanonicalPath target-dir) File/separatorChar name))
|
rlm@0
|
197 (concat
|
rlm@0
|
198 [name "lib" "src"]
|
rlm@0
|
199 [:dir (.getCanonicalPath directory)])))
|
rlm@0
|
200
|
rlm@0
|
201 (defn export-archive
|
rlm@0
|
202 ([name]
|
rlm@0
|
203 (export-archive *ns* name))
|
rlm@0
|
204
|
rlm@0
|
205 ([namespace name nailgun?]
|
rlm@0
|
206 (binding [*nailgun* nailgun?]
|
rlm@0
|
207 (export-archive namespace name)))
|
rlm@0
|
208
|
rlm@0
|
209 ([namespace name]
|
rlm@0
|
210 (FileUtils/forceMkdir standard-base-directory)
|
rlm@0
|
211 (FileUtils/forceDelete standard-base-directory)
|
rlm@0
|
212 (FileUtils/forceMkdir standard-base-directory)
|
rlm@0
|
213 (let [new-dir
|
rlm@0
|
214 (file-str
|
rlm@0
|
215 (str
|
rlm@0
|
216 (.getCanonicalPath standard-base-directory)
|
rlm@0
|
217 (File/separatorChar)
|
rlm@0
|
218 name))]
|
rlm@0
|
219
|
rlm@0
|
220 (export-files namespace new-dir name)
|
rlm@0
|
221
|
rlm@0
|
222 (bzip-export-files new-dir (file-str "~/coderloop/") (str name "-clojure.tar.bz2"))
|
rlm@0
|
223 (FileUtils/copyFileToDirectory
|
rlm@0
|
224 (file-str (str "~/coderloop/" name "-clojure.tar.bz2"))
|
rlm@0
|
225 (file-str "~/coderloop-test")))))
|