cake 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. data/bin/cake +182 -102
  2. data/lib/bake.jar +0 -0
  3. data/lib/cake.jar +0 -0
  4. metadata +4 -4
data/bin/cake CHANGED
@@ -13,7 +13,7 @@ begin
13
13
  rescue LoadError => e
14
14
  module Readline
15
15
  HISTORY = []
16
- attr_accessor :completer_word_break_characters, :completion_proc
16
+ attr_accessor :basic_word_break_characters, :completion_proc
17
17
  def readline(prompt)
18
18
  $stdout.print prompt
19
19
  $stdout.flush
@@ -23,12 +23,21 @@ rescue LoadError => e
23
23
  end
24
24
  end
25
25
 
26
+ def project_dir(dir)
27
+ while dir != "/"
28
+ return dir if [".cake", "project.clj", "build.clj"].any? {|file| File.exists?("#{dir}/#{file}")}
29
+ dir = File.dirname(dir)
30
+ end
31
+ File.expand_path("~")
32
+ end
33
+
26
34
  PATH_SEP = ':'
27
35
  file = File.readlink(__FILE__) rescue __FILE__
28
- $bakedir = Dir.getwd
36
+ $bakedir = project_dir(Dir.getwd)
29
37
  $cakedir = File.dirname(File.dirname(file))
30
38
  $repo = "http://clojars.org/repo/cake/cake"
31
39
  $confdir = ".cake"
40
+ Dir.chdir($bakedir)
32
41
  File.makedirs($confdir)
33
42
 
34
43
  def get_cake(version, dest = nil)
@@ -89,6 +98,7 @@ def extract(jar, file, dest = File.dirname(jar))
89
98
  end
90
99
 
91
100
  def newer?(file1, file2)
101
+ return false unless File.exists?(file1)
92
102
  not File.exists?(file2) or test(?>, file1, file2)
93
103
  end
94
104
 
@@ -121,11 +131,11 @@ def verbose?
121
131
  end
122
132
 
123
133
  def config_updated?
124
- newer?(".cake/config", ".cake/cake.pid") or newer?(".cake/config", ".cake/bake.pid")
134
+ newer?(".cake/config", ".cake/cake.pid") or (File.exists?(".cake/bake.pid") and newer?(".cake/config", ".cake/bake.pid"))
125
135
  end
126
136
 
127
137
  def restart?
128
- $opts[:r] or $opts[:restart] or [:stop, :restart].include?($command) or config_updated?
138
+ $opts[:r] or $opts[:restart] or [:stop, :restart].include?($command)
129
139
  end
130
140
 
131
141
  def admin_command?
@@ -138,7 +148,7 @@ def log(command, *message)
138
148
  end
139
149
  end
140
150
 
141
- class Config < Hash
151
+ class Configuration < Hash
142
152
  def initialize(path)
143
153
  File.open(path, 'r') do |file|
144
154
  file.each do |line|
@@ -161,24 +171,19 @@ class Config < Hash
161
171
  end
162
172
 
163
173
  def config
164
- @config ||= Config.new(".cake/config")
174
+ @config ||= Configuration.new(".cake/config")
165
175
  end
166
176
 
167
177
  class JVM
168
- attr_reader :type, :classpath, :libpath, :port, :pid, :pidfile, :start_time
178
+ attr_reader :type, :classpath, :libpath, :port, :pid, :pidfile, :load_time
169
179
 
170
180
  def initialize(classpath, libpath)
171
181
  @type = self.class.name.downcase
172
182
  @classpath = make_path(classpath)
173
183
  @libpath = make_path(libpath)
174
184
  @pidfile = "#{$confdir}/#{type}.pid"
175
- @start_time = File.exists?(pidfile) ? File.mtime(pidfile) : Time.now
176
-
177
- @pid, @port = IO.read(pidfile).map {|l| l.to_i}
178
- Process.kill(0, @pid) # make sure pid is valid
179
-
180
- rescue Errno::ESRCH, Errno::ENOENT => e
181
- reset! # no pidfile or invalid pid
185
+ @load_time = File.exists?(pidfile) ? File.mtime(pidfile) : Time.now
186
+ refresh
182
187
  end
183
188
 
184
189
  def running?
@@ -190,8 +195,23 @@ class JVM
190
195
  end
191
196
 
192
197
  def init
193
- reload_stale_files if enabled? and running?
198
+ stale = reload_stale_files if enabled? and running?
194
199
  start
