class FoodCritic::CommandLine

Command line parsing.

def self.main(argv = ARGV, out = $stdout)

def self.main(argv = ARGV, out = $stdout)
  cmd_line = CommandLine.new(argv)
  review, status = Linter.run(cmd_line)
  printer = cmd_line.show_context? ? ContextOutput.new(out) : SummaryOutput.new(out)
  printer.output(review)
  status.to_i
end

def cookbook_paths

Returns:
  • (Array) - Path(s) to the cookbook(s) being checked.
def cookbook_paths
  @args + Array(@options[:cookbook_paths])
end

def environment_paths

Returns:
  • (Array) - Path(s) to the environment directories checked.
def environment_paths
  Array(@options[:environment_paths])
end

def help

Returns:
  • (String) - Help text describing the command-line options available.
def help
  @parser.help + show_end_of_life_msg
end

def initialize(args)

Parameters:
  • args (Array) -- The command line arguments
def initialize(args)
  @args = args
  @original_args = args.dup
  @options = {
    fail_tags: ["~opensource"],
    tags: [],
    include_rules: [],
    cookbook_paths: [],
    role_paths: [],
    environment_paths: [],
    exclude_paths: ["test/**/*", "spec/**/*", "features/**/*"],
    progress: true,
    ast_cache_size: 5,
  }
  @parser = OptionParser.new do |opts|
    opts.banner = "foodcritic [cookbook_paths]"
    opts.on("-t", "--tags TAGS",
      "Check against (or exclude ~) rules with the "\
      "specified tags.") do |t|
        @options[:tags] << t
      end
    opts.on("-l", "--list",
      "List all enabled rules and their descriptions.") do |t|
        @options[:list] = t
      end
    opts.on("-f", "--epic-fail TAGS",
      "Fail the build based on tags. Default of 'any' to fail "\
      "on all warnings.") do |t|
        @options[:fail_tags] << t
      end
    opts.on("-c", "--chef-version VERSION",
      "Only check against rules valid for this version "\
      "of Chef.") do |c|
        @options[:chef_version] = c
      end
    opts.on("-r", "--rule-file PATH",
      "Specify file with rules to be used or ignored ") do |c|
        @options[:rule_file] = c
      end
    opts.on("-s", "--ast-cache-size NUM", Integer,
      "Change the size of the AST cache.") do |s|
        @options[:ast_cache_size] = s
      end
    opts.on("-B", "--cookbook-path PATH",
      "Cookbook path(s) to check.") do |b|
        @options[:cookbook_paths] << b
      end
    opts.on("-C", "--[no-]context",
      "Show lines matched against rather than the "\
      "default summary.") do |c|
        @options[:context] = c
      end
    opts.on("-E", "--environment-path PATH",
      "Environment path(s) to check.") do |e|
        @options[:environment_paths] << e
      end
    opts.on("-I", "--include PATH",
      "Additional rule file path(s) to load.") do |i|
        @options[:include_rules] << i
      end
    opts.on("-G", "--search-gems",
      "Search rubygems for rule files with the path "\
      "foodcritic/rules/**/*.rb") do |g|
        @options[:search_gems] = true
      end
    opts.on("-P", "--[no-]progress",
      "Show progress of files being checked. default: true") do |q|
        @options[:progress] = q
      end
    opts.on("-R", "--role-path PATH",
      "Role path(s) to check.") do |r|
        @options[:role_paths] << r
      end
    opts.on("-S", "--search-grammar PATH",
      "Specify grammar to use when validating search syntax.") do |s|
        @options[:search_grammar] = s
      end
    opts.on("-V", "--version",
      "Display the foodcritic version.") do |v|
        @options[:version] = true
      end
    opts.on("-X", "--exclude PATH",
      "Exclude path(s) from being linted. PATH is relative to the cookbook, not an absolute PATH. Default test/**/*,spec/**/*,features/**/*") do |e|
        options[:exclude_paths] << e
      end
  end
  # -v is not implemented but OptionParser gives the Foodcritic's version
  # if that flag is passed
  if args.include? "-v"
    help
  else
    begin
      @parser.parse!(args) unless show_help?
    rescue OptionParser::InvalidOption => e
      e.recover args
    end
  end
end

def list_rules?

Returns:
  • (Boolean) - True if a rule listing is requested.
def list_rules?
  @options.key?(:list)
end

def options

Returns:
  • (Hash) - The parsed command-line options.
def options
  original_options.merge(
    {
      cookbook_paths: cookbook_paths,
      role_paths: role_paths,
      environment_paths: environment_paths,
    }
  )
end

def original_options

Returns:
  • (Hash) - The original command-line options.
def original_options
  @options
end

def role_paths

Returns:
  • (Array) - Path(s) to the role directories being checked.
def role_paths
  Array(@options[:role_paths])
end

def show_context?

Returns:
  • (Boolean) - True if matches should be shown with context.
def show_context?
  @options[:context]
end

def show_end_of_life_msg

Returns:
  • (String) - A text to warn end users about foodcritic's end of life
def show_end_of_life_msg
  "
*******************************************************************************
WARNING: Foodcritic will be end of life in April 2020
*******************************************************************************
Please use Cookstyle to ensure all of your Chef Infra code meets the latest
best practices.
Cookstyle is a code linting tool that helps you to write better Chef Infra
Cookbooks by detecting and automatically correct cookbook code.
For more information, use the command:
cookstyle -h
  "
end

def show_help?

Returns:
  • (Boolean) - True if help should be shown.
def show_help?
  @args.length == 1 && @args.first == "--help"
end

def show_version?

Returns:
  • (Boolean) - True if the version should be shown.
def show_version?
  @options.key?(:version)
end

def valid_grammar?

Returns:
  • (Boolean) - True if the grammar has not been provided or can be
def valid_grammar?
  return true unless options.key?(:search_grammar)
  return false unless File.exist?(options[:search_grammar])
  search = FoodCritic::Chef::Search.new
  search.create_parser([options[:search_grammar]])
  search.parser?
end

def valid_paths?

Returns:
  • (Boolean) - True if the paths exist.
def valid_paths?
  paths = options[:cookbook_paths] + options[:role_paths] +
    options[:environment_paths]
  paths.any? && paths.all? { |path| File.exist?(path) }
end

def version

Returns:
  • (String) - Current installed version.
def version
  "foodcritic #{FoodCritic::VERSION}"
end