Welcome to mirror list, hosted at ThFree Co, Russian Federation.

command_definition.rb « quick_actions « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d9135d1bacbd0e620805db077d27dd927a79886c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# frozen_string_literal: true

module Gitlab
  module QuickActions
    class CommandDefinition
      ParseError = Class.new(StandardError)

      attr_accessor :name, :aliases, :description, :explanation, :execution_message,
        :params, :condition_block, :parse_params_block, :action_block, :warning, :icon, :types

      def initialize(name, attributes = {})
        @name = name

        @aliases = attributes[:aliases] || []
        @description = attributes[:description] || ''
        @warning = attributes[:warning] || ''
        @icon = attributes[:icon] || ''
        @explanation = attributes[:explanation] || ''
        @execution_message = attributes[:execution_message] || ''
        @params = attributes[:params] || []
        @condition_block = attributes[:condition_block]
        @parse_params_block = attributes[:parse_params_block]
        @action_block = attributes[:action_block]
        @types = attributes[:types] || []
      end

      def all_names
        [name, *aliases]
      end

      def noop?
        action_block.nil?
      end

      def available?(context)
        return false unless valid_type?(context)
        return true unless condition_block

        context.instance_exec(&condition_block)
      end

      def explain(context, arg)
        return unless available?(context)

        message = if explanation.respond_to?(:call)
                    begin
                      execute_block(explanation, context, arg)
                    rescue ParseError => e
                      format(_('Problem with %{name} command: %{message}.'), name: name, message: e.message)
                    end
                  else
                    explanation
                  end

        warning_text = if warning.respond_to?(:call)
                         execute_block(warning, context, arg)
                       else
                         warning
                       end

        warning.empty? ? message : "#{message} (#{warning_text})"
      end

      def execute(context, arg)
        return if noop?

        count_commands_executed_in(context)

        return unless available?(context)

        execute_block(action_block, context, arg)
      rescue ParseError
        # message propagation is handled in `execution_message`.
      end

      def execute_message(context, arg)
        return if noop?
        return _('Could not apply %{name} command.') % { name: name } unless available?(context)

        if execution_message.respond_to?(:call)
          execute_block(execution_message, context, arg)
        else
          execution_message
        end
      rescue ParseError => e
        format _('Could not apply %{name} command. %{message}.'), name: name, message: e.message
      end

      def to_h(context)
        desc = description
        if desc.respond_to?(:call)
          desc = begin
            context.instance_exec(&desc)
          rescue StandardError
            ''
          end
        end

        warn = warning
        if warn.respond_to?(:call)
          warn = begin
            context.instance_exec(&warn)
          rescue StandardError
            ''
          end
        end

        prms = params
        if prms.respond_to?(:call)
          prms = begin
            Array(context.instance_exec(&prms))
          rescue StandardError
            params
          end
        end

        {
          name: name,
          aliases: aliases,
          description: desc,
          warning: warn,
          icon: icon,
          params: prms
        }
      end

      private

      def count_commands_executed_in(context)
        return unless context.respond_to?(:commands_executed_count=)

        context.commands_executed_count ||= 0
        context.commands_executed_count += 1
      end

      def execute_block(block, context, arg)
        if arg.present?
          parsed = parse_params(arg, context)
          context.instance_exec(parsed, &block)
        elsif block.arity == 0
          context.instance_exec(&block)
        end
      end

      def parse_params(arg, context)
        return arg unless parse_params_block

        context.instance_exec(arg, &parse_params_block)
      end

      def valid_type?(context)
        types.blank? || types.any? { |type| context.quick_action_target.is_a?(type) }
      end
    end
  end
end