Commit c85a19f9 authored by Bob Van Landuyt's avatar Bob Van Landuyt

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
...@@ -126,12 +126,12 @@ class IssuableBaseService < BaseService ...@@ -126,12 +126,12 @@ class IssuableBaseService < BaseService
merge_quick_actions_into_params!(issuable) merge_quick_actions_into_params!(issuable)
end end
def merge_quick_actions_into_params!(issuable) def merge_quick_actions_into_params!(issuable, only: nil)
original_description = params.fetch(:description, issuable.description) original_description = params.fetch(:description, issuable.description)
description, command_params = description, command_params =
QuickActions::InterpretService.new(project, current_user) 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 # Avoid a description already set on an issuable to be overwritten by a nil
params[:description] = description if description params[:description] = description if description
......
...@@ -7,7 +7,9 @@ module MergeRequests ...@@ -7,7 +7,9 @@ module MergeRequests
def execute def execute
@params_issue_iid = params.delete(:issue_iid) @params_issue_iid = params.delete(:issue_iid)
self.merge_request = MergeRequest.new 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.assign_attributes(params)
merge_request.author = current_user merge_request.author = current_user
......
...@@ -23,13 +23,13 @@ module QuickActions ...@@ -23,13 +23,13 @@ module QuickActions
# Takes a text and interprets the commands that are extracted from it. # 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. # 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) return [content, {}] unless current_user.can?(:use_quick_actions)
@issuable = issuable @issuable = issuable
@updates = {} @updates = {}
content, commands = extractor.extract_commands(content) content, commands = extractor.extract_commands(content, only: only)
extract_updates(commands) extract_updates(commands)
[content, @updates] [content, @updates]
......
...@@ -29,7 +29,7 @@ module Gitlab ...@@ -29,7 +29,7 @@ module Gitlab
# commands = extractor.extract_commands(msg) #=> [['labels', '~foo ~"bar baz"']] # commands = extractor.extract_commands(msg) #=> [['labels', '~foo ~"bar baz"']]
# msg #=> "hello\nworld" # msg #=> "hello\nworld"
# ``` # ```
def extract_commands(content) def extract_commands(content, only: nil)
return [content, []] unless content return [content, []] unless content
content = content.dup content = content.dup
...@@ -37,7 +37,7 @@ module Gitlab ...@@ -37,7 +37,7 @@ module Gitlab
commands = [] commands = []
content.delete!("\r") content.delete!("\r")
content.gsub!(commands_regex) do content.gsub!(commands_regex(only: only)) do
if $~[:cmd] if $~[:cmd]
commands << [$~[:cmd].downcase, $~[:arg]].reject(&:blank?) commands << [$~[:cmd].downcase, $~[:arg]].reject(&:blank?)
'' ''
...@@ -60,8 +60,8 @@ module Gitlab ...@@ -60,8 +60,8 @@ module Gitlab
# It looks something like: # It looks something like:
# #
# /^\/(?<cmd>close|reopen|...)(?:( |$))(?<arg>[^\/\n]*)(?:\n|$)/ # /^\/(?<cmd>close|reopen|...)(?:( |$))(?<arg>[^\/\n]*)(?:\n|$)/
def commands_regex def commands_regex(only:)
names = command_names.map(&:to_s) names = command_names(limit_to_commands: only).map(&:to_s)
@commands_regex ||= %r{ @commands_regex ||= %r{
(?<code> (?<code>
...@@ -133,10 +133,14 @@ module Gitlab ...@@ -133,10 +133,14 @@ module Gitlab
[content, commands] [content, commands]
end end
def command_names def command_names(limit_to_commands:)
command_definitions.flat_map do |command| command_definitions.flat_map do |command|
next if command.noop? next if command.noop?
if limit_to_commands && (command.all_names & limit_to_commands).empty?
next
end
command.all_names command.all_names
end.compact end.compact
end end
......
...@@ -272,5 +272,24 @@ describe Gitlab::QuickActions::Extractor do ...@@ -272,5 +272,24 @@ describe Gitlab::QuickActions::Extractor do
expect(commands).to be_empty expect(commands).to be_empty
expect(msg).to eq expected expect(msg).to eq expected
end 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
end end
...@@ -1213,6 +1213,15 @@ describe QuickActions::InterpretService do ...@@ -1213,6 +1213,15 @@ describe QuickActions::InterpretService do
end end
end 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 end
describe '#explain' do describe '#explain' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment