dsl.rb 5.52 KB
Newer Older
1 2
# frozen_string_literal: true

3
module Gitlab
4
  module QuickActions
5 6 7 8
    module Dsl
      extend ActiveSupport::Concern

      included do
Douwe Maan's avatar
Douwe Maan committed
9 10
        cattr_accessor :command_definitions, instance_accessor: false do
          []
11 12
        end

Douwe Maan's avatar
Douwe Maan committed
13 14
        cattr_accessor :command_definitions_by_name, instance_accessor: false do
          {}
15 16 17 18
        end
      end

      class_methods do
19
        # Allows to give a description to the next quick action.
20 21
        # This description is shown in the autocomplete menu.
        # It accepts a block that will be evaluated with the context given to
22
        # `CommandDefintion#to_h`.
23 24 25 26
        #
        # Example:
        #
        #   desc do
Alexandru Croitor's avatar
Alexandru Croitor committed
27
        #     "This is a dynamic description for #{quick_action_target.to_ability_name}"
28 29 30 31 32 33
        #   end
        #   command :command_key do |arguments|
        #     # Awesome code block
        #   end
        def desc(text = '', &block)
          @description = block_given? ? block : text
34 35
        end

36 37 38 39
        def warning(message = '')
          @warning = message
        end

40
        # Allows to define params for the next quick action.
41 42 43 44 45 46 47 48
        # These params are shown in the autocomplete menu.
        #
        # Example:
        #
        #   params "~label ~label2"
        #   command :command_key do |arguments|
        #     # Awesome code block
        #   end
49 50
        def params(*params, &block)
          @params = block_given? ? block : params
51 52
        end

53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
        # 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

Alexandru Croitor's avatar
Alexandru Croitor committed
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
        # 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

86 87
        # Allows to define conditions that must be met in order for the command
        # to be returned by `.command_names` & `.command_definitions`.
88 89
        # It accepts a block that will be evaluated with the context
        # of a QuickActions::InterpretService instance
90 91
        # Example:
        #
92 93 94
        #   condition do
        #     project.public?
        #   end
95 96 97
        #   command :command_key do |arguments|
        #     # Awesome code block
        #   end
98
        def condition(&block)
99
          @condition_block = block
100 101
        end

102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
        # 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

120 121 122
        # Registers a new command which is recognizeable from body of email or
        # comment.
        # It accepts aliases and takes a block.
123
        #
124 125 126 127 128
        # Example:
        #
        #   command :my_command, :alias_for_my_command do |arguments|
        #     # Awesome code block
        #   end
129
        def command(*command_names, &block)
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
          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)
153
          name, *aliases = command_names
154

155
          definition = klass.new(
156
            name,
157 158
            aliases: aliases,
            description: @description,
159
            warning: @warning,
160 161 162 163
            explanation: @explanation,
            params: @params,
            condition_block: @condition_block,
            parse_params_block: @parse_params_block,
Alexandru Croitor's avatar
Alexandru Croitor committed
164 165
            action_block: block,
            types: @types
166
          )
Douwe Maan's avatar
Douwe Maan committed
167 168 169 170 171 172

          self.command_definitions << definition

          definition.all_names.each do |name|
            self.command_definitions_by_name[name] = definition
          end
173 174

          @description = nil
175
          @explanation = nil
176
          @params = nil
177
          @condition_block = nil
178
          @warning = nil
179
          @parse_params_block = nil
Alexandru Croitor's avatar
Alexandru Croitor committed
180
          @types = nil
181
        end
182 183 184 185
      end
    end
  end
end