Class Heel::Server
In: lib/heel/server.rb
lib/heel/server.rb
Parent: Object

Methods

Attributes

options  [RW] 
options  [RW] 
parsed_options  [RW] 
parsed_options  [RW] 
stderr  [R] 
stderr  [R] 
stdin  [R] 
stdin  [R] 
stdout  [R] 
stdout  [R] 

Public Class methods

[Source]

    # File lib/heel/server.rb, line 32
32:       def kill_existing_proc
33:         Heel::Server.new.kill_existing_proc
34:       end

[Source]

    # File lib/heel/server.rb, line 32
32:       def kill_existing_proc
33:         Heel::Server.new.kill_existing_proc
34:       end

[Source]

    # File lib/heel/server.rb, line 37
37:     def initialize(argv = [])
38:       argv ||= []
39: 
40:       set_io
41: 
42:       @options        = default_options
43:       @parsed_options = ::OpenStruct.new
44:       @parser         = option_parser
45:       @error_message  = nil
46: 
47:       begin
48:         @parser.parse!(argv)
49:       rescue ::OptionParser::ParseError => pe
50:         msg = ["#{@parser.program_name}: #{pe}",
51:                         "Try `#{@parser.program_name} --help` for more information"]
52:                         @error_message = msg.join("\n")
53:       end
54:     end

[Source]

    # File lib/heel/server.rb, line 37
37:     def initialize(argv = [])
38:       argv ||= []
39: 
40:       set_io
41: 
42:       @options        = default_options
43:       @parsed_options = ::OpenStruct.new
44:       @parser         = option_parser
45:       @error_message  = nil
46: 
47:       begin
48:         @parser.parse!(argv)
49:       rescue ::OptionParser::ParseError => pe
50:         msg = ["#{@parser.program_name}: #{pe}",
51:                         "Try `#{@parser.program_name} --help` for more information"]
52:                         @error_message = msg.join("\n")
53:       end
54:     end

Public Instance methods

[Source]

    # File lib/heel/server.rb, line 72
72:     def default_directory
73:       ENV["HEEL_DEFAULT_DIRECTORY"] || File.join(::Heel::Server.home_directory,".heel")
74:     end

[Source]

    # File lib/heel/server.rb, line 72
72:     def default_directory
73:       ENV["HEEL_DEFAULT_DIRECTORY"] || File.join(::Heel::Server.home_directory,".heel")
74:     end

[Source]

    # File lib/heel/server.rb, line 56
56:     def default_options
57:       if @default_options.nil? then
58:         @default_options                 = ::OpenStruct.new
59:         @default_options.show_version    = false
60:         @default_options.show_help       = false
61:         @default_options.address         = "0.0.0.0"
62:         @default_options.port            = 4331
63:         @default_options.document_root   = Dir.pwd
64:         @default_options.daemonize       = false
65:         @default_options.highlighting    = false
66:         @default_options.kill            = false
67:         @default_options.launch_browser  = true
68:       end
69:       return @default_options
70:     end

[Source]

    # File lib/heel/server.rb, line 56
56:     def default_options
57:       if @default_options.nil? then
58:         @default_options                 = ::OpenStruct.new
59:         @default_options.show_version    = false
60:         @default_options.show_help       = false
61:         @default_options.address         = "0.0.0.0"
62:         @default_options.port            = 4331
63:         @default_options.document_root   = Dir.pwd
64:         @default_options.daemonize       = false
65:         @default_options.highlighting    = false
66:         @default_options.kill            = false
67:         @default_options.launch_browser  = true
68:       end
69:       return @default_options
70:     end

make sure that if we are daemonizing the process is not running

[Source]

     # File lib/heel/server.rb, line 198
198:     def ensure_not_running
199:       if options.daemonize and File.exist?(pid_file) then
200:         @stdout.puts "ERROR: PID File #{pid_file} already exists.  Heel may already be running."
201:         @stdout.puts "ERROR: Check the Log file #{log_file}"
202:         @stdout.puts "ERROR: Heel will not start until the .pid file is cleared (`heel --kill' to clean it up)."
203:         exit 1
204:       end
205:     end

