# frozen_string_literal: true module Groundskeeper # Formulas for managing releases. # rubocop:disable Metrics/ClassLength class Commands # rubocop:disable Metrics/MethodLength def self.build(console) repository = Repository.new project = Project.build(repository.name) git_hub = GitHub.build( username: project.source_control_username, repository_name: repository.name ) new( changelog: Changelog.build, console: console, git: Git.build, git_hub: git_hub, jira: Jira.build(project.jira_prefix), repository: repository, project: project, version_file: RailsVersion.new ) end # rubocop:enable Metrics/MethodLength # rubocop:disable Metrics/ParameterLists def initialize( changelog: nil, console:, git: nil, git_hub: nil, jira: nil, project: nil, repository: nil, version_file: ) @changelog = changelog @console = console @git = git @git_hub = git_hub @jira = jira @project = project @repository = repository @version_file = version_file @did_checkout_branch = false @did_push_to_remote = false end # rubocop:enable Metrics/ParameterLists # rubocop:disable Metrics/MethodLength def info return unrecognized_version unless version_file.exists? announce_version announce_latest_tag console.say( "version in current branch: " + version_file.current_version, :yellow ) console.say( "tag contained in: #{git.branches_containing_latest_tag}\n\n", :yellow ) end def release return unrecognized_version unless version_file.exists? summarize_recent_commits ask_next_version ask_new_branch update_version_file update_changelog commit_changes_and_tag ask_create_jira_version ask_push_with_tags ask_add_version_to_jira_issues open_pull_request_page end # rubocop:enable Metrics/MethodLength private # collaborators attr_reader :changelog, :console, :git, :git_hub, :jira, :project, :repository, :version_file # state attr_reader :next_version, :recent_commits, :did_checkout_branch, :did_push_to_remote def announce_version console.say("Groundskeeper version #{Groundskeeper::VERSION}\n\n", :bold) end def announce_latest_tag console.say( "latest tag on this repository: " + git.latest_tag_name_across_branches, :yellow ) end def summarize_recent_commits console.say("commits since last tag", :bold) @recent_commits = repository.changes_since_latest_tag console.say(recent_commits.join("\n"), :green) console.say("") end def ask_next_version type = console.ask( "Major, minor, or patch release?", :cyan, limited_to: %w[M m p] ) @next_version = repository.bumped_semantic_version(type) console.say("next tag will be: #{next_version}", :green) end def ask_new_branch @did_checkout_branch = console.yes?( "Checkout new branch #{new_branch_name}? [y, n]", :cyan ) git.create_and_checkout_branch(new_branch_name) if did_checkout_branch end def update_version_file version_file.update_version! next_version console.say("# updated version file", :green) end def update_changelog changelog.update_file(next_version, recent_commits) console.say("# updated changelog", :green) end def commit_changes_and_tag git.add_update git.commit(format(Repository::RELEASE_MESSAGE, next_version)) console.say("# committed changes", :green) git.add_tag(next_version) console.say("# tagged", :green) end def ask_create_jira_version create_jira_version = console.yes?("Create version #{next_version} in Jira? [y, n]", :cyan) jira.create_remote_version(next_jira_version_name) if create_jira_version end def ask_push_with_tags @did_push_to_remote = console.yes?( "Push to remote with tags? [y, n]", :cyan ) git.push_with_tags && console.say("# pushed tag") if @did_push_to_remote end def ask_add_version_to_jira_issues issue_ids = jira.included_issues(recent_commits) add_version_to_jira_issues = console.yes?( "Add #{next_jira_version_name} to #{issue_ids}? [y, n]", :cyan ) return unless add_version_to_jira_issues jira.add_version_to_remote_issues(next_jira_version_name, issue_ids) console.say("# added version to Jira issues", :green) end def next_jira_version_name "#{repository.name} #{next_version}" end def unrecognized_version console.say( "Unable to find version file, is this a Rails application?", :red ) end def open_pull_request_page return unless did_checkout_branch && did_push_to_remote git_hub.open_pull_request_page(new_branch_name) end def new_branch_name "v#{next_version}" end end # rubocop:enable Metrics/ClassLength end