gitlab-org--gitlab-foss/lib/gitlab/quick_actions/dsl.rb

228 lines
7.3 KiB
Ruby

# frozen_string_literal: true
module Gitlab
module QuickActions
module Dsl
extend ActiveSupport::Concern
included do
cattr_accessor :command_definitions, instance_accessor: false do
[]
end
cattr_accessor :command_definitions_by_name, instance_accessor: false do
{}
end
end
class_methods do
# Allows to give a description to the next quick action.
# This description is shown in the autocomplete menu.
# It accepts a block that will be evaluated with the context given to
# `CommandDefintion#to_h`.
#
# Example:
#
# desc do
# "This is a dynamic description for #{quick_action_target.to_ability_name}"
# end
# command :command_key do |arguments|
# # Awesome code block
# end
def desc(text = '', &block)
@description = block_given? ? block : text
end
def warning(text = '', &block)
@warning = block_given? ? block : text
end
def icon(string = '')
@icon = string
end
# Allows to define params for the next quick action.
# These params are shown in the autocomplete menu.
#
# Example:
#
# params "~label ~label2"
# command :command_key do |arguments|
# # Awesome code block
# end
def params(*params, &block)
@params = block_given? ? block : params
end
# Allows to give an explanation of what the command will do when
# executed. This explanation is shown when rendering the Markdown
# preview.
#
# Example:
#
# explanation do |arguments|
# "Adds label(s) #{arguments.join(' ')}"
# end
# command :command_key do |arguments|
# # Awesome code block
# end
def explanation(text = '', &block)
@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`.
#
# It is being evaluated before the conditions block is being evaluated
#
# If no types are passed then any type is allowed as the check is simply skipped.
#
# Example:
#
# types Commit, Issue, MergeRequest
# command :command_key do |arguments|
# # Awesome code block
# end
def types(*types_list)
@types = types_list
end
# Allows to define conditions that must be met in order for the command
# to be returned by `.command_names` & `.command_definitions`.
# It accepts a block that will be evaluated with the context
# of a QuickActions::InterpretService instance
# Example:
#
# condition do
# project.public?
# end
# command :command_key do |arguments|
# # Awesome code block
# end
def condition(&block)
@condition_block = block
end
# Allows to perform initial parsing of parameters. The result is passed
# both to `command` and `explanation` blocks, instead of the raw
# parameters.
# It accepts a block that will be evaluated with the context given to
# `CommandDefintion#to_h`.
#
# Example:
#
# parse_params do |raw|
# raw.strip
# end
# command :command_key do |parsed|
# # Awesome code block
# end
def parse_params(&block)
@parse_params_block = block
end
# Registers a new command which is recognizeable from body of email or
# 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)
end
# Registers a new substitution which is recognizable from body of email or
# comment.
# It accepts aliases and takes a block with the formatted content.
#
# Example:
#
# command :my_substitution, :alias_for_my_substitution do |text|
# "#{text} MY AWESOME SUBSTITUTION"
# end
def substitution(*substitution_names, &block)
define_command(SubstitutionDefinition, *substitution_names, &block)
end
def definition_by_name(name)
command_definitions_by_name[name.to_sym]
end
private
def define_command(klass, *command_names, &block)
name, *aliases = command_names
definition = klass.new(
name,
aliases: aliases,
description: @description,
warning: @warning,
icon: @icon,
explanation: @explanation,
execution_message: @execution_message,
params: @params,
condition_block: @condition_block,
parse_params_block: @parse_params_block,
action_block: block,
types: @types
)
self.command_definitions << definition
definition.all_names.each do |name|
self.command_definitions_by_name[name] = definition
end
@description = nil
@explanation = nil
@execution_message = nil
@params = nil
@condition_block = nil
@warning = nil
@icon = nil
@parse_params_block = nil
@types = nil
end
end
end
end
end