ramaze 2009.04 → 2009.05

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/CHANGELOG +168 -0
  2. data/MANIFEST +16 -6
  3. data/{README.markdown → README.md} +0 -14
  4. data/Rakefile +20 -20
  5. data/benchmark/bench_templates/bench.rb +67 -0
  6. data/benchmark/bench_templates/view/large.erb +79 -0
  7. data/benchmark/bench_templates/view/large.haml +41 -0
  8. data/benchmark/bench_templates/view/large.xhtml +79 -0
  9. data/benchmark/bench_templates/view/small.erb +21 -0
  10. data/benchmark/bench_templates/view/small.haml +12 -0
  11. data/benchmark/bench_templates/view/small.xhtml +21 -0
  12. data/benchmark/run.rb +14 -21
  13. data/benchmark/suite/minimal.rb +3 -5
  14. data/benchmark/suite/no_informer.rb +0 -2
  15. data/benchmark/suite/no_sessions.rb +3 -4
  16. data/benchmark/suite/no_template.rb +1 -3
  17. data/benchmark/suite/simple.rb +1 -3
  18. data/benchmark/suite/template_erubis.rb +0 -2
  19. data/benchmark/suite/template_etanni.rb +8 -0
  20. data/benchmark/suite/template_ezamar.rb +1 -3
  21. data/benchmark/suite/template_haml.rb +0 -2
  22. data/benchmark/suite/template_liquid.rb +0 -2
  23. data/benchmark/suite/template_markaby.rb +0 -2
  24. data/benchmark/suite/template_nagoro.rb +1 -3
  25. data/benchmark/suite/template_redcloth.rb +0 -2
  26. data/benchmark/suite/template_tenjin.rb +0 -2
  27. data/bin/ramaze +7 -300
  28. data/doc/AUTHORS +11 -7
  29. data/examples/app/chat/layout/{default.nag → default.xhtml} +0 -0
  30. data/examples/app/chat/view/{chat.nag → chat.xhtml} +0 -0
  31. data/examples/app/chat/view/{index.nag → index.xhtml} +0 -0
  32. data/examples/helpers/cache.rb +6 -4
  33. data/lib/ramaze.rb +2 -3
  34. data/lib/ramaze/cache/sequel.rb +17 -5
  35. data/lib/ramaze/gestalt.rb +3 -0
  36. data/lib/ramaze/helper/gestalt.rb +32 -0
  37. data/lib/ramaze/helper/paginate.rb +1 -0
  38. data/lib/ramaze/helper/ultraviolet.rb +2 -0
  39. data/lib/ramaze/log/rotatinginformer.rb +10 -10
  40. data/lib/ramaze/request.rb +1 -4
  41. data/lib/ramaze/tool/bin.rb +330 -0
  42. data/lib/ramaze/version.rb +1 -1
  43. data/lib/ramaze/view.rb +3 -13
  44. data/lib/ramaze/view/erubis.rb +2 -2
  45. data/lib/ramaze/view/ezamar.rb +2 -2
  46. data/lib/ramaze/view/gestalt.rb +14 -0
  47. data/lib/ramaze/view/haml.rb +1 -1
  48. data/lib/ramaze/view/liquid.rb +2 -2
  49. data/lib/ramaze/view/maruku.rb +2 -1
  50. data/lib/ramaze/view/sass.rb +1 -1
  51. data/lib/ramaze/view/tenjin.rb +7 -4
  52. data/lib/vendor/route_exceptions.rb +8 -9
  53. data/ramaze.gemspec +6 -9
  54. data/spec/examples/caching.rb +2 -4
  55. data/spec/examples/element.rb +1 -0
  56. data/spec/examples/templates/template_ezamar.rb +1 -0
  57. data/spec/examples/templates/template_nagoro.rb +1 -0
  58. data/spec/ramaze/error.rb +1 -1
  59. data/spec/ramaze/gestalt.rb +22 -16
  60. data/spec/ramaze/helper/localize.rb +10 -8
  61. data/spec/ramaze/helper/sequel_form.rb +2 -0
  62. data/spec/ramaze/helper/user.rb +2 -2
  63. data/spec/ramaze/view/gestalt.rb +94 -0
  64. data/spec/ramaze/view/gestalt/external.ges +8 -0
  65. data/tasks/install_dependencies.rake +1 -1
  66. data/tasks/release.rake +5 -4
  67. metadata +20 -20
  68. data/benchmark/suite/template_builder.rb +0 -12
  69. data/lib/ramaze/snippets/kernel/constant.rb +0 -41
