diff options
author | Eric Wong <normalperson@yhbt.net> | 2010-04-28 12:42:48 -0700 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2010-04-28 12:42:48 -0700 |
commit | dd84d98bce03e3da529c4b51d2eba761dda749e8 (patch) | |
tree | c0e5b7d11443573957d0b7f15d47affdbccd7dcb | |
parent | e32c35bac78a7e7d8d711d360c143c9ebc64eed2 (diff) | |
download | kcar-dd84d98bce03e3da529c4b51d2eba761dda749e8.tar.gz |
-rw-r--r-- | .document | 5 | ||||
-rw-r--r-- | GNUmakefile | 9 | ||||
-rw-r--r-- | README | 22 | ||||
-rw-r--r-- | Rakefile | 149 | ||||
-rw-r--r-- | kcar.gemspec | 40 |
5 files changed, 213 insertions, 12 deletions
diff --git a/.document b/.document new file mode 100644 index 0000000..36f52ab --- /dev/null +++ b/.document @@ -0,0 +1,5 @@ +README +NEWS +ChangeLog +lib +ext/kcar/kcar.c diff --git a/GNUmakefile b/GNUmakefile index 982c577..59b3a73 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -35,7 +35,7 @@ clean: -$(MAKE) -C ext/kcar clean $(RM) $(setup_rb_files) ext/kcar/Makefile -pkg_extra := GIT-VERSION-FILE NEWS ChangeLog +pkg_extra := GIT-VERSION-FILE NEWS ChangeLog ext/kcar/kcar.c manifest: $(pkg_extra) $(RM) .manifest $(MAKE) .manifest @@ -71,14 +71,9 @@ atom = <link rel="alternate" title="Atom feed" href="$(1)" \ # using rdoc 2.4.1+ doc: .document NEWS ChangeLog - for i in $(man1_bins); do > $$i; done rdoc -Na -t "$(shell sed -ne '1s/^= //p' README)" install -m644 COPYING doc/COPYING install -m644 $(shell grep '^[A-Z]' .document) doc/ - cd doc && for i in $(base_bins); do \ - html=$$(echo $$i | sed 's/\.rb/_rb/')_1.html; \ - sed -e '/"documentation">/r man1/'$$i'.1.html' \ - < $$html > tmp && mv tmp $$html; done $(RUBY) -i -p -e \ '$$_.gsub!("</title>",%q{\&$(call atom,$(cgit_atom))})' \ doc/ChangeLog.html @@ -87,7 +82,6 @@ doc: .document NEWS ChangeLog doc/NEWS.html doc/README.html $(RAKE) -s news_atom > doc/NEWS.atom.xml cd doc && ln README.html tmp && mv tmp index.html - $(RM) $(man1_bins) ifneq ($(VERSION),) rfproject := rainbows @@ -169,7 +163,6 @@ $(ext): ext/kcar/kcar.c $(hdr) ext/kcar/Makefile all:: test -export STRESS BENCHMARK build: $(ext) test_units := $(wildcard test/test_*.rb) test: test-unit @@ -1,11 +1,25 @@ -= kcar - retrevnoc esnopser kcaR ot maertsetyb += kcar - bytestream to Rack response converter + +kcar features an HTTP parser that will convert a bytestream into a +3-element array suitable for use as a Rack response. It is IO interface +agnostic, so it may be used with HTTP streams over Unix domain sockets, +regular files, FIFOs, StringIOs as well as traditional TCP sockets. + +A drop-in, Net::HTTP-compatible interface is planned. == Features -* RFC2616-compliant Ragel/C HTTP parser adapted from Unicorn and Mongrel +* RFC2616-compliant Ragel+C parser adapted from Unicorn and Mongrel -* decodes chunked bodies +* decodes chunked response bodies with an optional pass-through mode + (to avoid rechunking with Rack::Chunked) * handles odd things like trailers and multiline headers -* streaming interface for response bodies for incremental processing +* streaming interface for response bodies allows for incremental + processing of arbitrarily large responses. + +== Problems + +* kcar is only lightly tested and is not yet aware of all quirks found in + all real (possibly broken) web servers. diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..24c16ca --- /dev/null +++ b/Rakefile @@ -0,0 +1,149 @@ +desc "read news article from STDIN and post to rubyforge" +task :publish_news do + require 'rubyforge' + IO.select([STDIN], nil, nil, 1) or abort "E: news must be read from stdin" + msg = STDIN.readlines + subject = msg.shift + blank = msg.shift + blank == "\n" or abort "no newline after subject!" + subject.strip! + body = msg.join("").strip! + + rf = RubyForge.new.configure + rf.login + rf.post_news('rainbows', subject, body) +end + +def tags + timefmt = '%Y-%m-%dT%H:%M:%SZ' + @tags ||= `git tag -l`.split(/\n/).map do |tag| + next if tag == "v0.0.0" + if %r{\Av[\d\.]+\z} =~ tag + header, subject, body = `git cat-file tag #{tag}`.split(/\n\n/, 3) + header = header.split(/\n/) + tagger = header.grep(/\Atagger /).first + body ||= "initial" + { + :time => Time.at(tagger.split(/ /)[-2].to_i).utc.strftime(timefmt), + :tagger_name => %r{^tagger ([^<]+)}.match(tagger)[1], + :tagger_email => %r{<([^>]+)>}.match(tagger)[1], + :id => `git rev-parse refs/tags/#{tag}`.chomp!, + :tag => tag, + :subject => subject, + :body => body, + } + end + end.compact.sort { |a,b| b[:time] <=> a[:time] } +end + +cgit_url = "http://git.bogomips.org/cgit/kcar.git" +git_url = ENV['GIT_URL'] || 'git://git.bogomips.org/kcar.git' + +desc 'prints news as an Atom feed' +task :news_atom do + require 'nokogiri' + new_tags = tags[0,10] + puts(Nokogiri::XML::Builder.new do + feed :xmlns => "http://www.w3.org/2005/Atom" do + id! "http://kcar.rubyforge.org/NEWS.atom.xml" + title "Kcar news" + subtitle File.readlines("README").first + link! :rel => 'alternate', :type => 'text/html', + :href => 'http://bogomips.org/kcar/' + updated new_tags.first[:time] + new_tags.each do |tag| + entry do + title tag[:subject] + updated tag[:time] + published tag[:time] + author { + name tag[:tagger_name] + email tag[:tagger_email] + } + url = "#{cgit_url}/tag/?id=#{tag[:tag]}" + link! :rel => "alternate", :type => "text/html", :href =>url + id! url + content(:type => 'text') { tag[:body] } + end + end + end + end.to_xml) +end + +desc 'prints RDoc-formatted news' +task :news_rdoc do + tags.each do |tag| + time = tag[:time].tr!('T', ' ').gsub!(/:\d\dZ/, ' UTC') + puts "=== #{tag[:tag].sub(/^v/, '')} / #{time}" + puts "" + + body = tag[:body] + puts tag[:body].gsub(/^/sm, " ").gsub(/[ \t]+$/sm, "") + puts "" + end +end + +desc "print release changelog for Rubyforge" +task :release_changes do + version = ENV['VERSION'] or abort "VERSION= needed" + version = "v#{version}" + vtags = tags.map { |tag| tag[:tag] =~ /\Av/ and tag[:tag] }.sort + prev = vtags[vtags.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' + + spec = Gem::Specification.load('kcar.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 + +desc "post to RAA" +task :raa_update do + require 'rubygems' + require 'net/http' + require 'net/netrc' + rc = Net::Netrc.locate('kcar-raa') or abort "~/.netrc not found" + password = rc.password + + s = Gem::Specification.load('kcar.gemspec') + desc = [ s.description.strip ] + desc << "" + desc << "* #{s.email}" + desc << "* #{git_url}" + desc << "* #{cgit_url}" + desc = desc.join("\n") + uri = URI.parse('http://raa.ruby-lang.org/regist.rhtml') + form = { + :name => s.name, + :short_description => s.summary, + :version => s.version.to_s, + :status => 'experimental', + :owner => s.authors.first, + :email => s.email, + :category_major => 'Library', + :category_minor => 'WWW', + :url => s.homepage, + :download => 'http://rubyforge.org/frs/?group_id=8977', + :license => "Ruby's", + :description_style => 'Plain', + :description => desc, + :pass => password, + :submit => 'Update', + } + res = Net::HTTP.post_form(uri, form) + p res + puts res.body +end diff --git a/kcar.gemspec b/kcar.gemspec new file mode 100644 index 0000000..7b1ac70 --- /dev/null +++ b/kcar.gemspec @@ -0,0 +1,40 @@ +ENV["VERSION"] or abort "VERSION= must be specified" +manifest = File.readlines('.manifest').map! { |x| x.chomp! } +summary = File.readlines("README")[0].gsub(/\A=\s+\S+[^\w]+/, '').strip +description = File.read("README").split(/\n\n/)[1].strip + +Gem::Specification.new do |s| + s.name = %q{kcar} + s.version = ENV["VERSION"] + + s.homepage = 'http://bogomips.org/kcar' + s.authors = ["kcar"] + s.date = Time.now.utc.strftime('%Y-%m-%d') + s.description = description + s.email = %q{kcar@librelist.com} + + 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.rdoc_options = [ + "-a", + "-t", + summary + ] + s.require_paths = %w(lib ext) + s.rubyforge_project = %q{rainbows} + s.summary = summary + s.test_files = Dir['test/test_*.rb'] + s.extensions = %w(ext/kcar/extconf.rb) + + # s.license = %w(GPL Ruby) # disabled for compatibility with older RubyGems +end |