giraffesoft-unicorn 0.93.5

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.
Files changed (141) hide show
  1. data/.CHANGELOG.old +25 -0
  2. data/.document +16 -0
  3. data/.gitignore +20 -0
  4. data/.mailmap +26 -0
  5. data/CONTRIBUTORS +31 -0
  6. data/COPYING +339 -0
  7. data/DESIGN +105 -0
  8. data/Documentation/.gitignore +5 -0
  9. data/Documentation/GNUmakefile +30 -0
  10. data/Documentation/unicorn.1.txt +167 -0
  11. data/Documentation/unicorn_rails.1.txt +169 -0
  12. data/GIT-VERSION-GEN +40 -0
  13. data/GNUmakefile +270 -0
  14. data/HACKING +113 -0
  15. data/KNOWN_ISSUES +40 -0
  16. data/LICENSE +55 -0
  17. data/PHILOSOPHY +144 -0
  18. data/README +153 -0
  19. data/Rakefile +108 -0
  20. data/SIGNALS +97 -0
  21. data/TODO +16 -0
  22. data/TUNING +70 -0
  23. data/bin/unicorn +165 -0
  24. data/bin/unicorn_rails +208 -0
  25. data/examples/echo.ru +27 -0
  26. data/examples/git.ru +13 -0
  27. data/examples/init.sh +53 -0
  28. data/ext/unicorn_http/c_util.h +107 -0
  29. data/ext/unicorn_http/common_field_optimization.h +111 -0
  30. data/ext/unicorn_http/ext_help.h +73 -0
  31. data/ext/unicorn_http/extconf.rb +14 -0
  32. data/ext/unicorn_http/global_variables.h +91 -0
  33. data/ext/unicorn_http/unicorn_http.rl +715 -0
  34. data/ext/unicorn_http/unicorn_http_common.rl +74 -0
  35. data/lib/unicorn.rb +730 -0
  36. data/lib/unicorn/app/exec_cgi.rb +150 -0
  37. data/lib/unicorn/app/inetd.rb +109 -0
  38. data/lib/unicorn/app/old_rails.rb +31 -0
  39. data/lib/unicorn/app/old_rails/static.rb +60 -0
  40. data/lib/unicorn/cgi_wrapper.rb +145 -0
  41. data/lib/unicorn/configurator.rb +403 -0
  42. data/lib/unicorn/const.rb +37 -0
  43. data/lib/unicorn/http_request.rb +74 -0
  44. data/lib/unicorn/http_response.rb +74 -0
  45. data/lib/unicorn/launcher.rb +39 -0
  46. data/lib/unicorn/socket_helper.rb +138 -0
  47. data/lib/unicorn/tee_input.rb +174 -0
  48. data/lib/unicorn/util.rb +64 -0
  49. data/local.mk.sample +53 -0
  50. data/setup.rb +1586 -0
  51. data/test/aggregate.rb +15 -0
  52. data/test/benchmark/README +50 -0
  53. data/test/benchmark/dd.ru +18 -0
  54. data/test/exec/README +5 -0
  55. data/test/exec/test_exec.rb +855 -0
  56. data/test/rails/app-1.2.3/.gitignore +2 -0
  57. data/test/rails/app-1.2.3/Rakefile +7 -0
  58. data/test/rails/app-1.2.3/app/controllers/application.rb +6 -0
  59. data/test/rails/app-1.2.3/app/controllers/foo_controller.rb +36 -0
  60. data/test/rails/app-1.2.3/app/helpers/application_helper.rb +4 -0
  61. data/test/rails/app-1.2.3/config/boot.rb +11 -0
  62. data/test/rails/app-1.2.3/config/database.yml +12 -0
  63. data/test/rails/app-1.2.3/config/environment.rb +13 -0
  64. data/test/rails/app-1.2.3/config/environments/development.rb +9 -0
  65. data/test/rails/app-1.2.3/config/environments/production.rb +5 -0
  66. data/test/rails/app-1.2.3/config/routes.rb +6 -0
  67. data/test/rails/app-1.2.3/db/.gitignore +0 -0
  68. data/test/rails/app-1.2.3/public/404.html +1 -0
  69. data/test/rails/app-1.2.3/public/500.html +1 -0
  70. data/test/rails/app-2.0.2/.gitignore +2 -0
  71. data/test/rails/app-2.0.2/Rakefile +7 -0
  72. data/test/rails/app-2.0.2/app/controllers/application.rb +4 -0
  73. data/test/rails/app-2.0.2/app/controllers/foo_controller.rb +36 -0
  74. data/test/rails/app-2.0.2/app/helpers/application_helper.rb +4 -0
  75. data/test/rails/app-2.0.2/config/boot.rb +11 -0
  76. data/test/rails/app-2.0.2/config/database.yml +12 -0
  77. data/test/rails/app-2.0.2/config/environment.rb +17 -0
  78. data/test/rails/app-2.0.2/config/environments/development.rb +8 -0
  79. data/test/rails/app-2.0.2/config/environments/production.rb +5 -0
  80. data/test/rails/app-2.0.2/config/routes.rb +6 -0
  81. data/test/rails/app-2.0.2/db/.gitignore +0 -0
  82. data/test/rails/app-2.0.2/public/404.html +1 -0
  83. data/test/rails/app-2.0.2/public/500.html +1 -0
  84. data/test/rails/app-2.1.2/.gitignore +2 -0
  85. data/test/rails/app-2.1.2/Rakefile +7 -0
  86. data/test/rails/app-2.1.2/app/controllers/application.rb +4 -0
  87. data/test/rails/app-2.1.2/app/controllers/foo_controller.rb +36 -0
  88. data/test/rails/app-2.1.2/app/helpers/application_helper.rb +4 -0
  89. data/test/rails/app-2.1.2/config/boot.rb +111 -0
  90. data/test/rails/app-2.1.2/config/database.yml +12 -0
  91. data/test/rails/app-2.1.2/config/environment.rb +17 -0
  92. data/test/rails/app-2.1.2/config/environments/development.rb +7 -0
  93. data/test/rails/app-2.1.2/config/environments/production.rb +5 -0
  94. data/test/rails/app-2.1.2/config/routes.rb +6 -0
  95. data/test/rails/app-2.1.2/db/.gitignore +0 -0
  96. data/test/rails/app-2.1.2/public/404.html +1 -0
  97. data/test/rails/app-2.1.2/public/500.html +1 -0
  98. data/test/rails/app-2.2.2/.gitignore +2 -0
  99. data/test/rails/app-2.2.2/Rakefile +7 -0
  100. data/test/rails/app-2.2.2/app/controllers/application.rb +4 -0
  101. data/test/rails/app-2.2.2/app/controllers/foo_controller.rb +36 -0
  102. data/test/rails/app-2.2.2/app/helpers/application_helper.rb +4 -0
  103. data/test/rails/app-2.2.2/config/boot.rb +111 -0
  104. data/test/rails/app-2.2.2/config/database.yml +12 -0
  105. data/test/rails/app-2.2.2/config/environment.rb +17 -0
  106. data/test/rails/app-2.2.2/config/environments/development.rb +7 -0
  107. data/test/rails/app-2.2.2/config/environments/production.rb +5 -0
  108. data/test/rails/app-2.2.2/config/routes.rb +6 -0
  109. data/test/rails/app-2.2.2/db/.gitignore +0 -0
  110. data/test/rails/app-2.2.2/public/404.html +1 -0
  111. data/test/rails/app-2.2.2/public/500.html +1 -0
  112. data/test/rails/app-2.3.3.1/.gitignore +2 -0
  113. data/test/rails/app-2.3.3.1/Rakefile +7 -0
  114. data/test/rails/app-2.3.3.1/app/controllers/application_controller.rb +5 -0
  115. data/test/rails/app-2.3.3.1/app/controllers/foo_controller.rb +36 -0
  116. data/test/rails/app-2.3.3.1/app/helpers/application_helper.rb +4 -0
  117. data/test/rails/app-2.3.3.1/config/boot.rb +109 -0
  118. data/test/rails/app-2.3.3.1/config/database.yml +12 -0
  119. data/test/rails/app-2.3.3.1/config/environment.rb +17 -0
  120. data/test/rails/app-2.3.3.1/config/environments/development.rb +7 -0
  121. data/test/rails/app-2.3.3.1/config/environments/production.rb +6 -0
  122. data/test/rails/app-2.3.3.1/config/routes.rb +6 -0
  123. data/test/rails/app-2.3.3.1/db/.gitignore +0 -0
  124. data/test/rails/app-2.3.3.1/public/404.html +1 -0
  125. data/test/rails/app-2.3.3.1/public/500.html +1 -0
  126. data/test/rails/app-2.3.3.1/public/x.txt +1 -0
  127. data/test/rails/test_rails.rb +280 -0
  128. data/test/test_helper.rb +296 -0
  129. data/test/unit/test_configurator.rb +150 -0
  130. data/test/unit/test_http_parser.rb +492 -0
  131. data/test/unit/test_http_parser_ng.rb +308 -0
  132. data/test/unit/test_request.rb +184 -0
  133. data/test/unit/test_response.rb +110 -0
  134. data/test/unit/test_server.rb +188 -0
  135. data/test/unit/test_signals.rb +202 -0
  136. data/test/unit/test_socket_helper.rb +133 -0
  137. data/test/unit/test_tee_input.rb +229 -0
  138. data/test/unit/test_upload.rb +297 -0
  139. data/test/unit/test_util.rb +96 -0
  140. data/unicorn.gemspec +42 -0
  141. metadata +228 -0
