diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/quick_actions/command_definition.rb | 21 | ||||
-rw-r--r-- | lib/gitlab/quick_actions/commit_actions.rb | 7 | ||||
-rw-r--r-- | lib/gitlab/quick_actions/dsl.rb | 37 | ||||
-rw-r--r-- | lib/gitlab/quick_actions/issuable_actions.rb | 116 | ||||
-rw-r--r-- | lib/gitlab/quick_actions/issue_actions.rb | 43 | ||||
-rw-r--r-- | lib/gitlab/quick_actions/issue_and_merge_request_actions.rb | 103 | ||||
-rw-r--r-- | lib/gitlab/quick_actions/merge_request_actions.rb | 28 |
7 files changed, 289 insertions, 66 deletions
diff --git a/lib/gitlab/quick_actions/command_definition.rb b/lib/gitlab/quick_actions/command_definition.rb index 93030fd454e..ebdae139315 100644 --- a/lib/gitlab/quick_actions/command_definition.rb +++ b/lib/gitlab/quick_actions/command_definition.rb @@ -3,8 +3,8 @@ module Gitlab module QuickActions class CommandDefinition - attr_accessor :name, :aliases, :description, :explanation, :params, - :condition_block, :parse_params_block, :action_block, :warning, :types + attr_accessor :name, :aliases, :description, :explanation, :execution_message, + :params, :condition_block, :parse_params_block, :action_block, :warning, :types def initialize(name, attributes = {}) @name = name @@ -13,6 +13,7 @@ module Gitlab @description = attributes[:description] || '' @warning = attributes[:warning] || '' @explanation = attributes[:explanation] || '' + @execution_message = attributes[:execution_message] || '' @params = attributes[:params] || [] @condition_block = attributes[:condition_block] @parse_params_block = attributes[:parse_params_block] @@ -48,13 +49,23 @@ module Gitlab end def execute(context, arg) - return if noop? || !available?(context) + return unless executable?(context) count_commands_executed_in(context) execute_block(action_block, context, arg) end + def execute_message(context, arg) + return unless executable?(context) + + if execution_message.respond_to?(:call) + execute_block(execution_message, context, arg) + else + execution_message + end + end + def to_h(context) desc = description if desc.respond_to?(:call) @@ -77,6 +88,10 @@ module Gitlab private + def executable?(context) + !noop? && available?(context) + end + def count_commands_executed_in(context) return unless context.respond_to?(:commands_executed_count=) diff --git a/lib/gitlab/quick_actions/commit_actions.rb b/lib/gitlab/quick_actions/commit_actions.rb index 1018910e8e9..49f5ddf24eb 100644 --- a/lib/gitlab/quick_actions/commit_actions.rb +++ b/lib/gitlab/quick_actions/commit_actions.rb @@ -16,6 +16,13 @@ module Gitlab _("Tags this commit to %{tag_name}.") % { tag_name: tag_name } end end + execution_message do |tag_name, message| + if message.present? + _("Tagged this commit to %{tag_name} with \"%{message}\".") % { tag_name: tag_name, message: message } + else + _("Tagged this commit to %{tag_name}.") % { tag_name: tag_name } + end + end params 'v1.2.3 <message>' parse_params do |tag_name_and_message| tag_name_and_message.split(' ', 2) diff --git a/lib/gitlab/quick_actions/dsl.rb b/lib/gitlab/quick_actions/dsl.rb index ecb2169151e..5abbd377642 100644 --- a/lib/gitlab/quick_actions/dsl.rb +++ b/lib/gitlab/quick_actions/dsl.rb @@ -66,6 +66,35 @@ module Gitlab @explanation = block_given? ? block : text end + # Allows to provide a message about quick action execution result, success or failure. + # This message is shown after quick action execution and after saving the note. + # + # Example: + # + # execution_message do |arguments| + # "Added label(s) #{arguments.join(' ')}" + # end + # command :command_key do |arguments| + # # Awesome code block + # end + # + # Note: The execution_message won't be executed unless the condition block returns true. + # execution_message block is executed always after the command block has run, + # for this reason if the condition block doesn't return true after the command block has + # run you need to set the @execution_message variable inside the command block instead as + # shown in the following example. + # + # Example using instance variable: + # + # command :command_key do |arguments| + # # Awesome code block + # @execution_message[:command_key] = 'command_key executed successfully' + # end + # + def execution_message(text = '', &block) + @execution_message = block_given? ? block : text + end + # Allows to define type(s) that must be met in order for the command # to be returned by `.command_names` & `.command_definitions`. # @@ -121,10 +150,16 @@ module Gitlab # comment. # It accepts aliases and takes a block. # + # You can also set the @execution_message instance variable, on conflicts with + # execution_message method the instance variable has precedence. + # # Example: # # command :my_command, :alias_for_my_command do |arguments| # # Awesome code block + # @updates[:my_command] = 'foo' + # + # @execution_message[:my_command] = 'my_command executed successfully' # end def command(*command_names, &block) define_command(CommandDefinition, *command_names, &block) @@ -158,6 +193,7 @@ module Gitlab description: @description, warning: @warning, explanation: @explanation, + execution_message: @execution_message, params: @params, condition_block: @condition_block, parse_params_block: @parse_params_block, @@ -173,6 +209,7 @@ module Gitlab @description = nil @explanation = nil + @execution_message = nil @params = nil @condition_block = nil @warning = nil diff --git a/lib/gitlab/quick_actions/issuable_actions.rb b/lib/gitlab/quick_actions/issuable_actions.rb index f7f89d4e897..b975a967d03 100644 --- a/lib/gitlab/quick_actions/issuable_actions.rb +++ b/lib/gitlab/quick_actions/issuable_actions.rb @@ -12,10 +12,16 @@ module Gitlab included do # Issue, MergeRequest, Epic: quick actions definitions desc do - "Close this #{quick_action_target.to_ability_name.humanize(capitalize: false)}" + _('Close this %{quick_action_target}') % + { quick_action_target: quick_action_target.to_ability_name.humanize(capitalize: false) } end explanation do - "Closes this #{quick_action_target.to_ability_name.humanize(capitalize: false)}." + _('Closes this %{quick_action_target}.') % + { quick_action_target: quick_action_target.to_ability_name.humanize(capitalize: false) } + end + execution_message do + _('Closed this %{quick_action_target}.') % + { quick_action_target: quick_action_target.to_ability_name.humanize(capitalize: false) } end types Issuable condition do @@ -28,10 +34,16 @@ module Gitlab end desc do - "Reopen this #{quick_action_target.to_ability_name.humanize(capitalize: false)}" + _('Reopen this %{quick_action_target}') % + { quick_action_target: quick_action_target.to_ability_name.humanize(capitalize: false) } end explanation do - "Reopens this #{quick_action_target.to_ability_name.humanize(capitalize: false)}." + _('Reopens this %{quick_action_target}.') % + { quick_action_target: quick_action_target.to_ability_name.humanize(capitalize: false) } + end + execution_message do + _('Reopened this %{quick_action_target}.') % + { quick_action_target: quick_action_target.to_ability_name.humanize(capitalize: false) } end types Issuable condition do @@ -45,7 +57,10 @@ module Gitlab desc _('Change title') explanation do |title_param| - _("Changes the title to \"%{title_param}\".") % { title_param: title_param } + _('Changes the title to "%{title_param}".') % { title_param: title_param } + end + execution_message do |title_param| + _('Changed the title to "%{title_param}".') % { title_param: title_param } end params '<New title>' types Issuable @@ -61,7 +76,10 @@ module Gitlab explanation do |labels_param| labels = find_label_references(labels_param) - "Adds #{labels.join(' ')} #{'label'.pluralize(labels.count)}." if labels.any? + if labels.any? + _("Adds %{labels} %{label_text}.") % + { labels: labels.join(' '), label_text: 'label'.pluralize(labels.count) } + end end params '~label1 ~"label 2"' types Issuable @@ -71,21 +89,15 @@ module Gitlab find_labels.any? end command :label do |labels_param| - label_ids = find_label_ids(labels_param) - - if label_ids.any? - @updates[:add_label_ids] ||= [] - @updates[:add_label_ids] += label_ids - - @updates[:add_label_ids].uniq! - end + run_label_command(labels: find_labels(labels_param), command: :label, updates_key: :add_label_ids) end desc _('Remove all or specific label(s)') explanation do |labels_param = nil| - if labels_param.present? - labels = find_label_references(labels_param) - "Removes #{labels.join(' ')} #{'label'.pluralize(labels.count)}." if labels.any? + label_references = labels_param.present? ? find_label_references(labels_param) : [] + if label_references.any? + _("Removes %{label_references} %{label_text}.") % + { label_references: label_references.join(' '), label_text: 'label'.pluralize(label_references.count) } else _('Removes all labels.') end @@ -99,7 +111,9 @@ module Gitlab end command :unlabel do |labels_param = nil| if labels_param.present? - label_ids = find_label_ids(labels_param) + labels = find_labels(labels_param) + label_ids = labels.map(&:id) + label_references = labels_to_reference(labels, :name) if label_ids.any? @updates[:remove_label_ids] ||= [] @@ -109,7 +123,10 @@ module Gitlab end else @updates[:label_ids] = [] + label_references = [] end + + @execution_message[:unlabel] = remove_label_message(label_references) end desc _('Replace all label(s)') @@ -125,18 +142,12 @@ module Gitlab current_user.can?(:"admin_#{quick_action_target.to_ability_name}", parent) end command :relabel do |labels_param| - label_ids = find_label_ids(labels_param) - - if label_ids.any? - @updates[:label_ids] ||= [] - @updates[:label_ids] += label_ids - - @updates[:label_ids].uniq! - end + run_label_command(labels: find_labels(labels_param), command: :relabel, updates_key: :label_ids) end desc _('Add a todo') explanation _('Adds a todo.') + execution_message _('Added a todo.') types Issuable condition do quick_action_target.persisted? && @@ -148,6 +159,7 @@ module Gitlab desc _('Mark to do as done') explanation _('Marks to do as done.') + execution_message _('Marked to do as done.') types Issuable condition do quick_action_target.persisted? && @@ -159,7 +171,12 @@ module Gitlab desc _('Subscribe') explanation do - "Subscribes to this #{quick_action_target.to_ability_name.humanize(capitalize: false)}." + _('Subscribes to this %{quick_action_target}.') % + { quick_action_target: quick_action_target.to_ability_name.humanize(capitalize: false) } + end + execution_message do + _('Subscribed to this %{quick_action_target}.') % + { quick_action_target: quick_action_target.to_ability_name.humanize(capitalize: false) } end types Issuable condition do @@ -172,7 +189,12 @@ module Gitlab desc _('Unsubscribe') explanation do - "Unsubscribes from this #{quick_action_target.to_ability_name.humanize(capitalize: false)}." + _('Unsubscribes from this %{quick_action_target}.') % + { quick_action_target: quick_action_target.to_ability_name.humanize(capitalize: false) } + end + execution_message do + _('Unsubscribed from this %{quick_action_target}.') % + { quick_action_target: quick_action_target.to_ability_name.humanize(capitalize: false) } end types Issuable condition do @@ -187,6 +209,9 @@ module Gitlab explanation do |name| _("Toggles :%{name}: emoji award.") % { name: name } if name end + execution_message do |name| + _("Toggled :%{name}: emoji award.") % { name: name } if name + end params ':emoji:' types Issuable condition do @@ -215,6 +240,41 @@ module Gitlab substitution :tableflip do |comment| "#{comment} #{TABLEFLIP}" end + + private + + def run_label_command(labels:, command:, updates_key:) + return if labels.empty? + + @updates[updates_key] ||= [] + @updates[updates_key] += labels.map(&:id) + @updates[updates_key].uniq! + + label_references = labels_to_reference(labels, :name) + @execution_message[command] = case command + when :relabel + _('Replaced all labels with %{label_references} %{label_text}.') % + { + label_references: label_references.join(' '), + label_text: 'label'.pluralize(label_references.count) + } + when :label + _('Added %{label_references} %{label_text}.') % + { + label_references: label_references.join(' '), + label_text: 'label'.pluralize(labels.count) + } + end + end + + def remove_label_message(label_references) + if label_references.any? + _("Removed %{label_references} %{label_text}.") % + { label_references: label_references.join(' '), label_text: 'label'.pluralize(label_references.count) } + else + _('Removed all labels.') + end + end end end end diff --git a/lib/gitlab/quick_actions/issue_actions.rb b/lib/gitlab/quick_actions/issue_actions.rb index 85e62f950c8..0868bd85600 100644 --- a/lib/gitlab/quick_actions/issue_actions.rb +++ b/lib/gitlab/quick_actions/issue_actions.rb @@ -12,6 +12,9 @@ module Gitlab explanation do |due_date| _("Sets the due date to %{due_date}.") % { due_date: due_date.strftime('%b %-d, %Y') } if due_date end + execution_message do |due_date| + _("Set the due date to %{due_date}.") % { due_date: due_date.strftime('%b %-d, %Y') } if due_date + end params '<in 2 days | this Friday | December 31st>' types Issue condition do @@ -27,6 +30,7 @@ module Gitlab desc _('Remove due date') explanation _('Removes the due date.') + execution_message _('Removed the due date.') types Issue condition do quick_action_target.persisted? && @@ -49,22 +53,27 @@ module Gitlab current_user.can?(:"update_#{quick_action_target.to_ability_name}", quick_action_target) && quick_action_target.project.boards.count == 1 end - # rubocop: disable CodeReuse/ActiveRecord command :board_move do |target_list_name| - label_ids = find_label_ids(target_list_name) + labels = find_labels(target_list_name) + label_ids = labels.map(&:id) if label_ids.size == 1 label_id = label_ids.first # Ensure this label corresponds to a list on the board - next unless Label.on_project_boards(quick_action_target.project_id).where(id: label_id).exists? + next unless Label.on_project_board?(quick_action_target.project_id, label_id) @updates[:remove_label_ids] = - quick_action_target.labels.on_project_boards(quick_action_target.project_id).where.not(id: label_id).pluck(:id) + quick_action_target.labels.on_project_boards(quick_action_target.project_id).where.not(id: label_id).pluck(:id) # rubocop: disable CodeReuse/ActiveRecord @updates[:add_label_ids] = [label_id] + + message = _("Moved issue to %{label} column in the board.") % { label: labels_to_reference(labels).first } + else + message = _('Move this issue failed because you need to specify only one label.') end + + @execution_message[:board_move] = message end - # rubocop: enable CodeReuse/ActiveRecord desc _('Mark this issue as a duplicate of another issue') explanation do |duplicate_reference| @@ -81,7 +90,13 @@ module Gitlab if canonical_issue.present? @updates[:canonical_issue_id] = canonical_issue.id + + message = _("Marked this issue as a duplicate of %{duplicate_param}.") % { duplicate_param: duplicate_param } + else + message = _('Mark as duplicate failed because referenced issue was not found') end + + @execution_message[:duplicate] = message end desc _('Move this issue to another project.') @@ -99,13 +114,22 @@ module Gitlab if target_project.present? @updates[:target_project] = target_project + + message = _("Moved this issue to %{path_to_project}.") % { path_to_project: target_project_path } + else + message = _("Move this issue failed because target project doesn't exists") end + + @execution_message[:move] = message end desc _('Make issue confidential.') explanation do _('Makes this issue confidential') end + execution_message do + _('Made this issue confidential') + end types Issue condition do current_user.can?(:"admin_#{quick_action_target.to_ability_name}", quick_action_target) @@ -119,7 +143,14 @@ module Gitlab if branch_name _("Creates branch '%{branch_name}' and a merge request to resolve this issue") % { branch_name: branch_name } else - "Creates a branch and a merge request to resolve this issue" + _('Creates a branch and a merge request to resolve this issue') + end + end + execution_message do |branch_name = nil| + if branch_name + _("Created branch '%{branch_name}' and a merge request to resolve this issue") % { branch_name: branch_name } + else + _('Created a branch and a merge request to resolve this issue') end end params "<branch name>" diff --git a/lib/gitlab/quick_actions/issue_and_merge_request_actions.rb b/lib/gitlab/quick_actions/issue_and_merge_request_actions.rb index e1579cfddc0..41ffd51cde8 100644 --- a/lib/gitlab/quick_actions/issue_and_merge_request_actions.rb +++ b/lib/gitlab/quick_actions/issue_and_merge_request_actions.rb @@ -9,12 +9,9 @@ module Gitlab included do # Issue, MergeRequest: quick actions definitions desc _('Assign') - # rubocop: disable CodeReuse/ActiveRecord explanation do |users| - users = quick_action_target.allows_multiple_assignees? ? users : users.take(1) - "Assigns #{users.map(&:to_reference).to_sentence}." + _('Assigns %{assignee_users_sentence}.') % { assignee_users_sentence: assignee_users_sentence(users) } end - # rubocop: enable CodeReuse/ActiveRecord params do quick_action_target.allows_multiple_assignees? ? '@user1 @user2' : '@user' end @@ -26,7 +23,10 @@ module Gitlab extract_users(assignee_param) end command :assign do |users| - next if users.empty? + if users.empty? + @execution_message[:assign] = _("Assign command failed because no user was found") + next + end if quick_action_target.allows_multiple_assignees? @updates[:assignee_ids] ||= quick_action_target.assignees.map(&:id) @@ -34,6 +34,8 @@ module Gitlab else @updates[:assignee_ids] = [users.first.id] end + + @execution_message[:assign] = _('Assigned %{assignee_users_sentence}.') % { assignee_users_sentence: assignee_users_sentence(users) } end desc do @@ -44,9 +46,14 @@ module Gitlab end end explanation do |users = nil| - assignees = quick_action_target.assignees - assignees &= users if users.present? && quick_action_target.allows_multiple_assignees? - "Removes #{'assignee'.pluralize(assignees.size)} #{assignees.map(&:to_reference).to_sentence}." + assignees = assignees_for_removal(users) + _("Removes %{assignee_text} %{assignee_references}.") % + { assignee_text: 'assignee'.pluralize(assignees.size), assignee_references: assignees.map(&:to_reference).to_sentence } + end + execution_message do |users = nil| + assignees = assignees_for_removal(users) + _("Removed %{assignee_text} %{assignee_references}.") % + { assignee_text: 'assignee'.pluralize(assignees.size), assignee_references: assignees.map(&:to_reference).to_sentence } end params do quick_action_target.allows_multiple_assignees? ? '@user1 @user2' : '' @@ -74,6 +81,9 @@ module Gitlab explanation do |milestone| _("Sets the milestone to %{milestone_reference}.") % { milestone_reference: milestone.to_reference } if milestone end + execution_message do |milestone| + _("Set the milestone to %{milestone_reference}.") % { milestone_reference: milestone.to_reference } if milestone + end params '%"milestone"' types Issue, MergeRequest condition do @@ -92,6 +102,9 @@ module Gitlab explanation do _("Removes %{milestone_reference} milestone.") % { milestone_reference: quick_action_target.milestone.to_reference(format: :name) } end + execution_message do + _("Removed %{milestone_reference} milestone.") % { milestone_reference: quick_action_target.milestone.to_reference(format: :name) } + end types Issue, MergeRequest condition do quick_action_target.persisted? && @@ -116,17 +129,22 @@ module Gitlab extract_references(issuable_param, :merge_request).first end command :copy_metadata do |source_issuable| - if source_issuable.present? && source_issuable.project.id == quick_action_target.project.id + if can_copy_metadata?(source_issuable) @updates[:add_label_ids] = source_issuable.labels.map(&:id) @updates[:milestone_id] = source_issuable.milestone.id if source_issuable.milestone + + @execution_message[:copy_metadata] = _("Copied labels and milestone from %{source_issuable_reference}.") % { source_issuable_reference: source_issuable.to_reference } end end desc _('Set time estimate') explanation do |time_estimate| - time_estimate = Gitlab::TimeTrackingFormatter.output(time_estimate) - - _("Sets time estimate to %{time_estimate}.") % { time_estimate: time_estimate } if time_estimate + formatted_time_estimate = format_time_estimate(time_estimate) + _("Sets time estimate to %{time_estimate}.") % { time_estimate: formatted_time_estimate } if formatted_time_estimate + end + execution_message do |time_estimate| + formatted_time_estimate = format_time_estimate(time_estimate) + _("Set time estimate to %{time_estimate}.") % { time_estimate: formatted_time_estimate } if formatted_time_estimate end params '<1w 3d 2h 14m>' types Issue, MergeRequest @@ -144,18 +162,12 @@ module Gitlab desc _('Add or subtract spent time') explanation do |time_spent, time_spent_date| - if time_spent - if time_spent > 0 - verb = _('Adds') - value = time_spent - else - verb = _('Subtracts') - value = -time_spent - end - - _("%{verb} %{time_spent_value} spent time.") % { verb: verb, time_spent_value: Gitlab::TimeTrackingFormatter.output(value) } - end + spend_time_message(time_spent, time_spent_date, false) end + execution_message do |time_spent, time_spent_date| + spend_time_message(time_spent, time_spent_date, true) + end + params '<time(1h30m | -1h30m)> <date(YYYY-MM-DD)>' types Issue, MergeRequest condition do @@ -176,6 +188,7 @@ module Gitlab desc _('Remove time estimate') explanation _('Removes time estimate.') + execution_message _('Removed time estimate.') types Issue, MergeRequest condition do quick_action_target.persisted? && @@ -187,6 +200,7 @@ module Gitlab desc _('Remove spent time') explanation _('Removes spent time.') + execution_message _('Removed spent time.') condition do quick_action_target.persisted? && current_user.can?(:"admin_#{quick_action_target.to_ability_name}", project) @@ -198,6 +212,7 @@ module Gitlab desc _("Lock the discussion") explanation _("Locks the discussion") + execution_message _("Locked the discussion") types Issue, MergeRequest condition do quick_action_target.persisted? && @@ -210,6 +225,7 @@ module Gitlab desc _("Unlock the discussion") explanation _("Unlocks the discussion") + execution_message _("Unlocked the discussion") types Issue, MergeRequest condition do quick_action_target.persisted? && @@ -219,6 +235,47 @@ module Gitlab command :unlock do @updates[:discussion_locked] = false end + + private + + def assignee_users_sentence(users) + if quick_action_target.allows_multiple_assignees? + users + else + [users.first] + end.map(&:to_reference).to_sentence + end + + def assignees_for_removal(users) + assignees = quick_action_target.assignees + if users.present? && quick_action_target.allows_multiple_assignees? + assignees & users + else + assignees + end + end + + def can_copy_metadata?(source_issuable) + source_issuable.present? && source_issuable.project_id == quick_action_target.project_id + end + + def format_time_estimate(time_estimate) + Gitlab::TimeTrackingFormatter.output(time_estimate) + end + + def spend_time_message(time_spent, time_spent_date, paste_tense) + return unless time_spent + + if time_spent > 0 + verb = paste_tense ? _('Added') : _('Adds') + value = time_spent + else + verb = paste_tense ? _('Subtracted') : _('Subtracts') + value = -time_spent + end + + _("%{verb} %{time_spent_value} spent time.") % { verb: verb, time_spent_value: format_time_estimate(value) } + end end end end diff --git a/lib/gitlab/quick_actions/merge_request_actions.rb b/lib/gitlab/quick_actions/merge_request_actions.rb index bade59182a1..e9127095a0d 100644 --- a/lib/gitlab/quick_actions/merge_request_actions.rb +++ b/lib/gitlab/quick_actions/merge_request_actions.rb @@ -8,8 +8,9 @@ module Gitlab included do # MergeRequest only quick actions definitions - desc 'Merge (when the pipeline succeeds)' - explanation 'Merges this merge request when the pipeline succeeds.' + desc _('Merge (when the pipeline succeeds)') + explanation _('Merges this merge request when the pipeline succeeds.') + execution_message _('Scheduled to merge this merge request when the pipeline succeeds.') types MergeRequest condition do last_diff_sha = params && params[:merge_request_diff_head_sha] @@ -22,10 +23,22 @@ module Gitlab desc 'Toggle the Work In Progress status' explanation do - verb = quick_action_target.work_in_progress? ? 'Unmarks' : 'Marks' noun = quick_action_target.to_ability_name.humanize(capitalize: false) - "#{verb} this #{noun} as Work In Progress." + if quick_action_target.work_in_progress? + _("Unmarks this %{noun} as Work In Progress.") + else + _("Marks this %{noun} as Work In Progress.") + end % { noun: noun } end + execution_message do + noun = quick_action_target.to_ability_name.humanize(capitalize: false) + if quick_action_target.work_in_progress? + _("Unmarked this %{noun} as Work In Progress.") + else + _("Marked this %{noun} as Work In Progress.") + end % { noun: noun } + end + types MergeRequest condition do quick_action_target.respond_to?(:work_in_progress?) && @@ -36,9 +49,12 @@ module Gitlab @updates[:wip_event] = quick_action_target.work_in_progress? ? 'unwip' : 'wip' end - desc 'Set target branch' + desc _('Set target branch') explanation do |branch_name| - "Sets target branch to #{branch_name}." + _('Sets target branch to %{branch_name}.') % { branch_name: branch_name } + end + execution_message do |branch_name| + _('Set target branch to %{branch_name}.') % { branch_name: branch_name } end params '<Local branch name>' types MergeRequest |