class SCSSLint::Engine

Contains all information for a parsed SCSS file, including its name, contents, and parse tree.

Constants

ENGINE_OPTIONS

Attributes

any_control_commands[R]
contents[R]
filename[R]
lines[R]
tree[R]

Public Class Methods

new(options = {}) click to toggle source

Creates a parsed representation of an SCSS document from the given string or file.

@param options [Hash] @option options [String] :file The file to load @option options [String] :path The path of the file to load @option options [String] :code The code to parse @option options [String] :preprocess_command A preprocessing command @option options [List<String>] :preprocess_files A list of files that should be preprocessed

# File lib/scss_lint/engine.rb, line 24
def initialize(options = {})
  @preprocess_command = options[:preprocess_command]
  @preprocess_files = options[:preprocess_files]
  build(options)

  # Need to force encoding to avoid Windows-related bugs.
  # Need to encode with universal newline to avoid other Windows-related bugs.
  # Need `to_a` for Ruby 1.9.3.
  encoding = 'UTF-8'
  @lines = @contents.force_encoding(encoding)
                    .encode(encoding, universal_newline: true)
                    .lines.to_a
  @tree = @engine.to_tree
  find_any_control_commands
rescue Encoding::UndefinedConversionError, Sass::SyntaxError, ArgumentError => error
  if error.is_a?(Encoding::UndefinedConversionError) ||
     error.message.match(/invalid.*(byte sequence|character)/i)
    raise FileEncodingError,
          "Unable to parse SCSS file: #{error}",
          error.backtrace
  else
    raise
  end
end

Private Instance Methods

build(options) click to toggle source
# File lib/scss_lint/engine.rb, line 51
def build(options)
  if options[:path]
    build_from_file(options)
  elsif options[:code]
    build_from_string(options[:code])
  end
end
build_from_file(options) click to toggle source

@param options [Hash] @option file [IO] if provided, us this as the file object @option path [String] path of file, loading from this if `file` object not

given
# File lib/scss_lint/engine.rb, line 63
def build_from_file(options)
  @filename = options[:path]
  @contents = options[:file] ? options[:file].read : File.read(@filename)
  preprocess_contents
  @engine = Sass::Engine.new(@contents, ENGINE_OPTIONS.merge(filename: @filename))
end
build_from_string(scss) click to toggle source

@param scss [String]

# File lib/scss_lint/engine.rb, line 71
def build_from_string(scss)
  @contents = scss
  preprocess_contents
  @engine = Sass::Engine.new(@contents, ENGINE_OPTIONS)
end
find_any_control_commands() click to toggle source
# File lib/scss_lint/engine.rb, line 77
def find_any_control_commands
  @any_control_commands =
    @lines.any? { |line| line['scss-lint:disable'] || line['scss-line:enable'] }
end
preprocess_contents() click to toggle source
# File lib/scss_lint/engine.rb, line 82
def preprocess_contents # rubocop:disable CyclomaticComplexity
  return unless @preprocess_command
  # Never preprocess :code scss if @preprocess_files is specified.
  return if @preprocess_files && @filename.nil?
  return if @preprocess_files &&
            @preprocess_files.none? { |pattern| File.fnmatch(pattern, @filename) }
  @contents, status = Open3.capture2(@preprocess_command, stdin_data: @contents)
  raise SCSSLint::Exceptions::PreprocessorError if status != 0
end