zbatery 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +6 -0
- data/.gitignore +18 -0
- data/.manifest +21 -0
- data/COPYING +339 -0
- data/ChangeLog +35 -0
- data/Documentation/.gitignore +5 -0
- data/Documentation/GNUmakefile +30 -0
- data/Documentation/zbatery.1.txt +154 -0
- data/GIT-VERSION-FILE +1 -0
- data/GIT-VERSION-GEN +40 -0
- data/GNUmakefile +169 -0
- data/LICENSE +55 -0
- data/NEWS +4 -0
- data/README +130 -0
- data/Rakefile +158 -0
- data/bin/zbatery +166 -0
- data/lib/zbatery.rb +154 -0
- data/local.mk.sample +78 -0
- data/man/man1/zbatery.1 +187 -0
- data/setup.rb +1586 -0
- data/zbatery.gemspec +55 -0
- metadata +97 -0
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
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)
|