class SCSSLint::CLI

Responsible for parsing command-line options and executing the appropriate application logic based on the options specified.

Constants

EXIT_CODES

Subset of semantic exit codes conforming to `sysexits` documentation.

Attributes

config[R]
log[R]
options[R]

Public Class Methods

new(logger) click to toggle source

Create a CLI that outputs to the specified logger.

@param logger [SCSSLint::Logger]

# File lib/scss_lint/cli.rb, line 27
def initialize(logger)
  @log = logger
end

Public Instance Methods

run(args) click to toggle source
# File lib/scss_lint/cli.rb, line 31
def run(args)
  options = SCSSLint::Options.new.parse(args)
  act_on_options(options)
rescue => ex
  handle_runtime_exception(ex, options)
end

Private Instance Methods

act_on_options(options) click to toggle source
# File lib/scss_lint/cli.rb, line 42
def act_on_options(options)
  log.color_enabled = options.fetch(:color, log.tty?)
  load_required_paths(options)
  load_reporters(options)

  if options[:help]
    print_help(options)
  elsif options[:version]
    print_version
  elsif options[:show_formatters]
    print_formatters
  else
    config = setup_configuration(options)

    if options[:show_linters]
      print_linters
    else
      scan_for_lints(options, config)
    end
  end
end
halt(exit_status = :ok) click to toggle source

Used for ease-of testing @param exit_status [Symbol]

# File lib/scss_lint/cli.rb, line 261
def halt(exit_status = :ok)
  EXIT_CODES[exit_status]
end
handle_runtime_exception(exception, options) click to toggle source
# File lib/scss_lint/cli.rb, line 86
def handle_runtime_exception(exception, options) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/LineLength, Metrics/MethodLength
  case exception
  when SCSSLint::Exceptions::InvalidCLIOption
    log.error exception.message
    log.info 'Run `scss-lint --help` for usage documentation'
    halt :usage
  when SCSSLint::Exceptions::InvalidConfiguration
    log.error exception.message
    halt :config
  when SCSSLint::Exceptions::RequiredLibraryMissingError
    log.error exception.message
    halt :unavailable
  when SCSSLint::Exceptions::NoFilesError
    log.error exception.message
    halt :no_files
  when SCSSLint::Exceptions::PluginGemLoadError
    log.error exception.message
    halt :plugin
  when Errno::ENOENT
    log.error exception.message
    halt :no_input
  when NoSuchLinter
    log.error exception.message
    halt :usage
  when SCSSLint::Exceptions::PreprocessorError
    log.error exception.message
    halt :preprocessor
  else
    config_file = relevant_configuration_file(options) if options

    log.bold_error exception.message
    log.error exception.backtrace.join("\n")
    log.warning 'Report this bug at ', false
    log.info BUG_REPORT_URL
    log.newline
    log.success 'To help fix this issue, please include:'
    log.log '- The above stack trace'
    log.log '- SCSS-Lint version: ', false
    log.info SCSSLint::VERSION
    log.log '- Sass version: ', false
    log.info Gem.loaded_specs['sass'].version.to_s
    log.log '- Ruby version: ', false
    log.info RUBY_VERSION
    if config_file
      log.log '- Contents of ', false
      log.info File.expand_path(config_file)
    end
    halt :software
  end
end
load_reporters(options) click to toggle source
# File lib/scss_lint/cli.rb, line 209
def load_reporters(options)
  options[:reporters].map! do |reporter_name, output_file|
    begin
      reporter = SCSSLint::Reporter.const_get(reporter_name + 'Reporter')
    rescue NameError
      raise SCSSLint::Exceptions::InvalidCLIOption,
            "Invalid output format specified: #{reporter_name}"
    end
    [reporter, output_file]
  end
end
load_required_paths(options) click to toggle source
# File lib/scss_lint/cli.rb, line 200
def load_required_paths(options)
  Array(options[:required_paths]).each do |path|
    require path
  end
rescue LoadError => ex
  raise SCSSLint::Exceptions::RequiredLibraryMissingError,
        "Required library not found: #{ex.message}"
end
merge_options_with_config(options, config) click to toggle source

@param options [Hash] @param config [Config] @return [Config]

# File lib/scss_lint/cli.rb, line 160
def merge_options_with_config(options, config)
  if options[:excluded_files]
    options[:excluded_files].each do |file|
      config.exclude_file(file)
    end
  end

  if options[:included_linters]
    config.disable_all_linters
    LinterRegistry.extract_linters_from(options[:included_linters]).each do |linter|
      config.enable_linter(linter)
    end
  end

  if options[:excluded_linters]
    LinterRegistry.extract_linters_from(options[:excluded_linters]).each do |linter|
      config.disable_linter(linter)
    end
  end

  config
end
print_formatters() click to toggle source
print_help(options) click to toggle source

@param options [Hash]

print_linters() click to toggle source
print_version() click to toggle source

@param options [Hash]

relevant_configuration_file(options) click to toggle source

Return the path of the configuration file that should be loaded.

@param options [Hash] @return [String]

# File lib/scss_lint/cli.rb, line 147
def relevant_configuration_file(options)
  if options[:config_file]
    options[:config_file]
  elsif File.exist?(Config::FILE_NAME)
    Config::FILE_NAME
  elsif File.exist?(Config.user_file)
    Config.user_file
  end
end
report_lints(options, lints, files) click to toggle source

@param options [Hash] @param lints [Array<Lint>] @param files [Array<Hash>]

# File lib/scss_lint/cli.rb, line 186
def report_lints(options, lints, files)
  sorted_lints = lints.sort_by { |l| [l.filename, l.location] }
  options.fetch(:reporters).each do |reporter, output|
    results = reporter.new(sorted_lints, files, log).report_lints
    next unless results

    if output == :stdout
      log.log results
    else
      File.new(output, 'w+').print results
    end
  end
end
scan_for_lints(options, config) click to toggle source
# File lib/scss_lint/cli.rb, line 64
def scan_for_lints(options, config)
  runner = Runner.new(config)
  files =
    if options[:stdin_file_path]
      [{ file: STDIN, path: options[:stdin_file_path] }]
    else
      FileFinder.new(config).find(options[:files]).map do |file_path|
        { path: file_path }
      end
    end
  runner.run(files)
  report_lints(options, runner.lints, files)

  if runner.lints.any?(&:error?)
    halt :error
  elsif runner.lints.any?
    halt :warning
  else
    halt :ok
  end
end
setup_configuration(options) click to toggle source
# File lib/scss_lint/cli.rb, line 137
def setup_configuration(options)
  config_file = relevant_configuration_file(options)
  config = config_file ? Config.load(config_file) : Config.default
  merge_options_with_config(options, config)
end