@@ -1,25 +1,27 @@
1
1
  Following persons have contributed to ramaze.
2
2
  (Sorted by number of submitted patches, then alphabetically)
3
3
 
4
- 2394 Michael Fellinger <m.fellinger@gmail.com>
5
- 215 Aman Gupta <aman@ramaze.net>
4
+ 2532 Michael Fellinger <m.fellinger@gmail.com>
5
+ 216 Aman Gupta <aman@ramaze.net>
6
6
  87 Jonathan Buch <john@oxyliquit.de>
7
- 62 Clive Crous <clive@crous.co.za>
7
+ 63 Clive Crous <clive@crous.co.za>
8
8
  27 Keita Yamaguchi <keita.yamaguchi@gmail.com>
9
- 17 Ryan Grove <ryan@wonko.com>
10
- 11 Pistos <gitsomegrace.5.pistos@geoshell.com>
9
+ 20 Ryan Grove <ryan@wonko.com>
10
+ 13 Pistos <gitsomegrace.5.pistos@geoshell.com>
11
11
  11 Wang, Jinjing <nfjinjing@gmail.com>
12
+ 8 TJ Vanderpoel <bougy.man@gmail.com>
13
+ 7 Tadahiko Uehara <kikofx@gmail.com>
12
14
  6 Aki Reijonen <aki.reijonen@gmail.com>
13
15
  6 Sam Carr <samcarr@gmail.com>
14
- 5 Tadahiko Uehara <kikofx@gmail.com>
16
+ 5 bougyman <bougyman@falcon.(none)>
15
17
  4 James Tucker <jftucker@gmail.com>
18
+ 3 Andreas Karlsson <andreas@proxel.se>
16
19
  3 Chris Duncan <celldee@gmail.com>
17
20
  3 Clinton R. Nixon <clinton.nixon@viget.com>
18
21
  2 Andrew Farmer <xichekolas@gmail.com>
19
22
  2 Jonathan Buch <jonathan.buch@gmail.com>
20
23
  2 Lars Olsson <lasso@lassoweb.se>
21
24
  2 Riku Raisaenen <riku@helloit.fi>
22
- 1 Andreas Karlsson <andreas@proxel.se>
23
25
  1 Ara T. Howard <ara.t.howard@gmail.com>
24
26
  1 Carlo Zottmann <carlo@zottmann.org>
25
27
  1 Cheah Chu Yeow <chuyeow@gmail.com>
@@ -32,6 +34,8 @@ Following persons have contributed to ramaze.
32
34
  1 Martin Hilbig <blueonyx@dev-area.net>
33
35
  1 Matt Rubens <mrubens@goldencookie.localdomain>
34
36
  1 Rob Lievaart <rob@rebeltechnologies.nl>
37
+ 1 sean <sean@sean-t61p.(none)>
35
38
  1 Thomas Leitner <thomas.leitner@gmail.com>
39
+ 1 Victor Luft <victor.luft@ptomato.net>
36
40
  1 Vincent Roy <VincentRoy8@gmail.com>
37
41
  1 Yasushi Abe <yasushi.abe@gmail.com>
@@ -6,12 +6,14 @@ class MainController < Ramaze::Controller
6
6
  helper :cache
7
7
 
8
8
  def index
