# frozen_string_literal: true require 'git' require_relative '../data/version' module GFSM module Tools class VersionBumperSettings attr_reader :repository, :configuration, :force, :force_version, :prerelease, :prerelease_name, :from, :to, :initial_version def initialize(cli_args) @repository = GFSM::Tools::GitUtilities.load_repo(get_repository_path(cli_args)) @configuration = GFSM::Data::Configuration.new(get_configuration_file_path(cli_args)) @force = get_force(cli_args) @force_version = get_force_version(cli_args) @prerelease = get_prerelease(cli_args) @prerelease_name = get_prerelease_name(cli_args) @from = get_from(cli_args) @to = get_to(cli_args) @initial_version = get_initial_version(cli_args) @from = GFSM::Tools::GitUtilities.extract_last_tag_name(@repository) if @from.nil? end def self.cli_info options = <<~OPTIONS --force # When there are no commits with a changelog trailer the version won't get bumped. Use this flag to force the version bump. Unless specified, it will increase the patch --force-version <major|minor|match> # What section of the version to bump if the changelog trailer is not found. --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> # Name of the prerelease that will get added when the switch is enabled --configuration <path> # Path to the configuration YAML file --from <hash or tag> # The commit hash or tag to start from when extracting the commits. By default will use the latest tag --to <hash, tag or HEAD> # The commit hash or tag to stop at when extracting the commits. By default will use HEAD to get to the latest commit on the current branch --configuration <path> # Path to the configuration YAML file --path <path> # Path to the repository. By default will use the current directory --initial-version <x.y.z> # Version to use when no existing version is found, useful when initializing the first one OPTIONS environment_variables = <<~ENVVARS FORCE_BUMP # Equivalent to --force FORCE_BUMP_VERSION # Equivalent to --force-version PRERELEASE # Equivalent to --prerelease PRERELEASE_NAME # Equivalent to --prerelease-name CONFIGURATION_FILE # Equivalent to --configuration REPOSITORY_PATH # Equivalent to --path FROM_COMMIT # Equivalent to --from TO_COMMIT # Equivalent to --to INITIAL_VERSION # Equivalent to --initial-version ENVVARS return { usage: "[--force] [--force-version <major|minor|patch>] [--configuration <configuration_file_path>] [--prerelease] [--prerelease-name <prerelease_name>] [--from <hash or tag>] [--to <hash, tag or HEAD>] [--path <repository_path] [--initial-version <x.y.z>]", options: options, environment_variables: environment_variables } end private def extract_switch_value(args, switch, default_value, env_name = nil) return ENV.fetch(env_name) if ENV.has_key?(env_name) switch_index = args.find_index(switch) return default_value unless switch_index && (switch_index + 1) < args.length args[switch_index + 1] end def extract_boolean_value(args, switch, default_value, env_name = nil) if ENV.has_key?(env_name) return ENV.fetch(env_name) == "true" end switch_index = args.find_index(switch) return default_value unless switch_index true end def get_force(args) extract_boolean_value(args, "--force", false, "FORCE_BUMP") end def get_configuration_file_path(args) extract_switch_value(args, "--configuration", "./gfsmrc.yml", "CONFIGURATION_FILE") end def get_prerelease(args) extract_boolean_value(args, "--prerelease", false, "PRERELEASE") end def get_prerelease_name(args) extract_switch_value(args, "--prerelease-name", "pre", "PRERELEASE_NAME") end def get_repository_path(args) extract_switch_value(args, "--path", ".", "REPOSITORY_PATH") end def get_force_version(args) extract_switch_value(args, "--force-version", "patch", "FORCE_BUMP_VERSION") end def get_from(args) extract_switch_value(args, "--from", nil, "FROM_COMMIT") end def get_to(args) extract_switch_value(args, "--to", "HEAD", "TO_COMMIT") end def get_initial_version(args) extract_switch_value(args, "--initial-version", "0.0.0", "INITIAL_VERSION") end end class VersionBumper attr_reader :version, :subdivisions def initialize(settings) @settings = settings end def execute changelog_commits = GFSM::Tools::GitUtilities.extract_commits_with_changelog_trailer(@settings.repository, @settings.from, @settings.to) @version = GFSM::Tools::CurrentVersionLoader.load_current_version(@settings.repository, @settings.initial_version) @subdivisions = GFSM::Tools::CommitsSubdivider.subdivide_commits(@settings.configuration, changelog_commits) if !@subdivisions || @subdivisions.empty? if @settings.force @version.bump!(@settings.force_version == "major", @settings.force_version == "minor", @settings.force_version == "patch", @settings.prerelease, @settings.prerelease_name) end else highest_bump = GFSM::Data::ChangeType.find_highest_bump(@subdivisions.keys) @version.bump!(highest_bump == :major, highest_bump == :minor, highest_bump == :patch, @settings.prerelease, @settings.prerelease_name) end return @version end end end end