make sure that if we are daemonizing the process is not running

[Source]

     # File lib/heel/server.rb, line 198
198:     def ensure_not_running
199:       if options.daemonize and File.exist?(pid_file) then
200:         @stdout.puts "ERROR: PID File #{pid_file} already exists.  Heel may already be running."
201:         @stdout.puts "ERROR: Check the Log file #{log_file}"
202:         @stdout.puts "ERROR: Heel will not start until the .pid file is cleared (`heel --kill' to clean it up)."
203:         exit 1
204:       end
205:     end

if Version or Help options are set, then output the appropriate information instead of running the server.

[Source]

     # File lib/heel/server.rb, line 152
152:     def error_version_help_kill
153:       if @parsed_options.show_version then
154:         @stdout.puts "#{@parser.program_name}: version #{Heel::VERSION}"
155:         exit 0
156:       elsif @parsed_options.show_help then
157:         @stdout.puts @parser.to_s
158:         exit 0
159:       elsif @error_message then
160:         @stdout.puts @error_message
161:         exit 1
162:       elsif @parsed_options.kill then
163:         kill_existing_proc
164:       end
165:     end

if Version or Help options are set, then output the appropriate information instead of running the server.

[Source]

     # File lib/heel/server.rb, line 152
152:     def error_version_help_kill
153:       if @parsed_options.show_version then
154:         @stdout.puts "#{@parser.program_name}: version #{Heel::VERSION}"
155:         exit 0
156:       elsif @parsed_options.show_help then
157:         @stdout.puts @parser.to_s
158:         exit 0
159:       elsif @error_message then
160:         @stdout.puts @error_message
161:         exit 1
162:       elsif @parsed_options.kill then
163:         kill_existing_proc
164:       end
165:     end

kill an already running background heel process

[Source]

     # File lib/heel/server.rb, line 168
168:     def kill_existing_proc
169:       if File.exists?(pid_file) then
170:         begin
171:           pid = open(pid_file).read.to_i
172:           @stdout.puts "Sending TERM to process #{pid}"
173:           Process.kill("TERM", pid)
174:         rescue Errno::ESRCH
175:           @stdout.puts "Unable to kill process with pid #{pid}.  Process does not exist.  Removing stale pid file."
176:           File.unlink(pid_file)
177:         rescue Errno::EPERM 
178:           @stdout.puts "Unable to kill process with pid #{pid}.  No permissions to kill process."
179:         end
180:       else
181:         @stdout.puts "No pid file exists, no process to kill"
182:       end
183:       @stdout.puts "Done."
184:       exit 0
185:     end

kill an already running background heel process

[Source]

     # File lib/heel/server.rb, line 168
168:     def kill_existing_proc
169:       if File.exists?(pid_file) then
170:         begin
171:           pid = open(pid_file).read.to_i
172:           @stdout.puts "Sending TERM to process #{pid}"
173:           Process.kill("TERM", pid)
174:         rescue Errno::ESRCH
175:           @stdout.puts "Unable to kill process with pid #{pid}.  Process does not exist.  Removing stale pid file."
176:           File.unlink(pid_file)
177:         rescue Errno::EPERM 
178:           @stdout.puts "Unable to kill process with pid #{pid}.  No permissions to kill process."
179:         end
180:       else
181:         @stdout.puts "No pid file exists, no process to kill"
182:       end
183:       @stdout.puts "Done."
184:       exit 0
185:     end

[Source]

     # File lib/heel/server.rb, line 207
207:     def launch_browser
208:       Thread.new do 
209:         print "Launching your browser"
210:         if options.daemonize then
211:           puts " at http://#{options.address}:#{options.port}/"
212:         else
213:           puts "..."
214:         end
215:         ::Launchy.open("http://#{options.address}:#{options.port}/")
216:       end
217:     end

