Module: Datadog::DI::Utils Private

Defined in:
lib/datadog/di/utils.rb

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Class Method Summary collapse

Class Method Details

.normalize_windows_separators(path) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns path with Windows-style backslash separators translated to forward slashes (DEBUG-5111). Used to normalize probe source paths that originate from IDE tooling running on Windows.



88
89
90
# File 'lib/datadog/di/utils.rb', line 88

module_function def normalize_windows_separators(path)
  path.tr("\\", "/")
end

.path_can_match_spec?(path, spec) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns whether the provided path matches the "probe path" in spec. Attempts all of the fuzzy matches by stripping directories from the front of spec. Does not consider othr known paths to identify the case of (potentially) multiple matching paths for spec.

Matching is attempted case-sensitively first (steps 5-6 in the design comment above) and only falls back to case-insensitive (steps 7-8) when no case-sensitive match is found.

Returns:

  • (Boolean)


149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/datadog/di/utils.rb', line 149

module_function def path_can_match_spec?(path, spec)
  # Normalize Windows-style backslash separators (DEBUG-5111) so the
  # suffix-shortening loop's "/+" regex can strip leading components.
  spec = normalize_windows_separators(spec)

  [false, true].each do |case_insensitive|
    working_spec = spec.dup
    return true if path_matches_suffix?(path, working_spec, case_insensitive: case_insensitive)

    loop do
      break unless working_spec.include?("/")
      working_spec.sub!(%r{.*/+}, "")
      return true if path_matches_suffix?(path, working_spec, case_insensitive: case_insensitive)
    end
  end
  false
end

.path_matches_suffix?(path, suffix, case_insensitive: false) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns whether the provided path matches the user-designated file suffix (of a line probe).

Backslash separators in suffix are translated to forward slashes (DEBUG-5111) so paths typed by IDE tooling on Windows can match. Case-insensitive matching (DEBUG-5107) is opt-in via case_insensitive: true; callers that orchestrate matching against a set of known paths perform case-sensitive comparisons first and only fall back to case-insensitive when no case-sensitive match is found (see the design comment above, steps 5-8).

If suffix is an absolute path (i.e., it starts with a slash, possibly after backslash normalization), the path must be identical for it to match.

If suffix is not an absolute path, the path matches if its suffix is the provided suffix, at a path component boundary.

Returns:

  • (Boolean)


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
# File 'lib/datadog/di/utils.rb', line 109

module_function def path_matches_suffix?(path, suffix, case_insensitive: false)
  if path.nil?
    raise ArgumentError, "nil path passed"
  end
  if suffix.nil?
    raise ArgumentError, "nil suffix passed"
  end

  suffix = normalize_windows_separators(suffix)
  if case_insensitive
    path = path.downcase
    suffix = suffix.downcase
  end

  if suffix.start_with?("/")
    path == suffix
  else
    # Exact match is not possible here, meaning any matching path
    # has to be longer than the suffix. Require full component matches,
    # meaning either the first character of the suffix is a slash
    # or the previous character in the path is a slash.
    !!
    if path.length > suffix.length && path.end_with?(suffix)
      previous_char = path[path.length - suffix.length - 1]
      previous_char == "/" || suffix[0] == "/"
    end

    # Alternative implementation using a regular expression:
    # !!(path =~ %r,(/|\A)#{Regexp.quote(suffix)}\z,)
  end
end