Files | Admin

Notes:

Release Name: 0.93.0

Notes:
Unicorn is a HTTP server for Rack applications designed to take
advantage of features in Unix/Unix-like kernels and only serve fast
clients on low-latency, high-bandwidth connections.  Slow clients should
only be served by placing a reverse proxy capable of fully-buffering
both the the request and response in between Unicorn and slow clients.

* http://unicorn.bogomips.org/
* mongrel-unicorn@rubyforge.org
* git://git.bogomips.org/unicorn.git

Changes:

The one minor bugfix is only for Rails 2.3.x+ users who set the
RAILS_RELATIVE_URL_ROOT environment variable in a config file.
Users of the "--path" switch or those who set the environment
variable in the shell were unaffected by this bug.  Note that we
still don't have relative URL root support for Rails < 2.3, and
are unlikely to bother with it unless there is visible demand
for it.

New features includes support for :tries and :delay when
specifying a "listen" in an after_fork hook.  This was inspired
by Chris Wanstrath's example of binding per-worker listen
sockets in a loop while migrating (or upgrading) Unicorn.
Setting a negative value for :tries means we'll retry the listen
indefinitely until the socket becomes available.

So you can do something like this in an after_fork hook:

    after_fork do |server, worker|
      addr = "127.0.0.1:#{9293 + worker.nr}"
      server.listen(addr, :tries => -1, :delay => 5)
    end

There's also the usual round of added documentation, packaging
fixes, code cleanups, small fixes and minor performance
improvements that are viewable in the "git log" output.

Eric Wong (55):
      build: hardcode the canonical git URL
      build: manifest dropped manpages
      build: smaller ChangeLog
      doc/LATEST: remove trailing newline
      http: don't force -fPIC if it can't be used
      .gitignore on *.rbc files Rubinius generates
      README/gemspec: a better description, hopefully
      GNUmakefile: add missing .manifest dep on test installs
      Add HACKING document
      configurator: fix user switch example in RDoc
      local.mk.sample: time and perms enforcement
      unicorn_rails: show "RAILS_ENV" in help message
      gemspec: compatibility with older Rubygems
      Split out KNOWN_ISSUES document
      KNOWN_ISSUES: add notes about the "isolate" gem
      gemspec: fix test_files regexp match
      gemspec: remove tests that fork from test_files
      test_signals: ensure we can parse pids in response
      GNUmakefile: cleanup test/manifest generation
      util: remove APPEND_FLAGS constant
      http_request: simplify and remove handle_body method
      http_response: simplify and remove const dependencies
      local.mk.sample: fix .js times
      TUNING: notes about benchmarking a high :backlog
      HttpServer#listen accepts :tries and :delay parameters
      "make install" avoids installing multiple .so objects
      Use Configurator#expand_addr in HttpServer#listen
      configurator: move initialization stuff to #initialize
      Remove "Z" constant for binary strings
      cgi_wrapper: don't warn about stdoutput usage
      cgi_wrapper: simplify status handling in response
      cgi_wrapper: use Array#concat instead of +=
      server: correctly unset reexec_pid on child death
      configurator: update and modernize examples
      configurator: add colons in front of listen() options
      configurator: remove DEFAULT_LOGGER constant
      gemspec: clarify commented-out licenses section
      Add makefile targets for non-release installs
      cleanup: use question mark op for 1-byte comparisons
      RDoc for Unicorn::HttpServer::Worker
      small cleanup to pid file handling + documentation
      rails: RAILS_RELATIVE_URL_ROOT may be set in Unicorn config
      unicorn_rails: undeprecate --path switch
      manpages: document environment variables
      README: remove reference to different versions
      Avoid a small window when a pid file can be empty
      configurator: update some migration examples
      configurator: listen :delay must be Numeric
      test: don't rely on .manifest for test install
      SIGNALS: state that we stole semantics from nginx
      const: DEFAULT_PORT as a string doesn't make sense
      test_helper: unused_port rejects 8080 unconditionally
      GNUmakefile: SINCE variable may be unset
      tests: GIT-VERSION-GEN is a test install dependency
      unicorn 0.93.0