[Source]

     # File lib/heel/server.rb, line 207
207:     def launch_browser
208:       Thread.new do 
209:         print "Launching your browser"
210:         if options.daemonize then
211:           puts " at http://#{options.address}:#{options.port}/"
212:         else
213:           puts "..."
214:         end
215:         ::Launchy.open("http://#{options.address}:#{options.port}/")
216:       end
217:     end

[Source]

    # File lib/heel/server.rb, line 80
80:     def log_file
81:       File.join(default_directory,"heel.log")
82:     end

[Source]

    # File lib/heel/server.rb, line 80
80:     def log_file
81:       File.join(default_directory,"heel.log")
82:     end

[Source]

     # File lib/heel/server.rb, line 133
133:     def merge_options
134:       options = default_options.marshal_dump
135:       @parsed_options.marshal_dump.each_pair do |key,value|
136:         options[key] = value
137:       end
138: 
139:       @options = OpenStruct.new(options)
140:     end

[Source]

     # File lib/heel/server.rb, line 133
133:     def merge_options
134:       options = default_options.marshal_dump
135:       @parsed_options.marshal_dump.each_pair do |key,value|
136:         options[key] = value
137:       end
138: 
139:       @options = OpenStruct.new(options)
140:     end

[Source]

     # File lib/heel/server.rb, line 84
 84:     def option_parser
 85:       OptionParser.new do |op|
 86:         op.separator ""
 87: 
 88:         op.on("-a", "--address ADDRESS", "Address to bind to",
 89:                                         "  (default: #{default_options.address})") do |add|
 90:           @parsed_options.address = add
 91:                                         end
 92: 
 93:         op.on("-d", "--daemonize", "Run daemonized in the background") do 
 94:           raise ::OptionParser::ParseError, "Daemonizing is not supported on windows" if Thin.win? 
 95:           @parsed_options.daemonize = true
 96:         end
 97: 
 98:         op.on("-h", "--help", "Display this text") do 
 99:           @parsed_options.show_help = true
100:         end
101: 
102:         op.on("-k", "--kill", "Kill an existing daemonized heel process") do
103:           @parsed_options.kill = true
104:         end
105: 
106:         op.on("--[no-]highlighting", "Turn on or off syntax highlighting",
107:                                              "  (default: off)") do |highlighting|
108:           @parsed_options.highlighting = highlighting
109:                                              end
110: 
111:         op.on("--[no-]launch-browser", "Turn on or off automatic browser launch",
112:                                                "  (default: on)") do |l|
113:           @parsed_options.launch_browser = l
114:                                                end
115: 
116:         op.on("-p", "--port PORT", Integer, "Port to bind to",
117:                                         "  (default: #{default_options.port})") do |port|
118:           @parsed_options.port = port
119:                                         end
120: 
121:         op.on("-r","--root ROOT", 
122:                       "Set the document root"," (default: #{default_options.document_root})") do |document_root|
123:           @parsed_options.document_root = File.expand_path(document_root)
124:           raise ::OptionParser::ParseError, "#{@parsed_options.document_root} is not a valid directory" if not File.directory?(@parsed_options.document_root)
125:                       end
126: 
127:         op.on("-v", "--version", "Show version") do 
128:           @parsed_options.show_version = true
129:         end
130:       end
131:     end

[Source]

     # File lib/heel/server.rb, line 84
 84:     def option_parser
 85:       OptionParser.new do |op|
 86:         op.separator ""
 87: 
 88:         op.on("-a", "--address ADDRESS", "Address to bind to",
 89:                                         "  (default: #{default_options.address})") do |add|
 90:           @parsed_options.address = add
 91:                                         end
 92: 
 93:         op.on("-d", "--daemonize", "Run daemonized in the background") do 
 94:           raise ::OptionParser::ParseError, "Daemonizing is not supported on windows" if Thin.win? 
 95:           @parsed_options.daemonize = true
 96:         end
 97: 
 98:         op.on("-h", "--help", "Display this text") do 
 99:           @parsed_options.show_help = true
