news_to_releases_xml.rb: add script for converting NEWS.md file to releases.xml

This commit is contained in:
Moritz Bunkus 2016-12-29 17:03:03 +01:00
parent 9053e09b19
commit 507a3cd734
2 changed files with 122 additions and 0 deletions

52
src/tools/modules/news.rb Normal file
View File

@ -0,0 +1,52 @@
def parse_news file_name
news = []
current_line = []
version = 'HEAD'
date = 'unknown'
type = 'Other changes'
flush = lambda do
if !current_line.empty?
news << {
:content => current_line.join(' '),
:version => version,
:date => date,
:type => type
}
current_line = []
end
end
IO.readlines(file_name).each do |line|
is_continuation = %r{^\s}.match(line)
line = line.chomp.gsub(%r{^\s+}, '').gsub(%r{\s+}, ' ')
next if line.empty?
flush.call if %r{^[#*]}.match(line)
# # Version 9.7.1 "Pandemonium" 2016-12-27
# # Version 0.6.4 2003-08-27
if match = %r{ ^\# \s+ Version \s+ (?<version> [0-9.-]+) (?: \s+ " (?<codename>.+) " )? \s+ (?<year>\d+)-(?<month>\d+)-(?<day>\d+) }x.match(line)
version = match[:version]
date = sprintf("%04d-%02d-%02d", match[:year].to_i, match[:month].to_i, match[:day].to_i)
type = 'Other changes'
elsif %r{ ^\#\# \s+ (.+) }x.match(line)
type = $1
elsif %r{ ^\# }x.match(line) && !is_continuation
fail "Don't know what to do with this line: #{line}"
else
flush.call if /^\*/.match(line)
current_line << line.gsub(/^\*\s*/, '') unless line.empty?
end
end
flush.call
news.chunk { |e| e[:version] }
end

View File

@ -0,0 +1,70 @@
#!/usr/bin/env ruby
require 'rubygems'
require 'pp'
require 'builder'
require 'rexml/document'
require 'trollop'
require_relative 'modules/news'
def create_all_releases_xml news
releases_xml = REXML::Document.new File.new($opts[:releases])
builder = Builder::XmlMarkup.new( :indent => $opts[:noindent] ? 0 : 2 )
node_to_hash = lambda { |xpath|
begin
Hash[ *REXML::XPath.first(releases_xml, xpath).elements.collect { |e| [ e.name, e.text ] }.flatten ]
rescue
Hash.new
end
}
builder.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
xml = builder.tag!('mkvtoolnix-releases') do
builder.tag!('latest-source', node_to_hash.call("/mkvtoolnix-releases/latest-source"))
builder.tag!('latest-windows-pre', node_to_hash.call("/mkvtoolnix-releases/latest-windows-pre"))
builder.tag! 'latest-windows-binary' do
builder.tag! 'installer-url', node_to_hash.call("/mkvtoolnix-releases/latest-windows-binary/installer-url")
builder.tag! 'portable-url', node_to_hash.call("/mkvtoolnix-releases/latest-windows-binary/portable-url")
end
news.each do |release|
attributes = {
"version" => release[0],
}.merge node_to_hash.call("/mkvtoolnix-releases/release[version='#{release[0]}']")
builder.release attributes do
builder.changes do
release[1].each do |entry|
builder.change(entry[:content], entry.reject { |key| [:version, :content, :date].include? key })
end
end
end
end
end
puts xml
end
def parse_opts
opts = Trollop::options do
opt :news, "News source file", :type => String, :default => 'NEWS.md'
opt :releases, "releases.xml source file", :type => String, :default => 'releases.xml'
opt :noindent, "do not indent the XML"
end
Trollop::die :news, "must be given and exist" if !opts[:news] || !File.exist?(opts[:news])
Trollop::die :releases, "must be given and exist" if !opts[:releases] || !File.exist?(opts[:releases])
opts
end
def main
$opts = parse_opts
create_all_releases_xml parse_news($opts[:news])
end
main