Changes: .document | 2 + .gitignore | 1 + Documentation/unicorn.1.txt | 9 ++ Documentation/unicorn_rails.1.txt | 19 +++++ GIT-VERSION-GEN | 2 +- GNUmakefile | 55 +++++++++---- HACKING | 113 +++++++++++++++++++++++++ KNOWN_ISSUES | 27 ++++++ README | 28 ++----- Rakefile | 4 +- SIGNALS | 5 +- TUNING | 9 ++- bin/unicorn_rails | 20 +++-- ext/unicorn_http/extconf.rb | 8 +- lib/unicorn.rb | 70 ++++++++++++---- lib/unicorn/app/exec_cgi.rb | 8 +- lib/unicorn/app/inetd.rb | 7 +- lib/unicorn/cgi_wrapper.rb | 14 +--- lib/unicorn/configurator.rb | 154 +++++++++++++++++++++++------------ lib/unicorn/const.rb | 4 +- lib/unicorn/http_request.rb | 27 ++---- lib/unicorn/http_response.rb | 54 ++++++------- lib/unicorn/socket_helper.rb | 2 +- lib/unicorn/tee_input.rb | 4 +- lib/unicorn/util.rb | 6 +- local.mk.sample | 9 ++- test/exec/test_exec.rb | 2 +- test/rails/app-2.3.3.1/public/x.txt | 1 + test/rails/test_rails.rb | 25 ++++++ test/test_helper.rb | 6 +- test/unit/test_configurator.rb | 30 +++++++ test/unit/test_signals.rb | 2 + unicorn.gemspec | 21 +++-- 33 files changed, 535 insertions(+), 213 deletions(-) commit 76207a66002f088c24423f66f71fa38460e706fc Author: Eric Wong Date: Fri Oct 2 13:50:46 2009 -0700 unicorn 0.93.0 The one minor bugfix is only for Rails 2.3.x+ users who set the RAILS_RELATIVE_URL_ROOT environment variable in a config file. Users of the "--path" switch or those who set the environment variable in the shell were unaffected by this bug. Note that we still don't have relative URL root support for Rails < 2.3, and are unlikely to bother with it unless there is visible demand for it. New features includes support for :tries and :delay when specifying a "listen" in an after_fork hook. This was inspired by Chris Wanstrath's example of binding per-worker listen sockets in a loop while migrating (or upgrading) Unicorn. Setting a negative value for :tries means we'll retry the listen indefinitely until the socket becomes available. So you can do something like this in an after_fork hook: after_fork do |server, worker| addr = "127.0.0.1:#{9293 + worker.nr}" server.listen(addr, :tries => -1, :delay => 5) end There's also the usual round of added documentation, packaging fixes, code cleanups, small fixes and minor performance improvements that are viewable in the "git log" output. Eric Wong (54): build: hardcode the canonical git URL build: manifest dropped manpages build: smaller ChangeLog doc/LATEST: remove trailing newline http: don't force -fPIC if it can't be used .gitignore on *.rbc files Rubinius generates README/gemspec: a better description, hopefully GNUmakefile: add missing .manifest dep on test installs Add HACKING document configurator: fix user switch example in RDoc local.mk.sample: time and perms enforcement unicorn_rails: show "RAILS_ENV" in help message gemspec: compatibility with older Rubygems Split out KNOWN_ISSUES document KNOWN_ISSUES: add notes about the "isolate" gem gemspec: fix test_files regexp match gemspec: remove tests that fork from test_files test_signals: ensure we can parse pids in response GNUmakefile: cleanup test/manifest generation util: remove APPEND_FLAGS constant http_request: simplify and remove handle_body method http_response: simplify and remove const dependencies local.mk.sample: fix .js times TUNING: notes about benchmarking a high :backlog HttpServer#listen accepts :tries and :delay parameters "make install" avoids installing multiple .so objects Use Configurator#expand_addr in HttpServer#listen configurator: move initialization stuff to #initialize Remove "Z" constant for binary strings cgi_wrapper: don't warn about stdoutput usage cgi_wrapper: simplify status handling in response cgi_wrapper: use Array#concat instead of += server: correctly unset reexec_pid on child death configurator: update and modernize examples configurator: add colons in front of listen() options configurator: remove DEFAULT_LOGGER constant gemspec: clarify commented-out licenses section Add makefile targets for non-release installs cleanup: use question mark op for 1-byte comparisons RDoc for Unicorn::HttpServer::Worker small cleanup to pid file handling + documentation rails: RAILS_RELATIVE_URL_ROOT may be set in Unicorn config unicorn_rails: undeprecate --path switch manpages: document environment variables README: remove reference to different versions Avoid a small window when a pid file can be empty configurator: update some migration examples configurator: listen :delay must be Numeric test: don't rely on .manifest for test install SIGNALS: state that we stole semantics from nginx const: DEFAULT_PORT as a string doesn't make sense test_helper: unused_port rejects 8080 unconditionally GNUmakefile: SINCE variable may be unset tests: GIT-VERSION-GEN is a test install dependency commit 0d41fa1cae20138d7215dd2ca18220c686539582 Author: Eric Wong Date: Fri Oct 2 13:49:41 2009 -0700 tests: GIT-VERSION-GEN is a test install dependency commit 5510698bbe765fc4d3fcdbc81a78d702895a05e9 Author: Eric Wong Date: Fri Oct 2 13:40:29 2009 -0700 GNUmakefile: SINCE variable may be unset Makes it easier for new projects with no tags yet to reuse this snippet. commit 65717ecbab432f4acd093d2efefd52bce66409d8 Author: Eric Wong Date: Fri Oct 2 13:35:29 2009 -0700 test_helper: unused_port rejects 8080 unconditionally Checking for addr to match the DEFAULT_HOST constant is wrong since having only 127.0.0.1:8080 will still prevent 0.0.0.0:8080 from being bound. commit cc6ffaf42307ab3bd072c58bd492fb5c5204e687 Author: Eric Wong Date: Fri Oct 2 13:30:58 2009 -0700 const: DEFAULT_PORT as a string doesn't make sense TCP ports are always integers, and it was always allowing a randomly-generated value of 8080 through in the unused_port method of test_helper. commit 66e9f47ee861ed69c57fc110a6d5b3d28f5e373a Author: Eric Wong Date: Fri Oct 2 11:29:44 2009 -0700 SIGNALS: state that we stole semantics from nginx commit eef8d4c4332078ce28959b4afc5870c71a820fdb Author: Eric Wong Date: Fri Oct 2 00:46:01 2009 -0700 test: don't rely on .manifest for test install This lets us run tests out-of-the-box on fresh checkouts and minimizes the overhead needed for creating/updating the test installs. commit d7381d2d96deeb95aac484780b38202b1a7d8115 Author: Eric Wong Date: Fri Oct 2 00:25:01 2009 -0700 configurator: listen :delay must be Numeric :delay may be a Float to represent fractional seconds. commit 62206b128f71f64a684a5e14103178dc6a516125 Author: Eric Wong Date: Fri Oct 2 00:25:00 2009 -0700 configurator: update some migration examples We now give an example of how a before_fork hook can be used to incrementally migrate off the old code base without hitting a thundering herd (especially in the "preload_app false") case. Also comment on the per-worker listen usage in the RDoc, not just a hidden comment. commit eb619c04765ef31b0e88329cbfd138d24558776e Author: Eric Wong Date: Thu Oct 1 13:21:57 2009 -0700 Avoid a small window when a pid file can be empty There's always been a small window of opportunity for a script to do File.read(pid).to_i would cause File.read() to read an empty file and return "". This closes that window while hopefully retaining backwards compatibility... We've always checked for dirname(pid) writability in Configurator, so we can safely write to a temporary file in the intended directory and then atomically rename() it to the destination path. commit 9dcbd1387c4c23c84f5a733b6e2e2839b239bdac Author: Eric Wong Date: Wed Sep 30 23:54:38 2009 -0700 README: remove reference to different versions The >= 0.90.x series has been working out pretty well so far with only a few minor bug fixes in between, so it'll be less confusing. commit a0384e6adeb4e9d072cc2fa39a47212ee784ecf8 Author: Eric Wong Date: Wed Sep 30 23:51:13 2009 -0700 manpages: document environment variables Mostly for `unicorn_rails`, but TMPDIR is universal. commit 6befcbc2457f6d6eebd836adc08ee34e696588bd Author: Eric Wong Date: Wed Sep 30 23:49:53 2009 -0700 unicorn_rails: undeprecate --path switch ..but keep -P deprecated. --path is still useful for testing ad-hoc changes when you don't want to commit your changes permanently to a configuration file. commit e87d9decb82fbbde50926911167fecebd4bcc25e Author: Eric Wong Date: Wed Sep 30 15:02:59 2009 -0700 rails: RAILS_RELATIVE_URL_ROOT may be set in Unicorn config Since Unicorn config files are written in Ruby, setting RAILS_RELATIVE_URL_ROOT should be possible (and even encouraged) in the config file if it is done at all. commit e417bd2d262f703212d4d671498420e554105639 Author: Eric Wong Date: Wed Sep 30 13:41:29 2009 -0700 small cleanup to pid file handling + documentation It's pointless to try and stat a file before trying to read it. Instead just try opening it and rescue ENOENT because it would've been racy anyways. Additionally add some comments to keep us from forgetting why we did the things we did with the pid file management. commit f3f43f1b6c3930525a892c8ce860f072184fe981 Author: Eric Wong Date: Wed Sep 30 13:41:28 2009 -0700 RDoc for Unicorn::HttpServer::Worker I'd rather document and maintain a stable interface for the Worker class than to have to deal with potential (portability and security) issues with with supporting user privilege management right now. There's already an example of user/group-switching support in the after_fork() hook and the error handling involved may be different depending on the application and environment so I remain hesitant to add official support for it... commit 407724b49069ee539e9a918ce75e9d1290552471 Author: Eric Wong Date: Wed Sep 30 13:41:27 2009 -0700 cleanup: use question mark op for 1-byte comparisons It's compatible with both Ruby 1.8 and 1.9 without needing a Range object. commit 9cc4f87353b84f5229d4a8bae78260c24cd02154 Author: Eric Wong Date: Wed Sep 30 13:41:26 2009 -0700 Add makefile targets for non-release installs This should make it easier to test and run unreleased versions. commit 31533ab442959f975306c4275daa6c6770d29246 Author: Eric Wong Date: Mon Sep 28 01:21:36 2009 -0700 gemspec: clarify commented-out licenses section It may have caused confusion that the licenses we're under were incompatible with older Rubygems which is not the case. commit aafc9bf7f051c6f2fb0047647d4ed26b3a825ea3 Author: Eric Wong Date: Mon Sep 28 00:15:35 2009 -0700 configurator: remove DEFAULT_LOGGER constant We no longer have external lookups for it so just stick it in the DEFAULTS hash for now. Since the Configurator::DEFAULTS hash can be considered a stable interface for other modules to interact with, they can eventually just use it instead of relying on another constant. commit 69b6f9aaec80f3da2f9d249545c06ccb6ec316cb Author: Eric Wong Date: Mon Sep 28 00:13:12 2009 -0700 configurator: add colons in front of listen() options Hopefuly make it more obvious that they're Ruby symbols and not strings. While we're at it, fix ordering of :{rcv,snd}buf descriptions to (logically) match the order of mention. commit 3c1449df986387f6d812a97adf5f8fa47c28c891 Author: Eric Wong Date: Mon Sep 28 00:03:46 2009 -0700 configurator: update and modernize examples * Use the new :tries and :default parameters for listen() instead of the ugly and less-effective "rescue nil" * ActiveRecord connection management examples for hooks when using for "preload_app true" * combine "preload_app true" example with REE COW-friendly optimization for memory savings Some of these are based on Chris Wanstrath's configuration posted here: http://gist.github.com/189623 commit 762db4854c06196b8941fe9fb303280429fe4cdc Author: Eric Wong Date: Sun Sep 27 23:47:57 2009 -0700 server: correctly unset reexec_pid on child death Sometimes the upgraded version won't survive and we can fail to unset that pid and instead accidentally create a local variable. This is unlikely to be a problem in practice because this variable is immediately reclobbered when we fork. commit 2f1155794a6a1709f9e48b8115d6bd3531b2d814 Author: Eric Wong Date: Sun Sep 27 23:23:20 2009 -0700 cgi_wrapper: use Array#concat instead of += Array#concat avoids an intermediate Array object from being allocated (yes, still supporting Rails <= 1.2.x apps...) commit 9d27c9a2ee7902788e0f8abc433c7da6302e4c24 Author: Eric Wong Date: Sun Sep 27 23:16:15 2009 -0700 cgi_wrapper: simplify status handling in response Our HttpResponse class interprets non-Integer string status now as well as falling back if it can't be looked up. commit 6d7230207e43bf8a6f6bdbe505fb05fbd70389ac Author: Eric Wong Date: Sun Sep 27 23:11:32 2009 -0700 cgi_wrapper: don't warn about stdoutput usage It really shouldn't be a problem for existing CGI apps to write to the StringIO object.. commit 79c270990ec3a657c23510ee4f2f7f2b4c2c748f Author: Eric Wong Date: Sun Sep 27 20:48:20 2009 -0700 Remove "Z" constant for binary strings We've started using magic comments to ensure any strings we create are binary instead. Additionally, ensure we create any StringIO objects with an explicit string (which default to binary) to ensure the StringIO object is binary. This is because StringIO.new (with no arguments) will always use the process-wide default encoding since it does not know about magic comments (and couldn't, really...) commit 3b0fcbf8baafbb88b2f15631b949fde9c8acff3b Author: Eric Wong Date: Sun Sep 27 19:33:21 2009 -0700 configurator: move initialization stuff to #initialize Avoids making the #listen method any noisier than it should be. commit 23fcda1c47db663ab8b809dc1dcae2726709dcc5 Author: Eric Wong Date: Sun Sep 27 19:18:19 2009 -0700 Use Configurator#expand_addr in HttpServer#listen This may be redundant for the "normal" configuration file directive, but allows the same syntax to be used in after_fork hooks where HttpServer#listen() may be called. commit 134a0b59c87a0f42653ca4bce8900a3cb1144ca9 Author: Eric Wong Date: Sun Sep 27 19:02:44 2009 -0700 "make install" avoids installing multiple .so objects Sometimes we test with unicorn_http.so in lib, but that gets mistakenly picked up by setup.rb and can wreak havoc for on upgrades if ABIs change. commit aa83722ab57fe05ac88164cfac949bb13c4aa7a5 Author: Eric Wong Date: Sun Sep 27 18:09:28 2009 -0700 HttpServer#listen accepts :tries and :delay parameters This allows per-worker listeners to be configured to retry and and not continue until the equivalent worker belonging to a previous master (or even another server) has released the socket. In the Configurator RDoc, include better examples for per-worker server.listen calls using these :tries == -1. Inspired by an example by Chris Wanstrath. commit 7774d770f0021e25a644e85ad404e8acb7b81afc Author: Eric Wong Date: Sun Sep 27 18:01:53 2009 -0700 TUNING: notes about benchmarking a high :backlog Based on the experiences of Tom Preston-Werner: http://thread.gmane.org/gmane.comp.lang.ruby.unicorn.general/24/focus=28 commit 3c873b25891b6aa3c46b29026dc8c4011dd18bc7 Author: Eric Wong Date: Sun Sep 27 17:31:04 2009 -0700 local.mk.sample: fix .js times Also make files easier to overwrite while we're at it commit 32d5db4f499dbbe3e9026969eee66592800dd725 Author: Eric Wong Date: Sun Sep 27 17:27:01 2009 -0700 http_response: simplify and remove const dependencies We don't need the Z constant anymore and inlining the header writing gives a small overall performance improvement in microbenchmarks. This also makes this method reentrant and thread-safe for Rainbows as well. commit 8e1f0620e567cd676902e4ed34edb042f28ec3b0 Author: Eric Wong Date: Sun Sep 27 17:26:59 2009 -0700 http_request: simplify and remove handle_body method It is simpler and even slightly faster in micro benchmarks when inlined. commit 0d43e19396a325ac9fe8b6c0a6031c87c0202697 Author: Eric Wong Date: Sun Sep 27 17:26:57 2009 -0700 util: remove APPEND_FLAGS constant One less thing to RDoc commit dd400a46dc101bb679e173e37e79fa31d96b8acf Author: Eric Wong Date: Sun Sep 27 17:26:56 2009 -0700 GNUmakefile: cleanup test/manifest generation The .manifest dependencies were causing unnecessarily copies for the tests to run. commit 0c3ec1aca5ad3b6f687ecdc75f193e2a0f0ae4a1 Author: Eric Wong Date: Sun Sep 27 17:26:54 2009 -0700 test_signals: ensure we can parse pids in response We don't want to accidentally kill every process in the process group. commit 9c00824720ec9be3b13ac8d66175e063c28885f0 Author: Eric Wong Date: Sun Sep 27 17:26:51 2009 -0700 gemspec: remove tests that fork from test_files This allows `gem check -t unicorn` to work. The rest of the tests run with GNU make but I don't have the patience to get them working with pure-Ruby since I can't stand running those tests sequentially anyways. commit 68df54e341a118b6658cfe0dcd2ff9b006883d20 Author: Eric Wong Date: Sun Sep 27 17:26:48 2009 -0700 gemspec: fix test_files regexp match Not sure if anybody runs tests with Rubygems directly (instead of unpacking the source tree, but it's there) commit 899bee1fe5eb01efbadc44a00eed71358e77141b Author: Eric Wong Date: Thu Sep 24 18:33:26 2009 -0700 KNOWN_ISSUES: add notes about the "isolate" gem This issue is still being looked at, but hopefully this note can help folks if they run into this. commit 554a4f63b8e0571bbd15d2b99637952da4b8f881 Author: Eric Wong Date: Thu Sep 24 17:20:37 2009 -0700 Split out KNOWN_ISSUES document This deserves to be a separate document and easier to find/edit. commit 39dbbc97fbbf04c6b7ba956e71648222589beb44 Author: Eric Wong Date: Thu Sep 24 13:37:56 2009 -0700 gemspec: compatibility with older Rubygems "licenses=" is not in older Rubygems and some organizations are still stuck on those... commit 5a87a2630ec15ab8e730a2bf3bf03c6fd84ff4a2 Author: Eric Wong Date: Thu Sep 24 13:33:19 2009 -0700 unicorn_rails: show "RAILS_ENV" in help message This matches the manpage and the rest of the documentation. commit dbf7eb6748d5b7ea8d2f309748756ffc336ba484 Author: Eric Wong Date: Tue Sep 22 11:40:01 2009 -0700 local.mk.sample: time and perms enforcement commit 3ac1670c870cf26a6e578c880151c49b7b289a82 Author: Eric Wong Date: Tue Sep 22 11:30:06 2009 -0700 configurator: fix user switch example in RDoc We changed this in 97e469fc3afb751618b8b9a7b364cb447aaf90dd but never updated the example. commit 2730d875650ee8c3121d457743419dce7ce69aef Author: Eric Wong Date: Sat Sep 19 19:01:03 2009 -0700 Add HACKING document commit 179dec40d0760c2456d1f3e7b94dda5073d5b0a4 Author: Eric Wong Date: Fri Sep 18 17:32:45 2009 -0700 GNUmakefile: add missing .manifest dep on test installs Now tests run after a clean checkout (as long as rack libraries are in $LOAD_PATH, probably via RUBYLIB). commit ce2602376cf586e68d11174004539609de6fa6b0 Author: Eric Wong Date: Fri Sep 18 16:59:44 2009 -0700 README/gemspec: a better description, hopefully commit 14709a4e306aec175cadd88ddcabe599f4636ed5 Author: Eric Wong Date: Fri Sep 18 16:41:04 2009 -0700 .gitignore on *.rbc files Rubinius generates commit 4f58f4a4d60806af7233193852be134cb74c7c21 Author: Eric Wong Date: Fri Sep 18 16:39:15 2009 -0700 http: don't force -fPIC if it can't be used Not everybody can use it, even if most of the world can. commit 413322fa1851917b749383e9207d16ba58274f59 Author: Eric Wong Date: Fri Sep 18 16:00:11 2009 -0700 doc/LATEST: remove trailing newline Make finger output as meaningful as possible to folks on slower connections and small terminals commit b3fb60334bbb62bbcc62348128bd4b3897bd2ad5 Author: Eric Wong Date: Fri Sep 18 15:25:12 2009 -0700 build: smaller ChangeLog No need to bloat our tarballs too much with information people are unlikely to ever read, NEWS is more user-oriented. commit 3bdcb9c6b1852448d3b47fbb46cf6c65b3227477 Author: Eric Wong Date: Fri Sep 18 14:57:18 2009 -0700 build: manifest dropped manpages $(wildcard) is evaluated as soon as the target command is called, resulting in the manpages not being globbed since we just generated them. Also, bundle manpages with documentation. commit f1e3d4a3828c377ef19f1f3d754457221c200bc4 Author: Eric Wong Date: Fri Sep 18 14:51:22 2009 -0700 build: hardcode the canonical git URL I just distributed a tarball with my local FS path in the documentation :(