data/LICENSE ADDED
@@ -0,0 +1,55 @@
1
+ Unicorn is copyrighted free software by all contributors, see logs in
2
+ revision control for names and email addresses of all of them. You can
3
+ redistribute it 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/PHILOSOPHY ADDED
@@ -0,0 +1,144 @@
1
+ = The Philosophy Behind Unicorn
2
+
3
+ Being a server that only runs on Unix-like platforms, Unicorn is
4
+ strongly tied to the Unix philosophy of doing one thing and (hopefully)
5
+ doing it well. Despite using HTTP, Unicorn is strictly a _backend_
6
+ application server for running Rack-based Ruby applications.
7
+
8
+ == Avoid Complexity
9
+
10
+ Instead of attempting to be efficient at serving slow clients, Unicorn
11
+ relies on a buffering reverse proxy to efficiently deal with slow
12
+ clients.
13
+
14
+ Unicorn uses an old-fashioned preforking worker model with blocking I/O.
15
+ Our processing model is the antithesis of more modern (and theoretically
16
+ more efficient) server processing models using threads or non-blocking
17
+ I/O with events.
18
+
19
+ === Threads and Events Are Hard
20
+
21
+ ...to many developers. Reasons for this is beyond the scope of this
22
+ document. Unicorn avoids concurrency within each worker process so you
23
+ have fewer things to worry about when developing your application. Of
24
+ course Unicorn can use multiple worker processes to utilize multiple
25
+ CPUs or spindles. Applications can still use threads internally, however.
26
+
27
+ == Slow Clients Are Problematic
28
+
29
+ Most benchmarks we've seen don't tell you this, and Unicorn doesn't
30
+ care about slow clients... but <i>you</i> should.
31
+
32
+ A "slow client" can be any client outside of your datacenter. Network
33
+ traffic within a local network is always faster than traffic that
34
+ crosses outside of it. The laws of physics do not allow otherwise.
35
+
36
+ Persistent connections were introduced in HTTP/1.1 reduce latency from
37
+ connection establishment and TCP slow start. They also waste server
38
+ resources when clients are idle.
39
+
40
+ Persistent connections mean one of the Unicorn worker processes
41
+ (depending on your application, it can be very memory hungry) would
42
+ spend a significant amount of its time idle keeping the connection alive
43
+ <i>and not doing anything else</i>. Being single-threaded and using
44
+ blocking I/O, a worker cannot serve other clients while keeping a
45
+ connection alive. Thus Unicorn does not implement persistent
46
+ connections.
47
+
48
+ If your application responses are larger than the socket buffer or if
49
+ you're handling large requests (uploads), worker processes will also be
50
+ bottlenecked by the speed of the *client* connection. You should
51
+ not allow Unicorn to serve clients outside of your local network.
52
+
53
+ == Application Concurrency != Network Concurrency
54
+
55
+ Performance is asymmetric across the different subsystems of the machine
56
+ and parts of the network. CPUs and main memory can process gigabytes of
57
+ data in a second; clients on the Internet are usually only capable of a
58
+ tiny fraction of that. Unicorn deployments should avoid dealing with
59
+ slow clients directly and instead rely on a reverse proxy to shield it
60
+ from the effects of slow I/O.
61
+
62
+ == Improved Performance Through Reverse Proxying
63
+
64
+ By acting as a buffer to shield Unicorn from slow I/O, a reverse proxy
65
+ will inevitably incur overhead in the form of extra data copies.
66
+ However, as I/O within a local network is fast (and faster still
67
+ with local sockets), this overhead is neglible for the vast majority
68
+ of HTTP requests and responses.
69
+
70
+ The ideal reverse proxy complements the weaknesses of Unicorn.
71
+ A reverse proxy for Unicorn should meet the following requirements:
72
+
73
+ 1. It should fully buffer all HTTP requests (and large responses).
74
+ Each request should be "corked" in the reverse proxy and sent
75
+ as fast as possible to the backend Unicorn processes. This is
76
+ the most important feature to look for when choosing a
77
+ reverse proxy for Unicorn.
78
+
79
+ 2. It should spend minimal time in userspace. Network (and disk) I/O
80
+ are system-level tasks and usually managed by the kernel.
81
+ This may change if userspace TCP stacks become more popular in the
82
+ future; but the reverse proxy should not waste time with
83
+ application-level logic. These concerns should be separated
84
+
85
+ 3. It should avoid context switches and CPU scheduling overhead.
86
+ In many (most?) cases, network devices and their interrupts are
87
+ only be handled by one CPU at a time. It should avoid contention
88
+ within the system by serializing all network I/O into one (or few)
89
+ userspace procceses. Network I/O is not a CPU-intensive task and
90
+ it is not helpful to use multiple CPU cores (at least not for GigE).
91
+
92
+ 4. It should efficiently manage persistent connections (and
93
+ pipelining) to slow clients. If you care to serve slow clients
94
+ outside your network, then these features of HTTP/1.1 will help.
95
+
96
+ 5. It should (optionally) serve static files. If you have static
97
+ files on your site (especially large ones), they are far more
98
+ efficiently served with as few data copies as possible (e.g. with
99
+ sendfile() to completely avoid copying the data to userspace).
100
+
101
+ nginx is the only (Free) solution we know of that meets the above
102
+ requirements.
103
+
104
+ Indeed, the folks behind Unicorn have deployed nginx as a reverse-proxy not
105
+ only for Ruby applications, but also for production applications running
106
+ Apache/mod_perl, Apache/mod_php and Apache Tomcat. In every single
107
+ case, performance improved because application servers were able to use
108
+ backend resources more efficiently and spend less time waiting on slow
109
+ I/O.
110
+
111
+ == Worse Is Better
112
+
113
+ Requirements and scope for applications change frequently and
114
+ drastically. Thus languages like Ruby and frameworks like Rails were
115
+ built to give developers fewer things to worry about in the face of
116
+ rapid change.
117
+
118
+ On the other hand, stable protocols which host your applications (HTTP
119
+ and TCP) only change rarely. This is why we recommend you NOT tie your
120
+ rapidly-changing application logic directly into the processes that deal
121
+ with the stable outside world. Instead, use HTTP as a common RPC
122
+ protocol to communicate between your frontend and backend.
123
+
124
+ In short: separate your concerns.
125
+
126
+ Of course a theoretical "perfect" solution would combine the pieces
127
+ and _maybe_ give you better performance at the end of the day, but
128
+ that is not the Unix way.
129
+
130
+ == Just Worse in Some Cases
131
+
132
+ Unicorn is not suited for all applications. Unicorn is optimized for
133
+ applications that are CPU/memory/disk intensive and spend little time
134
+ waiting on external resources (e.g. a database server or external API).
135
+
136
+ Unicorn is highly inefficient for Comet/reverse-HTTP/push applications
137
+ where the HTTP connection spends a large amount of time idle.
138
+ Nevertheless, the ease of troubleshooting, debugging, and management of
139
+ Unicorn may still outweigh the drawbacks for these applications.
140
+
141
+ The {Rainbows!}[http://rainbows.rubyforge.org/] aims to fill the gap for
142
+ odd corner cases where the nginx + Unicorn combination is not enough.
143
+ Keep in mind that Rainbows! is still very new (as of October 2009), far
144
+ more ambitious, and far less tested than Unicorn.
data/README ADDED
@@ -0,0 +1,153 @@
1
+ = Unicorn: Rack HTTP server for fast clients and Unix
2
+
3
+ Unicorn is a HTTP server for Rack applications designed to only serve
4
+ fast clients on low-latency, high-bandwidth connections and take
5
+ advantage of features in Unix/Unix-like kernels. Slow clients should
6
+ only be served by placing a reverse proxy capable of fully buffering
7
+ both the the request and response in between Unicorn and slow clients.
8
+
9
+ == Features
10
+
11
+ * Designed for Rack, Unix, fast clients, and ease-of-debugging. We
12
+ cut out everything that is better supported by the operating system,
13
+ {nginx}[http://nginx.net/] or {Rack}[http://rack.rubyforge.org/].
14
+
15
+ * Compatible with both Ruby 1.8 and 1.9. Rubinius support is in-progress.
16
+
17
+ * Process management: Unicorn will reap and restart workers that
18
+ die from broken apps. There is no need to manage multiple processes
19
+ or ports yourself. Unicorn can spawn and manage any number of
20
+ worker processes you choose to scale to your backend.
21
+
22
+ * Load balancing is done entirely by the operating system kernel.
23
+ Requests never pile up behind a busy worker process.
24
+
25
+ * Does not care if your application is thread-safe or not, workers
26
+ all run within their own isolated address space and only serve one
27
+ client at a time for maximum robustness.
28
+
29
+ * Supports all Rack applications, along with pre-Rack versions of
30
+ Ruby on Rails via a Rack wrapper.
31
+
32
+ * Builtin reopening of all log files in your application via
33
+ USR1 signal. This allows logrotate to rotate files atomically and
34
+ quickly via rename instead of the racy and slow copytruncate method.
35
+ Unicorn also takes steps to ensure multi-line log entries from one
36
+ request all stay within the same file.
37
+
38
+ * nginx-style binary upgrades without losing connections.
39
+ You can upgrade Unicorn, your entire application, libraries
40
+ and even your Ruby interpreter without dropping clients.
41
+
42
+ * before_fork and after_fork hooks in case your application
43
+ has special needs when dealing with forked processes. These
44
+ should not be needed when the "preload_app" directive is
45
+ false (the default).
46
+
47
+ * Can be used with copy-on-write-friendly memory management
48
+ to save memory (by setting "preload_app" to true).
49
+
50
+ * Able to listen on multiple interfaces including UNIX sockets,
51
+ each worker process can also bind to a private port via the
52
+ after_fork hook for easy debugging.
53
+
54
+ * Simple and easy Ruby DSL for configuration.
55
+
56
+ * Decodes chunked transfers on-the-fly, thus allowing upload progress
57
+ notification to be implemented as well as being able to tunnel
58
+ arbitrary stream-based protocols over HTTP.
59
+
60
+ == License
61
+
62
+ Unicorn is copyright 2009 by all contributors (see logs in git).
63
+ It is based on Mongrel and carries the same license.
64
+
65
+ Mongrel is copyright 2007 Zed A. Shaw and contributors. It is licensed
66
+ under the Ruby license and the GPL2. See the included LICENSE file for
67
+ details.
68
+
69
+ Unicorn is 100% Free Software.
70
+
71
+ == Install
72
+
73
+ The library consists of a C extension so you'll need a C compiler
74
+ and Ruby development libraries/headers.
75
+
76
+ You may download the tarball from the Mongrel project page on Rubyforge
77
+ and run setup.rb after unpacking it:
78
+
79
+ http://rubyforge.org/frs/?group_id=1306
80
+
81
+ You may also install it via Rubygems on Rubyforge:
82
+
83
+ gem install unicorn
84
+
85
+ You can get the latest source via git from the following locations
86
+ (these versions may not be stable):
87
+
88
+ git://git.bogomips.org/unicorn.git
89
+ http://git.bogomips.org/unicorn.git
90
+ git://repo.or.cz/unicorn.git (mirror)
91
+ http://repo.or.cz/r/unicorn.git (mirror)
92
+
93
+ You may browse the code from the web and download the latest snapshot
94
+ tarballs here:
95
+
96
+ * http://git.bogomips.org/cgit/unicorn.git (cgit)
97
+ * http://repo.or.cz/w/unicorn.git (gitweb)
98
+
99
+ == Usage
100
+
101
+ === non-Rails Rack applications
102
+
103
+ In APP_ROOT, run:
104
+
105
+ unicorn
106
+
107
+ === for Rails applications (should work for all 1.2 or later versions)
108
+
109
+ In RAILS_ROOT, run:
110
+
111
+ unicorn_rails
112
+
113
+ Unicorn will bind to all interfaces on TCP port 8080 by default.
114
+ You may use the +--listen/-l+ switch to bind to a different
115
+ address:port or a UNIX socket.
116
+
117
+ === Configuration File(s)
118
+
119
+ Unicorn will look for the config.ru file used by rackup in APP_ROOT.
120
+
121
+ For deployments, it can use a config file for Unicorn-specific options
122
+ specified by the +--config-file/-c+ command-line switch. See
123
+ Unicorn::Configurator for the syntax of the Unicorn-specific options.
124
+ The default settings are designed for maximum out-of-the-box
125
+ compatibility with existing applications.
126
+
127
+ Most command-line options for other Rack applications (above) are also
128
+ supported. Run `unicorn -h` or `unicorn_rails -h` to see command-line
129
+ options.
130
+
131
+ == Disclaimer
132
+
133
+ Like the creatures themselves, production deployments of Unicorn are
134
+ rare. There is NO WARRANTY whatsoever if anything goes wrong, but let
135
+ us know and we'll try our best to fix it.
136
+
137
+ Unicorn is designed to only serve fast clients either on the local host
138
+ or a fast LAN. See the PHILOSOPHY and DESIGN documents for more details
139
+ regarding this.
140
+
141
+ == Contact
142
+
143
+ All feedback (bug reports, user/development dicussion, patches, pull
144
+ requests) go to the mailing list/newsgroup. Patches must be sent inline
145
+ (git format-patch -M + git send-email). No subscription is necessary
146
+ to post on the mailing list. No top posting. Address replies +To:+
147
+ the mailing list.
148
+
149
+ * email: mailto:mongrel-unicorn@rubyforge.org
150
+ * nntp: nntp://news.gmane.org/gmane.comp.lang.ruby.unicorn.general
151
+ * archives: http://rubyforge.org/pipermail/mongrel-unicorn/
152
+ * subscribe: http://rubyforge.org/mailman/listinfo/mongrel-unicorn/
153
+ * finger: unicorn@bogomips.org
data/Rakefile ADDED
@@ -0,0 +1,108 @@
1
+ # -*- encoding: binary -*-
2
+
3
+ # most tasks are in the GNUmakefile which offers better parallelism
4
+
5
+ def old_summaries
6
+ @old_summaries ||= File.readlines(".CHANGELOG.old").inject({}) do |hash, line|
7
+ version, summary = line.split(/ - /, 2)
8
+ hash[version] = summary
9
+ hash
10
+ end
11
+ end
12
+
13
+ def tags
14
+ timefmt = '%Y-%m-%dT%H:%M:%SZ'
15
+ @tags ||= `git tag -l`.split(/\n/).map do |tag|
16
+ next if tag == "v0.0.0"
17
+ if %r{\Av[\d\.]+\z} =~ tag
18
+ header, subject, body = `git cat-file tag #{tag}`.split(/\n\n/, 3)
19
+ header = header.split(/\n/)
20
+ tagger = header.grep(/\Atagger /).first
21
+ body ||= "initial"
22
+ {
23
+ :time => Time.at(tagger.split(/ /)[-2].to_i).utc.strftime(timefmt),
24
+ :tagger_name => %r{^tagger ([^<]+)}.match(tagger)[1].strip,
25
+ :tagger_email => %r{<([^>]+)>}.match(tagger)[1].strip,
26
+ :id => `git rev-parse refs/tags/#{tag}`.chomp!,
27
+ :tag => tag,
28
+ :subject => subject,
29
+ :body => (old = old_summaries[tag]) ? "#{old}\n#{body}" : body,
30
+ }
31
+ end
32
+ end.compact.sort { |a,b| b[:time] <=> a[:time] }
33
+ end
34
+
35
+ cgit_url = "http://git.bogomips.org/cgit/unicorn.git"
36
+
37
+ desc 'prints news as an Atom feed'
38
+ task :news_atom do
39
+ require 'nokogiri'
40
+ new_tags = tags[0,10]
41
+ puts(Nokogiri::XML::Builder.new do
42
+ feed :xmlns => "http://www.w3.org/2005/Atom" do
43
+ id! "http://unicorn.bogomips.org/NEWS.atom.xml"
44
+ title "Unicorn news"
45
+ subtitle "Rack HTTP server for Unix and fast clients"
46
+ link! :rel => 'alternate', :type => 'text/html',
47
+ :href => 'http://unicorn.bogomips.org/NEWS.html'
48
+ updated new_tags.first[:time]
49
+ new_tags.each do |tag|
50
+ entry do
51
+ title tag[:subject]
52
+ updated tag[:time]
53
+ published tag[:time]
54
+ author {
55
+ name tag[:tagger_name]
56
+ email tag[:tagger_email]
57
+ }
58
+ url = "#{cgit_url}/tag/?id=#{tag[:tag]}"
59
+ link! :rel => "alternate", :type => "text/html", :href =>url
60
+ id! url
61
+ content({:type => 'text'}, tag[:body])
62
+ end
63
+ end
64
+ end
65
+ end.to_xml)
66
+ end
67
+
68
+ desc 'prints RDoc-formatted news'
69
+ task :news_rdoc do
70
+ tags.each do |tag|
71
+ time = tag[:time].tr!('T', ' ').gsub!(/:\d\dZ/, ' UTC')
72
+ puts "=== #{tag[:tag].sub(/^v/, '')} / #{time}"
73
+ puts ""
74
+
75
+ body = tag[:body]
76
+ puts tag[:body].gsub(/^/sm, " ").gsub(/[ \t]+$/sm, "")
77
+ puts ""
78
+ end
79
+ end
80
+
81
+ desc "print release changelog for Rubyforge"
82
+ task :release_changes do
83
+ version = ENV['VERSION'] or abort "VERSION= needed"
84
+ version = "v#{version}"
85
+ vtags = tags.map { |tag| tag[:tag] =~ /\Av/ and tag[:tag] }.sort
86
+ prev = vtags[vtags.index(version) - 1]
87
+ system('git', 'diff', '--stat', prev, version) or abort $?
88
+ puts ""
89
+ system('git', 'log', "#{prev}..#{version}") or abort $?
90
+ end
91
+
92
+ desc "print release notes for Rubyforge"
93
+ task :release_notes do
94
+ require 'rubygems'
95
+
96
+ git_url = ENV['GIT_URL'] || 'git://git.bogomips.org/unicorn.git'
97
+
98
+ spec = Gem::Specification.load('unicorn.gemspec')
99
+ puts spec.description.strip
100
+ puts ""
101
+ puts "* #{spec.homepage}"
102
+ puts "* #{spec.email}"
103
+ puts "* #{git_url}"
104
+
105
+ _, _, body = `git cat-file tag v#{spec.version}`.split(/\n\n/, 3)
106
+ print "\nChanges:\n\n"
107
+ puts body
108
+ end