100:         end
101: 
102:         op.on("-k", "--kill", "Kill an existing daemonized heel process") do
103:           @parsed_options.kill = true
104:         end
105: 
106:         op.on("--[no-]highlighting", "Turn on or off syntax highlighting",
107:                                              "  (default: off)") do |highlighting|
108:           @parsed_options.highlighting = highlighting
109:                                              end
110: 
111:         op.on("--[no-]launch-browser", "Turn on or off automatic browser launch",
112:                                                "  (default: on)") do |l|
113:           @parsed_options.launch_browser = l
114:                                                end
115: 
116:         op.on("-p", "--port PORT", Integer, "Port to bind to",
117:                                         "  (default: #{default_options.port})") do |port|
118:           @parsed_options.port = port
119:                                         end
120: 
121:         op.on("-r","--root ROOT", 
122:                       "Set the document root"," (default: #{default_options.document_root})") do |document_root|
123:           @parsed_options.document_root = File.expand_path(document_root)
124:           raise ::OptionParser::ParseError, "#{@parsed_options.document_root} is not a valid directory" if not File.directory?(@parsed_options.document_root)
125:                       end
126: 
127:         op.on("-v", "--version", "Show version") do 
128:           @parsed_options.show_version = true
129:         end
130:       end
131:     end

[Source]

    # File lib/heel/server.rb, line 76
76:     def pid_file
77:       File.join(default_directory,"heel.pid")
78:     end

[Source]

    # File lib/heel/server.rb, line 76
76:     def pid_file
77:       File.join(default_directory,"heel.pid")
78:     end

run the heel server with the current options.

[Source]

     # File lib/heel/server.rb, line 280
280:     def run
281: 
282:       error_version_help_kill
283:       merge_options
284:       setup_heel_dir
285:       ensure_not_running
286: 
287:       server_thread = start_thin_server
288: 
289:       if options.launch_browser then
290:         launch_browser.join
291:       end
292:       server_thread.join
293:     end

run the heel server with the current options.

[Source]

     # File lib/heel/server.rb, line 280
280:     def run
281: 
282:       error_version_help_kill
283:       merge_options
284:       setup_heel_dir
285:       ensure_not_running
286: 
287:       server_thread = start_thin_server
288: 
289:       if options.launch_browser then
290:         launch_browser.join
291:       end
292:       server_thread.join
293:     end

set the IO objects in a single method call. This is really only for testing instrumentation

[Source]

     # File lib/heel/server.rb, line 144
144:     def set_io(stdin = $stdin, stdout = $stdout ,setderr = $stderr)
145:       @stdin  = stdin
146:       @stdout = stdout
147:       @stderr = stderr
148:     end

set the IO objects in a single method call. This is really only for testing instrumentation

[Source]

     # File lib/heel/server.rb, line 144
144:     def set_io(stdin = $stdin, stdout = $stdout ,setderr = $stderr)
145:       @stdin  = stdin
146:       @stdout = stdout
147:       @stderr = stderr
148:     end

setup the directory that heel will use as the location to run from, where its logs will be stored and its PID file if backgrounded.

[Source]

     # File lib/heel/server.rb, line 189
189:     def setup_heel_dir
190:       if not File.exists?(default_directory) then
191:         FileUtils.mkdir_p(default_directory)
192:         @stdout.puts "Created #{default_directory}"
193:         @stdout.puts "heel's PID (#{pid_file}) and log file (#{log_file}) are stored here"
194:       end
195:     end

setup the directory that heel will use as the location to run from, where its logs will be stored and its PID file if backgrounded.

[Source]

     # File lib/heel/server.rb, line 189