200
+ stale
201
+ end
202
+
203
+ def refresh
204
+ @pid, @port = IO.read(pidfile).map {|l| l.to_i}
205
+ Process.kill(0, @pid) # make sure pid is valid
206
+ TCPSocket.new("localhost", @port).close if @port # make sure jvm is running on port
207
+ rescue Errno::ENOENT, Errno::ESRCH, Errno::ECONNREFUSED => e
208
+ log(:start, "defunct #{type} jvm") if debug? and e.kind_of?(Errno::ECONNREFUSED)
209
+ reset! # no pidfile or invalid pid or connection refused
210
+ end
211
+
212
+ def reload
213
+ refresh
214
+ init
195
215
  end
196
216
 
197
217
  def reload_stale_files
@@ -199,6 +219,7 @@ class JVM
199
219
 
200
220
  if stale_files.empty?
201
221
  log(:reload, "no stale #{type} files found") if verbose? and admin_command?
222
+ false
202
223
  else
203
224
  log(:reload, "the following #{type} files have changed: #{stale_files.join(', ')}") if debug?
204
225
 
@@ -212,7 +233,7 @@ class JVM
212
233
  socket.write ":reload [#{stale_files.join(" ")}]\n"
213
234
  if socket.eof?
214
235
  FileUtils.touch(pidfile)
215
- @start_time = Time.now
236
+ @load_time = Time.now
216
237
  else
217
238
  inspect(socket) if debug?
218
239
  log(:reload, "unable to reload all #{type} files, restarting") if verbose?
@@ -220,6 +241,7 @@ class JVM
220
241
  end
221
242
  end
222
243
  end
244
+ true
223
245
  end
224
246
  end
225
247
 
@@ -233,12 +255,16 @@ class JVM
233
255
  MAX_PORT = 2**16
234
256
 
235
257
  def start