9
- %[
9
+ @number = rand * 100
10
+
11
+ %q[
10
12
  <html>
11
13
  <head><title>examples/caching</title></head>
12
14
  <body>
13
15
  <p>
14
- This action just shows you a random number: #{rand * 100}.<br />
16
+ This action just shows you a random number: #{@number}.<br />
15
17
  If you <a href="/">refresh</a> the page it won't change since you see a cached version.<br />
16
18
  But if you <a href="/invalidate">invalidate</a> it, the page will be regenerated.
17
19
  </p>
@@ -20,10 +22,10 @@ class MainController < Ramaze::Controller
20
22
  ]
21
23
  end
22
24
 
23
- cache_action :method => :index
25
+ cache_action :method => 'index'
24
26
 
25
27
  def invalidate
26
- Ramaze::Cache.action.delete(:method => 'index')
28
+ Ramaze::Cache.action.delete('/')
27
29
  redirect :/
28
30
  end
29
31
  end
@@ -62,7 +62,7 @@ module Ramaze
62
62
 
63
63
  middleware! :dev do |m|
64
64
  m.use Rack::Lint
65
- m.use Rack::CommonLogger
65
+ m.use Rack::CommonLogger, Ramaze::Log
66
66
  m.use Ramaze::Reloader
67
67
  m.use Rack::ShowStatus
68
68
  m.use Rack::RouteExceptions
@@ -75,10 +75,9 @@ module Ramaze
75
75
  end
76
76
 
77
77
  middleware! :live do |m|
78
- m.use Rack::CommonLogger
78
+ m.use Rack::CommonLogger, Ramaze::Log
79
79
  m.use Rack::RouteExceptions
80
80
  m.use Rack::ShowStatus
81
- m.use Rack::ShowExceptions
82
81
  m.use Rack::Head
83
82
  m.use Rack::ETag
84
83
  m.use Rack::ConditionalGet
@@ -1,14 +1,23 @@
1
1
  # Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
2
2
  # All files in this distribution are subject to the terms of the Ruby license.
3
3
 
4
+ require 'sequel'
5
+
4
6
  module Ramaze
5
7
  class Cache
6
8
 
7
9
  # Cache based on a Sequel model using relational databases.
10
+ #
11
+ # Please note that this cache might not work perfectly with Sequel 3.0.0,
12
+ # as the #[] and #[]= methods do not respect serialization.
13
+ # I'll lobby for a change in that direction.
8
14
  class Sequel
9
15
  include Cache::API
10
16
 
11
17
  class Table < ::Sequel::Model(:ramaze_cache)
18
+ plugin :schema
19
+ plugin :serialization, :marshal, :value
20
+
12
21
  set_schema do
13
22
  primary_key :id
14
23
  string :key
@@ -17,10 +26,13 @@ module Ramaze
17
26
  index :key, :unique => true
18
27
  end
19
28
 
20
- transform :value => [
21
- lambda{|value| ::Marshal.load(value.unpack('m*')[0]) },
22
- lambda{|value| [::Marshal.dump(value)].pack('m*') }
23
- ]
29
+ def [](column)
30
+ if column == :value
31
+ deserialized_values[column] = deserialize_value(@values[column])
32
+ else
33
+ super
34
+ end
35
+ end
24
36
  end
25
37
 
26
38
  # Setup the table, not suitable for multiple apps yet.
@@ -32,7 +44,7 @@ module Ramaze
32
44
 
33
45
  # Wipe out _all_ data in the table, use with care.
34
46
  def cache_clear
35
- Table.delete_all
47
+ Table.delete
36
48
  end
37
49
 
38
50
  # Delete records for given +keys+
@@ -84,6 +84,9 @@ module Ramaze
84
84
  if args.size == 1 and args[0].kind_of? Hash
85
85
  # args are just attributes, children in block...
86
86
  _gestalt_build_tag name, args[0], &block
87
+ elsif args[1].kind_of? Hash
88
+ # args are text and attributes ie. a('mylink', :href => '/mylink')
89
+ _gestalt_build_tag(name, args[1], args[0], &block)
87
90
  else
88
91
  # no attributes, but text
89
92
  _gestalt_build_tag name, {}, args, &block
@@ -3,6 +3,8 @@ require 'ramaze/gestalt'
3
3
  module Ramaze
4
4
  module Helper
5
5
  module Gestalt
6
+ CACHE_G = {}
7
+
6
8
  def gestalt(&block)
7
9
  Ramaze::Gestalt.new(&block)
8
10
  end
@@ -10,6 +12,36 @@ module Ramaze
10
12
  def build(&block)
11
13
  Ramaze::Gestalt.build(&block)
12
14
  end
15
+
16
+ def g(meth = nil, view = nil)
17
+ meth ||= caller[0].slice(/`(.*)'?/).gsub(/[\`\']/, '')
18
+ view_name = (self.class.to_s.sub('Controller', '') + 'View').split('::')
19
+ view ||= view_name.inject(Object){ |ns, name| ns.const_get(name) }
20
+
21
+ gestalt_class = CACHE_G[view] ||= g_class
22
+ gestalt = gestalt_class.new
23
+ gestalt.extend(view)
24
+ instance_variables.each do |iv|
25
+ gestalt.instance_variable_set(iv, instance_variable_get(iv))
26
+ end
27
+ gestalt.__send__(meth)
28
+ gestalt.to_s
29
+ end
30
+
31
+ def g_class
32
+ ancs = self.class.ancestors
33
+ helpers = Ramaze::Helper.constants.map{ |c| Ramaze::Helper.const_get(c)}
34
+ our_helpers = ancs & helpers
35
+ our_helpers.delete(Ramaze::Helper::Gestalt)
36
+ gestalt_class = Class.new(Ramaze::Gestalt){ include(*our_helpers) }
37
+ end
38
+
39
+ def method_missing(sym, *args, &block)
40
+ @gestalt ||= gestalt
41
+ @gestalt.send(sym, *args, &block)
42
+ end
13
43
  end
14
44
  end
15
45
  end
46
+
47
+ module Ramaze::Helper::Link; undef :a end
@@ -155,6 +155,7 @@ module Ramaze
155
155
  def last_page?; @pager.last_page?; end
156
156
  def next_page; @pager.next_page; end
157
157
  def empty?; @pager.empty?; end
158
+ def count; @pager.count; end
158
159
 
159
160
  private
160
161
 
@@ -1,6 +1,8 @@
1
1
  module Ramaze
2
2
  module Helper
3
3
  module Ultraviolet
4
+ include Innate::Traited
5
+
4
6
  trait :ultraviolet => {
5
7
  :output => 'xhtml',
6
8
  :syntax => nil, # syntax_name, nil|false indicates automatic detection
@@ -1,16 +1,16 @@
1
1
  module Ramaze
2
-
2
+
3
3
  module Logger
4
4
 
5
5
  # A customized logger (based on Informer) that creates multiple log files based on time
6
6
 
7
7
  class RotatingInformer
8
-
8
+ include Innate::Traited
9
9
  include Logging
10
10
 
11
11
  attr_accessor :time_format, :log_levels
12
12
  attr_reader :base_dir
13
-
13
+
14
14
  # parameter for Time.now.strftime
15
15
  trait :timestamp => "%Y-%m-%d %H:%M:%S"
16
16
 
@@ -47,24 +47,24 @@ module Ramaze
47
47
  def initialize(base_dir, time_format = '%Y-%m-%d.log', log_levels = [:debug, :error, :info, :warn])
48
48
  # Verify and set base directory
49
49
  send :base_dir=, base_dir, true
50
-
50
+
51
51
  @time_format = time_format
52
52
  @log_levels = log_levels
53
-
53
+
54
54
  # Keep track of log shutdown (to prevent StackErrors due to recursion)
55
55
  @in_shutdown = false
56
56
  end
57
57
 
58
58
  # Set the base directory for log files
59
- #
59
+ #
60
60
  # If this method is called with the raise_exception
61
61
  # parameter set to true the method will raise an exception
62
62
  # if the specified directory does not exist or is unwritable.
63
- #
63
+ #
64
64
  # If raise_exception is set to false, the method will just
65
65
  # silently fail if the specified directory does not exist
66
66
  # or is unwritable
67
-
67
+
68
68
  def base_dir=(directory, raise_exception = false)
69
69
  # Expand directory path
70
70
  base_dir = File.expand_path(directory)
@@ -85,7 +85,7 @@ module Ramaze
85
85
  raise Exception.new("#{base_dir} does not exist.") if raise_exception
86
86
  end
87
87
  end
88
-
88
+
89
89
  # Close the file we log to if it isn't closed already.
90
90
 
91
91
  def shutdown
@@ -106,7 +106,7 @@ module Ramaze
106
106
  return unless @log_levels.include?(tag)
107
107
 
108
108
  # Update current log
109
- update_current_log
109
+ update_current_log
110
110
 
111
111
  messages.flatten!
112
112
 
@@ -1,17 +1,14 @@
1
- # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
1
+ # Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
2
2
  # All files in this distribution are subject to the terms of the Ruby license.
3
3
 
4
4
  module Ramaze
5
5
  # The purpose of this class is to act as a simple wrapper for Rack::Request
6
6
  # and provide some convinient methods for our own use.
7
7
  class Request < Innate::Request
8
- # Currently active request out of STATE[:request]
9
- def self.current; Current.request; end
10
8
 
11
9
  # you can access the original @request via this method_missing,
12
10
  # first it tries to match your method with any of the HTTP parameters
13
11
  # then, in case that fails, it will relay to @request
14
-
15
12
  def method_missing meth, *args
16
13
  key = meth.to_s.upcase
17
14
  return env[key] if env.has_key?(key)
@@ -0,0 +1,330 @@
1
+ #!/usr/bin/env ruby
2
+ ### This module offers the functionality to start, stop, restart, create,
3
+ ### Check status, or run a console of a ramaze application
4
+ ### see ramaze -h for usage
5
+ module Ramaze
6
+ module Tool
7
+ module Bin
8
+ module Helpers # Helper methods {{{
9
+
10
+ def default_pidfile # {{{
11
+ return @default_pidfile if @default_pidfile
12
+ require "pathname"
13
+ @default_pidfile = (Pathname.new(".").expand_path.basename.to_s + ".pid").strip
14
+ end # }}}
15
+
16
+ # We're really only concerned about win32ole, so we focus our check on its
17
+ # ability to load that
18
+ def is_windows? # {{{
19
+ return @is_win if @is_win
20
+ begin
21
+ require "win32ole"
22
+ rescue LoadError
23
+ end
24
+ @is_win ||= Object.const_defined?("WIN32OLE")
25
+ end # }}}
26
+
27
+ # Find the path to rackup, by searching for -R (undocumented cli argument),
28
+ # then checking RUBYLIB for the _first_ rack it can find there, finally
29
+ # falling back to gems and looking for rackup in the gem bindir.
30
+ # If we can't find rackup we're raising; not even #usage is sane without
31
+ # rackup.
32
+ def rackup_path # {{{
33
+ return @rackup_path if @rackup_path
34
+ # Use the supplied path if the user supplied -R
35
+ if path_supplied = ARGV.delete("-R")
36
+ @rackup_path = ARGV.delete(@ourargs[@ourargs.index("-R") + 1])
37
+ if @rackup_path and File.file?(@rackup_path)
38
+ return @rackup_path
39
+ else
40
+ $stderr.puts "rackup does not exist at #{@rackup_path} (given with -R)"
41
+ end
42
+ end
43
+ # Check with 'which' on platforms which support it
44
+ unless is_windows?
45
+ @rackup_path = %x{which rackup}.to_s.chomp
46
+ if @rackup_path.size > 0 and File.file?(@rackup_path)
47
+ return @rackup_path
48
+ end
49
+ end
50
+ # check for rackup in RUBYLIB
51
+ libs = ENV["RUBYLIB"].to_s.split(is_windows? ? ";" : ":")
52
+ if rack_lib = libs.detect { |r| r.match %r<(\\|/)rack\1> }
53
+ require "pathname"
54
+ @rackup_path = Pathname.new(rack_lib).parent.join("bin").join("rackup").expand_path
55
+ return @rackup_path if File.file?(@rackup_path)
56
+ end
57
+ begin
58
+ require "rubygems"
59
+ require "rack"
60
+ require "pathname"
61
+ @rackup_path = Pathname.new(Gem.bindir).join("rackup").to_s
62
+ return @rackup_path if File.file?(@rackup_path)
63
+ rescue LoadError
64
+ nil
65
+ end
66
+ @rackup_path = nil
67
+ raise "Cannot find path to rackup, please supply full path to rackup with -R"
68
+ end # }}}
69
+
70
+ def is_running?(pid) # {{{
71
+ if is_windows?
72
+ wmi = WIN32OLE.connect("winmgmts://")
73
+ processes, ours = wmi.ExecQuery("select * from win32_process where ProcessId = #{pid}"), []
74
+ processes.each { |process| ours << process.Name }
75
+ ours.first.nil?
76
+ else
77
+ begin
78
+ prio = Process.getpriority(Process::PRIO_PROCESS, pid)
79
+ true
80
+ rescue Errno::ESRCH
81
+ false
82
+ end
83
+ end
84
+ end # }}}
85
+
86
+ def check_running?(pid_file) # {{{
87
+ return false unless File.file?(pid_file)
88
+ is_running?(File.read(pid_file).to_i)
89
+ end # }}}
90
+
91
+ def find_pid(pid_file) # {{{
92
+ if pid_file.nil? or not File.file?(pid_file)
93
+ pid_file = default_pidfile
94
+ end
95
+ unless File.file?(pid_file)
96
+ $stderr.puts "Could not find running process id."
97
+ return false
98
+ end
99
+ pid_file
100
+ end # }}}
101
+ end # End helper methods }}}
102
+
103
+ class Cmd # This class contains the command methods {{{
104
+ include Helpers
105
+ attr_accessor :command
106
+
107
+ def initialize(args = nil)
108
+ args ||= ARGV
109
+ raise "arguments must be an array!" unless args.respond_to?(:detect)
110
+ @ourargs = args.dup
111
+ @command = args.detect { |arg| arg.match(/^(?:--?)?(?:start|stop|restart|create|h(?:elp)?|v(?:ersion)?|console|status)/) }
112
+ if command.nil?
113
+ @command = ""
114
+ else
115
+ args.delete(@command)
116
+ end
117
+ ARGV.replace(args)
118
+ end
119
+
120
+ # {{{ #run is called when we're interactive ($0 == __FILE__)
121
+ def self.run(args = nil)
122
+ cmd = new(args)
123
+ case cmd.command
124
+ when /^(?:--?)?status$/
125
+ cmd.status(cmd.command)
126
+ when /^(?:--?)?restart$/
127
+ cmd.stop(cmd.command)
128
+ cmd.start
129
+ when /^(?:--?)?start$/
130
+ cmd.start
131
+ when /^(?:--?)?create$/
132
+ cmd.create(cmd.command)
133
+ when /^(?:--?)?stop$/
134
+ if cmd.stop(cmd.command)
135
+ puts "Ramazement has ended, go in peace."
136
+ $stdout.flush
137
+ else
138
+ puts "Ramaze failed to stop (or was not running)"
139
+ end
140
+ when /^(?:--?)?console$/
141
+ require "ramaze"
142
+ require "irb"
143
+ require "irb/completion"
144
+ Ramaze.options.started = true
145
+ require "start"
146
+ IRB.start
147
+ puts "Ramazement has ended, go in peace."
148
+ when /^(?:--?)?h(elp)?$/
149
+ puts cmd.usage
150
+ when /^(?:--?)?v(ersion)?$/
151
+ cmd.include_ramaze
152
+ puts Ramaze::VERSION
153
+ exit
154
+ when /^$/
155
+ puts "Must supply a valid command"
156
+ puts cmd.usage
157
+ exit 1
158
+ else
159
+ puts "#{command} not implemented"
160
+ puts cmd.usage
161
+ exit 1
162
+ end
163
+ end # }}}
164
+
165
+ def include_ramaze # {{{
166
+ begin
167
+ $:.unshift File.join(File.dirname(__FILE__), '/../lib')
168
+ require 'ramaze'
169
+ rescue LoadError
170
+ $:.shift
171
+
172
+ begin
173
+ require 'rubygems'
174
+ rescue LoadError
175
+ end
176
+ require 'ramaze'
177
+ end
178
+ end # }}}
179
+
180
+ def usage # {{{
181
+ txt = [
182
+ "\n Usage:",
183
+ "ramaze <start [PIDFILE]|stop [PIDFILE]|restart [PIDFILE]|status [PIDFILE]|create PROJECT|console> [ruby/rack options]\n",
184
+ "Commands:\n",
185
+ " * All commands which take an optional PIDFILE (defaults to PROJECT.pid otherwise).",
186
+ " * All commands which start a ramaze instance will default to webrick on port 7000",
187
+ " unless you supply the rack options -p/--port PORT and/or * -s/--server SERVER.\n",
188
+ " start - Starts an instance of this application.\n",
189
+ " stop - Stops a running instance of this application.\n",
190
+ " restart - Stops running instance of this application, then starts it back up. Pidfile",
191
+ " (if supplied) is used for both stop and start.\n",
192
+ " status - Gives status of a running ramaze instance\n",
193
+ " create - Creates a new prototype Ramaze application in a directory named PROJECT in",
194
+ " the current directory. ramaze create foo would make ./foo containing an",
195
+ " application prototype. Rack options are ignored here.\n",
196
+ " console - Starts an irb console with app.rb (and irb completion) loaded. This command",
197
+ " ignores rack options, ARGV is passed on to IRB.\n\n\t"
198
+ ].join("\n\t")
199
+
200
+ if is_windows?
201
+ txt << %x{ruby #{rackup_path} --help}.split("\n").reject { |line| line.match(/^Usage:/) }.join("\n\t")
202
+ else
203
+ txt << %x{#{rackup_path} --help}.split("\n").reject { |line| line.match(/^Usage:/) }.join("\n\t")
204
+ end
205
+ end # }}}
206
+
207
+ ### Methods for commands {{{
208
+ def start # {{{
209
+ # Find the name of this app
210
+ app_name = default_pidfile.sub(/\.pid$/,'')
211
+ added_args = []
212
+ if daemonize = @ourargs.detect { |arg| arg.match(/^(-[dD]|--daemonize)$/) }
213
+ if pid_arg = @ourargs.detect { |arg| arg.match(/^(-P|--pid)/) }
214
+ puts "User supplied pid: #{pid_arg}"
215
+ pid_file = @ourargs[@ourargs.index(pid_arg) + 1]
216
+ puts "Starting daemon with user defined pidfile: #{pid_file}"
217
+ else
218
+ puts "Starting daemon with default pidfile: #{pid_file = default_pidfile}"
219
+ added_args += ["-P", pid_file]
220
+ end
221
+ if check_running?(pid_file)
222
+ $stderr.puts "Ramaze is already running with pidfile: #{pid_file}"
223
+ exit 127
224
+ end
225
+ end
226
+ added_args += ["-p", "7000"] unless @ourargs.detect { |arg| arg.match(/^(-p|--port)/) }
227
+ added_args += ["-s", "webrick"] unless @ourargs.detect { |arg| arg.match(/^(-s|--server)/) }
228
+ if is_windows?
229
+ exec("ruby", rackup_path.to_s, "config.ru", *(ARGV + added_args))
230
+ else
231
+ exec(rackup_path.to_s, "config.ru", *(ARGV + added_args))
232
+ end
233
+ end # }}}
234
+
235
+ def create(command) # {{{
236
+ opts = {}
237
+ if forced = @ourargs.detect { |arg| arg.match(/^(--force)/) }
238
+ puts "Overwriting any existing files as requested."
239
+ opts[:force] = true
240
+ @ourargs.delete(forced)
241
+ end
242
+ if amended = @ourargs.detect { |arg| arg.match(/^(--amend)/) }
243
+ puts "Only amending missing files as requested."
244
+ opts[:amend] = true
245
+ @ourargs.delete(amended)
246
+ end
247
+ project_name = @ourargs[@ourargs.index(command) + 1]
248
+ if project_name.nil?
249
+ $stderr.puts "Must supply a project name" if project_name.nil?
250
+ puts usage
251
+ exit 1
252
+ end
253
+ include_ramaze
254
+ require 'ramaze/tool/create'
255
+ Ramaze::Tool::Create.create(project_name, opts)
256
+ end # }}}
257
+
258
+ def stop(command) # {{{
259
+ unless pid_file = find_pid(@ourargs[@ourargs.index(command) + 1])
260
+ $stderr.puts "No pid_file found! Cannot stop ramaze (may not be started)."
261
+ return false
262
+ end
263
+ pid = File.read(pid_file).to_i
264
+ puts "Stopping pid #{pid}"
265
+ Process.kill("INT", pid)
266
+ sleep 2
267
+ if is_running?(pid)
268
+ $stderr.puts "Process #{pid} did not die, forcing it with -9"
269
+ Process.kill(9, pid)
270
+ File.unlink(pid_file) if File.file?(pid_file)
271
+ true
272
+ else
273
+ File.unlink(pid_file) if File.file?(pid_file)
274
+ true
275
+ end
276
+ end # }}}
277
+
278
+ def status(command) # {{{
279
+ unless pid_file = find_pid(@ourargs[@ourargs.index(command) + 1])
280
+ $stderr.puts "No pid_file found! Ramaze may not be started."
281
+ exit 1
282
+ end
283
+ puts "Pid file #{pid_file} found, PID is #{pid = File.read(pid_file)}"
284
+ unless is_running?(pid.to_i)
285
+ $stderr.puts "PID #{pid} is not running"
286
+ exit 1
287
+ end
288
+ if is_windows?
289
+ wmi = WIN32OLE.connect("winmgmts://")
290
+ processes, ours = wmi.ExecQuery("select * from win32_process where ProcessId = #{pid}"), []
291
+ processes.each { |p| ours << [p.Name, p.CommandLine, p.VirtualSize, p.CreationDate, p.ExecutablePath, p.Status ] }
292
+ puts "Ramaze is running!\n\tName: %s\n\tCommand Line: %s\n\tVirtual Size: %s\n\tStarted: %s\n\tExec Path: %s\n\tStatus: %s" % ours.first
293
+ else
294
+ require "pathname"
295
+ # Check for /proc
296
+ if File.directory?(proc_dir = Pathname.new("/proc"))
297
+ proc_dir = proc_dir.join(pid)
298
+ # If we have a "stat" file, we'll assume linux and get as much info
299
+ # as we can
300
+ if File.file?(stat_file = proc_dir.join("stat"))
301
+ stats = File.read(stat_file).split
302
+ puts "Ramaze is running!\n\tCommand Line: %s\n\tVirtual Size: %s\n\tStarted: %s\n\tExec Path: %s\n\tStatus: %s" % [
303
+ File.read(proc_dir.join("cmdline")).split("\000").join(" "),
304
+ "%s k" % (stats[22].to_f / 1024),
305
+ File.mtime(proc_dir),
306
+ File.readlink(proc_dir.join("exe")),
307
+ stats[2]
308
+ ]
309
+ exit
310
+ end
311
+ end
312
+ # Fallthrough status, just print a ps
313
+ puts "Ramaze process #{pid} is running!"
314
+ begin
315
+ puts %x{ps l #{pid}}
316
+ rescue
317
+ puts "No further information available"
318
+ end
319
+ end
320
+ end # }}}
321
+
322
+ ### End of command methods }}}
323
+ end # }}}
324
+ end
325
+ end
326
+ end
327
+
328
+ if $0 == __FILE__
329
+ Ramaze::Tool::Bin::Cmd.run(ARGV)
330
+ end