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