From ddbc6236c1cbda79ff0606166137fa2c37b7e2b0 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 26 Jun 2010 08:14:21 +0000 Subject: [PATCH] fixup packaging Switch to the same system used by some of my other projects, which includes Atom feeds and Freshmeat/RAA updating. --- .document | 9 ++- .gitignore | 12 +++ LICENSE.txt => COPYING | 0 GIT-VERSION-GEN | 40 ++++++++++ GNUmakefile | 164 ++++++++++++++++++++++++++++++++++++----- History.txt | 7 -- LICENSE | 5 ++ Manifest.txt | 10 --- README.txt => README | 25 ++++--- Rakefile | 195 ++++++++++++++++++++++++++++++++++++++++++++++--- lib/local_openid.rb | 3 +- local-openid.gemspec | 34 +++++++++ 12 files changed, 439 insertions(+), 65 deletions(-) rename LICENSE.txt => COPYING (100%) create mode 100755 GIT-VERSION-GEN rewrite GNUmakefile (62%) delete mode 100644 History.txt create mode 100644 LICENSE delete mode 100644 Manifest.txt rename README.txt => README (82%) rewrite Rakefile (98%) create mode 100644 local-openid.gemspec diff --git a/.document b/.document index 34f4172..956b42d 100644 --- a/.document +++ b/.document @@ -1,4 +1,5 @@ -History.txt -LICENSE.txt -README.txt -bin/local-openid +NEWS +LICENSE +ChangeLog +README +lib/ diff --git a/.gitignore b/.gitignore index b6fc95d..5b6817b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,14 @@ pkg doc +*.rbc +/.config +/InstalledFiles +/doc +pkg/ +/NEWS +/ChangeLog +/.manifest +/GIT-VERSION-FILE +/man +tags +TAGS diff --git a/LICENSE.txt b/COPYING similarity index 100% rename from LICENSE.txt rename to COPYING diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN new file mode 100755 index 0000000..e36125a --- /dev/null +++ b/GIT-VERSION-GEN @@ -0,0 +1,40 @@ +#!/bin/sh + +GVF=GIT-VERSION-FILE +DEF_VER=v0.2.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 dissimilarity index 62% index 531f07a..b20efba 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,19 +1,145 @@ -all: - -publish_doc: - -git set-file-times - $(MAKE) doc - $(MAKE) doc_gz - rsync -av --delete doc/ dcvr:/srv/bogomips/local-openid/ - git ls-files | xargs touch - -doc: .document - rdoc -Na -m README.txt -t "$(shell sed -ne '1s/^= //p' README.txt)" - -# Create gzip variants of the same timestamp as the original so nginx -# "gzip_static on" can serve the gzipped versions directly. -doc_gz: suf := html js css -doc_gz: globs := $(addprefix doc/*.,$(suf)) $(addprefix doc/*/*.,$(suf)) -doc_gz: docs := $(wildcard $(globs)) -doc_gz: - for i in $(docs); do gzip < $$i > $$i.gz; touch -r $$i $$i.gz; done +all:: +RUBY = ruby +RAKE = rake +RSYNC = rsync +GIT_URL = git://git.bogomips.org/local-openid.git + +GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE + @./GIT-VERSION-GEN +-include GIT-VERSION-FILE + +pkg_extra := GIT-VERSION-FILE NEWS ChangeLog +manifest: $(pkg_extra) + $(RM) .manifest + $(MAKE) .manifest + +.manifest: + (git ls-files && \ + for i in $@ $(pkg_extra) $(man1_paths); \ + do echo $$i; done) | LC_ALL=C sort > $@+ + cmp $@+ $@ || mv $@+ $@ + $(RM) $@+ + +NEWS: GIT-VERSION-FILE + $(RAKE) -s news_rdoc > $@+ + mv $@+ $@ + +SINCE = 0.1.0 +ChangeLog: LOG_VERSION = \ + $(shell git rev-parse -q "$(GIT_VERSION)" >/dev/null 2>&1 && \ + echo $(GIT_VERSION) || git describe) +ifneq ($(SINCE),) +ChangeLog: log_range = v$(SINCE)..$(LOG_VERSION) +endif +ChangeLog: GIT-VERSION-FILE + @echo "ChangeLog from $(GIT_URL) ($(log_range))" > $@+ + @echo >> $@+ + git log $(log_range) | sed -e 's/^/ /' >> $@+ + mv $@+ $@ + +news_atom := http://bogomips.org/local-openid/NEWS.atom.xml +cgit_atom := http://git.bogomips.org/cgit/local-openid.git/atom/?h=master +atom = + +doc: .document NEWS ChangeLog + find bin lib -type f -name '*.rbc' -exec rm -f '{}' ';' + rdoc -a -t "$(shell sed -ne '1s/^= //p' README)" + install -m644 COPYING doc/COPYING + install -m644 $(shell grep '^[A-Z]' .document) doc/ + $(RUBY) -i -p -e \ + '$$_.gsub!("",%q{\&$(call atom,$(cgit_atom))})' \ + doc/ChangeLog.html + $(RUBY) -i -p -e \ + '$$_.gsub!("",%q{\&$(call atom,$(news_atom))})' \ + doc/NEWS.html doc/README.html + $(RAKE) -s news_atom > doc/NEWS.atom.xml + cd doc && ln README.html tmp && mv tmp index.html + +publish_doc: + -git set-file-times + $(RM) -r doc ChangeLog NEWS + $(MAKE) doc LOG_VERSION=$(shell git tag -l | tail -1) + @awk 'BEGIN{RS="=== ";ORS=""}NR==2{sub(/\n$$/,"");print RS""$$0 }' \ + < NEWS > doc/LATEST + find doc/images doc/js -type f | \ + TZ=UTC xargs touch -d '1970-01-01 00:00:00' doc/rdoc.css + $(MAKE) doc_gz + chmod 644 $$(find doc -type f) + $(RSYNC) -av --delete doc/ bogomips.org:/srv/bogomips/local-openid/ + git ls-files | xargs touch + +ifneq ($(VERSION),) +rfproject := qrp +rfpackage := local-openid +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 $@+ $@ + +# ensures we're actually on the tagged $(VERSION), only used for release +verify: + test x"$(shell umask)" = x0022 + 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)^{}` + +fix-perms: + -git ls-tree -r HEAD | awk '/^100644 / {print $$NF}' | xargs chmod 644 + -git ls-tree -r HEAD | awk '/^100755 / {print $$NF}' | xargs chmod 755 + +gem: $(pkggem) + +install-gem: $(pkggem) + gem install $(CURDIR)/$< + +$(pkggem): manifest fix-perms + gem build $(rfpackage).gemspec + mkdir -p pkg + mv $(@F) $@ + +$(pkgtgz): distdir = $(basename $@) +$(pkgtgz): HEAD = v$(VERSION) +$(pkgtgz): manifest fix-perms + @test -n "$(distdir)" + $(RM) -r $(distdir) + mkdir -p $(distdir) + tar cf - `cat .manifest` | (cd $(distdir) && tar xf -) + cd pkg && tar c $(basename $(@F)) | gzip -9 > $(@F)+ + mv $@+ $@ + +package: $(pkgtgz) $(pkggem) + +test-release: verify package $(release_notes) $(release_changes) +release: verify package $(release_notes) $(release_changes) + # make tgz release on RubyForge + rubyforge add_release -f -n $(release_notes) -a $(release_changes) \ + $(rfproject) $(rfpackage) $(VERSION) $(pkgtgz) + # push gem to Gemcutter + gem push $(pkggem) + # in case of gem downloads from RubyForge releases page + -rubyforge add_file \ + $(rfproject) $(rfpackage) $(VERSION) $(pkggem) +else +gem install-gem: GIT-VERSION-FILE + $(MAKE) $@ VERSION=$(GIT_VERSION) +endif + +# Create gzip variants of the same timestamp as the original so nginx +# "gzip_static on" can serve the gzipped versions directly. +doc_gz: docs = $(shell find doc -type f ! -regex '^.*\.\(gif\|jpg\|png\|gz\)$$') +doc_gz: + touch doc/NEWS.atom.xml -d "$$(awk 'NR==1{print $$4,$$5,$$6}' NEWS)" + for i in $(docs); do \ + gzip --rsyncable -9 < $$i > $$i.gz; touch -r $$i $$i.gz; done +.PHONY: .FORCE-GIT-VERSION-FILE doc manifest diff --git a/History.txt b/History.txt deleted file mode 100644 index 9ec159b..0000000 --- a/History.txt +++ /dev/null @@ -1,7 +0,0 @@ -=== 0.1.1 / 2009-04-06 - -* add Sinatra dependency - -=== 0.1.0 / 2009-04-04 - -* initial diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d796ed9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,5 @@ +local-openid is copyrighted free software by all contributors, see logs +in revision control for names and email addresses of all of them. You +can redistribute it and/or modify it under either the terms of the GNU +Affero General Public License, version 3. See the link:COPYING file +for details. diff --git a/Manifest.txt b/Manifest.txt deleted file mode 100644 index 3715975..0000000 --- a/Manifest.txt +++ /dev/null @@ -1,10 +0,0 @@ -.document -.gitignore -GNUmakefile -History.txt -LICENSE.txt -Manifest.txt -README.txt -Rakefile -bin/local-openid -setup.rb diff --git a/README.txt b/README similarity index 82% rename from README.txt rename to README index 5286175..b8def5e 100644 --- a/README.txt +++ b/README @@ -1,9 +1,5 @@ = local-openid: Single User, Ephemeral OpenID Provider -* http://bogomips.org/local-openid - -== Description - local-openid allows users with shell accounts on servers to authenticate with OpenID consumers by editing a YAML file in their home directory instead of authenticating through HTTP/HTTPS. @@ -43,17 +39,26 @@ setup.rb is also provided for non-Rubygems users. == Requirements local-openid is a small Sinatra application. It requires the Ruby -OpenID library (2.x), Sinatra (0.9+), Rack (0.9+), and any Rack-enabled +OpenID library (2.x), Sinatra (1.0), Rack and any Rack-enabled server. To be useful, it also depends on having a user account on a machine with a publically-accessible IP and DNS name to use as your OpenID identity. +"local-openid" should be installed in your $PATH by RubyGems. +It is a Sinatra application and takes all the usual command-line +arguments. Run "local-openid -h" for help. + == Hacking I don't have any plans for more development with local-openid. It was after all, just a weekend hack. It does what I want it to and nothing more. +You can use the {mailing list}[mailto:local.openid@librelist.com] to +share ideas, patches, pull requests with other users. Remember, I +wrote local-openid because I find the web difficult to use. So I'll +only accept communication about local-openid via email :) + Feel free to fork it and customize it to your needs. Of course, drop me a line if you fix any bugs or notice any security holes in it. @@ -69,11 +74,6 @@ You may browse the code from the web and download the latest tarballs here: * http://git.bogomips.org/cgit/local-openid.git * http://repo.or.cz/w/local-openid.git (gitweb mirror) -== License - -Copyright 2009 Eric Wong. It is licensed under the GNU Affero General -Public License, version 3. See the LICENSE file for details. - == Disclaimer There is NO WARRANTY whatsoever, implied or otherwise. OpenID may not @@ -84,5 +84,6 @@ credentials when your provider implementation has 99.999% downtime :) == Contact -Eric Wong, normalperson@yhbt.net -OpenID: http://e.yhbt.net/ +* Original author: Eric Wong, normalperson@yhbt.net +* OpenID: http://e.yhbt.net/ +* mailing list: local.openid@librelist.com diff --git a/Rakefile b/Rakefile dissimilarity index 98% index 16fd51a..3f4b240 100644 --- a/Rakefile +++ b/Rakefile @@ -1,12 +1,183 @@ -require 'rubygems' -require 'hoe' - -readme = File.readlines('README.txt') - -Hoe.new('local-openid', '0.1.1') do |p| - p.rubyforge_name = 'qrp' - p.developer('Eric Wong', 'normalperson@yhbt.net') - p.summary = readme[0].split(/\s*:\s*/)[1] - p.url = 'http://bogomips.org/local-openid' - p.extra_deps << [ 'sinatra', '>= 0.9' ] -end +# -*- encoding: binary -*- +autoload :Gem, 'rubygems' + +def tags + timefmt = '%Y-%m-%dT%H:%M:%SZ' + @tags ||= `git tag -l`.split(/\n/).map do |tag| + 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].strip, + :tagger_email => %r{<([^>]+)>}.match(tagger)[1].strip, + :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/local-openid.git" +git_url = ENV['GIT_URL'] || 'git://git.bogomips.org/local-openid.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://bogomips.org/local-openid/NEWS.atom.xml" + title "local-openid news" + subtitle %q{Single User, Ephemeral OpenID Provider} + link! :rel => 'alternate', :type => 'text/html', + :href => 'http://bogomips.org/local-openid/NEWS.html' + updated(new_tags.empty? ? "1970-01-01T00:00:00Z" : 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 + message_only = tag[:body].split(/\n.+\(\d+\):\n {6}/s).first.strip + content({:type =>:text}, message_only) + content(:type =>:xhtml) { pre 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] + if prev + system('git', 'diff', '--stat', prev, version) or abort $? + puts "" + system('git', 'log', "#{prev}..#{version}") or abort $? + else + system('git', 'log', version) or abort $? + end +end + +desc "print release notes for Rubyforge" +task :release_notes do + spec = Gem::Specification.load('local-openid.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 "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('qrp', subject, body) +end + +desc "post to RAA" +task :raa_update do + require 'net/http' + require 'net/netrc' + rc = Net::Netrc.locate('local-openid-raa') or abort "~/.netrc not found" + password = rc.password + + s = Gem::Specification.load('local-openid.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 => 'stable', + :owner => s.authors.first, + :email => s.email, + :category_major => 'Application', + :category_minor => 'WWW', + :url => s.homepage, + :download => 'http://rubyforge.org/frs/?group_id=5626', + :license => "OpenSource", # AGPLv3, specifically + :description_style => 'Plain', + :description => desc, + :pass => password, + :submit => "Update", + } + res = Net::HTTP.post_form(uri, form) + p res + puts res.body +end + +desc "post to FM" +task :fm_update do + require 'tempfile' + require 'net/http' + require 'net/netrc' + require 'json' + version = ENV['VERSION'] or abort "VERSION= needed" + uri = URI.parse('http://freshmeat.net/projects/local-openid/releases.json') + rc = Net::Netrc.locate('local-openid-fm') or abort "~/.netrc not found" + api_token = rc.password + changelog = tags.find { |t| t[:tag] == "v#{version}" }[:body] + tmp = Tempfile.new('fm-changelog') + tmp.syswrite(changelog) + system(ENV["VISUAL"], tmp.path) or abort "#{ENV["VISUAL"]} failed: #$?" + changelog = File.read(tmp.path).strip + + req = { + "auth_code" => api_token, + "release" => { + "tag_list" => "Stable", + "version" => version, + "changelog" => changelog, + }, + }.to_json + Net::HTTP.start(uri.host, uri.port) do |http| + p http.post(uri.path, req, {'Content-Type'=>'application/json'}) + end +end diff --git a/lib/local_openid.rb b/lib/local_openid.rb index 34ff753..3d87d5f 100644 --- a/lib/local_openid.rb +++ b/lib/local_openid.rb @@ -2,7 +2,7 @@ # a YAML file on the server where this application runs # (~/.local-openid/config.yml by default) instead of via HTTP/HTTPS # form authentication in the browser. - +#:stopdoc: require 'tempfile' require 'time' require 'yaml' @@ -299,3 +299,4 @@ class LocalOpenID < Sinatra::Base err("Lock: #{lock} exists! Possible hijacking attempt") rescue nil end end +#:startdoc: diff --git a/local-openid.gemspec b/local-openid.gemspec new file mode 100644 index 0000000..ac16906 --- /dev/null +++ b/local-openid.gemspec @@ -0,0 +1,34 @@ +ENV["VERSION"] or abort "VERSION= must be specified" +manifest = File.readlines('.manifest').map! { |x| x.chomp! } + +Gem::Specification.new do |s| + s.name = %q{local-openid} + s.version = ENV["VERSION"] + + s.authors = ["Eric Wong"] + s.date = Time.now.utc.strftime('%Y-%m-%d') + s.description = File.read("README").split(/\n\n/)[1] + s.email = %q{local-openid@librelist.com} + s.executables = %w(local-openid) + + 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://bogomips.org/local-openid/} + s.summary = %q{Single User, Ephemeral OpenID Provider} + s.rdoc_options = [ "-a", "-t", "local-openid - #{s.summary}" ] + s.require_paths = %w(lib) + s.rubyforge_project = %q{qrp} + s.add_dependency(%q, ["~> 1.0.0"]) + s.add_dependency(%q, ["~> 2.1.7"]) + # s.licenses = %w(AGPLv3) # accessor not compatible with older RubyGems +end -- 2.11.4.GIT