unicorn 0.99.0 → 0.990.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/.document +1 -0
  2. data/.gitignore +3 -1
  3. data/Documentation/unicorn.1.txt +1 -1
  4. data/FAQ +3 -2
  5. data/GIT-VERSION-GEN +1 -1
  6. data/GNUmakefile +43 -8
  7. data/KNOWN_ISSUES +3 -24
  8. data/PHILOSOPHY +3 -2
  9. data/Rakefile +23 -2
  10. data/Sandbox +78 -0
  11. data/bin/unicorn_rails +14 -36
  12. data/examples/big_app_gc.rb +33 -0
  13. data/examples/unicorn.conf.minimal.rb +13 -0
  14. data/examples/unicorn.conf.rb +9 -3
  15. data/ext/unicorn_http/unicorn_http.rl +14 -2
  16. data/ext/unicorn_http/unicorn_http_common.rl +1 -1
  17. data/lib/unicorn.rb +5 -11
  18. data/lib/unicorn/configurator.rb +22 -8
  19. data/lib/unicorn/const.rb +3 -1
  20. data/lib/unicorn/oob_gc.rb +58 -0
  21. data/lib/unicorn/util.rb +7 -9
  22. data/local.mk.sample +32 -36
  23. data/t/GNUmakefile +7 -2
  24. data/t/rails3-app/.gitignore +4 -0
  25. data/t/rails3-app/Gemfile +26 -0
  26. data/t/rails3-app/Rakefile +10 -0
  27. data/t/rails3-app/app/controllers/application_controller.rb +4 -0
  28. data/t/rails3-app/app/helpers/application_helper.rb +2 -0
  29. data/t/rails3-app/app/views/layouts/application.html.erb +14 -0
  30. data/t/rails3-app/config.ru +4 -0
  31. data/t/rails3-app/config/application.rb +46 -0
  32. data/t/rails3-app/config/boot.rb +6 -0
  33. data/t/rails3-app/config/database.yml +22 -0
  34. data/t/rails3-app/config/environment.rb +5 -0
  35. data/t/rails3-app/config/environments/development.rb +19 -0
  36. data/t/rails3-app/config/environments/production.rb +42 -0
  37. data/t/rails3-app/config/environments/test.rb +32 -0
  38. data/t/rails3-app/config/initializers/backtrace_silencers.rb +7 -0
  39. data/t/rails3-app/config/initializers/inflections.rb +10 -0
  40. data/t/rails3-app/config/initializers/mime_types.rb +5 -0
  41. data/t/rails3-app/config/initializers/secret_token.rb +7 -0
  42. data/t/rails3-app/config/initializers/session_store.rb +8 -0
  43. data/t/rails3-app/config/locales/en.yml +5 -0
  44. data/t/rails3-app/config/routes.rb +58 -0
  45. data/t/rails3-app/db/seeds.rb +7 -0
  46. data/t/rails3-app/doc/README_FOR_APP +2 -0
  47. data/{test/rails/app-2.3.5/db/.gitignore → t/rails3-app/lib/tasks/.gitkeep} +0 -0
  48. data/{test/rails/app-2.3.5 → t/rails3-app}/public/404.html +0 -0
  49. data/{test/rails/app-2.3.5 → t/rails3-app}/public/500.html +0 -0
  50. data/{test/rails/app-2.3.5 → t/rails3-app}/public/x.txt +0 -0
  51. data/t/rails3-app/script/rails +9 -0
  52. data/t/rails3-app/test/performance/browsing_test.rb +9 -0
  53. data/t/rails3-app/test/test_helper.rb +13 -0
  54. data/t/rails3-app/vendor/plugins/.gitkeep +0 -0
  55. data/t/t0300-rails3-basic.sh +56 -0
  56. data/t/test-lib.sh +2 -1
  57. data/test/exec/test_exec.rb +20 -3
  58. data/test/rails/{app-2.3.5 → app-2.3.8}/.gitignore +0 -0
  59. data/test/rails/{app-2.3.5 → app-2.3.8}/Rakefile +0 -0
  60. data/test/rails/{app-2.3.5 → app-2.3.8}/app/controllers/application_controller.rb +0 -0
  61. data/test/rails/{app-2.3.5 → app-2.3.8}/app/controllers/foo_controller.rb +0 -0
  62. data/test/rails/{app-2.3.5 → app-2.3.8}/app/helpers/application_helper.rb +0 -0
  63. data/test/rails/{app-2.3.5 → app-2.3.8}/config/boot.rb +0 -0
  64. data/test/rails/{app-2.3.5 → app-2.3.8}/config/database.yml +0 -0
  65. data/test/rails/{app-2.3.5 → app-2.3.8}/config/environment.rb +0 -0
  66. data/test/rails/{app-2.3.5 → app-2.3.8}/config/environments/development.rb +0 -0
  67. data/test/rails/{app-2.3.5 → app-2.3.8}/config/environments/production.rb +0 -0
  68. data/test/rails/{app-2.3.5 → app-2.3.8}/config/routes.rb +0 -0
  69. data/test/rails/app-2.3.8/db/.gitignore +0 -0
  70. data/test/rails/app-2.3.8/public/404.html +1 -0
  71. data/test/rails/app-2.3.8/public/500.html +1 -0
  72. data/test/rails/app-2.3.8/public/x.txt +1 -0
  73. data/test/rails/test_rails.rb +4 -0
  74. data/test/unit/test_http_parser.rb +11 -1
  75. data/test/unit/test_http_parser_ng.rb +21 -1
  76. data/test/unit/test_signals.rb +2 -2
  77. data/test/unit/test_socket_helper.rb +5 -3
  78. data/test/unit/test_util.rb +22 -18
  79. data/unicorn.gemspec +2 -0
  80. metadata +66 -18
