Module: HamlLint::Utils
- Defined in:
- lib/haml_lint/utils.rb
Overview
A miscellaneous set of utility functions.
Class Method Summary collapse
-
.any_glob_matches?(globs_or_glob, file) ⇒ Boolean
Returns whether a glob pattern (or any of a list of patterns) matches the specified file.
-
.camel_case(str) ⇒ String
Converts a string containing underscores/hyphens/spaces into CamelCase.
- .check_error_when_compiling_haml(haml_string) ⇒ Object
-
.count_consecutive(items, offset = 0) {|item| ... } ⇒ Integer
Count the number of consecutive items satisfying the given Proc.
-
.extract_interpolated_values(text) {|interpolated_code, line| ... } ⇒ Object
Yields interpolated values within a block of text.
-
.extract_substring_positions(text, substr) ⇒ Array<Integer>
Returns indexes of all occurrences of a substring within a string.
-
.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.
-
.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.
- .handle_interpolation_with_indexes(text) ⇒ Object
- .indent(string, nb_indent) ⇒ Object
- .insert_after_indentation(code, insert) ⇒ Object
-
.is_blank_line?(line) ⇒ Boolean
Returns true if line is only whitespace.
- .map_after_first!(array, &block) ⇒ Object
- .map_subset!(array, range, &block) ⇒ Object
-
.process_erb(content) ⇒ String
Process ERB, providing some values for for versions to it.
- .regexp_for_parts(parts, join_regexp) ⇒ Object
-
.with_captured_streams(stdin_str, &_block) ⇒ String
Overrides the global stdin, stdout and stderr while within the block, to push a string in stdin, and capture both stdout and stderr which are returned.
-
.with_environment(env) ⇒ Object
Calls a block of code with a modified set of environment variables, restoring them once the code has executed.
Instance Method Summary collapse
-
#handle_interpolation_with_newline(str) ⇒ Object
Same as Haml::Util.handle_interpolation, but enables multiline mode on the regex.
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.
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.
136 137 138 |
# File 'lib/haml_lint/utils.rb', line 136 def camel_case(str) str.split(/_|-| /).map { |part| part.sub(/^\w/, &:upcase) }.join end |
.check_error_when_compiling_haml(haml_string) ⇒ Object
240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/haml_lint/utils.rb', line 240 def check_error_when_compiling_haml(haml_string) begin ruby_code = ::HamlLint::Adapter.detect_class.new(haml_string).precompile rescue StandardError => e return e end eval("BEGIN {return nil}; #{ruby_code}", binding, __FILE__, __LINE__) # rubocop:disable Security/Eval # The eval will return nil rescue ::SyntaxError $! end |
.count_consecutive(items, offset = 0) {|item| ... } ⇒ Integer
Count the number of consecutive items satisfying the given Proc.
177 178 179 180 181 |
# File 'lib/haml_lint/utils.rb', line 177 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.
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 |
# File 'lib/haml_lint/utils.rb', line 55 def extract_interpolated_values(text) # rubocop:disable Metrics/AbcSize dumped_text = text.dump # Basically, match pairs of '\' and '\ followed by the letter 'n' quoted_regex_s = "(#{Regexp.quote('\\\\')}|#{Regexp.quote('\\n')})" newline_positions = extract_substring_positions(dumped_text, quoted_regex_s) # Filter the matches to only keep those ending in 'n'. # This way, escaped \n will not be considered newline_positions.select! do |pos| dumped_text[pos - 1] == 'n' end Haml::Util.handle_interpolation(dumped_text) do |scan| line = (newline_positions.find_index { |marker| scan.charpos <= 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.
125 126 127 128 129 130 |
# File 'lib/haml_lint/utils.rb', line 125 def extract_substring_positions(text, substr) positions = [] scanner = StringScanner.new(text) positions << scanner.charpos 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.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/haml_lint/utils.rb', line 152 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.
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.(Dir.pwd)) if original_path.absolute? [path, original_path.relative_path_from(root_dir_path)] else [root_dir_path + original_path, path] end end |
.handle_interpolation_with_indexes(text) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/haml_lint/utils.rb', line 82 def handle_interpolation_with_indexes(text) newline_indexes = extract_substring_positions(text, "\n") handle_interpolation_with_newline(text) do |scan| line_index = newline_indexes.find_index { |index| scan.charpos <= index } line_index ||= newline_indexes.size line_start_char_index = if line_index == 0 0 else newline_indexes[line_index - 1] end char_index = scan.charpos - line_start_char_index yield scan, line_index, char_index end end |
.indent(string, nb_indent) ⇒ Object
215 216 217 218 219 220 221 |
# File 'lib/haml_lint/utils.rb', line 215 def indent(string, nb_indent) if nb_indent < 0 string.gsub(/^ {1,#{-nb_indent}}/, '') else string.gsub(/^/, ' ' * nb_indent) end end |
.insert_after_indentation(code, insert) ⇒ Object
194 195 196 197 |
# File 'lib/haml_lint/utils.rb', line 194 def insert_after_indentation(code, insert) index = code.index(/\S/) "#{code[0...index]}#{insert}#{code[index..]}" end |
.is_blank_line?(line) ⇒ Boolean
Returns true if line is only whitespace. Note, this is not like blank? is rails. For nil, this returns false.
236 237 238 |
# File 'lib/haml_lint/utils.rb', line 236 def is_blank_line?(line) line && line.index(/\S/).nil? end |
.map_after_first!(array, &block) ⇒ Object
230 231 232 |
# File 'lib/haml_lint/utils.rb', line 230 def map_after_first!(array, &block) map_subset!(array, 1..-1, &block) end |
.map_subset!(array, range, &block) ⇒ Object
223 224 225 226 227 228 |
# File 'lib/haml_lint/utils.rb', line 223 def map_subset!(array, range, &block) subset = array[range] return if subset.nil? || subset.empty? array[range] = subset.map(&block) end |
.process_erb(content) ⇒ String
Process ERB, providing some values for for versions to it
187 188 189 190 191 192 |
# File 'lib/haml_lint/utils.rb', line 187 def process_erb(content) # Variables for use in the ERB's post-processing rubocop_version = HamlLint::VersionComparer.for_rubocop ERB.new(content).result(binding) end |
.regexp_for_parts(parts, join_regexp) ⇒ Object
280 281 282 283 |
# File 'lib/haml_lint/utils.rb', line 280 def regexp_for_parts(parts, join_regexp) regexp_code = parts.map { |c| Regexp.quote(c) }.join(join_regexp) Regexp.new(regexp_code) end |
.with_captured_streams(stdin_str, &_block) ⇒ String
Overrides the global stdin, stdout and stderr while within the block, to push a string in stdin, and capture both stdout and stderr which are returned.
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/haml_lint/utils.rb', line 258 def with_captured_streams(stdin_str, &_block) original_stdin = $stdin # The dup is needed so that stdin_data isn't altered (encoding-wise at least) $stdin = StringIO.new(stdin_str.dup) begin original_stdout = $stdout $stdout = StringIO.new begin original_stderr = $stderr $stderr = StringIO.new yield [$stdout.string, $stderr.string] ensure $stderr = original_stderr end ensure $stdout = original_stdout end ensure $stdin = original_stdin end |
.with_environment(env) ⇒ Object
Calls a block of code with a modified set of environment variables, restoring them once the code has executed.
203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/haml_lint/utils.rb', line 203 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 |
Instance Method Details
#handle_interpolation_with_newline(str) ⇒ Object
Same as Haml::Util.handle_interpolation, but enables multiline mode on the regex
103 104 105 106 107 |
# File 'lib/haml_lint/utils.rb', line 103 def handle_interpolation_with_newline(str) scan = StringScanner.new(str) yield scan while scan.scan(/(.*?)(\\*)#([{@$])/m) scan.rest end |