189:     def setup_heel_dir
190:       if not File.exists?(default_directory) then
191:         FileUtils.mkdir_p(default_directory)
192:         @stdout.puts "Created #{default_directory}"
193:         @stdout.puts "heel's PID (#{pid_file}) and log file (#{log_file}) are stored here"
194:       end
195:     end

[Source]

     # File lib/heel/server.rb, line 253
253:     def  start_thin_serverstart_thin_server
254:       server = thin_server
255: 
256:       server_thread = Thread.new do
257:         begin
258:           if options.daemonize then
259:             if cpid = fork then
260:               # wait for the top child of the server double fork to exit
261:               Process.waitpid(cpid)
262:             else
263:               server.daemonize
264:               server.start
265:             end
266:           else
267:             begin
268:               server.start
269:             rescue RuntimeError 
270:               $stderr.puts "ERROR: Unable to start server.  Heel may already be running.  Please check running processes or run `heel --kill'"
271:               exit 1
272:             end
273:           end
274:         end
275:       end
276:     end

[Source]

     # File lib/heel/server.rb, line 253
253:     def  start_thin_serverstart_thin_server
254:       server = thin_server
255: 
256:       server_thread = Thread.new do
257:         begin
258:           if options.daemonize then
259:             if cpid = fork then
260:               # wait for the top child of the server double fork to exit
261:               Process.waitpid(cpid)
262:             else
263:               server.daemonize
264:               server.start
265:             end
266:           else
267:             begin
268:               server.start
269:             rescue RuntimeError 
270:               $stderr.puts "ERROR: Unable to start server.  Heel may already be running.  Please check running processes or run `heel --kill'"
271:               exit 1
272:             end
273:           end
274:         end
275:       end
276:     end

[Source]

     # File lib/heel/server.rb, line 219
219:     def thin_server
220:       server = Thin::Server.new(options.address, options.port)
221: 
222:       # overload the name of the process so it shows up as heel not thin
223:       def server.name
224:         "heel (v#{Heel::VERSION})"
225:       end
226: 
227:       server.pid_file = pid_file
228:       server.log_file = log_file
229: 
230:       app = Heel::RackApp.new({ :document_root => options.document_root,
231:                                 :highlighting  => options.highlighting})
232: 
233:       Heel::Logger.log_file = log_file
234:       server.app = Rack::Builder.new {
235:         use Heel::Logger
236:         map "/" do 
237:           run app
238:         end
239:         map "/heel_css" do 
240:           run Rack::File.new(Heel::Configuration.data_path( "css" )) 
241:         end
242:         map "/heel_icons" do
243:           run Rack::File.new(Heel::Configuration.data_path("famfamfam", "icons")) 
244:         end
245: 
246:       }
247:       
248:       server.app = Thin::Stats::Adapter.new(server.app, "/heel_stats")
249: 
250:       return server
251:     end

[Source]

     # File lib/heel/server.rb, line 219
219:     def thin_server
220:       server = Thin::Server.new(options.address, options.port)
221: 
222:       # overload the name of the process so it shows up as heel not thin
223:       def server.name
224:         "heel (v#{Heel::VERSION})"
225:       end
226: 
227:       server.pid_file = pid_file
228:       server.log_file = log_file
229: 
230:       app = Heel::RackApp.new({ :document_root => options.document_root,
231:                                 :highlighting  => options.highlighting})
232: 
233:       Heel::Logger.log_file = log_file
234:       server.app = Rack::Builder.new {
235:         use Heel::Logger
236:         map "/" do 
237:           run app
238:         end
239:         map "/heel_css" do 
240:           run Rack::File.new(Heel::Configuration.data_path( "css" )) 
241:         end
242:         map "/heel_icons" do
243:           run Rack::File.new(Heel::Configuration.data_path("famfamfam", "icons")) 
244:         end
245: 
246:       }
247:       
248:       server.app = Thin::Stats::Adapter.new(server.app, "/heel_stats")
249: 
250:       return server
251:     end

[Validate]