@@ -0,0 +1,13 @@
1
+ # Minimal sample configuration file for Unicorn (not Rack) when used
2
+ # with daemonization (unicorn -D) started in your working directory.
3
+ #
4
+ # See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
5
+ # documentation.
6
+ # See also http://unicorn.bogomips.org/examples/unicorn.conf.rb for
7
+ # a more verbose configuration using more features.
8
+
9
+ listen 2007 # by default Unicorn listens on port 8080
10
+ worker_processes 2 # this should be >= nr_cpus
11
+ pid "/path/to/app/shared/pids/unicorn.pid"
12
+ stderr_path "/path/to/app/shared/log/unicorn.log"
13
+ stdout_path "/path/to/app/shared/log/unicorn.log"
@@ -1,4 +1,9 @@
1
- # Sample configuration file for Unicorn (not Rack)
1
+ # Sample verbose configuration file for Unicorn (not Rack)
2
+ #
3
+ # This configuration file documents many features of Unicorn
4
+ # that may not be needed for some applications. See
5
+ # http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb
6
+ # for a much simpler configuration file.
2
7
  #
3
8
  # See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
4
9
  # documentation.
@@ -22,8 +27,9 @@ timeout 30
22
27
  # feel free to point this anywhere accessible on the filesystem
23
28
  pid "/path/to/app/shared/pids/unicorn.pid"
24
29
 
25
- # some applications/frameworks log to stderr or stdout, so prevent
26
- # them from going to /dev/null when daemonized here:
30
+ # By default, the Unicorn logger will write to stderr.
31
+ # Additionally, ome applications/frameworks log to stderr or stdout,
32
+ # so prevent them from going to /dev/null when daemonized here:
27
33
  stderr_path "/path/to/app/shared/log/unicorn.stderr.log"
28
34
  stdout_path "/path/to/app/shared/log/unicorn.stdout.log"
29
35
 
