# frozen_string_literal: true module GFSM module Commands class Changelog < BaseCommand NEXT_ENTRY_MARKER = "" def self.help <<~HELP Usage: gfsm changelog [help] [--output-file []] [--no-incremental] [--force] [--prerelease] [--prerelease-name ] [--configuration ] [--path ] # Path to the output changelog file. Defaults to 'CHANGELOG.md'. # If not specified, the generate changelog content will be written to stdout --no-incremental # When provided, the generated changelog won't look for an existing # changelog file. When outputting to stdout the changelog will never be incremental --force # When there are no commits with a changelog trailer # the version won't get bumped. Use this flag to force # the version bump (will increase the patch version) --prerelease # Use this switch to also include a prerelease in the version. # By default will add 'pre' and increment it like 'pre.1', # 'pre.2' and so on --prerelease-name # Name of the prerelease that will get added when the # switch is enabled --configuration # Path to the configuration YAML file --path # Path to the repository. By default will use the current directory HELP end def run(args = []) if !args.empty? && args[0] == "help" GFSM::Output.puts(GFSM::Commands::Changelog.help) else no_incremental = args.include?("--no-incremental") output_file_path = get_output_file_path(args) changelog_section = compute_this_version_section(args) if !output_file_path GFSM::Output.puts <<~CHANGELOG # Changelog #{changelog_section} CHANGELOG else if File.exists?(output_file_path) && !no_incremental existing_content = File.read(output_file_path) file_content = existing_content.gsub(/#{Regexp.quote(NEXT_ENTRY_MARKER)}/i, changelog_section) File.open(output_file_path, 'w') { |file| file.write file_content } else File.open(output_file_path, 'w') do |file| file.write <<~CHANGELOG # Changelog #{changelog_section} CHANGELOG end end end end true end private def compute_this_version_section(args) force = args.include?("--force") prerelease = args.include?("--prerelease") prerelease_name = get_prerelease_name(args) repository_path = get_repository_path(args) configuration_file_path = get_configuration_file_path(args) version_bumper = GFSM::Tools::VersionBumper.new() version = version_bumper.compute_version!(force, prerelease, prerelease_name, repository_path, configuration_file_path) subdivisions = version_bumper.subdivisions changelog_entries = "" subdivisions.each do |change_type, commits| changelog_entries += "\n#{change_type.to_changelog_entry}\n\n" commits.each do |commit| changelog_entries += "- #{commit.to_changelog_entry}\n" end end if !subdivisions || subdivisions.empty? changelog_section = "#{NEXT_ENTRY_MARKER}\n\n## #{version}\n\n" else changelog_section = "#{NEXT_ENTRY_MARKER}\n\n## #{version}\n#{changelog_entries}" end end def extract_switch_value(args, switch, default_value) switch_index = args.find_index(switch) return default_value unless switch_index && (switch_index + 1) < args.length args[switch_index + 1] end def extract_switch_value_if_present(args, switch, default_value) switch_index = args.find_index(switch) return nil unless switch_index return default_value unless (switch_index + 1) < args.length args[switch_index + 1] end def get_output_file_path(args) extract_switch_value_if_present(args, "--output-file", "./CHANGELOG.md") end def get_configuration_file_path(args) extract_switch_value(args, "--configuration", "./gfsmrc.yml") end def get_prerelease_name(args) extract_switch_value(args, "--prerelease-name", "pre") end def get_repository_path(args) extract_switch_value(args, "--path", ".") end end end end