#!/usr/bin/ruby require 'net/http' require 'rexml/document' require 'rss/0.9' require 'tempfile' require 'uri' require 'yaml' include REXML ISSUE_NUMBER=/[A-Z]{1}[A-Z0-9]{1,7}-[0-9]{1,4}/ class Issue attr_accessor :issue, :category, :description def initialize(url) @issue = id(url) @links = [url] end def to_wiki links = @links.map { |url| "[#{id(url)}|#{url}]" }.join("/") "#{links} - #{@description}" end def id(url) url.scan(ISSUE_NUMBER)[0] end def <=>(other) return (@issue <=> other.issue) end def ==(other) @issue == other.issue end def hash @issue.hash end def eql?(other) self == other end end class ReleaseNotes def initialize(version) @version = version @issues = Array.new end def read_svn(revision) temp_file = Tempfile.new('release_notes') system("svn log -r #{revision}:HEAD > #{temp_file.path}") IO.foreach(temp_file.path) { |line| line.scan(ISSUE_NUMBER).uniq.each { |id| readRssFeed("http://issues.apache.org/activemq/si/jira.issueviews:issue-xml/#{id}/#{id}.xml") { |issue,item| @issues << issue unless nil == issue } } } end def readRssFeed(url) response = Net::HTTP.get_response(URI.parse(url)) if (response.code == '302') then response = Net::HTTP.get_response(URI.parse(response['Location'])) end begin response.value(); # this raises an HTTP error if status != 2xx doc = Document.new(response.body) XPath.each(doc, "//item") do |item| issue = Issue.new(XPath.first(item, "link/text()").to_s) issue.category = XPath.first(item, "type/text()").to_s issue.description = XPath.first(item, "title/text()").to_s.gsub(/\[\(?[A-Z0-9]{2,7}-[0-9]{1,4}\)?\]/, "").strip yield issue, item end rescue Exception => e puts "Error while reading #{url}: #{e}" yield nil, nil end end def to_wiki puts puts "h3. {excerpt}Release notes - #{@version}{excerpt}" categories = @issues.map { |issue| issue.category }.uniq.sort categories.each { |category| puts puts "h4. #{category}" @issues.uniq.select { |issue| issue.category == category }.sort.each { |issue| puts "* #{issue.to_wiki}" } } end end class Project def initialize @versions = Array.new trunk = svn_info(".")['URL'] @tags = trunk.sub(/\/trunk/, "/tags/").sub(/https/, "http") response = Net::HTTP.get_response(URI.parse(@tags)) response.value(); # this raises an HTTP error if status != 2xx response.body.scan(/