# frozen_string_literal: true require 'rake' require 'readline' require 'fileutils' # rubocop:disable Metrics/BlockLength namespace :version do PROJECT_ROOT = File.expand_path(FileUtils.pwd).freeze PROJECT_NAME = ENV['PROJECT_NAME'] || File.basename(PROJECT_ROOT) desc 'Write changes to the CHANGELOG' task :changes do text = ask('CHANGELOG Entry:') text.insert( 0, "*#{read_version.join('.')}* (#{Time.now.strftime('%B %d, %Y')})\n\n" ) text << "\n" prepend_changelog(text) launch_editor(changelog) end desc 'Increment the patch version and write changes to the changelog' task :bump_patch do exit unless check_branch_and_warn major, minor, patch = read_version patch = patch.to_i + 1 write_version_file([major, minor, patch]) update_readme_version_strings Rake::Task['version:changes'].invoke end desc 'Alias for :bump_patch' task bump: :bump_patch desc 'Increment the minor version and write changes to the changelog' task :bump_minor do exit unless check_branch_and_warn major, minor, _patch = read_version minor = minor.to_i + 1 patch = 0 write_version_file([major, minor, patch]) update_readme_version_strings Rake::Task['version:changes'].invoke end desc 'Increment the major version and write changes to the changelog' task :bump_major do exit unless check_branch_and_warn major, _minor, _patch = read_version major = major.to_i + 1 minor = 0 patch = 0 write_version_file([major, minor, patch]) update_readme_version_strings Rake::Task['version:changes'].invoke end private def version_file_path split = PROJECT_NAME.split('-') "#{PROJECT_ROOT}/lib/#{split.join('/')}/version.rb" end def module_name case PROJECT_NAME when /-/ PROJECT_NAME.split('-').map(&:capitalize).join('::') when /_/ PROJECT_NAME.split('_').map(&:capitalize).join else PROJECT_NAME.capitalize end end def read_version silence_warnings do load version_file_path end text = eval("#{module_name}::VERSION") text.split('.') end def write_version_file(version_array) version = version_array.join('.') new_version = %( VERSION = '#{version}'.freeze) lines = File.readlines(version_file_path) File.open(version_file_path, 'w') do |f| lines.each do |line| if line =~ /VERSION/ f.write("#{new_version}\n") else f.write(line) end end end end def update_readme_version_strings version_string = read_version.join('.') readme = open('README.md').read regex = /^\*\*Version: [0-9.]+\*\*$/i return nil unless readme =~ regex File.open('README.md', 'w') do |f| f.write(readme.gsub(regex, "**Version: #{version_string}**")) end end def changelog return @changelog_path if @changelog_path @changelog_path = File.join(PROJECT_ROOT, 'CHANGELOG') FileUtils.touch(@changelog_path) @changelog_path end def prepend_changelog(text_array) old = File.read(changelog).to_s.chomp text_array.push(old) File.open(changelog, 'w') do |f| text_array.flatten.each do |line| f.puts(line) end end end # rubocop:disable Lint/AssignmentInCondition def ask(message) response = [] puts message puts 'Hit -D when finished:' while line = Readline.readline('* ', false) response << "* #{line.chomp}" unless line.nil? end response end # rubocop:enable Lint/AssignmentInCondition def current_branch `git symbolic-ref --short HEAD`.chomp end def branch_warning_message <<~STRING You typically do not want to bump versions on the 'master' branch unless you plan to rebase or back-merge into 'develop'. If you don't care or don't know what I'm talking about just enter 'y' and continue. Optionally, you can hit 'n' to abort and switch your branch to 'develop' or whatever branch you use for development, bump the version, merge to 'master' then 'rake release'. Do you really want to bump the version on your 'master' branch? (y/n) STRING end def check_branch_and_warn return true unless current_branch == 'master' puts(branch_warning_message) while (line = $stdin.gets.chomp) return true if line =~ /[yY]/ puts 'Aborting version bump.' return false end end def launch_editor(file) system("#{ENV['EDITOR']} #{file}") if ENV['EDITOR'] end def silence_warnings original_verbosity = $VERBOSE $VERBOSE = nil yield ensure $VERBOSE = original_verbosity end end # rubocop:enable Metrics/BlockLength