Module: HamlLint::Utils

Defined in:
lib/haml_lint/utils.rb

Overview

A miscellaneous set of utility functions.

Class Method Summary collapse

Class Method Details

.any_glob_matches?(globs_or_glob, file) ⇒ Boolean

Returns whether a glob pattern (or any of a list of patterns) matches the specified file.

This is defined here so our file globbing options are consistent everywhere we perform globbing.

Parameters:

  • glob (String, Array)
  • file (String)

Returns:

  • (Boolean)

19
20
21
22
23
24
25
26
27
# File 'lib/haml_lint/utils.rb', line 19

def any_glob_matches?(globs_or_glob, file)
  get_abs_and_rel_path(file).any? do |path|
    Array(globs_or_glob).any? do |glob|
      ::File.fnmatch?(glob, path,
                      ::File::FNM_PATHNAME | # Wildcards don't match path separators
                      ::File::FNM_DOTMATCH)  # `*` wildcard matches dotfiles
    end
  end
end

.camel_case(str) ⇒ String

Converts a string containing underscores/hyphens/spaces into CamelCase.

Parameters:

  • str (String)

Returns:

  • (String)

92
93
94
# File 'lib/haml_lint/utils.rb', line 92

def camel_case(str)
  str.split(/_|-| /).map { |part| part.sub(/^\w/, &:upcase) }.join
end

.count_consecutive(items, offset = 0) {|item| ... } ⇒ Integer

Count the number of consecutive items satisfying the given Proc.

Parameters:

  • items (Array)
  • offset (Fixnum) (defaults to: 0)

    index to start searching from

Yields:

  • (item)

    Passes item to the provided block.

Yield Parameters:

  • item (Object)

    Item to evaluate as matching criteria for inclusion

Yield Returns:

  • (Boolean)

    whether to include the item

Returns:

  • (Integer)

133
134
135
136
137
# File 'lib/haml_lint/utils.rb', line 133

def count_consecutive(items, offset = 0)
  count = 1
  count += 1 while (offset + count < items.count) && yield(items[offset + count])
  count
end

.extract_interpolated_values(text) {|interpolated_code, line| ... } ⇒ Object

Yields interpolated values within a block of text.

Parameters:

  • text (String)

Yields:

  • Passes interpolated code and line number that code appears on in the text.

Yield Parameters:

  • interpolated_code (String)

    code that was interpolated

  • line (Integer)

    line number code appears on in text


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/haml_lint/utils.rb', line 55

def extract_interpolated_values(text) # rubocop:disable Metrics/AbcSize
  dumped_text = text.dump
  newline_positions = extract_substring_positions(dumped_text, '\\\n')

  Haml::Util.handle_interpolation(dumped_text) do |scan|
    line = (newline_positions.find_index { |marker| scan.pos <= marker } ||
            newline_positions.size) + 1

    escape_count = (scan[2].size - 1) / 2
    break unless escape_count.even?

    dumped_interpolated_str = Haml::Util.balance(scan, '{', '}', 1)[0][0...-1]

    # Hacky way to turn a dumped string back into a regular string
    yield [eval('"' + dumped_interpolated_str + '"'), line] # rubocop:disable Security/Eval
  end
end

.extract_substring_positions(text, substr) ⇒ Array<Integer>

Returns indexes of all occurrences of a substring within a string.

Note, this will not return overlaping substrings, so searching for “aa” in “aaa” will only find one substring, not two.

Parameters:

  • text (String)

    the text to search

  • substr (String)

    the substring to search for

Returns:

  • (Array<Integer>)

    list of indexes where the substring occurs


81
82
83
84
85
86
# File 'lib/haml_lint/utils.rb', line 81

def extract_substring_positions(text, substr)
  positions = []
  scanner = StringScanner.new(text)
  positions << scanner.pos while scanner.scan(/(.*?)#{substr}/)
  positions
end

.for_consecutive_items(items, satisfies, min_consecutive = 2) {|group| ... } ⇒ Object

Find all consecutive items satisfying the given block of a minimum size, yielding each group of consecutive items to the provided block.

Parameters:

  • items (Array)
  • satisfies (Proc)

    function that takes an item and returns true/false

  • min_consecutive (Fixnum) (defaults to: 2)

    minimum number of consecutive items before yielding the group

Yields:

  • Passes list of consecutive items all matching the criteria defined by the `satisfies` Proc to the provided block

Yield Parameters:

  • group (Array)

    List of consecutive items

Yield Returns:

  • (Boolean)

    block should return whether item matches criteria for inclusion


108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/haml_lint/utils.rb', line 108

def for_consecutive_items(items, satisfies, min_consecutive = 2)
  current_index = -1

  while (current_index += 1) < items.count
    next unless satisfies[items[current_index]]

    count = count_consecutive(items, current_index, &satisfies)
    next unless count >= min_consecutive

    # Yield the chunk of consecutive items
    yield items[current_index...(current_index + count)]

    current_index += count # Skip this patch of consecutive items to find more
  end
end

.get_abs_and_rel_path(path) ⇒ Array<String>

Returns an array of two items, the first being the absolute path, the second the relative path.

The relative path is relative to the current working dir. The path passed can be either relative or absolute.

Parameters:

  • path (String)

    Path to get absolute and relative path of

Returns:

  • (Array<String>)

    Absolute and relative path


37
38
39
40
41
42
43
44
45
46
# File 'lib/haml_lint/utils.rb', line 37

def get_abs_and_rel_path(path)
  original_path = Pathname.new(path)
  root_dir_path = Pathname.new(File.expand_path(Dir.pwd))

  if original_path.absolute?
    [path, original_path.relative_path_from(root_dir_path)]
  else
    [root_dir_path + original_path, path]
  end
end

.with_environment(env) ⇒ Object

Calls a block of code with a modified set of environment variables, restoring them once the code has executed.

Parameters:

  • env (Hash)

    environment variables to set


143
144
145
146
147
148
149
150
151
152
153
# File 'lib/haml_lint/utils.rb', line 143

def with_environment(env)
  old_env = {}
  env.each do |var, value|
    old_env[var] = ENV[var.to_s]
    ENV[var.to_s] = value
  end

  yield
ensure
  old_env.each { |var, value| ENV[var.to_s] = value }
end