@@ -173,8 +173,20 @@ static void write_value(VALUE req, struct http_parser *hp,
173
173
  VALIDATE_MAX_LENGTH(LEN(mark, p), FIELD_VALUE);
174
174
  v = LEN(mark, p) == 0 ? rb_str_buf_new(128) : STR_NEW(mark, p);
175
175
  if (NIL_P(f)) {
176
- VALIDATE_MAX_LENGTH(hp->s.field_len, FIELD_NAME);
177
- f = uncommon_field(PTR_TO(start.field), hp->s.field_len);
176
+ const char *field = PTR_TO(start.field);
177
+ size_t flen = hp->s.field_len;
178
+
179
+ VALIDATE_MAX_LENGTH(flen, FIELD_NAME);
180
+
181
+ /*
182
+ * ignore "Version" headers since they conflict with the HTTP_VERSION
183
+ * rack env variable.
184
+ */
185
+ if (CONST_MEM_EQ("VERSION", field, flen)) {
186
+ hp->cont = Qnil;
187
+ return;
188
+ }
189
+ f = uncommon_field(field, flen);
178
190
  } else if (f == g_http_connection) {
179
191
  hp_keepalive_connection(hp, v);
180
192
  } else if (f == g_content_length) {
@@ -54,7 +54,7 @@
54
54
 
55
55
  value_cont = lws+ any* >start_value %write_cont_value;
56
56
 
57
- message_header = ((field_name ":" " "* field_value)|value_cont) :> CRLF;
57
+ message_header = ((field_name ":" lws* field_value)|value_cont) :> CRLF;
58
58
  chunk_ext_val = token*;
59
59
  chunk_ext_name = token*;
60
60
  chunk_extension = ( ";" " "* chunk_ext_name ("=" chunk_ext_val)? )*;
data/lib/unicorn.rb CHANGED
@@ -137,12 +137,6 @@ module Unicorn
137
137
  # * :cwd - the working directory of the application, this is where
138
138
  # you originally started Unicorn.
139
139
  #
140
- # The following example may be used in your Unicorn config file to
141
- # change your working directory during a config reload (HUP) without
142
- # upgrading or restarting:
143
- #
144
- # Dir.chdir(Unicorn::HttpServer::START_CTX[:cwd] = path)
145
- #
146
140
  # To change your unicorn executable to a different path without downtime,
147
141
  # you can set the following in your Unicorn config file, HUP and then
148
142
  # continue with the traditional USR2 + QUIT upgrade steps:
@@ -489,11 +483,11 @@ module Unicorn
489
483
  # Wake up every second anyways to run murder_lazy_workers
490
484
  def master_sleep(sec)
491
485
  begin
492
- ready = IO.select([SELF_PIPE.first], nil, nil, sec) or return
493
- ready.first && ready.first.first or return
494
- loop { SELF_PIPE.first.read_nonblock(Const::CHUNK_SIZE) }
486
+ IO.select([ SELF_PIPE.first ], nil, nil, sec) or return
487
+ SELF_PIPE.first.read_nonblock(Const::CHUNK_SIZE, HttpRequest::BUF)
495
488
  rescue Errno::EAGAIN, Errno::EINTR
496
- end
489
+ break
490
+ end while true
497
491
  end
498
492
 
499
493
  def awaken_master
@@ -797,7 +791,7 @@ module Unicorn
797
791
  logger.info "done reloading config_file=#{config.config_file}"
798
792
  rescue StandardError, LoadError, SyntaxError => e
799
793
  logger.error "error reloading config_file=#{config.config_file}: " \
800
- "#{e.class} #{e.message}"
794
+ "#{e.class} #{e.message} #{e.backtrace}"
801
795
  self.app = loaded_app
802
796
  end
803
797
  end
@@ -7,9 +7,11 @@ module Unicorn
7
7
 
8
8
  # Implements a simple DSL for configuring a Unicorn server.
9
9
  #
10
- # See http://unicorn.bogomips.org/examples/unicorn.conf.rb for an
11
- # example config file. An example config file for use with nginx is
12
- # also available at http://unicorn.bogomips.org/examples/nginx.conf
10
+ # See http://unicorn.bogomips.org/examples/unicorn.conf.rb and
11
+ # http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb
12
+ # example configuration files. An example config file for use with
13
+ # nginx is also available at
14
+ # http://unicorn.bogomips.org/examples/nginx.conf
13
15
  class Configurator < Struct.new(:set, :config_file, :after_reload)
14
16
 
15
17
  # Default settings for Unicorn
@@ -54,7 +56,7 @@ module Unicorn
54
56
  [ :pid, :stderr_path, :stdout_path ].each do |var|
55
57
  String === (path = set[var]) or next
56
58
  path = File.expand_path(path)
57
- test(?w, path) || test(?w, File.dirname(path)) or \
59
+ File.writable?(path) || File.writable?(File.dirname(path)) or \
58
60
  raise ArgumentError, "directory for #{var}=#{path} not writable"
59
61
  end
60
62
 
@@ -77,9 +79,13 @@ module Unicorn
77
79
 
78
80
  # sets object to the +new+ Logger-like object. The new logger-like
79
81
  # object must respond to the following methods:
80
- # +debug+, +info+, +warn+, +error+, +fatal+, +close+
82
+ # +debug+, +info+, +warn+, +error+, +fatal+
83
+ # The default Logger will log its output to the path specified
84
+ # by +stderr_path+. If you're running Unicorn daemonized, then
85
+ # you must specify a path to prevent error messages from going
86
+ # to /dev/null.
81
87
  def logger(new)
82
- %w(debug info warn error fatal close).each do |m|
88
+ %w(debug info warn error fatal).each do |m|
83
89
  new.respond_to?(m) and next
84
90
  raise ArgumentError, "logger=#{new} does not respond to method=#{m}"
85
91
  end
@@ -310,11 +316,19 @@ module Unicorn
310
316
  # file will be opened with the File::APPEND flag and writes
311
317
  # synchronized to the kernel (but not necessarily to _disk_) so
312
318
  # multiple processes can safely append to it.
319
+ #
320
+ # If you are daemonizing and using the default +logger+, it is important
321
+ # to specify this as errors will otherwise be lost to /dev/null.
322
+ # Some applications/libraries may also triggering warnings that go to
323
+ # stderr, and they will end up here.
313
324
  def stderr_path(path)
314
325
  set_path(:stderr_path, path)
315
326
  end
316
327
 
317
- # Same as stderr_path, except for $stdout
328
+ # Same as stderr_path, except for $stdout. Not many Rack applications
329
+ # write to $stdout, but any that do will have their output written here.
330
+ # It is safe to point this to the same location a stderr_path.
331
+ # Like stderr_path, this defaults to /dev/null when daemonized.
318
332
  def stdout_path(path)
319
333
  set_path(:stdout_path, path)
320
334
  end
@@ -327,7 +341,7 @@ module Unicorn
327
341
  path = File.expand_path(path)
328
342
  if config_file &&
329
343
  config_file[0] != ?/ &&
330
- ! test(?r, "#{path}/#{config_file}")
344
+ ! File.readable?("#{path}/#{config_file}")
331
345
  raise ArgumentError,
332
346
  "config_file=#{config_file} would not be accessible in" \
333
347
  " working_directory=#{path}"
data/lib/unicorn/const.rb CHANGED
@@ -7,7 +7,9 @@ module Unicorn
7
7
  # gave about a 3% to 10% performance improvement over using the strings directly.
8
8
  # Symbols did not really improve things much compared to constants.
9
9
  module Const
10
- UNICORN_VERSION="0.99.0"
10
+
11
+ # The current version of Unicorn, currently 0.990.0
12
+ UNICORN_VERSION="0.990.0"
11
13
 
12
14
  DEFAULT_HOST = "0.0.0.0" # default TCP listen host address
13
15
  DEFAULT_PORT = 8080 # default TCP listen port
@@ -0,0 +1,58 @@
1
+ # -*- encoding: binary -*-
2
+ module Unicorn
3
+
4
+ # Run GC after every request, after closing the client socket and
5
+ # before attempting to accept more connections.
6
+ #
7
+ # This shouldn't hurt overall performance as long as the server cluster
8
+ # is at <50% CPU capacity, and improves the performance of most memory
9
+ # intensive requests. This serves to improve _client-visible_
10
+ # performance (possibly at the cost of overall performance).
11
+ #
12
+ # We'll call GC after each request is been written out to the socket, so
13
+ # the client never sees the extra GC hit it.
14
+ #
15
+ # This middleware is _only_ effective for applications that use a lot
16
+ # of memory, and will hurt simpler apps/endpoints that can process
17
+ # multiple requests before incurring GC.
18
+ #
19
+ # This middleware is only designed to work with Unicorn, as it harms
20
+ # keepalive performance.
21
+ #
22
+ # Example (in config.ru):
23
+ #
24
+ # require 'unicorn/oob_gc'
25
+ #
26
+ # # GC ever two requests that hit /expensive/foo or /more_expensive/foo
27
+ # # in your app. By default, this will GC once every 5 requests
28
+ # # for all endpoints in your app
29
+ # use Unicorn::OobGC, 2, %r{\A/(?:expensive/foo|more_expensive/foo)}
30
+ class OobGC < Struct.new(:app, :interval, :path, :nr, :env, :body)
31
+
32
+ def initialize(app, interval = 5, path = %r{\A/})
33
+ super(app, interval, path, interval)
34
+ end
35
+
36
+ def call(env)
37
+ status, headers, self.body = app.call(self.env = env)
38
+ [ status, headers, self ]
39
+ end
40
+
41
+ def each(&block)
42
+ body.each(&block)
43
+ end
44
+
45
+ # in Unicorn, this is closed _after_ the client socket
46
+ def close
47
+ body.close if body.respond_to?(:close)
48
+
49
+ if path =~ env['PATH_INFO'] && ((self.nr -= 1) <= 0)
50
+ self.nr = interval
51
+ self.body = nil
52
+ env.clear
53
+ GC.start
54
+ end
55
+ end
56
+
57
+ end
58
+ end
data/lib/unicorn/util.rb CHANGED
@@ -22,6 +22,7 @@ module Unicorn
22
22
 
23
23
  ! fp.closed? &&
24
24
  fp.sync &&
25
+ fp.path &&
25
26
  fp.path[0] == ?/ &&
26
27
  (fp.fcntl(Fcntl::F_GETFL) & append_flags) == append_flags
27
28
  end
@@ -41,10 +42,11 @@ module Unicorn
41
42
  # 4) unbuffered (as far as userspace buffering goes, not O_SYNC)
42
43
  # Returns the number of files reopened
43
44
  def reopen_logs
45
+ to_reopen = []
44
46
  nr = 0
47
+ ObjectSpace.each_object(File) { |fp| is_log?(fp) and to_reopen << fp }
45
48
 
46
- ObjectSpace.each_object(File) do |fp|
47
- is_log?(fp) or next
49
+ to_reopen.each do |fp|
48
50
  orig_st = fp.stat
49
51
  begin
50
52
  b = File.stat(fp.path)
@@ -52,19 +54,15 @@ module Unicorn
52
54
  rescue Errno::ENOENT
53
55
  end
54
56
 
55
- open_arg = 'a'
56
- if fp.respond_to?(:external_encoding) && enc = fp.external_encoding
57
- open_arg << ":#{enc.to_s}"
58
- enc = fp.internal_encoding and open_arg << ":#{enc.to_s}"
59
- end
60
- fp.reopen(fp.path, open_arg)
57
+ File.open(fp.path, 'a') { |tmpfp| fp.reopen(tmpfp) }
61
58
  fp.sync = true
62
59
  new_st = fp.stat
63
60
  if orig_st.uid != new_st.uid || orig_st.gid != new_st.gid
64
61
  fp.chown(orig_st.uid, orig_st.gid)
65
62
  end
66
63
  nr += 1
67
- end # each_object
64
+ end
65
+
68
66
  nr
69
67
  end
70
68
 
data/local.mk.sample CHANGED
@@ -5,22 +5,34 @@
5
5
  # This is depends on a bunch of GNU-isms from bash, sed, touch.
6
6
 
7
7
  DLEXT := so
8
- gems := rack-1.1.0
9
8
 
10
9
  # Avoid loading rubygems to speed up tests because gmake is
11
10
  # fork+exec heavy with Ruby.
12
11
  prefix = $(HOME)
13
- ifeq ($(r19),)
14
- RUBY := $(prefix)/bin/ruby
15
- gem_paths := $(addprefix $(prefix)/lib/ruby/gems/1.8/gems/,$(gems))
12
+ ifeq ($(r192),)
13
+ ifeq ($(r19),)
14
+ ifeq ($(rbx),)
15
+ RUBY := $(prefix)/bin/ruby
16
+ else
17
+ prefix := $(prefix)/rbx
18
+ export PATH := $(prefix)/bin:$(PATH)
19
+ RUBY := $(prefix)/bin/rbx
20
+ endif
21
+ else
22
+ prefix := $(prefix)/ruby-1.9
23
+ export PATH := $(prefix)/bin:$(PATH)
24
+ RUBY := $(prefix)/bin/ruby --disable-gems
25
+ endif
16
26
  else
17
- prefix := $(prefix)/ruby-1.9
27
+ prefix := $(prefix)/ruby-1.9.2
18
28
  export PATH := $(prefix)/bin:$(PATH)
19
29
  RUBY := $(prefix)/bin/ruby --disable-gems
20
- gem_paths := $(addprefix $(prefix)/lib/ruby/gems/1.9.1/gems/,$(gems))
21
30
  endif
22
31
 
23
- ifdef gem_paths
32
+ # FIXME: use isolate more
33
+ ifndef RUBYLIB
34
+ gems := rack-1.1.0
35
+ gem_paths := $(addprefix $(HOME)/lib/ruby/gems/1.8/gems/,$(gems))
24
36
  sp :=
25
37
  sp +=
26
38
  export RUBYLIB := $(subst $(sp),:,$(addsuffix /lib,$(gem_paths)))
@@ -30,33 +42,17 @@ endif
30
42
  # SHELL := /bin/bash -e -o pipefail
31
43
  SHELL := /bin/ksh93 -e -o pipefail
32
44
 
33
- full-test: test-18 test-19
34
- test-18:
35
- $(MAKE) test test-rails 2>&1 | sed -e 's!^!1.8 !'
36
- test-19:
37
- $(MAKE) test test-rails r19=1 2>&1 | sed -e 's!^!1.9 !'
38
-
39
- latest: NEWS
40
- @awk 'BEGIN{RS="=== ";ORS=""}NR==2{sub(/\n$$/,"");print RS""$$0 }' < $<
45
+ full-test: test-18 test-191 test-192 test-rbx
41
46
 
42
- # publishes docs to http://unicorn.bogomips.org
43
- publish_doc:
44
- -git set-file-times
45
- $(RM) -r doc ChangeLog NEWS
46
- $(MAKE) doc LOG_VERSION=$(shell git tag -l | tail -1)
47
- $(MAKE) -s latest > doc/LATEST
48
- find doc/images doc/js -type f | \
49
- TZ=UTC xargs touch -d '1970-01-01 00:00:00' doc/rdoc.css
50
- $(MAKE) doc_gz
51
- tar cf - $$(git ls-files examples/) | (cd doc && tar xf -)
52
- chmod 644 $$(find doc -type f)
53
- rsync -av doc/ dcvr:/srv/unicorn/
54
- git ls-files | xargs touch
55
-
56
- # Create gzip variants of the same timestamp as the original so nginx
57
- # "gzip_static on" can serve the gzipped versions directly.
58
- doc_gz: docs = $(shell find doc -type f ! -regex '^.*\.\(gif\|jpg\|png\|gz\)$$')
59
- doc_gz:
60
- touch doc/NEWS.atom.xml -d "$$(awk 'NR==1{print $$4,$$5,$$6}' NEWS)"
61
- for i in $(docs); do \
62
- gzip --rsyncable -9 < $$i > $$i.gz; touch -r $$i $$i.gz; done
47
+ # FIXME: keep eye on Rubinius activity and wait for fixes from upstream
48
+ # so we don't need RBX_SKIP anymore
49
+ test-rbx: export RBX_SKIP := 1
50
+ test-rbx: export RUBY := $(RUBY)
51
+ test-rbx:
52
+ $(MAKE) test test-integration rbx=T 2>&1 |sed -e 's!^!rbx !'
53
+ test-18:
54
+ $(MAKE) test-all 2>&1 |sed 's!^!1.8 !'
55
+ test-191:
56
+ $(MAKE) test-all r19=1 2>&1 |sed 's!^!1.9.1 !'
57
+ test-192:
58
+ $(MAKE) test-all r192=1 2>&1 |sed 's!^!1.9.2 !'
data/t/GNUmakefile CHANGED
@@ -4,6 +4,7 @@ all::
4
4
  pid := $(shell echo $$PPID)
5
5
 
6
6
  RUBY = ruby
7
+ RAKE = rake
7
8
  -include ../local.mk
8
9
  ifeq ($(RUBY_VERSION),)
9
10
  RUBY_VERSION := $(shell $(RUBY) -e 'puts RUBY_VERSION')
@@ -13,12 +14,15 @@ ifeq ($(RUBY_VERSION),)
13
14
  $(error unable to detect RUBY_VERSION)
14
15
  endif
15
16
 
17
+ RUBY_ENGINE := $(shell $(RUBY) -e 'puts((RUBY_ENGINE rescue "ruby"))')
18
+ export RUBY_ENGINE
19
+
16
20
  T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
17
21
 
18
22
  all:: $(T)
19
23
 
20
24
  # can't rely on "set -o pipefail" since we don't require bash or ksh93 :<
21
- t_pfx = trash/$@-$(RUBY_VERSION)
25
+ t_pfx = trash/$@-$(RUBY_ENGINE)-$(RUBY_VERSION)
22
26
  TEST_OPTS =
23
27
  # TRACER = strace -f -o $(t_pfx).strace -s 100000
24
28
  # TRACER = /usr/bin/time -o $(t_pfx).time
@@ -47,11 +51,12 @@ $(deps):
47
51
  @mv $@.$(pid) $@
48
52
  dep: $(deps)
49
53
 
50
- test_prefix := $(CURDIR)/../test/install-$(RUBY_VERSION)
54
+ test_prefix := $(CURDIR)/../test/$(RUBY_ENGINE)-$(RUBY_VERSION)
51
55
  $(test_prefix)/.stamp:
52
56
  $(MAKE) -C .. test-install
53
57
 
54
58
  $(T): export RUBY := $(RUBY)
59
+ $(T): export RAKE := $(RAKE)
55
60
  $(T): export PATH := $(test_prefix)/bin:$(PATH)
56
61
  $(T): export RUBYLIB := $(test_prefix)/lib:$(RUBYLIB)
57
62
  $(T): dep $(test_prefix)/.stamp trash/.gitignore
@@ -0,0 +1,4 @@
1
+ .bundle
2
+ db/*.sqlite3
3
+ log/*.log
4
+ tmp/**/*
@@ -0,0 +1,26 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # gem 'rails', '3.0.0.beta3'
4
+
5
+ # Bundle edge Rails instead:
6
+ # gem 'rails', :git => 'git://github.com/rails/rails.git'
7
+
8
+ # gem 'sqlite3-ruby', :require => 'sqlite3'
9
+
10
+ # Use unicorn as the web server
11
+ # gem 'unicorn'
12
+
13
+ # Deploy with Capistrano
14
+ # gem 'capistrano'
15
+
16
+ # Bundle the extra gems:
17
+ # gem 'bj'
18
+ # gem 'nokogiri', '1.4.1'
19
+ # gem 'sqlite3-ruby', :require => 'sqlite3'
20
+ # gem 'aws-s3', :require => 'aws/s3'
21
+
22
+ # Bundle gems for certain environments:
23
+ # gem 'rspec', :group => :test
24
+ # group :test do
25
+ # gem 'webrat'
26
+ # end