#!/System/Library/Frameworks/Ruby.framework/Versions/Current/usr/bin/ruby -w
require 'optparse'
require 'shellwords'

outfile = '/dev/stdout'
inplace = false
dump_version = false

OptionParser.new do |opts|
  opts.banner = "Usage: #{File.basename(__FILE__)} [options]"
  opts.on_tail('-h', '--help', 'Show this message.') { puts opts; exit }

  opts.on("-o", "--output FILE", "Defaults to ‘#{outfile}’.") do |file|
    outfile = file
  end

  opts.on("-i", "--inplace", "Overwrite input file") do
    inplace = true
  end

  opts.on("-d", "--dump-version", "Write new version number to stdout") do
    dump_version = true
  end
end.parse!

infile  = ARGV.shift || '/dev/stdin'
outfile = infile if inplace && !infile.start_with?('/dev/')
success = false

data = File.read(infile)

data.sub!(%r{^#+ .* \((v\d+(?:\.\d+)*(-\w+(?:\.\w+)*)?)\)}) do |match, cap|
  success = true

  lastVersion = $1
  newVersion  = lastVersion.sub(/(.*\b)(\d+)/) { "#$1%d" % ($2.to_i + 1) }

  changes = %x{git log --pretty=tformat:'* %s *[%an]*' --date=short --reverse #{lastVersion.shellescape}..}
  abort "#{File.basename(__FILE__)}: Error calling ‘git log’: #{changes}" unless $? == 0

  STDOUT << newVersion if dump_version

  changes.gsub!(/\.?( \*\[(?:Allan Odgaard|(.+?))\]\*)$/) do
    $2.nil? ? "." : ".#$1"
  end

  res = "## #{Time.now.strftime('%Y-%m-%d')} (#{newVersion})\n"
  res << "\n"
  res << changes
  res << "* See [all changes since #{lastVersion}](https://github.com/textmate/textmate/compare/#{lastVersion}...#{newVersion})\n"
  res << "\n"
  res << match

  res
end

abort "No version number found in #{infile}." unless success

File.write(outfile, data)
