Module: Gitlab::Fp::RopHelpers

Defined in:
lib/gitlab/fp/rop_helpers.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(base) ⇒ Object

Returns void.

Parameters:

  • base (Class)

Returns:

  • void



9
10
11
12
13
# File 'lib/gitlab/fp/rop_helpers.rb', line 9

def self.extended(base)
  base.class_eval do
    private_class_method :retrieve_single_public_singleton_method, :public_singleton_methods_to_ignore
  end
end

Instance Method Details

#public_singleton_methods_to_ignoreArray<Symbol>

Returns:

  • (Array<Symbol>)


56
57
58
59
60
61
# File 'lib/gitlab/fp/rop_helpers.rb', line 56

def public_singleton_methods_to_ignore
  # Singleton methods added by other libraries that we need to ignore.
  Module.singleton_methods(false) +
    Class.singleton_methods(false) +
    [:_] # NOTE: `_` (from GettextI18nRails) is ignored because we mock it globally in fast_spec_helper
end

#retrieve_single_public_singleton_method(fp_module_or_class) ⇒ Symbol

Parameters:

  • fp_module_or_class (Class)

Returns:

  • (Symbol)

Raises:

  • (RuntimeError)


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
# File 'lib/gitlab/fp/rop_helpers.rb', line 18

def retrieve_single_public_singleton_method(fp_module_or_class)
  fp_class_singleton_methods = fp_module_or_class.singleton_methods(false)
  public_singleton_methods = fp_class_singleton_methods - public_singleton_methods_to_ignore

  # Note: Intentionally using Array#[] instead of Array#first here, because there appears to be a bug
  #       in the type declaration, that doesn't indicate that #first should have `implicitly-returns-nil`
  #       behavior. See https://github.com/ruby/rbs/pull/1226, this probably needs to be fixed for #first too.
  #       Until then, we use #[] to avoid type inspection warnings in RubyMine.
  return public_singleton_methods[0] if public_singleton_methods.size == 1

  fp_doc_link =
    "https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/remote_development/README.md#functional-patterns"

  rop_doc_link =
    "https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/remote_development/README.md#railway-oriented-programming-and-the-result-class"

  if public_singleton_methods.size > 1
    err_msg =
      "Railway Oriented Programming (ROP) pattern violation in class `#{fp_module_or_class}`. " \
        "Expected exactly one (1) public entry point singleton/class method to be present " \
        "in a class which is used with the ROP pattern, but " \
        "#{public_singleton_methods.size} " \
        "public singleton methods were found: #{public_singleton_methods.sort.join(', ')}. " \
        "You can make the non-entry-point method(s) private via `private_class_method :method_name`. " \
        "See #{fp_doc_link} and #{rop_doc_link} for more information."
    raise(ArgumentError, err_msg)
  end

  err_msg =
    "Railway Oriented Programming (ROP) pattern violation in class `#{fp_module_or_class}`. " \
      "Expected exactly one public entry point singleton/class method to be present " \
      "in a class which is used with the ROP pattern, but " \
      "no public singleton methods were found. " \
      "See #{fp_doc_link} and #{rop_doc_link} for more information."
  raise(ArgumentError, err_msg)
end