From 4f119b0dd6742db7bfa6eb517886a5b8e4fb1fcb Mon Sep 17 00:00:00 2001 From: Javier Torres Date: Fri, 10 Aug 2018 17:24:39 +0200 Subject: [PATCH] Script to bump versions --- bump.rb | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100755 bump.rb diff --git a/bump.rb b/bump.rb new file mode 100755 index 0000000000..40eb702af9 --- /dev/null +++ b/bump.rb @@ -0,0 +1,132 @@ +#!/usr/bin/env ruby + +require 'date' + +Dir.chdir(File.dirname(__FILE__)) + +NEWS_HEADER_REGEX = /^(\d+)\.(\d+)\.(\d+) \(\d{4}-\d{2}-\d{2}\)$\n-+/ +PARTS = ['major', 'minor', 'patch'].freeze +NEWS_HEADER = <<-EOF +Development +----------- + +### NOTICES +- None yet + +### Features +- None yet + +### Bug fixes / enhancements +- None yet + +EOF + +class Version < Array + def initialize(parts) + raise "Expected three version parts" unless parts.count == 3 + super(parts.map(&:to_i)) + end + + def bump(pos) + self[pos] += 1 + (pos+1..2).each { |p| self[p] = 0 } + end + + def to_s + join('.') + end +end + +def version_from_tag(tag) + m = tag.match(/^v(\d+)\.(\d+)\.(\d+)$/) + raise "Could not parse tag #{tag}" unless m + + Version.new(m[1..3]) +end + +def version_from_news(news) + m = news.match(NEWS_HEADER_REGEX) + raise "Could not find NEWS version" unless m + + Version.new(m[1..3]) +end + +def updated_news(news, next_version) + NEWS_HEADER + tag_header(next_version) + clean_development(news) +end + +def tag_header(next_version) + h = "#{next_version} (#{Date.today})" + h + "\n#{'-' * h.length}\n\n" +end + +def clean_development(news) + development, header, rest = news.partition(NEWS_HEADER_REGEX) + development_lines = development.split("\n") + development_lines.delete('Development') + development_lines.delete('-----------') + + # Write non-empty sections + news_sections(development_lines).map { |name, lines| + if name && lines.any? { |l| !l.strip.empty? } + "### #{name}\n#{lines.join("\n")}\n" + end + }.compact.join('') + "\n#{header}#{rest}" +end + +def news_sections(lines) + sections = [] + section_lines = [] + section_name = nil + lines.each do |line| + if line.start_with?('###') + if section_name + sections << [section_name, section_lines] + end + section_lines = [] + section_name = line[4..-1] + elsif line != '- None yet' + # Replace initial `-` for `*` + section_lines << "#{line.sub(/^(\s)*-/, '\1*')}" + end + end + sections << [section_name, section_lines] if section_name + + sections +end + +def help + puts 'Usage: ' + puts ' bump.rb [ major | minor | patch ] (defaults to `patch`)' + exit(1) +end + +ARGV << 'patch' if ARGV.empty? +help unless ARGV.count == 1 + +raise 'Not in master branch' unless `git rev-parse --abbrev-ref HEAD`.strip == 'master' + +puts 'Pulling and fetching tags...' +`git pull --tags` + +news_content = File.read('NEWS.md') + +puts 'Calculating current version...' +tag_version = version_from_tag(`git describe --abbrev=0`) +news_version = version_from_news(news_content) + +unless tag_version == news_version + raise "Mismatched versions between git tag (#{tag_version}) and NEWS (#{news_version})" +end + +part = PARTS.index(ARGV[0]) +help unless part + +next_version = tag_version.dup +next_version.bump(part) + +puts "Bumping from #{tag_version} to #{next_version}. Enter to confirm, Ctrl+C to cancel" +STDIN.getc + +puts "Updating NEWS..." +File.write('NEWS.md', updated_news(news_content, next_version))