1# frozen_string_literal: true
2
3module Gitlab
4  module DependencyLinker
5    class MethodLinker < BaseLinker
6      private
7
8      # Links package names in a method call or assignment string argument.
9      #
10      # Example:
11      #   link_method_call('gem')
12      #   # Will link `package` in `gem "package"`, `gem("package")` and `gem = "package"`
13      #
14      #   link_method_call('gem', 'specific_package')
15      #   # Will link `specific_package` in `gem "specific_package"`
16      #
17      #   link_method_call('github', /[^\/"]+\/[^\/"]+/)
18      #   # Will link `user/repo` in `github "user/repo"`, but not `github "package"`
19      #
20      #   link_method_call(%w[add_dependency add_development_dependency])
21      #   # Will link `spec.add_dependency "package"` and `spec.add_development_dependency "package"`
22      #
23      #   link_method_call('name')
24      #   # Will link `package` in `self.name = "package"`
25      def link_method_call(method_name, value = nil, &url_proc)
26        regex = method_call_regex(method_name, value)
27
28        link_regex(regex, &url_proc)
29      end
30
31      def method_call_regex(method_name, value = nil)
32        method_name = regexp_for_value(method_name)
33        value = regexp_for_value(value)
34
35        %r{
36          #{method_name}            # Method name
37          \s*                       # Whitespace
38          [(=]?                     # Opening brace or equals sign
39          \s*                       # Whitespace
40          ['"](?<name>#{value})['"] # Package name in quotes
41        }x
42      end
43    end
44  end
45end
46