From 8d1b95587c1ebea4631c66b8e7e4130153c70b26 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 17 Sep 2009 02:55:01 -0700 Subject: Remove Echoe and roll our own packaging/release... * Manifest/CHANGELOG can be maintainance is painful. I really hate having those in the source tree when I have a version control system that already: 1) encourages me to make meaningful commits 2) is highly scriptable for generating manifests/changelogs * hand-rolled gemspec allows more control for specifying pre-release gem versions * Less magic over what the `rubyforge` command does, being able to spawn $VISUAL on changelogs/release notes and make edits on them is nice. Additionally I still strongly prefer GNU make over Rake for many tasks since it offers better parallelization and some things are easier *for me* in shell than Ruby. --- .CHANGELOG.old | 25 ++++++++++ .gitignore | 2 + CHANGELOG | 25 ---------- GIT-VERSION-GEN | 40 ++++++++++++++++ GNUmakefile | 76 ++++++++++++++++++++++++++----- Manifest | 138 -------------------------------------------------------- Rakefile | 83 ++++++++++++++++++---------------- unicorn.gemspec | 46 +++++++++++++++++++ 8 files changed, 222 insertions(+), 213 deletions(-) create mode 100644 .CHANGELOG.old delete mode 100644 CHANGELOG create mode 100755 GIT-VERSION-GEN delete mode 100644 Manifest create mode 100644 unicorn.gemspec diff --git a/.CHANGELOG.old b/.CHANGELOG.old new file mode 100644 index 0000000..8326f53 --- /dev/null +++ b/.CHANGELOG.old @@ -0,0 +1,25 @@ +v0.91.0 - HTTP/0.9 support, multiline header support, small fixes +v0.90.0 - switch chunking+trailer handling to Ragel, v0.8.4 fixes +v0.9.2 - Ruby 1.9.2 preview1 compatibility +v0.9.1 - FD_CLOEXEC portability fix (v0.8.2 port) +v0.9.0 - bodies: "Transfer-Encoding: chunked", rewindable streaming +v0.8.4 - pass through unknown HTTP status codes +v0.8.3 - Ruby 1.9.2 preview1 compatibility +v0.8.2 - socket handling bugfixes and usability tweaks +v0.8.1 - safer timeout handling, more consistent reload behavior +v0.8.0 - enforce Rack dependency, minor performance improvements and fixes +v0.7.1 - minor fixes, cleanups and documentation improvements +v0.7.0 - rack.version is 1.0 +v0.6.0 - cleanups + optimizations, signals to {in,de}crement processes +v0.5.4 - fix data corruption with some small uploads (not curl) +v0.5.3 - fix 100% CPU usage when idle, small cleanups +v0.5.2 - force Status: header for compat, small cleanups +v0.5.1 - exit correctly on INT/TERM, QUIT is still recommended, however +v0.5.0 - {after,before}_fork API change, small tweaks/fixes +v0.4.2 - fix Rails ARStore, FD leak prevention, descriptive proctitles +v0.4.1 - Rails support, per-listener backlog and {snd,rcv}buf +v0.2.3 - Unlink Tempfiles after use (they were closed, just not unlinked) +v0.2.2 - small bug fixes, fix Rack multi-value headers (Set-Cookie:) +v0.2.1 - Fix broken Manifest that cause unicorn_rails to not be bundled +v0.2.0 - unicorn_rails launcher script. +v0.1.0 - Unicorn - UNIX-only fork of Mongrel free of threading diff --git a/.gitignore b/.gitignore index 1872bac..8a85024 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ pkg/ /vendor /NEWS /ChangeLog +/.manifest +/GIT-VERSION-FILE diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index 8326f53..0000000 --- a/CHANGELOG +++ /dev/null @@ -1,25 +0,0 @@ -v0.91.0 - HTTP/0.9 support, multiline header support, small fixes -v0.90.0 - switch chunking+trailer handling to Ragel, v0.8.4 fixes -v0.9.2 - Ruby 1.9.2 preview1 compatibility -v0.9.1 - FD_CLOEXEC portability fix (v0.8.2 port) -v0.9.0 - bodies: "Transfer-Encoding: chunked", rewindable streaming -v0.8.4 - pass through unknown HTTP status codes -v0.8.3 - Ruby 1.9.2 preview1 compatibility -v0.8.2 - socket handling bugfixes and usability tweaks -v0.8.1 - safer timeout handling, more consistent reload behavior -v0.8.0 - enforce Rack dependency, minor performance improvements and fixes -v0.7.1 - minor fixes, cleanups and documentation improvements -v0.7.0 - rack.version is 1.0 -v0.6.0 - cleanups + optimizations, signals to {in,de}crement processes -v0.5.4 - fix data corruption with some small uploads (not curl) -v0.5.3 - fix 100% CPU usage when idle, small cleanups -v0.5.2 - force Status: header for compat, small cleanups -v0.5.1 - exit correctly on INT/TERM, QUIT is still recommended, however -v0.5.0 - {after,before}_fork API change, small tweaks/fixes -v0.4.2 - fix Rails ARStore, FD leak prevention, descriptive proctitles -v0.4.1 - Rails support, per-listener backlog and {snd,rcv}buf -v0.2.3 - Unlink Tempfiles after use (they were closed, just not unlinked) -v0.2.2 - small bug fixes, fix Rack multi-value headers (Set-Cookie:) -v0.2.1 - Fix broken Manifest that cause unicorn_rails to not be bundled -v0.2.0 - unicorn_rails launcher script. -v0.1.0 - Unicorn - UNIX-only fork of Mongrel free of threading diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN new file mode 100755 index 0000000..366063e --- /dev/null +++ b/GIT-VERSION-GEN @@ -0,0 +1,40 @@ +#!/bin/sh + +GVF=GIT-VERSION-FILE +DEF_VER=v0.91.0.GIT + +LF=' +' + +# First see if there is a version file (included in release tarballs), +# then try git-describe, then default. +if test -f version +then + VN=$(cat version) || VN="$DEF_VER" +elif test -d .git -o -f .git && + VN=$(git describe --abbrev=4 HEAD 2>/dev/null) && + case "$VN" in + *$LF*) (exit 1) ;; + v[0-9]*) + git update-index -q --refresh + test -z "$(git diff-index --name-only HEAD --)" || + VN="$VN-dirty" ;; + esac +then + VN=$(echo "$VN" | sed -e 's/-/./g'); +else + VN="$DEF_VER" +fi + +VN=$(expr "$VN" : v*'\(.*\)') + +if test -r $GVF +then + VC=$(sed -e 's/^GIT_VERSION = //' <$GVF) +else + VC=unset +fi +test "$VN" = "$VC" || { + echo >&2 "GIT_VERSION = $VN" + echo "GIT_VERSION = $VN" >$GVF +} diff --git a/GNUmakefile b/GNUmakefile index 3d07600..bfce815 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,7 +3,13 @@ all:: test ruby = ruby rake = rake ragel = ragel +GIT_URL = $(shell git config --get remote.origin.url 2>/dev/null || \ + echo git://git.bogomips.org/unicorn.git) RLFLAGS = -G2 + +GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE + @./GIT-VERSION-GEN +-include GIT-VERSION-FILE -include local.mk ruby_bin := $(shell which $(ruby)) ifeq ($(DLEXT),) # "so" for Linux @@ -30,8 +36,9 @@ test_prefix = $(CURDIR)/test/install-$(RUBY_VERSION) ext := ext/unicorn_http c_files := $(ext)/unicorn_http.c $(wildcard $(ext)/*.h) -rl_files := $(addprefix $(ext)/,unicorn_http.rl unicorn_http_common.rl) -rb_files := $(shell grep '^\(bin\|lib\)' Manifest) +rl_files := $(wildcard $(ext)/*.rl) +bins := $(wildcard bin/*) +rb_files := $(bins) $(shell find lib -type f -name '*.rb') inst_deps := $(c_files) $(rb_files) ragel: $(ext)/unicorn_http.c @@ -49,13 +56,11 @@ http: lib/unicorn_http.$(DLEXT) $(test_prefix)/.stamp: $(inst_deps) mkdir -p $(test_prefix)/.ccache - tar c `cat Manifest` | (cd $(test_prefix) && tar x) + tar c `cat .manifest` | (cd $(test_prefix) && tar x) $(MAKE) -C $(test_prefix) clean $(MAKE) -C $(test_prefix) http shebang > $@ -bins := $(wildcard bin/*) - # this is only intended to be run within $(test_prefix) shebang: $(bins) $(ruby) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $^ @@ -124,17 +129,18 @@ clean: $(RM) $(setup_rb_files) $(t_log) $(RM) -r $(test_prefix) -Manifest: - (git ls-files && echo $(ext)/unicorn_http.c) | LC_ALL=C sort > $@+ +.manifest: GIT-VERSION-FILE NEWS ChangeLog $(ext)/unicorn_http.c + (git ls-files && \ + for i in $@ $^; do echo $$i; done) | LC_ALL=C sort > $@+ cmp $@+ $@ || mv $@+ $@ - $(RM) -f $@+ + $(RM) $@+ -NEWS: +NEWS: GIT-VERSION-FILE $(rake) -s history > $@+ mv $@+ $@ -ChangeLog: - @echo ChangeLog from git://git.bogomips.org/unicorn.git > $@+ +ChangeLog: GIT-VERSION-FILE + @echo "ChangeLog from $(GIT_URL) ($(GIT_VERSION))" > $@+ @echo >> $@+ git log | sed -e 's/^/ /' >> $@+ mv $@+ $@ @@ -164,4 +170,50 @@ $(T_r).%.r: export RAILS_GIT_REPO = $(CURDIR)/$(rails_git) $(T_r).%.r: $(test_prefix)/.stamp $(rails_git)/info/cloned-stamp $(run_test) -.PHONY: doc $(T) $(slow_tests) Manifest ChangeLog +ifneq ($(VERSION),) +rfproject := mongrel +rfpackage := unicorn +pkggem := pkg/$(rfpackage)-$(VERSION).gem +pkgtgz := pkg/$(rfpackage)-$(VERSION).tgz +release_notes := release_notes-$(VERSION) +release_changes := release_changes-$(VERSION) + +release-notes: $(release_notes) +release-changes: $(release_changes) +$(release_changes): + $(rake) -s release_changes > $@+ + $(VISUAL) $@+ && test -s $@+ && mv $@+ $@ +$(release_notes): + GIT_URL=$(GIT_URL) $(rake) -s release_notes > $@+ + $(VISUAL) $@+ && test -s $@+ && mv $@+ $@ +verify: + git rev-parse --verify refs/tags/v$(VERSION)^{} + git diff-index --quiet HEAD^0 + test `git rev-parse --verify HEAD^0` = \ + `git rev-parse --verify refs/tags/v$(VERSION)^{}` + +$(pkggem): .manifest + gem build $(rfpackage).gemspec + mkdir -p pkg + mv $(@F) $@ + +$(pkgtgz): distdir = $(basename $@) +$(pkgtgz): HEAD = v$(VERSION) +$(pkgtgz): .manifest + @test -n "$(distdir)" + $(RM) -r $(distdir) + git archive --format=tar --prefix=$(distdir)/ $(HEAD) | tar xv + install -m644 $^ $(distdir)/ + cd pkg && tar c $(basename $(@F)) | gzip -9 > $(@F)+ + mv $@+ $@ + +package: $(pkgtgz) $(pkggem) + +release: package $(release_notes) $(release_changes) + rubyforge add_release -f -n $(release_notes) -a $(release_changes) \ + $(rfproject) $(rfpackage) $(VERSION) $(pkggem) + rubyforge add_file \ + $(rfproject) $(rfpackage) $(VERSION) $(pkgtgz) +endif + +.PHONY: .FORCE-GIT-VERSION-FILE doc $(T) $(slow_tests) .manifest diff --git a/Manifest b/Manifest deleted file mode 100644 index 498094a..0000000 --- a/Manifest +++ /dev/null @@ -1,138 +0,0 @@ -.document -.gitignore -.mailmap -CHANGELOG -CONTRIBUTORS -COPYING -DESIGN -GNUmakefile -LICENSE -Manifest -PHILOSOPHY -README -Rakefile -SIGNALS -TODO -TUNING -bin/unicorn -bin/unicorn_rails -examples/echo.ru -examples/git.ru -examples/init.sh -ext/unicorn_http/c_util.h -ext/unicorn_http/common_field_optimization.h -ext/unicorn_http/ext_help.h -ext/unicorn_http/extconf.rb -ext/unicorn_http/global_variables.h -ext/unicorn_http/unicorn_http.c -ext/unicorn_http/unicorn_http.rl -ext/unicorn_http/unicorn_http_common.rl -lib/unicorn.rb -lib/unicorn/app/exec_cgi.rb -lib/unicorn/app/inetd.rb -lib/unicorn/app/old_rails.rb -lib/unicorn/app/old_rails/static.rb -lib/unicorn/cgi_wrapper.rb -lib/unicorn/configurator.rb -lib/unicorn/const.rb -lib/unicorn/http_request.rb -lib/unicorn/http_response.rb -lib/unicorn/launcher.rb -lib/unicorn/socket_helper.rb -lib/unicorn/tee_input.rb -lib/unicorn/util.rb -local.mk.sample -setup.rb -test/aggregate.rb -test/benchmark/README -test/benchmark/dd.ru -test/exec/README -test/exec/test_exec.rb -test/rails/app-1.2.3/.gitignore -test/rails/app-1.2.3/Rakefile -test/rails/app-1.2.3/app/controllers/application.rb -test/rails/app-1.2.3/app/controllers/foo_controller.rb -test/rails/app-1.2.3/app/helpers/application_helper.rb -test/rails/app-1.2.3/config/boot.rb -test/rails/app-1.2.3/config/database.yml -test/rails/app-1.2.3/config/environment.rb -test/rails/app-1.2.3/config/environments/development.rb -test/rails/app-1.2.3/config/environments/production.rb -test/rails/app-1.2.3/config/routes.rb -test/rails/app-1.2.3/db/.gitignore -test/rails/app-1.2.3/log/.gitignore -test/rails/app-1.2.3/public/404.html -test/rails/app-1.2.3/public/500.html -test/rails/app-2.0.2/.gitignore -test/rails/app-2.0.2/Rakefile -test/rails/app-2.0.2/app/controllers/application.rb -test/rails/app-2.0.2/app/controllers/foo_controller.rb -test/rails/app-2.0.2/app/helpers/application_helper.rb -test/rails/app-2.0.2/config/boot.rb -test/rails/app-2.0.2/config/database.yml -test/rails/app-2.0.2/config/environment.rb -test/rails/app-2.0.2/config/environments/development.rb -test/rails/app-2.0.2/config/environments/production.rb -test/rails/app-2.0.2/config/routes.rb -test/rails/app-2.0.2/db/.gitignore -test/rails/app-2.0.2/log/.gitignore -test/rails/app-2.0.2/public/404.html -test/rails/app-2.0.2/public/500.html -test/rails/app-2.1.2/.gitignore -test/rails/app-2.1.2/Rakefile -test/rails/app-2.1.2/app/controllers/application.rb -test/rails/app-2.1.2/app/controllers/foo_controller.rb -test/rails/app-2.1.2/app/helpers/application_helper.rb -test/rails/app-2.1.2/config/boot.rb -test/rails/app-2.1.2/config/database.yml -test/rails/app-2.1.2/config/environment.rb -test/rails/app-2.1.2/config/environments/development.rb -test/rails/app-2.1.2/config/environments/production.rb -test/rails/app-2.1.2/config/routes.rb -test/rails/app-2.1.2/db/.gitignore -test/rails/app-2.1.2/log/.gitignore -test/rails/app-2.1.2/public/404.html -test/rails/app-2.1.2/public/500.html -test/rails/app-2.2.2/.gitignore -test/rails/app-2.2.2/Rakefile -test/rails/app-2.2.2/app/controllers/application.rb -test/rails/app-2.2.2/app/controllers/foo_controller.rb -test/rails/app-2.2.2/app/helpers/application_helper.rb -test/rails/app-2.2.2/config/boot.rb -test/rails/app-2.2.2/config/database.yml -test/rails/app-2.2.2/config/environment.rb -test/rails/app-2.2.2/config/environments/development.rb -test/rails/app-2.2.2/config/environments/production.rb -test/rails/app-2.2.2/config/routes.rb -test/rails/app-2.2.2/db/.gitignore -test/rails/app-2.2.2/log/.gitignore -test/rails/app-2.2.2/public/404.html -test/rails/app-2.2.2/public/500.html -test/rails/app-2.3.3.1/.gitignore -test/rails/app-2.3.3.1/Rakefile -test/rails/app-2.3.3.1/app/controllers/application_controller.rb -test/rails/app-2.3.3.1/app/controllers/foo_controller.rb -test/rails/app-2.3.3.1/app/helpers/application_helper.rb -test/rails/app-2.3.3.1/config/boot.rb -test/rails/app-2.3.3.1/config/database.yml -test/rails/app-2.3.3.1/config/environment.rb -test/rails/app-2.3.3.1/config/environments/development.rb -test/rails/app-2.3.3.1/config/environments/production.rb -test/rails/app-2.3.3.1/config/routes.rb -test/rails/app-2.3.3.1/db/.gitignore -test/rails/app-2.3.3.1/log/.gitignore -test/rails/app-2.3.3.1/public/404.html -test/rails/app-2.3.3.1/public/500.html -test/rails/test_rails.rb -test/test_helper.rb -test/unit/test_configurator.rb -test/unit/test_http_parser.rb -test/unit/test_http_parser_ng.rb -test/unit/test_request.rb -test/unit/test_response.rb -test/unit/test_server.rb -test/unit/test_signals.rb -test/unit/test_socket_helper.rb -test/unit/test_tee_input.rb -test/unit/test_upload.rb -test/unit/test_util.rb diff --git a/Rakefile b/Rakefile index c5e45ba..27e750a 100644 --- a/Rakefile +++ b/Rakefile @@ -1,54 +1,61 @@ # -*- encoding: binary -*- -require 'rubygems' -require 'echoe' - -Echoe.new("unicorn") do |p| - p.summary = "Rack HTTP server for Unix, fast clients and nothing else" - p.author = "Eric Wong" - p.email = "normalperson@yhbt.net" - p.clean_pattern = ['ext/unicorn_http/*.{bundle,so,o,obj,pdb,lib,def,exp}', - 'lib/*.{bundle,so,o,obj,pdb,lib,def,exp}', - 'ext/unicorn_http/Makefile', - 'pkg', 'lib/*.bundle', '*.gem', - 'site/output', '.config', 'coverage', - 'test_*.log', 'log', 'doc'] - p.url = "http://unicorn.bogomips.org/" - p.ignore_pattern = /^(pkg|site|projects|doc|log)|CVS|\.log/ - p.need_tar_gz = false - p.need_tgz = true - p.dependencies = [ 'rack' ] - - p.extension_pattern = ["ext/**/extconf.rb"] - - # Eric hasn't bothered to figure out running exec tests properly - # from Rake, but Eric prefers GNU make to Rake for tests anyways... - p.test_pattern = [ 'test/unit/test*.rb' ] -end - -#### Ragel builder - -desc "Rebuild the Ragel sources" -task :ragel do - Dir.chdir "ext/unicorn_http" do - target = "unicorn_http.c" - File.unlink target if File.exist? target - sh "ragel unicorn_http.rl -C -G2 -o #{target}" - raise "Failed to build C source" unless File.exist? target - end -end +# most tasks are in the GNUmakefile which offers better parallelism desc 'prints RDoc-formatted history' task :history do tags = `git tag -l`.split(/\n/).grep(/^v[\d\.]+$/).reverse timefmt = '%Y-%m-%d %H:%M UTC' + + old_summaries = File.readlines(".CHANGELOG.old").inject({}) do |hash, line| + version, summary = line.split(/ - /, 2) + hash[version] = summary + hash + end + tags.each do |tag| header, subject, body = `git cat-file tag #{tag}`.split(/\n\n/, 3) tagger = header.split(/\n/).grep(/^tagger /).first.split(/\s/) time = Time.at(tagger[-2].to_i).utc puts "=== #{tag.sub(/^v/, '')} / #{time.strftime(timefmt)}" puts "" - puts body ? body.gsub(/^/sm, " ") : " initial" + + if old_summary = old_summaries[tag] + print " #{old_summary}\n" + end + + puts body ? body.gsub(/^/sm, " ").gsub(/[ \t]+$/sm, "") : " initial" puts "" end end + +desc "print release changelog for Rubyforge" +task :release_changes do + version = ENV['VERSION'] or abort "VERSION= needed" + version = "v#{version}" + tags = `git tag -l`.split(/\n/) + prev = tags[tags.index(version) - 1] + system('git', 'diff', '--stat', prev, version) or abort $? + puts "" + system('git', 'log', "#{prev}..#{version}") or abort $? +end + +desc "print release notes for Rubyforge" +task :release_notes do + require 'rubygems' + + git_url = ENV['GIT_URL'] || + `git config --get remote.origin.url 2>/dev/null`.chomp! || + 'git://git.bogomips.org/unicorn.git' + + spec = Gem::Specification.load('unicorn.gemspec') + puts spec.description.strip + puts "" + puts "* #{spec.homepage}" + puts "* #{spec.email}" + puts "* #{git_url}" + + _, _, body = `git cat-file tag v#{spec.version}`.split(/\n\n/, 3) + print "\nChanges:\n\n" + puts body +end diff --git a/unicorn.gemspec b/unicorn.gemspec new file mode 100644 index 0000000..c2e1a99 --- /dev/null +++ b/unicorn.gemspec @@ -0,0 +1,46 @@ +# -*- encoding: binary -*- + +ENV["VERSION"] or abort "VERSION= must be specified" +manifest = File.readlines('.manifest').map! { |x| x.chomp! } + +Gem::Specification.new do |s| + s.name = %q{unicorn} + s.version = ENV["VERSION"] + + s.authors = ["Eric Wong"] + s.date = Time.now.utc.strftime('%Y-%m-%d') + + s.description = %q{ +HTTP server for Rack applications designed to take advantage of features +in Unix/Unix-like operating systems and serve low-latency, high-bandwidth +clients (such as a buffering reverse proxy server). +}.strip + + s.email = %q{mongrel-unicorn@rubyforge.org} + s.executables = %w(unicorn unicorn_rails) + s.extensions = %w(ext/unicorn_http/extconf.rb) + + s.extra_rdoc_files = File.readlines('.document').map! do |x| + x.chomp! + if File.directory?(x) + manifest.grep(%r{\A#{x}/}) + elsif File.file?(x) + x + else + nil + end + end.flatten.compact + + s.files = manifest + s.homepage = %q{http://unicorn.bogomips.org/} + + s.rdoc_options = [ "-Na", "-t", + "Unicorn: Rack HTTP server for Unix and fast clients" ] + s.require_paths = %w(lib ext) + s.rubyforge_project = %q{mongrel} + s.summary = %q{Rack HTTP server for Unix and fast clients} + s.test_files = manifest.grep(%r{\Atest/unit/test_*\.rb\z}) + + s.add_dependency(%q) + s.licenses = %w(GPLv2 Ruby) +end -- cgit v1.2.3-24-ge0c7