exec: disable embedded switch parsing in config.ru
[unicorn.git] / bin / unicorn
blob0956d6fddbf316cfcfbe211c58139db9cf901645
1 #!/home/ew/bin/ruby
2 STDIN.sync = STDOUT.sync = STDERR.sync = true
3 require 'unicorn' # require this first to populate Unicorn::DEFAULT_START_CTX
4 require 'rack'
5 require 'optparse'
7 env = "development"
8 daemonize = false
9 listeners = []
10 options = { :listeners => listeners }
11 host = Unicorn::Const::DEFAULT_HOST
12 port = Unicorn::Const::DEFAULT_PORT
14 opts = OptionParser.new("", 24, ' ') do |opts|
15 opts.banner = "Usage: #{File.basename($0)} " \
16 "[ruby options] [unicorn options] [rackup config file]"
18 opts.separator ""
19 opts.separator "Ruby options:"
21 lineno = 1
22 opts.on("-e", "--eval LINE", "evaluate a LINE of code") do |line|
23 eval line, TOPLEVEL_BINDING, "-e", lineno
24 lineno += 1
25 end
27 opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") do
28 $DEBUG = true
29 end
31 opts.on("-w", "--warn", "turn warnings on for your script") do
32 $-w = true
33 end
35 opts.on("-I", "--include PATH",
36 "specify $LOAD_PATH (may be used more than once)") do |path|
37 $LOAD_PATH.unshift(*path.split(/:/))
38 end
40 opts.on("-r", "--require LIBRARY",
41 "require the library, before executing your script") do |library|
42 require library
43 end
45 opts.separator ""
46 opts.separator "Unicorn options:"
48 # some of these switches exist for rackup command-line compatibility,
50 opts.on("-o", "--host HOST", "listen on HOST (default: 0.0.0.0)") do |h|
51 warn "The --host/-o option is not recommended, see --listen/-l"
52 host = h
53 end
55 opts.on("-p", "--port PORT", "use PORT (default: 8080)") do |p|
56 warn "The --port/-p option is not recommended, see --listen/-l"
57 port = p.to_i
58 end
60 opts.on("-E", "--env ENVIRONMENT",
61 "use ENVIRONMENT for defaults (default: development)") do |e|
62 env = e
63 end
65 opts.on("-D", "--daemonize", "run daemonized in the background") do |d|
66 daemonize = d ? true : false
67 end
69 opts.on("-P", "--pid FILE", "file to store PID (default: none)") do |f|
70 options[:pid] = File.expand_path(f)
71 end
73 # Unicorn-specific stuff
74 opts.on("-l", "--listen <address:port|/path/to/socket>",
75 "listen on address:port or UNIX socket " \
76 "(default: 0.0.0.0:8080)" \
77 " this may be specified multiple times") do |address|
78 listeners << address
79 end
81 opts.on("-C", "--directory PATH", "run in this directory") do |d|
82 options[:directory] = d
83 end
85 opts.on("-c", "--config-file FILE", "Unicorn-specific config file") do |f|
86 options[:config_file] = File.expand_path(f)
87 end
89 # I'm avoiding Unicorn-specific config options on the command-line.
90 # IMNSHO, config options on the command-line are redundant given a
91 # config files and make things unnecessarily complicated with multiple
92 # places to look for a config option.
94 opts.separator ""
95 opts.separator "Common options:"
97 opts.on_tail("-h", "--help", "Show this message") do
98 puts opts
99 exit
102 opts.on_tail("--version", "Show version") do
103 puts "unicorn v#{Unicorn::Const::UNICORN_VERSION}"
104 exit
107 opts.parse! ARGV
110 require 'pp' if $DEBUG
112 config = ARGV[0] || "config.ru"
113 abort "configuration file #{config} not found" unless File.exist?(config)
115 if config =~ /\.ru$/
116 cfgfile = File.read(config)
117 if cfgfile[/^#\\(.*)/]
118 warn %(not parsing embedded command-line options: "#$1")
120 inner_app = eval "Rack::Builder.new {(#{cfgfile}\n)}.to_app", nil, config
121 else
122 require config
123 inner_app = Object.const_get(File.basename(config, '.rb').capitalize)
126 app = case env
127 when "development"
128 Rack::Builder.new do
129 use Rack::CommonLogger, STDERR
130 use Rack::ShowExceptions
131 use Rack::Lint
132 run inner_app
133 end.to_app
134 when "deployment"
135 Rack::Builder.new do
136 use Rack::CommonLogger, STDERR
137 run inner_app
138 end.to_app
139 else
140 inner_app
143 if listeners.empty?
144 listener = "#{host}:#{port}"
145 listeners << listener if listener != Unicorn::Const::DEFAULT_LISTEN
148 if $DEBUG
149 pp({
150 :unicorn_options => options,
151 :app => app,
152 :inner_app => inner_app,
153 :daemonize => daemonize,
157 # only daemonize if we're not inheriting file descriptors from our parent
158 if daemonize
159 unless ENV['UNICORN_FD']
160 exit if fork
161 Process.setsid
162 exit if fork
165 Dir.chdir("/") # setting options[:directory] will override this later on
166 File.umask(0000)
167 STDIN.reopen("/dev/null")
169 # we can redirect these again in the Unicorn {before,after}_fork hooks
170 STDOUT.reopen("/dev/null", "a")
171 STDERR.reopen("/dev/null", "a")
174 Unicorn.run(app, options)