zbatery 0.0.0

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.
data/GNUmakefile ADDED
@@ -0,0 +1,169 @@
1
+ # use GNU Make to run tests in parallel, and without depending on RubyGems
2
+ all::
3
+ RUBY = ruby
4
+ RAKE = rake
5
+ GIT_URL = git://git.bogomips.org/zbatery.git
6
+
7
+ GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
8
+ @./GIT-VERSION-GEN
9
+ -include GIT-VERSION-FILE
10
+ -include local.mk
11
+ ifeq ($(DLEXT),) # "so" for Linux
12
+ DLEXT := $(shell $(RUBY) -rrbconfig -e 'puts Config::CONFIG["DLEXT"]')
13
+ endif
14
+ ifeq ($(RUBY_VERSION),)
15
+ RUBY_VERSION := $(shell $(RUBY) -e 'puts RUBY_VERSION')
16
+ endif
17
+
18
+ base_bins := zbatery
19
+ bins := $(addprefix bin/, $(base_bins))
20
+ man1_bins := $(addsuffix .1, $(base_bins))
21
+ man1_paths := $(addprefix man/man1/, $(man1_bins))
22
+
23
+ install: $(bins)
24
+ $(prep_setup_rb)
25
+ $(RM) -r .install-tmp
26
+ mkdir .install-tmp
27
+ cp -p bin/* .install-tmp
28
+ $(RUBY) setup.rb all
29
+ $(RM) $^
30
+ mv .install-tmp/* bin/
31
+ $(RM) -r .install-tmp
32
+ $(prep_setup_rb)
33
+
34
+ setup_rb_files := .config InstalledFiles
35
+ prep_setup_rb := @-$(RM) $(setup_rb_files);$(MAKE) -C $(ext) clean
36
+
37
+ clean:
38
+ -$(MAKE) -C $(ext) clean
39
+ -$(MAKE) -C Documentation clean
40
+ $(RM) $(setup_rb_files) $(t_log)
41
+
42
+ man:
43
+ $(MAKE) -C Documentation install-man
44
+
45
+ pkg_extra := GIT-VERSION-FILE NEWS ChangeLog
46
+ manifest: $(pkg_extra) man
47
+ $(RM) .manifest
48
+ $(MAKE) .manifest
49
+
50
+ .manifest:
51
+ (git ls-files && \
52
+ for i in $@ $(pkg_extra) $(man1_paths); \
53
+ do echo $$i; done) | LC_ALL=C sort > $@+
54
+ cmp $@+ $@ || mv $@+ $@
55
+ $(RM) $@+
56
+
57
+ NEWS: GIT-VERSION-FILE
58
+ $(RAKE) -s news_rdoc > $@+
59
+ mv $@+ $@
60
+
61
+ SINCE =
62
+ ChangeLog: LOG_VERSION = \
63
+ $(shell git rev-parse -q "$(GIT_VERSION)" >/dev/null 2>&1 && \
64
+ echo $(GIT_VERSION) || git describe)
65
+ ifneq ($(SINCE),)
66
+ ChangeLog: log_range = v$(SINCE)..$(LOG_VERSION)
67
+ endif
68
+ ChangeLog: GIT-VERSION-FILE
69
+ @echo "ChangeLog from $(GIT_URL) ($(log_range))" > $@+
70
+ @echo >> $@+
71
+ git log $(log_range) | sed -e 's/^/ /' >> $@+
72
+ mv $@+ $@
73
+
74
+ news_atom := http://zbatery.bogomip.org/NEWS.atom.xml
75
+ cgit_atom := http://git.bogomips.org/cgit/zbatery.git/atom/?h=master
76
+ atom = <link rel="alternate" title="Atom feed" href="$(1)" \
77
+ type="application/atom+xml"/>
78
+
79
+ # using rdoc 2.4.1+
80
+ doc: .document NEWS ChangeLog
81
+ for i in $(man1_bins); do > $$i; done
82
+ rdoc -Na -t "$(shell sed -ne '1s/^= //p' README)"
83
+ install -m644 COPYING doc/COPYING
84
+ install -m644 $(shell grep '^[A-Z]' .document) doc/
85
+ $(MAKE) -C Documentation install-html install-man
86
+ install -m644 $(man1_paths) doc/
87
+ cd doc && for i in $(base_bins); do \
88
+ sed -e '/"documentation">/r man1/'$$i'.1.html' \
89
+ < $${i}_1.html > tmp && mv tmp $${i}_1.html; done
90
+ $(RUBY) -i -p -e \
91
+ '$$_.gsub!("</title>",%q{\&$(call atom,$(cgit_atom))})' \
92
+ doc/ChangeLog.html
93
+ $(RUBY) -i -p -e \
94
+ '$$_.gsub!("</title>",%q{\&$(call atom,$(news_atom))})' \
95
+ doc/NEWS.html doc/README.html
96
+ $(RAKE) -s news_atom > doc/NEWS.atom.xml
97
+ cd doc && ln README.html tmp && mv tmp index.html
98
+ $(RM) $(man1_bins)
99
+
100
+ ifneq ($(VERSION),)
101
+ rfproject := rainbows
102
+ rfpackage := zbatery
103
+ pkggem := pkg/$(rfpackage)-$(VERSION).gem
104
+ pkgtgz := pkg/$(rfpackage)-$(VERSION).tgz
105
+ release_notes := release_notes-$(VERSION)
106
+ release_changes := release_changes-$(VERSION)
107
+
108
+ release-notes: $(release_notes)
109
+ release-changes: $(release_changes)
110
+ $(release_changes):
111
+ $(RAKE) -s release_changes > $@+
112
+ $(VISUAL) $@+ && test -s $@+ && mv $@+ $@
113
+ $(release_notes):
114
+ GIT_URL=$(GIT_URL) $(RAKE) -s release_notes > $@+
115
+ $(VISUAL) $@+ && test -s $@+ && mv $@+ $@
116
+
117
+ # ensures we're actually on the tagged $(VERSION), only used for release
118
+ verify:
119
+ test x"$(shell umask)" = x0022
120
+ git rev-parse --verify refs/tags/v$(VERSION)^{}
121
+ git diff-index --quiet HEAD^0
122
+ test `git rev-parse --verify HEAD^0` = \
123
+ `git rev-parse --verify refs/tags/v$(VERSION)^{}`
124
+
125
+ fix-perms:
126
+ -git ls-tree -r HEAD | awk '/^100644 / {print $$NF}' | xargs chmod 644
127
+ -git ls-tree -r HEAD | awk '/^100755 / {print $$NF}' | xargs chmod 755
128
+
129
+ gem: $(pkggem)
130
+
131
+ install-gem: $(pkggem)
132
+ gem install $(CURDIR)/$<
133
+
134
+ $(pkggem): manifest fix-perms
135
+ gem build $(rfpackage).gemspec
136
+ mkdir -p pkg
137
+ mv $(@F) $@
138
+
139
+ $(pkgtgz): distdir = $(basename $@)
140
+ $(pkgtgz): HEAD = v$(VERSION)
141
+ $(pkgtgz): manifest fix-perms
142
+ @test -n "$(distdir)"
143
+ $(RM) -r $(distdir)
144
+ mkdir -p $(distdir)
145
+ tar c `cat .manifest` | (cd $(distdir) && tar x)
146
+ cd pkg && tar c $(basename $(@F)) | gzip -9 > $(@F)+
147
+ mv $@+ $@
148
+
149
+ package: $(pkgtgz) $(pkggem)
150
+
151
+ release: verify package $(release_notes) $(release_changes)
152
+ # make tgz release on RubyForge
153
+ rubyforge add_release -f -n $(release_notes) -a $(release_changes) \
154
+ $(rfproject) $(rfpackage) $(VERSION) $(pkggem)
155
+ # push gem to Gemcutter
156
+ gem push $(pkggem)
157
+ # in case of gem downloads from RubyForge releases page
158
+ -rubyforge add_file \
159
+ $(rfproject) $(rfpackage) $(VERSION) $(pkggem)
160
+ else
161
+ gem install-gem: GIT-VERSION-FILE
162
+ $(MAKE) $@ VERSION=$(GIT_VERSION)
163
+ endif
164
+
165
+ all:: test
166
+ test:
167
+ $(MAKE) -C t
168
+
169
+ .PHONY: .FORCE-GIT-VERSION-FILE doc manifest man test
data/LICENSE ADDED
@@ -0,0 +1,55 @@
1
+ Zbatery is copyrighted Free Software by all contributors, see the
2
+ logs in revision control for all of them. You can redistribute it
3
+ and/or modify it under either the terms of the
4
+ {GPL2}[http://www.gnu.org/licenses/gpl-2.0.txt] (see link:COPYING) or
5
+ the conditions below:
6
+
7
+ 1. You may make and give away verbatim copies of the source form of the
8
+ software without restriction, provided that you duplicate all of the
9
+ original copyright notices and associated disclaimers.
10
+
11
+ 2. You may modify your copy of the software in any way, provided that
12
+ you do at least ONE of the following:
13
+
14
+ a) place your modifications in the Public Domain or otherwise make them
15
+ Freely Available, such as by posting said modifications to Usenet or an
16
+ equivalent medium, or by allowing the author to include your
17
+ modifications in the software.
18
+
19
+ b) use the modified software only within your corporation or
20
+ organization.
21
+
22
+ c) rename any non-standard executables so the names do not conflict with
23
+ standard executables, which must also be provided.
24
+
25
+ d) make other distribution arrangements with the author.
26
+
27
+ 3. You may distribute the software in object code or executable
28
+ form, provided that you do at least ONE of the following:
29
+
30
+ a) distribute the executables and library files of the software,
31
+ together with instructions (in the manual page or equivalent) on where
32
+ to get the original distribution.
33
+
34
+ b) accompany the distribution with the machine-readable source of the
35
+ software.
36
+
37
+ c) give non-standard executables non-standard names, with
38
+ instructions on where to get the original software distribution.
39
+
40
+ d) make other distribution arrangements with the author.
41
+
42
+ 4. You may modify and include the part of the software into any other
43
+ software (possibly commercial). But some files in the distribution
44
+ are not written by the author, so that they are not under this terms.
45
+
46
+ 5. The scripts and library files supplied as input to or produced as
47
+ output from the software do not automatically fall under the
48
+ copyright of the software, but belong to whomever generated them,
49
+ and may be sold commercially, and may be aggregated with this
50
+ software.
51
+
52
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
53
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
54
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
55
+ PURPOSE.
data/NEWS ADDED
@@ -0,0 +1,4 @@
1
+ === 0.0.0 / 2009-12-10 08:49 UTC
2
+
3
+ Initial release of Rainbows! without fork()
4
+
data/README ADDED
@@ -0,0 +1,130 @@
1
+ = Zbatery: Rack HTTP server without a fork stuck in it
2
+
3
+ Zbatery is an HTTP server for Rack applications on systems that either
4
+ do not support fork(), or have no memory (nor need) to run the
5
+ master/worker model. It is based on Rainbows! (which is based on
6
+ Unicorn (which is based on Mongrel)) and inherits parts of each.
7
+ Zbatery supports your choice of all the thread/fiber/event/actor-based
8
+ concurrency models and Rack middleware that Rainbows! supports (or will
9
+ ever support) in a single process.
10
+
11
+ Zbatery will still exploit certain features of Unix for transparent
12
+ upgrades, log reopening, and graceful stops, but does not rely on them
13
+ for basic functionality.
14
+
15
+ == Features
16
+
17
+ * Designed for {Rack}[http://rack.rubyforge.org/], the standard for
18
+ modern Ruby HTTP applications.
19
+
20
+ * Configuration files are compatible with Rainbows!, a superset
21
+ of the Unicorn
22
+ {DSL}[http://unicorn.bogomips.org/Unicorn/Configurator.html].
23
+
24
+ * Inherits all features and concurrency models Rainbows! supports
25
+ (and ever will support): http://rainbows.rubyforge.org/Summary.html
26
+
27
+ * -Untested- Works under operating systems that don't support signals,
28
+ pipe and fork(). Unicorn 0.95.2+ has rake-compiler support, so
29
+ compiling the HTTP parser should be easier at least.
30
+
31
+ * -Untested- HTML 5 Web Sockets support
32
+
33
+ == License
34
+
35
+ Zbatery is copyright 2009 by all contributors (see logs in git).
36
+ It is ultimately based on Mongrel and carries the same license.
37
+
38
+ Mongrel is copyright 2007 Zed A. Shaw and contributors. It is licensed
39
+ under the Ruby license and the GPL2. See the included LICENSE file for
40
+ details.
41
+
42
+ Zbatery is 100% Free Software.
43
+
44
+ == Install
45
+
46
+ You may download the tarball from the Rainbows project page on Rubyforge
47
+ and run setup.rb after unpacking it:
48
+
49
+ http://rubyforge.org/frs/?group_id=8977
50
+
51
+ You may also install it via RubyGems on Gemcutter:
52
+
53
+ gem install zbatery
54
+
55
+ == Usage
56
+
57
+ === for Rack applications
58
+
59
+ In APP_ROOT (where config.ru is located), run:
60
+
61
+ zbatery
62
+
63
+ Zbatery will bind to all interfaces on TCP port 8080 by default.
64
+
65
+ === Configuration File(s)
66
+
67
+ Zbatery will look for the config.ru file used by rackup in APP_ROOT.
68
+
69
+ For deployments, it can use a config file for Unicorn and
70
+ Rainbows!-specific options specified by the +--config-file/-c+
71
+ command-line switch. Zbatery accepts all options found in
72
+ {Unicorn::Configurator}[http://unicorn.bogomips.org/Unicorn/Configurator.html]
73
+ as well as the "Rainbows!" block, so you can have the following in your
74
+ config file:
75
+
76
+ Rainbows! do
77
+ use :FiberSpawn
78
+ worker_connections 400
79
+ end
80
+
81
+ See the Rainbows! configuration
82
+ {documentation}[http://rainbows.rubyforge.org/Rainbows.html#M000001]
83
+ for more details.
84
+
85
+ == Disclaimer
86
+
87
+ There is NO WARRANTY whatsoever if anything goes wrong, but let us know
88
+ and we'll try our best to fix it.
89
+
90
+ This project may be temporary and may eventually have its name encoded
91
+ with uncrackable ROT13 encryption leaving you with no way to upgrade.
92
+
93
+ == Development
94
+
95
+ Most of the work is done in Rainbows!, Zbatery is just a shim to
96
+ allow access to Rainbows! without requiring fork() or signals.
97
+
98
+ You can get the latest source via git from the following locations:
99
+
100
+ git://git.bogomips.org/zbatery.git
101
+ git://repo.or.cz/zbatery.git (mirror)
102
+
103
+ You may browse the code from the web and download the latest snapshot
104
+ tarballs here:
105
+
106
+ * http://git.bogomips.org/cgit/zbatery.git (cgit)
107
+ * http://repo.or.cz/w/zbatery.git (gitweb)
108
+
109
+ Inline patches (from "git format-patch") to the mailing list are
110
+ preferred because they allow code review and comments in the reply to
111
+ the patch.
112
+
113
+ We will adhere to mostly the same conventions for patch submissions as
114
+ git itself. See the Documentation/SubmittingPatches document
115
+ distributed with git on on patch submission guidelines to follow. Just
116
+ don't email the git mailing list or maintainer with Zbatery patches.
117
+
118
+ == Tests
119
+
120
+ There currently are no tests specific to Zbatery. Keep in mind that
121
+ Zbatery is only a small shim to drive Rainbows! (and Unicorn)
122
+ underneath. Rainbows! and Unicorn both have extensive (but very
123
+ UNIX-specific) test suites.
124
+
125
+ == Contact
126
+
127
+ All feedback (bug reports, user/development dicussion, patches, pull
128
+ requests) go to the mailing list/newsgroup. We are currently
129
+ borrowing the Rainbows! mailing list since most of our code (and
130
+ problems) are related to Rainbows! mailto:rainbows-talk@rubyforge.org.
data/Rakefile ADDED
@@ -0,0 +1,158 @@
1
+ # -*- encoding: binary -*-
2
+
3
+ # most tasks are in the GNUmakefile which offers better parallelism
4
+
5
+ def tags
6
+ timefmt = '%Y-%m-%dT%H:%M:%SZ'
7
+ @tags ||= `git tag -l`.split(/\n/).map do |tag|
8
+ if %r{\Av[\d\.]+\z} =~ tag
9
+ header, subject, body = `git cat-file tag #{tag}`.split(/\n\n/, 3)
10
+ header = header.split(/\n/)
11
+ tagger = header.grep(/\Atagger /).first
12
+ body ||= "initial"
13
+ {
14
+ :time => Time.at(tagger.split(/ /)[-2].to_i).utc.strftime(timefmt),
15
+ :tagger_name => %r{^tagger ([^<]+)}.match(tagger)[1].strip,
16
+ :tagger_email => %r{<([^>]+)>}.match(tagger)[1].strip,
17
+ :id => `git rev-parse refs/tags/#{tag}`.chomp!,
18
+ :tag => tag,
19
+ :subject => subject,
20
+ :body => body,
21
+ }
22
+ end
23
+ end.compact.sort { |a,b| b[:time] <=> a[:time] }
24
+ end
25
+
26
+ cgit_url = "http://git.bogomips.org/cgit/zbatery.git"
27
+ git_url = ENV['GIT_URL'] || 'git://git.bogomips.org/zbatery.git'
28
+
29
+ desc 'prints news as an Atom feed'
30
+ task :news_atom do
31
+ require 'nokogiri'
32
+ new_tags = tags[0,10]
33
+ puts(Nokogiri::XML::Builder.new do
34
+ feed :xmlns => "http://www.w3.org/2005/Atom" do
35
+ id! "http://zbatery.bogomip.org/NEWS.atom.xml"
36
+ title "Zbatery news"
37
+ subtitle "HTTP server without a fork stuck in it"
38
+ link! :rel => 'alternate', :type => 'text/html',
39
+ :href => 'http://zbatery.bogomip.org/NEWS.html'
40
+ updated(new_tags.empty? ? "1970-01-01T00:00:00Z" : new_tags.first[:time])
41
+ new_tags.each do |tag|
42
+ entry do
43
+ title tag[:subject]
44
+ updated tag[:time]
45
+ published tag[:time]
46
+ author {
47
+ name tag[:tagger_name]
48
+ email tag[:tagger_email]
49
+ }
50
+ url = "#{cgit_url}/tag/?id=#{tag[:tag]}"
51
+ link! :rel => "alternate", :type => "text/html", :href =>url
52
+ id! url
53
+ message_only = tag[:body].split(/\n.+\(\d+\):\n {6}/s).first.strip
54
+ content({:type =>:text}, message_only)
55
+ content(:type =>:xhtml) { pre tag[:body] }
56
+ end
57
+ end
58
+ end
59
+ end.to_xml)
60
+ end
61
+
62
+ desc 'prints RDoc-formatted news'
63
+ task :news_rdoc do
64
+ tags.each do |tag|
65
+ time = tag[:time].tr!('T', ' ').gsub!(/:\d\dZ/, ' UTC')
66
+ puts "=== #{tag[:tag].sub(/^v/, '')} / #{time}"
67
+ puts ""
68
+
69
+ body = tag[:body]
70
+ puts tag[:body].gsub(/^/sm, " ").gsub(/[ \t]+$/sm, "")
71
+ puts ""
72
+ end
73
+ end
74
+
75
+ desc "print release changelog for Rubyforge"
76
+ task :release_changes do
77
+ version = ENV['VERSION'] or abort "VERSION= needed"
78
+ version = "v#{version}"
79
+ vtags = tags.map { |tag| tag[:tag] =~ /\Av/ and tag[:tag] }.sort
80
+ prev = vtags[vtags.index(version) - 1]
81
+ if prev
82
+ system('git', 'diff', '--stat', prev, version) or abort $?
83
+ puts ""
84
+ system('git', 'log', "#{prev}..#{version}") or abort $?
85
+ else
86
+ system('git', 'log', version) or abort $?
87
+ end
88
+ end
89
+
90
+ desc "print release notes for Rubyforge"
91
+ task :release_notes do
92
+ require 'rubygems'
93
+
94
+ spec = Gem::Specification.load('zbatery.gemspec')
95
+ puts spec.description.strip
96
+ puts ""
97
+ puts "* #{spec.homepage}"
98
+ puts "* #{spec.email}"
99
+ puts "* #{git_url}"
100
+
101
+ _, _, body = `git cat-file tag v#{spec.version}`.split(/\n\n/, 3)
102
+ print "\nChanges:\n\n"
103
+ puts body
104
+ end
105
+
106
+ desc "read news article from STDIN and post to rubyforge"
107
+ task :publish_news do
108
+ require 'rubyforge'
109
+ IO.select([STDIN], nil, nil, 1) or abort "E: news must be read from stdin"
110
+ msg = STDIN.readlines
111
+ subject = msg.shift
112
+ blank = msg.shift
113
+ blank == "\n" or abort "no newline after subject!"
114
+ subject.strip!
115
+ body = msg.join("").strip!
116
+
117
+ rf = RubyForge.new.configure
118
+ rf.login
119
+ rf.post_news('rainbows', subject, body)
120
+ end
121
+
122
+ desc "post to RAA"
123
+ task :raa_update do
124
+ require 'rubygems'
125
+ require 'net/http'
126
+ require 'net/netrc'
127
+ rc = Net::Netrc.locate('zbatery-raa') or abort "~/.netrc not found"
128
+ password = rc.password
129
+
130
+ s = Gem::Specification.load('zbatery.gemspec')
131
+ desc = [ s.description.strip ]
132
+ desc << ""
133
+ desc << "* #{s.email}"
134
+ desc << "* #{git_url}"
135
+ desc << "* #{cgit_url}"
136
+ desc = desc.join("\n")
137
+ uri = URI.parse('http://raa.ruby-lang.org/regist.rhtml')
138
+ form = {
139
+ :name => s.name,
140
+ :short_description => s.summary,
141
+ :version => s.version.to_s,
142
+ :status => 'experimental',
143
+ :owner => s.authors.first,
144
+ :email => s.email,
145
+ :category_major => 'Library',
146
+ :category_minor => 'Web',
147
+ :url => s.homepage,
148
+ :download => "http://rubyforge.org/frs/?group_id=8977",
149
+ :license => "Ruby's",
150
+ :description_style => 'Plain',
151
+ :description => desc,
152
+ :pass => password,
153
+ :submit => "Update",
154
+ }
155
+ res = Net::HTTP.post_form(uri, form)
156
+ p res
157
+ puts res.body
158
+ end
data/bin/zbatery ADDED
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/ruby
2
+ # -*- encoding: binary -*-
3
+ require 'unicorn/launcher'
4
+ require 'zbatery'
5
+ require 'optparse'
6
+
7
+ ENV["RACK_ENV"] ||= "development"
8
+ daemonize = false
9
+ listeners = []
10
+ options = { :listeners => listeners }
11
+ host, port = Unicorn::Const::DEFAULT_HOST, Unicorn::Const::DEFAULT_PORT
12
+ set_listener = false
13
+
14
+ opts = OptionParser.new("", 24, ' ') do |opts|
15
+ opts.banner = "Usage: #{File.basename($0)} " \
16
+ "[ruby options] [zbatery options] [rackup config file]"
17
+
18
+ opts.separator "Ruby options:"
19
+
20
+ lineno = 1
21
+ opts.on("-e", "--eval LINE", "evaluate a LINE of code") do |line|
22
+ eval line, TOPLEVEL_BINDING, "-e", lineno
23
+ lineno += 1
24
+ end
25
+
26
+ opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") do
27
+ $DEBUG = true
28
+ end
29
+
30
+ opts.on("-w", "--warn", "turn warnings on for your script") do
31
+ $-w = true
32
+ end
33
+
34
+ opts.on("-I", "--include PATH",
35
+ "specify $LOAD_PATH (may be used more than once)") do |path|
36
+ $LOAD_PATH.unshift(*path.split(/:/))
37
+ end
38
+
39
+ opts.on("-r", "--require LIBRARY",
40
+ "require the library, before executing your script") do |library|
41
+ require library
42
+ end
43
+
44
+ opts.separator "Zbatery options:"
45
+
46
+ # some of these switches exist for rackup command-line compatibility,
47
+
48
+ opts.on("-o", "--host HOST",
49
+ "listen on HOST (default: #{Unicorn::Const::DEFAULT_HOST})") do |h|
50
+ host = h
51
+ set_listener = true
52
+ end
53
+
54
+ opts.on("-p", "--port PORT",
55
+ "use PORT (default: #{Unicorn::Const::DEFAULT_PORT})") do |p|
56
+ port = p.to_i
57
+ set_listener = true
58
+ end
59
+
60
+ opts.on("-E", "--env ENVIRONMENT",
61
+ "use ENVIRONMENT for defaults (default: development)") do |e|
62
+ ENV["RACK_ENV"] = e
63
+ end
64
+
65
+ opts.on("-D", "--daemonize", "run daemonized in the background") do |d|
66
+ daemonize = d ? true : false
67
+ end
68
+
69
+ opts.on("-P", "--pid FILE", "DEPRECATED") do |f|
70
+ warn %q{Use of --pid/-P is strongly discouraged}
71
+ warn %q{Use the 'pid' directive in the Zbatery config file instead}
72
+ options[:pid] = f
73
+ end
74
+
75
+ opts.on("-s", "--server SERVER",
76
+ "this flag only exists for compatibility") do |s|
77
+ warn "-s/--server only exists for compatibility with rackup"
78
+ end
79
+
80
+ # Zbatery/Unicorn-specific stuff
81
+ opts.on("-l", "--listen {HOST:PORT|PATH}",
82
+ "listen on HOST:PORT or PATH",
83
+ "this may be specified multiple times",
84
+ "(default: #{Unicorn::Const::DEFAULT_LISTEN})") do |address|
85
+ listeners << address
86
+ end
87
+
88
+ opts.on("-c", "--config-file FILE", "Unicorn-specific config file") do |f|
89
+ options[:config_file] = f
90
+ end
91
+
92
+ # I'm avoiding Unicorn-specific config options on the command-line.
93
+ # IMNSHO, config options on the command-line are redundant given
94
+ # config files and make things unnecessarily complicated with multiple
95
+ # places to look for a config option.
96
+
97
+ opts.separator "Common options:"
98
+
99
+ opts.on_tail("-h", "--help", "Show this message") do
100
+ puts opts.to_s.gsub(/^.*DEPRECATED.*$/s, '')
101
+ exit
102
+ end
103
+
104
+ opts.on_tail("-v", "--version", "Show version") do
105
+ puts "zbatery v#{Zbatery::VERSION}"
106
+ exit
107
+ end
108
+
109
+ opts.parse! ARGV
110
+ end
111
+
112
+ config = ARGV[0] || "config.ru"
113
+ abort "configuration file #{config} not found" unless File.exist?(config)
114
+
115
+ if config =~ /\.ru$/
116
+ # parse embedded command-line options in config.ru comments
117
+ if File.open(config, "rb") { |fp| fp.sysread(fp.stat.size) } =~ /^#\\(.*)/
118
+ opts.parse! $1.split(/\s+/)
119
+ end
120
+ end
121
+
122
+ require 'pp' if $DEBUG
123
+
124
+ app = lambda do ||
125
+ # require Rack as late as possible in case $LOAD_PATH is modified
126
+ # in config.ru or command-line
127
+ inner_app = case config
128
+ when /\.ru$/
129
+ raw = File.open(config, "rb") { |fp| fp.sysread(fp.stat.size) }
130
+ raw.sub!(/^__END__\n.*/, '')
131
+ eval("Rack::Builder.new {(#{raw}\n)}.to_app", nil, config)
132
+ else
133
+ require config
134
+ Object.const_get(File.basename(config, '.rb').capitalize)
135
+ end
136
+ pp({ :inner_app => inner_app }) if $DEBUG
137
+ case ENV["RACK_ENV"]
138
+ when "development"
139
+ Rack::Builder.new do
140
+ use Rack::CommonLogger, $stderr
141
+ use Rack::ShowExceptions
142
+ use Rack::Lint
143
+ run inner_app
144
+ end.to_app
145
+ when "deployment"
146
+ Rack::Builder.new do
147
+ use Rack::CommonLogger, $stderr
148
+ run inner_app
149
+ end.to_app
150
+ else
151
+ inner_app
152
+ end
153
+ end
154
+
155
+ listeners << "#{host}:#{port}" if set_listener
156
+
157
+ if $DEBUG
158
+ pp({
159
+ :zbatery_options => options,
160
+ :app => app,
161
+ :daemonize => daemonize,
162
+ })
163
+ end
164
+
165
+ Unicorn::Launcher.daemonize! if daemonize
166
+ Zbatery.run(app, options)