236
- return if not enabled? or running?
237
- @port = rand(MAX_PORT - MIN_PORT) + MIN_PORT
238
- log(:start, "starting #{type} jvm on port #{port}") if debug?
239
- @pid = daemon %{ java -Dcake.project=#{$bakedir} #{java_opts} clojure.main -e "(use '#{type})(start-server #{port})" /dev/null }
240
- File.open(pidfile, 'w') {|f| f.write("#{pid}\n#{port}\n") }
241
- log(:start, "#{type} jvm started") if verbose?
258
+ return unless enabled?
259
+ if running?
260
+ log(:start, "#{type} jvm already running") if $command == :start
261
+ return
262
+ else
263
+ log(:start, "starting #{type} jvm") if verbose? or $command == :start
264
+ @port = rand(MAX_PORT - MIN_PORT) + MIN_PORT
265
+ @pid = daemon %{ java -Dcake.project=#{$bakedir} #{java_opts} clojure.main -e "(use '#{type})(start-server #{port})" /dev/null }
266
+ File.open(pidfile, 'w') {|f| f.write("#{pid}\n#{port}\n") }
267
+ end
242
268
  rescue Errno::EADDRNOTAVAIL => e
243
269
  retry
244
270
  end
@@ -249,7 +275,7 @@ class JVM
249
275
  log(mode, "sending #{action} to #{type} jvm on port #{port}") if debug?
250
276
  socket.write(":#{action}\n")
251
277
  if socket.eof?
252
- log(mode, "#{type} jvm stopped") if verbose?
278
+ log(mode, "#{type} jvm stopped") if restart?
253
279
  reset!
254
280
  else
255
281
  inspect(socket) if debug?
@@ -260,7 +286,7 @@ class JVM
260
286
  log(mode, " close active connections or use 'cake stop' to force quit")
261
287
  end
262
288
  end
263
- end || (log(mode, "#{type} jvm not running") if verbose?)
289
+ end || (log(mode, "#{type} jvm not running") if $command == :stop)
264
290
  end
265
291
 
266
292
  def kill
@@ -268,7 +294,7 @@ class JVM
268
294
  end
269
295
 
270
296
  def files
271
- files = []
297
+ files = ["project.clj"]
272
298
  classpath.split(PATH_SEP).uniq.each do |path|
273
299
  if path =~ /(.*)\/\*$/
274
300
  files.concat Dir["#{path}.jar"] << "#{$1}/." # include the directory itself so deletions will be detected
@@ -282,6 +308,31 @@ class JVM
282
308
  files
283
309
  end
284
310
 
311
+ def ping
312
+ return unless enabled?
313
+ with_socket(10) do |socket|
314
+ socket.write ":ping\n"
315
+ log($command, "#{type} jvm not running") unless socket.gets == "pong\n"
316
+ end
317
+ end
318
+
319
+ REPL_PROMPT = "REPL_PROMPT__#{rand}"
320
+ def repl
321
+ load_history
322
+ loop do
323
+ with_socket do |socket|
324
+ socket.write %{:repl "#{REPL_PROMPT}"}
325
+ while @ns = read_until_prompt(socket)
326
+ line = readline
327
+ return unless line
328
+ socket.write(line + "\n")
329
+ end
330
+ end
331
+ end
332
+ ensure
333
+ save_history
334
+ end
335
+
285
336
  private
286
337
 
287
338
  def make_path(paths)
@@ -299,11 +350,11 @@ private
299
350
  def reset!
300
351
  File.unlink(pidfile) if File.exists?(pidfile)
301
352
  @pid, @port = []
302
- @start_time = Time.now
353
+ @load_time = Time.now
303
354
  end
304
355
 
305
356
  def stale?(file)
306
- File.exists?(file) and File.mtime(file) > start_time
357
+ File.exists?(file) and File.mtime(file) > load_time
307
358
  end
308
359
 
309
360
  def daemon(cmd)
@@ -328,70 +379,9 @@ private
328
379
  ensure
329
380
  socket.close if socket
330
381
  end
331
- end
332
-
333
- class Cake < JVM
334
- attr_accessor :bakeport
335
-
336
- def files
337
- super.concat ["project.clj", "build.clj", ".cake/swank"]
338
- end
339
-
340
- def send_command(command, *args)
341
- with_socket do |socket|
342
- socket.write("(#{command} [#{args.join(' ')}] #{bakeport})\n")
343
- while(line = socket.gets)
344
- puts line
345
- end
346
- command
347
- end
348
- end
349
-
350
- def java_opts
351
- [ENV['CAKE_JAVA_OPTS'], config['cake.java_opts'], super].compact.join(' ')
352
- end
353
- end
354
-
355
- class Bake < JVM
356
- MARKER = "=#{rand.to_s}="
357
- PROMPT = /^(.*)#{MARKER}$/
358
- START_REPL = <<-END
359
- (clojure.main/repl
360
- :init #(in-ns 'user)
361
- :prompt #(printf "%s#{MARKER}\n" (ns-name *ns*)))
362
- END
363
-
364
- def repl
365
- load_history
366
- loop do
367
- with_socket do |socket|
368
- socket.write START_REPL
369
- socket.gets # burn extra prompt
370
-
371
- while @ns = read_until_prompt(socket)
372
- line = readline
373
- return unless line
374
- socket.write(line + "\n")
375
- end
376
- end
377
- end
378
- ensure
379
- save_history
380
- end
381
-
382
- def java_opts
383
- [ENV['JAVA_OPTS'], config['project.java_opts'], super].compact.join(' ')
384
- end
385
-
386
- def enabled?
387
- Dir["lib/*.jar"].any?
388
- end
389
-
390
- private
391
382
 
392
383
  HISTORY_NUM = 500
393
384
  HISTORY_FILE = ".cake/history"
394
-
395
385
  def load_history
396
386
  open(HISTORY_FILE) do |file|
397
387
  file.each {|line| Readline::HISTORY << line.chomp}
@@ -407,7 +397,7 @@ private
407
397
 
408
398
  def read_until_prompt(socket)
409
399
  while line = socket.gets
410
- return $1 if line =~ PROMPT
400
+ return $1 if line =~ /^#{REPL_PROMPT}(.*)$/
411
401
  puts line
412
402
  end
413
403
  end
@@ -421,8 +411,7 @@ private
421
411
  end
422
412
  end
423
413
 
424
- Readline.completer_word_break_characters = " \t\n\"'`~@;#&{}()[]"
425
-
414
+ Readline.basic_word_break_characters = " \t\n\"'`~@;#&{}()[]"
426
415
  def readline
427
416
  input = []
428
417
  prompt = "#{@ns}=> "
@@ -454,6 +443,74 @@ private
454
443
  end
455
444
  end
456
445
 
446
+ class Cake < JVM
447
+ attr_accessor :bakeport
448
+
449
+ READLINE = "READLINE__#{rand}"
450
+ def send_command(command, args = [])
451
+ with_socket do |socket|
452
+ args = args.collect{|arg| '"' + arg.gsub('"', '\"').gsub("\n", "\\n") + '"'}
453
+ cmd = %{(#{command} [#{args.join(' ')}] #{bakeport}) "#{READLINE}"}
454
+ log(command, "sending: " + cmd) if debug?
455
+ socket.write(cmd)
456
+ while (line = socket.gets)
457
+ if line =~ /^#{READLINE}(.*)$/
458
+ socket.write(prompt($1))
459
+ elsif line =~ /^@#{READLINE}(.*)$/
460
+ socket.write(prompt($1, :echo => false))
461
+ else
462
+ puts line
463
+ end
464
+ end
465
+ end
466
+ end
467
+
468
+ def files
469
+ super.concat ["build.clj", ".cake/swank"]
470
+ end
471
+
472
+ def java_opts
473
+ [ENV['CAKE_JAVA_OPTS'], config['cake.java_opts'], super].compact.join(' ')
474
+ end
475
+
476
+ private
477
+
478
+ def prompt(prompt, opts = {})
479
+ if opts[:echo] == false
480
+ echo_off = system("stty -echo 2&> /dev/null")
481
+ prompt << " (WARNING, input will be visible on console!)" unless echo_off
482
+ end
483
+ input = Readline.readline(prompt + ": ") || ''
484
+ input + "\n"
485
+ ensure
486
+ if echo_off
487
+ system("stty echo 2&> /dev/null")
488
+ puts
489
+ end
490
+ end
491
+ end
492
+
493
+ class Bake < JVM
494
+ def java_opts
495
+ [ENV['JAVA_OPTS'], config['project.java_opts'], super].compact.join(' ')
496
+ end
497
+
498
+ def enabled?
499
+ Dir["lib/*.jar"].any?
500
+ end
501
+
502
+ def eval(*forms)
503
+ forms = forms.join(' ')
504
+ with_socket do |socket|
505
+ log(:eval, forms) if debug?
506
+ socket.write('[' + forms + ']')
507
+ while (line = socket.gets)
508
+ puts line
509
+ end
510
+ end
511
+ end
512
+ end
513
+
457
514
  # Bootstrap cake dependencies.
458
515
  lib = "#{$cakedir}/lib"
459
516
  if File.exists?("#{$cakedir}/.gitignore")
@@ -482,7 +539,7 @@ else
482
539
  end
483
540
 
484
541
  cake = Cake.new(
485
- [cakepath, "src", "src/clj", config['cake.classpath'], "lib/dev/*"],
542
+ [cakepath, "src", "src/clj", config['cake.claspath'], "lib/dev/*"],
486
543
  [config['cake.library.path'], "lib/dev/native"]
487
544
  )
488
545
  bake = Bake.new(
@@ -502,8 +559,9 @@ if $command == :kill
502
559
  end
503
560
  exit
504
561
  elsif $command == :ps
505
- exec "jps -v | grep cake.project"
506
- elsif restart?
562
+ puts `jps -v | grep cake.project`.sort.reverse
563
+ exit
564
+ elsif restart? or config_updated?
507
565
  cake.stop
508
566
  bake.stop
509
567
  exit if $command == :stop
@@ -512,22 +570,44 @@ end
512
570
  cake.init
513
571
  if not [:deps, :clean].include?($command) and File.exists?('project.clj')
514
572
  if newer?('project.clj', 'pom.xml')
515
- deps = cake.send_command(:deps)
516
- elsif File.exist?('.cake/swank')
517
- deps = cake.send_command(:"swank-deps")
573
+ cake.send_command(:deps)
574
+ cake.init
575
+ elsif File.exist?('.cake/swank')
576
+ cake.send_command(:"swank-deps")
577
+ cake.init
518
578
  end
519
579
 
520
580
  bake.init
521
- cake.init if deps # must check if dev dependencies have changed
522
581
  end
523
582
 
524
583
  if $command == :repl
525
- if File.exists?('project.clj')
584
+ if File.exists?('project.clj') and not $opts[:cake]
526
585
  bake.repl
527
586
  else
528
- log(:repl, "cannot start repl without project.clj")
587
+ cake.repl
588
+ end
589
+ elsif $command == :eval
590
+ bake.eval(*$opts[:eval])
591
+ elsif [:start, :reload, :restart].include?($command)
592
+ if $opts[:l] or $opts[:log]
593
+ system("tail -f .cake/bake.log")
594
+ else
595
+ cake.ping
596
+ bake.ping
529
597
  end
530
- elsif not [:start, :reload, :restart].include?($command)
598
+ else
531
599
  cake.bakeport = bake.port
532
- cake.send_command($command, ARGV)
600
+ if $command == :test and $opts[:auto]
601
+ interval = $opts[:auto].last.to_i
602
+ interval = (config['test.auto.interval'].to_i if config['test.auto.interval']) || (1 if interval == 0)
603
+ run_tests = true
604
+ while true
605
+ cake.send_command($command, ARGV) if run_tests
606
+ run_tests = bake.reload
607
+ cake.reload
608
+ sleep(interval)
609
+ end
610
+ else
611
+ cake.send_command($command, ARGV)
612
+ end
533
613
  end
data/lib/bake.jar CHANGED
Binary file
data/lib/cake.jar CHANGED
Binary file
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cake
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 1
10
- version: 0.3.1
9
+ - 2
10
+ version: 0.3.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Justin Balthrop
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-07-08 00:00:00 -07:00
19
+ date: 2010-07-26 00:00:00 -07:00
20
20
  default_executable: cake
21
21
  dependencies: []
22
22