Skip to content
Snippets Groups Projects
Commit c85a19f9 authored by Bob Van Landuyt's avatar Bob Van Landuyt
Browse files

Allow limiting quick actions to execute

Sometimes we don't want to trigger any quick actions that cause side
effects. For example when building a record to validate. This allows
listing the quick actions that need to be performed.
parent 6fbdc5ed
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -126,12 +126,12 @@ class IssuableBaseService < BaseService
merge_quick_actions_into_params!(issuable)
end
 
def merge_quick_actions_into_params!(issuable)
def merge_quick_actions_into_params!(issuable, only: nil)
original_description = params.fetch(:description, issuable.description)
 
description, command_params =
QuickActions::InterpretService.new(project, current_user)
.execute(original_description, issuable)
.execute(original_description, issuable, only: only)
 
# Avoid a description already set on an issuable to be overwritten by a nil
params[:description] = description if description
Loading
Loading
Loading
Loading
@@ -7,7 +7,9 @@ module MergeRequests
def execute
@params_issue_iid = params.delete(:issue_iid)
self.merge_request = MergeRequest.new
merge_quick_actions_into_params!(merge_request)
# TODO: this should handle all quick actions that don't have side effects
# https://gitlab.com/gitlab-org/gitlab-ce/issues/53658
merge_quick_actions_into_params!(merge_request, only: [:target_branch])
merge_request.assign_attributes(params)
 
merge_request.author = current_user
Loading
Loading
Loading
Loading
@@ -23,13 +23,13 @@ module QuickActions
 
# Takes a text and interprets the commands that are extracted from it.
# Returns the content without commands, and hash of changes to be applied to a record.
def execute(content, issuable)
def execute(content, issuable, only: nil)
return [content, {}] unless current_user.can?(:use_quick_actions)
 
@issuable = issuable
@updates = {}
 
content, commands = extractor.extract_commands(content)
content, commands = extractor.extract_commands(content, only: only)
extract_updates(commands)
 
[content, @updates]
Loading
Loading
Loading
Loading
@@ -29,7 +29,7 @@ module Gitlab
# commands = extractor.extract_commands(msg) #=> [['labels', '~foo ~"bar baz"']]
# msg #=> "hello\nworld"
# ```
def extract_commands(content)
def extract_commands(content, only: nil)
return [content, []] unless content
 
content = content.dup
Loading
Loading
@@ -37,7 +37,7 @@ module Gitlab
commands = []
 
content.delete!("\r")
content.gsub!(commands_regex) do
content.gsub!(commands_regex(only: only)) do
if $~[:cmd]
commands << [$~[:cmd].downcase, $~[:arg]].reject(&:blank?)
''
Loading
Loading
@@ -60,8 +60,8 @@ module Gitlab
# It looks something like:
#
# /^\/(?<cmd>close|reopen|...)(?:( |$))(?<arg>[^\/\n]*)(?:\n|$)/
def commands_regex
names = command_names.map(&:to_s)
def commands_regex(only:)
names = command_names(limit_to_commands: only).map(&:to_s)
 
@commands_regex ||= %r{
(?<code>
Loading
Loading
@@ -133,10 +133,14 @@ module Gitlab
[content, commands]
end
 
def command_names
def command_names(limit_to_commands:)
command_definitions.flat_map do |command|
next if command.noop?
 
if limit_to_commands && (command.all_names & limit_to_commands).empty?
next
end
command.all_names
end.compact
end
Loading
Loading
Loading
Loading
@@ -272,5 +272,24 @@ describe Gitlab::QuickActions::Extractor do
expect(commands).to be_empty
expect(msg).to eq expected
end
it 'limits to passed commands when they are passed' do
msg = <<~MSG.strip
Hello, we should only extract the commands passed
/reopen
/labels hello world
/power
MSG
expected_msg = <<~EXPECTED.strip
Hello, we should only extract the commands passed
/power
EXPECTED
expected_commands = [['reopen'], ['labels', 'hello world']]
msg, commands = extractor.extract_commands(msg, only: [:open, :labels])
expect(commands).to eq(expected_commands)
expect(msg).to eq expected_msg
end
end
end
Loading
Loading
@@ -1213,6 +1213,15 @@ describe QuickActions::InterpretService do
end
end
end
it 'limits to commands passed ' do
content = "/shrug\n/close"
text, commands = service.execute(content, issue, only: [:shrug])
expect(commands).to be_empty
expect(text).to eq("#{described_class::SHRUG}\n/close")
end
end
 
describe '#explain' do
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment