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