diff src/export_files.clj.orig @ 0:307a81e46071 tip

initial committ
author Robert McIntyre <rlm@mit.edu>
date Tue, 18 Oct 2011 01:17:49 -0700
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/export_files.clj.orig	Tue Oct 18 01:17:49 2011 -0700
     1.3 @@ -0,0 +1,225 @@
     1.4 +(ns coderloop.export-files
     1.5 +  (:use clojure.java.io)
     1.6 +  (:use [clojure.contrib [duck-streams :only [file-str]]])
     1.7 +  (:use [rlm
     1.8 +	 [classpath-utils :only [classpath]]
     1.9 +	 [shell-write :only [sw]]])
    1.10 +  (:require clojure.string)
    1.11 +  (:import java.io.File)
    1.12 +  (:import [org.apache.commons.io FileUtils])
    1.13 +  )
    1.14 +
    1.15 +
    1.16 +(defn trans-print [x] (println x) x) 
    1.17 +
    1.18 +(def *nailgun* true)
    1.19 +
    1.20 +;;; put standard base-path on the classpath
    1.21 +(def standard-base-directory (file-str "~/.clojure-exports/"))
    1.22 +
    1.23 +(defn better-export-files [namespace name]
    1.24 +    (binding [*compile-path* (.getPath standard-base-directory)]
    1.25 +    ;;clear out classes -- prepare temp directory
    1.26 +    (FileUtils/forceMkdir standard-base-directory)
    1.27 +    (FileUtils/deleteDirectory standard-base-directory)
    1.28 +    (FileUtils/forceMkdir standard-base-directory)      
    1.29 +      ;; make classes
    1.30 +    (compile (symbol (str namespace)))
    1.31 +    
    1.32 +    ;; make jar
    1.33 +;;    (jar {:jarfile jar-name :basedir temp-class-dir})
    1.34 +    
    1.35 +    ;; move jar
    1.36 +;;    (FileUtils/copyFileToDirectory jar-name target-lib-dir)
    1.37 +    ))
    1.38 +
    1.39 +(defmulti source-location class)
    1.40 +
    1.41 +(defmethod source-location clojure.lang.Var [sym]
    1.42 +	   (let [source? (:file (meta sym))]
    1.43 +	     (if source?
    1.44 +	       (.getResource (clojure.lang.RT/baseLoader) source?)
    1.45 +	       nil)))
    1.46 +
    1.47 +(defmethod source-location java.lang.Class [sym]
    1.48 +	   (let [source? (.getCodeSource (.getProtectionDomain sym))]
    1.49 +	     (if source?
    1.50 +	       (.getLocation source?)
    1.51 +	       nil)))
    1.52 +
    1.53 +(defn all-dependent-namespaces [namespace]
    1.54 +  (set
    1.55 +   (concat
    1.56 +    [namespace]
    1.57 +    (vals (ns-aliases namespace))
    1.58 +    (map #(.ns %)
    1.59 +	 (filter #(= (class %) clojure.lang.Var)
    1.60 +		 (concat 
    1.61 +		  (vals (ns-map namespace))
    1.62 +		  (vals (ns-refers namespace))))))))
    1.63 +
    1.64 +(defn deep-dependent-namespaces [namespace-set]
    1.65 +  (let [new-namespaces (set (mapcat all-dependent-namespaces namespace-set))]
    1.66 +    ;;(println (count new-namespaces))
    1.67 +    (if (= new-namespaces namespace-set)
    1.68 +      namespace-set
    1.69 +      (recur new-namespaces))))
    1.70 +
    1.71 +(defn dependencies-url
    1.72 +  "returns all of the files necessary to succesfully run the namespace."
    1.73 +  [namespace]
    1.74 +  (set
    1.75 +   (remove
    1.76 +    nil?
    1.77 +    (map source-location
    1.78 +	 (map second
    1.79 +	      (mapcat ns-map (deep-dependent-namespaces #{namespace})))))))
    1.80 +
    1.81 +(defn dependencies-file [namespace]
    1.82 +  (map file-str
    1.83 +       (set
    1.84 +	(map #(.replaceFirst % "file:" "")
    1.85 +	     (map  #(if (.contains % ".jar!/")
    1.86 +		      (clojure.string/replace % #"\.jar.*" ".jar") %)
    1.87 +		   (map #(.getFile %) (dependencies-url namespace)))))))
    1.88 +
    1.89 +(defn classpath-files []
    1.90 +  (map file-str (clojure.string/split (classpath) #":")))
    1.91 +
    1.92 +;;Every file that comes back from dependencies-file is also on the classpath.
    1.93 +;;In order to recreate the right project structure, we need to copy the files 
    1.94 +;;with the appropiate classpath nesting.
    1.95 +
    1.96 +(defn bifurcate
    1.97 +  "split a collection between f and not f"
    1.98 +  [f coll]
    1.99 +  (list
   1.100 +   (filter f coll)
   1.101 +   (filter (comp not f) coll)))
   1.102 +
   1.103 +(defn jar? [#^java.io.File f]
   1.104 +  (re-matches  #".*\.jar$" (.getCanonicalPath f)))
   1.105 +
   1.106 +(defn contains-file? [#^java.io.File parent #^java.io.File child]
   1.107 +  (let [new-child (.getParentFile child)]
   1.108 +    (cond (nil? new-child) false
   1.109 +	  (= new-child parent) true
   1.110 +	  true (recur parent new-child))))
   1.111 +
   1.112 +(defn destination [base-path-list #^java.io.File current-file #^java.io.File base-destination]
   1.113 +  (let [base-path (last (filter #(contains-file? % current-file) base-path-list))]
   1.114 +    (file-str
   1.115 +     (.replaceFirst (.getCanonicalPath current-file)
   1.116 +		    (.getCanonicalPath base-path)
   1.117 +		    (.getCanonicalPath base-destination)))))
   1.118 +
   1.119 +(defn export-dependencies [namespace #^java.io.File target]
   1.120 +  (let [[jars sources] (bifurcate jar? (dependencies-file namespace))
   1.121 +	jars (if *nailgun*
   1.122 +	       (conj jars (file-str "~/roBin/nailgun-0.7.1/nailgun-0.7.1.jar"))
   1.123 +	       jars)
   1.124 +       
   1.125 +	lib (file-str (str (.getCanonicalPath target) File/separatorChar "lib"))
   1.126 +	src (file-str (str (.getCanonicalPath target) File/separatorChar "src"))]
   1.127 +    (if *nailgun*
   1.128 +      (do
   1.129 +	(FileUtils/copyFileToDirectory (file-str "~/roBin/nailgun-0.7.1/ng") lib)
   1.130 +	(sw (str "chmod +x " (.getCanonicalPath target) File/separatorChar "lib/ng"))))
   1.131 +    (dorun (map #(FileUtils/copyFileToDirectory % lib) jars))
   1.132 +    (dorun (map #(FileUtils/copyFile % (destination (classpath-files) % src)) sources))))
   1.133 +
   1.134 +(defn run-script-text [namespace]
   1.135 +  
   1.136 +  (if *nailgun*
   1.137 +    (str
   1.138 +     
   1.139 +     "#!/usr/bin/perl
   1.140 +
   1.141 +if (`./lib/ng ng-alias 2>&1 1>/dev/null` eq \"connect: Connection refused\\n\"){
   1.142 +	
   1.143 +	$nailgun_init = 
   1.144 +	\"java -Xmn500M -Xms2000M -Xmx2000M \" . 
   1.145 +	\"-classpath ./src/:lib/*\" . \" -server \". 
   1.146 +	\"com.martiansoftware.nailgun.NGServer \". 
   1.147 +	\" >/dev/null 2>/dev/null &\";
   1.148 +	`$nailgun_init`;
   1.149 +	}\n\n"
   1.150 +     
   1.151 +     
   1.152 +     "while (`./lib/ng ng-alias 2>&1 1>/dev/null` eq \"connect: Connection refused\\n\"){
   1.153 +    }\n\n"
   1.154 +     
   1.155 +     "$command = "
   1.156 +     
   1.157 +     
   1.158 +     "\"./lib/ng clojure.main "
   1.159 +     "./src/"
   1.160 +     (.replace (.replace (str *ns*) \. File/separatorChar) \- \_)
   1.161 +     ".clj "
   1.162 +     " @ARGV\";\n"
   1.163 +     
   1.164 +     "print `$command`;\n")
   1.165 +    (str
   1.166 +     "#!/bin/bash\n"
   1.167 +     "java -Xmn500M -Xms2000M -Xmx2000M -server -cp ./lib/*:./src clojure.main "
   1.168 +     "./src/"
   1.169 +     (.replace (.replace (str *ns*) \. File/separatorChar) \- \_)
   1.170 +     ".clj "
   1.171 +     " $@\n")))
   1.172 +
   1.173 +
   1.174 +
   1.175 +(defn make-run-script [namespace base-dir name]
   1.176 +  (let [w (clojure.java.io/writer
   1.177 +	   (str (.getCanonicalPath base-dir) File/separatorChar name))]
   1.178 +    (.write w (run-script-text namespace))
   1.179 +    (.close w))
   1.180 +  (let [f (file-str  (str (.getCanonicalPath base-dir) File/separatorChar name))]
   1.181 +    (.setExecutable f true)))
   1.182 +
   1.183 +(defn export-files [namespace base-dir name]
   1.184 +  (export-dependencies namespace base-dir)
   1.185 +  (make-run-script namespace base-dir name))
   1.186 +
   1.187 +(defn bzip-folder [#^java.io.File destination #^java.io.File directory]
   1.188 +  (apply (partial sw "tar" "-cvjf" (.getCanonicalPath destination))
   1.189 +	 (concat
   1.190 +	  (rest
   1.191 +	   (map #(.replaceFirst
   1.192 +		  %
   1.193 +		  (str (.getCanonicalPath directory) File/separatorChar ) "")
   1.194 +		(map str (file-seq directory))))
   1.195 +	  [:dir (.getCanonicalPath directory)])))
   1.196 +
   1.197 +(defn bzip-export-files [directory target-dir name]
   1.198 +  (apply (partial sw "tar" "-cvjf"
   1.199 +		  (str (.getCanonicalPath target-dir) File/separatorChar name))
   1.200 +	 (concat
   1.201 +	  [name "lib" "src"]
   1.202 +	  [:dir (.getCanonicalPath directory)])))
   1.203 +
   1.204 +(defn export-archive
   1.205 +  ([name]
   1.206 +     (export-archive *ns* name))
   1.207 +  
   1.208 +  ([namespace name nailgun?]
   1.209 +     (binding [*nailgun* nailgun?]
   1.210 +       (export-archive namespace name)))
   1.211 +  
   1.212 +  ([namespace name]
   1.213 +     (FileUtils/forceMkdir standard-base-directory)
   1.214 +     (FileUtils/forceDelete standard-base-directory)
   1.215 +     (FileUtils/forceMkdir standard-base-directory)
   1.216 +     (let [new-dir
   1.217 +	   (file-str
   1.218 +	    (str
   1.219 +	     (.getCanonicalPath standard-base-directory)
   1.220 +	     (File/separatorChar)
   1.221 +	     name))]
   1.222 +       
   1.223 +       (export-files namespace new-dir name)
   1.224 +
   1.225 +       (bzip-export-files new-dir (file-str "~/coderloop/") (str name "-clojure.tar.bz2"))
   1.226 +       (FileUtils/copyFileToDirectory
   1.227 +	(file-str (str "~/coderloop/" name "-clojure.tar.bz2"))
   1.228 +	(file-str "~/coderloop-test")))))