Permalink
Browse files

use Xbootclasspath with clojure.jar in cake jvm for improved startup …

…speed. fetch clojure separately from cake jar. remove version from internal bake jar. add progress bars to bootstrap downloads. release bin/cake to cake-standalone on github for stable releases.
  • Loading branch information...
1 parent 3d9da49 commit a0e79ec291e7caa5725b42ff17fa552354cc0742 @ninjudd committed Sep 2, 2010
Showing with 104 additions and 79 deletions.
  1. +77 −63 bin/cake
  2. +1 −1 gem/cake.gemspec
  3. +8 −7 src/cake/tasks/jar.clj
  4. +18 −8 tasks.clj
View
140 bin/cake
@@ -3,10 +3,8 @@
require 'find'
require 'open-uri'
require 'socket'
-require 'timeout'
require 'fileutils'
require 'io/wait'
-require 'pp'
if RUBY_PLATFORM =~ /(mingw|mswin)(32|64)$/
begin
@@ -231,47 +229,58 @@ rescue NotImplementedError, Errno::EINVAL
file
end
-def download(url, path)
- log(:deps, "downloading #{url}")
- open(url) do |remote|
- open(path, "wb") do |local|
- while (buf = remote.read(8192))
- local.write buf
+def download(url, dir, dest = nil)
+ path = "#{dir}/#{File.basename(url)}"
+ if dest.nil? or not File.exists?(path)
+ FileUtils.makedirs(dir)
+ open(url, progress_bar(url)) do |remote|
+ open(path, "wb") do |local|
+ while (buf = remote.read(8192))
+ local.write buf
+ end
+ puts
end
end
end
+ copy(path, dest)
+rescue OpenURI::HTTPError
+ raise "resource not found: #{url}"
end
-def get_cake(version, dest = nil, opts = {})
- jar = "cake-#{version}.jar"
- repo = File.expand_path("~/.m2/repository/cake/cake/#{version}")
- path = "#{repo}/#{jar}"
+def get_cake(version, dest = nil)
+ download("#{$github}/jars/cake-#{version}.jar", "#{$m2}/cake/cake/#{snapshot(version)}", dest)
+end
- if not File.exists?(path)
- url = "#{$repo}/jars/#{jar}"
- log(:deps, "fetching cake libraries. this may take a moment...") unless @logged; @logged = true
- FileUtils.makedirs(repo)
- download(url, path)
- end
- return path unless dest
+def get_clojure(dest = nil, repo = "http://build.clojure.org/releases", version = "1.2.0")
+ path = "org/clojure/clojure/#{version}"
+ download("#{repo}/#{path}/clojure-#{version}.jar", "#{$m2}/#{path}", dest)
+end
+
+def progress_bar(label, ch = '=', bg = '', width = nil, out = $stdout, progress = 0, total = nil)
+ width ||= [`stty size 2>&1`.split[1].to_i, 80].max - (label.size + 4)
+ { :progress_proc => lambda {|c| progress += ((width * c/total).to_i - progress).times { out.print_flush(ch) }},
+ :content_length_proc => lambda {|t| printf("%1$s [%2$#{width}s]\r%1$s [", label, bg); total = t}}
+end
+def copy(src, dest)
+ return src unless dest
+ return unless File.exists?(src)
dest = File.expand_path(dest)
FileUtils.makedirs(dest)
- FileUtils.copy(path, dest)
- "#{dest}/#{jar}"
-rescue OpenURI::HTTPError => e
- raise if opts[:raise]
- log(:deps, "unable to find cake version #{version} on clojars.")
- log(:deps, "please check http://github.com/ninjudd/cake for latest install instructions.")
- exit
+ FileUtils.copy(src, dest)
+ "#{dest}/#{File.basename(src)}"
end
-def current_version(tag = :current)
- version = open("#{$repo}/#{tag}").gets
+def cake_current(tag = :current)
+ version = open("#{$github}/#{tag}").gets
log(:deps, "most recent standalone version is #{version}") if debug?
version
end
+def snapshot(version)
+ version.gsub(/\d{8}\.\d{6}$/, "SNAPSHOT")
+end
+
def extract(jar, file, dest = File.dirname(jar))
if not File.exists?("#{dest}/#{file}")
log(:deps, "extracting #{file} from #{jar}") if verbose?
@@ -299,7 +308,7 @@ class JVM
@type = self.class.name.downcase
@classpath = make_path(classpath)
@libpath = make_path(libpath)
- @pidfile = "#{$confdir}/#{type}.pid"
+ @pidfile = ".cake/#{type}.pid"
@load_time = File.exists?(pidfile) ? File.mtime(pidfile) : Time.now
refresh
end
@@ -475,16 +484,17 @@ class JVM
save_history
end
- def run(file = $script)
+ def run
+ file = File.expand_path($opts[:run].first)
with_socket do |socket|
log(:run, "running file #{file}") if debug?
socket.write(":run #{$vars} #{file.inspect}")
socket.duplex($stdin, $stdout)
end
end
- def eval(forms = $opts[:eval])
- forms = forms.collect do |form|
+ def eval
+ forms = $opts[:eval].collect do |form|
form == '-' ? $stdin.gets(nil) : form
end.join(' ')
forms = "(doall (map println [#{forms}]))" unless $opts[:q]
@@ -496,7 +506,8 @@ class JVM
end
EOL = "EOL__#{rand}"
- def filter(forms = $opts[:filter])
+ def filter
+ forms = $opts[:filter]
with_socket do |socket|
socket.write %(:filter #{$vars} "#{EOL}")
while line = $stdin.gets
@@ -646,7 +657,8 @@ class Cake < JVM
end
def java_opts
- [ENV['CAKE_JAVA_OPTS'], $config['cake.java_opts'], super].compact.join(' ')
+ bootclasspath = %{-Xbootclasspath/a:"#{$clojure}"}
+ [ENV['CAKE_JAVA_OPTS'], $config['cake.java_opts'], bootclasspath, super].compact.join(' ')
end
private
@@ -675,16 +687,16 @@ class Bake < JVM
end
def enabled?
- Dir["lib/*.jar"].any?
+ Dir['lib/*.jar'].any?
end
end
-#==================================
-
-FileUtils.makedirs("#{$home}/.cake")
-project_clj = "#{$home}/.cake/project.clj"
-File.open(project_clj, 'w') do |file|
- file.write <<END
+def initialize_cake_dirs
+ FileUtils.makedirs("#{$bakedir}/.cake")
+ FileUtils.makedirs("#{$home}/.cake")
+ project_clj = "#{$home}/.cake/project.clj"
+ File.open(project_clj, 'w') do |file|
+ file.write <<END
(defproject global "0.0.0"
:description "Don't rename this project, but you can change the version if you want."
:dependencies [[clojure "1.2.0"]
@@ -698,21 +710,23 @@ File.open(project_clj, 'w') do |file|
;; 4. Configuration options in ~/.cake/config are used in all projects.
;;--------------------
END
-end unless File.exists?(project_clj)
+ end unless File.exists?(project_clj)
+end
+
+#==================================
parse_opts!
-$script = File.expand_path($opts[:run].first) if $opts[:run]
$pwd = Dir.getwd
$bakedir = project_dir($pwd)
$cakedir = File.dirname(File.dirname(readlink(__FILE__)))
-$repo = "http://github.com/ninjudd/cake-standalone/raw/master"
-$confdir = ".cake"
+$github = "http://github.com/ninjudd/cake-standalone/raw/master"
+$m2 = "#{$home}/.m2/repository"
$config = Configuration.new("#{$home}/.cake/config", ".cake/config")
-$timeout = ($config['connect.timeout'] || 20).to_i
$vars = {:env => ENV.to_hash, :pwd => $pwd, :args => ARGV, :opts => $opts, :script => $0}.to_clj
+$timeout = ($config['connect.timeout'] || 20).to_i
Dir.chdir($bakedir)
-FileUtils.makedirs($confdir)
+initialize_cake_dirs
if debug?
puts "config: #{$config.inspect}"
@@ -738,19 +752,14 @@ if File.exists?("#{$cakedir}/.gitignore") and File.exists?(project)
if Dir["#{lib}/*.jar"].empty? or Dir["#{lib}/dev/*.jar"].empty?
# In a new git checkout, need to fetch dependencies.
- begin
- version = $version
- cakejar = get_cake(version, lib, :raise => true)
- rescue OpenURI::HTTPError => e
- version = current_version
- cakejar = get_cake(version, lib)
- end
- bake_version = version.gsub(/\d{8}\.\d{6}/, "SNAPSHOT")
- extract(cakejar, "bake-#{bake_version}.jar", "#{lib}/dev")
+ log(:deps, "Fetching cake dependencies...")
+ cakejar = get_cake($version, lib) rescue get_cake(cake_current, lib)
+ extract(cakejar, "bake.jar", "#{lib}/dev")
end
+ $clojure = get_clojure(lib)
- cakepath = ["#{$cakedir}/src", "#{lib}/*:#{lib}/dev/*"].join(PATH_SEP)
- bakepath = ["#{$cakedir}/bake", "#{lib}/dev/*"].join(PATH_SEP)
+ cakepath = ["#{$cakedir}/src", "#{lib}/*:#{lib}/dev/*"]
+ bakepath = ["#{$cakedir}/bake", "#{lib}/dev/*"]
else
cakejar = "#{lib}/cake.jar"
bakejar = "#{lib}/bake.jar"
@@ -763,16 +772,21 @@ else
end
$version = File.basename(File.dirname(lib)).split('-')[1]
- cakepath = cakejar
+ $clojure = "#{lib}/clojure.jar"
+
+ cakepath = [cakejar, $clojure]
bakepath = bakejar
else
# Standalone script.
log(:cake, "running from standalone script") if verbose?
- download("http://github.com/ninjudd/cake/raw/master/bin/cake", __FILE__) if $command == :upgrade
+ download("#{$github}/cake", __FILE__) if $command == :upgrade
+
+ $version = cake_current(:stable)
+ cakejar = get_cake($version)
+ $clojure = get_clojure
- $version = current_version(:stable)
- cakepath = get_cake($version)
- bakepath = extract(cakepath, "bake-#{$version}.jar")
+ cakepath = [cakejar, $clojure]
+ bakepath = extract(cakejar, "bake.jar")
end
end
View
@@ -9,6 +9,6 @@ Gem::Specification.new do |s|
s.description = "Save your fork, there's cake!"
s.email = 'code@justinbalthrop.com'
s.executables = ['cake']
- s.files = ['cake.gemspec', 'bin/cake', 'lib/cake.jar', 'lib/bake.jar']
+ s.files = ['cake.gemspec', 'bin/cake', 'lib/cake.jar', 'lib/bake.jar', 'lib/clojure.jar']
s.homepage = 'http://github.com/ninjudd/cake'
end
View
@@ -1,5 +1,6 @@
(ns cake.tasks.jar
(:use cake cake.core cake.ant ordered-set
+ [clojure.string :only [join]]
[useful :only [absorb]])
(:import [org.apache.tools.ant.taskdefs Jar War Copy Delete]
[org.apache.tools.ant.types FileSet ZipFileSet]
@@ -68,18 +69,18 @@
(defn uberjarfile []
(file (format "%s-%s-standalone.jar" (:artifact-id *project*) (:version *project*))))
-(defn jars []
- (let [jar (jarfile)]
+(defn jars [& opts]
+ (let [opts (apply hash-map opts)
+ jar (jarfile)]
(into (ordered-set jar)
- (fileset-seq {:dir "lib" :includes "*.jar"}))))
+ (fileset-seq {:dir "lib" :includes "*.jar" :excludes (join "," (:excludes opts))}))))
(defn rebuild-uberjar? [jarfile jars]
(let [last-mod (.lastModified jarfile)]
(some #(< last-mod (.lastModified %)) jars)))
-(defn build-uberjar []
- (let [jars (jars)
- jarfile (uberjarfile)]
+(defn build-uberjar [jars]
+ (let [jarfile (uberjarfile)]
(when (rebuild-uberjar? jarfile jars)
(log "Building jar:" jarfile)
(doto (DefaultShader.)
@@ -88,7 +89,7 @@
(deftask uberjar #{jar}
"Create a standalone jar containing all project dependencies."
- (build-uberjar))
+ (build-uberjar (jars)))
(defn warfile []
(file (format "%s-%s.war" (:artifact-id *project*) (:version *project*))))
View
@@ -1,19 +1,25 @@
(ns user
(:use cake cake.core cake.ant
[useful :only [abort]]
- [cake.tasks.jar :only [uberjarfile]]
+ [cake.tasks.jar :only [build-uberjar jars uberjarfile]]
[cake.tasks.release :only [upload-to-clojars]])
(:import [org.apache.tools.ant.taskdefs Jar Copy Move ExecTask]
[java.io File]))
(defn bakejar []
- (file (format "bake-%s.jar" (:version *project*))))
+ (file "bake.jar"))
(defn add-dev-jars [task]
(doseq [jar (fileset-seq {:dir "lib/dev" :includes "*.jar"})]
(add-zipfileset task {:src jar :includes "**/*.clj" :excludes "META-INF/**/project.clj"})))
-(deftask uberjar
+(defn clojure-jar []
+ (str "clojure-" (.replace (clojure-version) "SNAPSHOT" "*") ".jar"))
+
+(undeftask uberjar)
+(deftask uberjar #{jar}
+ "Create a standalone jar containing all project dependencies."
+ (build-uberjar (jars :excludes [(clojure-jar)]))
(let [jarfile (uberjarfile)
bakejar (bakejar)]
(ant Jar {:dest-file bakejar}
@@ -34,6 +40,8 @@
(do (run-task 'uberjar)
(ant Copy {:file (uberjarfile) :tofile (file "gem/lib/cake.jar")})
(ant Copy {:file (bakejar) :tofile (file "gem/lib/bake.jar")})
+ (ant Copy {:tofile (file "gem/lib/clojure.jar")}
+ (add-fileset {:dir "lib" :includes (clojure-jar)}))
(ant Copy {:file (file "bin/cake") :tofile (file "gem/bin/cake")})
(ant ExecTask {:executable "gem" :dir (file "gem")}
(env {"CAKE_VERSION" version})
@@ -55,13 +63,15 @@
snapshot? (snapshot? version)
version (if snapshot? (snapshot-timestamp version) version)
jar (format "jars/cake-%s.jar" version)]
- (ant Copy {:file (uberjarfile) :tofile (file "releases" jar)})
- (spit (file "releases/current") version)
- (when-not snapshot? (spit (file "releases/stable") version))
+ (ant Copy {:file (uberjarfile) :tofile (file "releases" jar)})
+ (spit (file "releases/current") version)
+ (when-not snapshot?
+ (ant Copy {:file (file "bin" "cake") :tofile (file "releases" "cake")})
+ (spit (file "releases/stable") version))
(binding [*root* "releases"]
- (git "add" jar "current" "stable")
+ (git "add" jar "cake" "current" "stable")
(git "commit" "-m" (format "'release cake %s'" (:version *project*)))
- (comment git "push"))
+ (git "push"))
(when-not snapshot?
(let [gem (str "cake-" version ".gem")]
(log "Releasing gem:" gem)

0 comments on commit a0e79ec

Please sign in to comment.