Exclude globs as arguments

Examples:

  $ ameba path/to/shard/*.cr !path/to/shard/lib
  $ ameba . !lib
This commit is contained in:
Vitalii Elenhaupt 2019-01-12 23:19:00 +02:00
parent 5aa7ee4854
commit 3c5e3cdef4
No known key found for this signature in database
GPG Key ID: 7558EF3A4056C706
9 changed files with 125 additions and 32 deletions

View File

@ -18,7 +18,7 @@ Benchmark.ips do |x|
].each do |n|
config = Ameba::Config.load
config.formatter = Ameba::Formatter::BaseFormatter.new
config.files = get_files(n)
config.globs = get_files(n)
s = n == 1 ? "" : "s"
x.report("#{n} source#{s}") { Ameba.run config }
end

View File

@ -114,9 +114,9 @@ module Ameba::Cli
end
end
it "accepts unknown args as files" do
it "accepts unknown args as globs" do
c = Cli.parse_args %w(source1.cr source2.cr)
c.files.should eq %w(source1.cr source2.cr)
c.globs.should eq %w(source1.cr source2.cr)
end
it "accepts one unknown arg as explain location if it has correct format" do
@ -132,7 +132,7 @@ module Ameba::Cli
it "allows args to be blank" do
c = Cli.parse_args [] of String
c.formatter.should be_nil
c.files.should be_nil
c.globs.should be_nil
c.only.should be_nil
c.except.should be_nil
c.config.should eq Config::PATH

View File

@ -12,28 +12,37 @@ module Ameba
it "loads custom config" do
config = Config.load config_sample
config.should_not be_nil
config.files.should_not be_nil
config.globs.should_not be_nil
config.formatter.should_not be_nil
end
it "loads default config" do
config = Config.load
config.should_not be_nil
config.files.should_not be_nil
config.globs.should_not be_nil
config.formatter.should_not be_nil
end
end
describe "#files, #files=" do
describe "#globs, #globs=" do
config = Config.load config_sample
it "holds source files" do
config.files.should contain "spec/ameba/config_spec.cr"
it "holds source globs" do
config.globs.should contain "spec/ameba/config_spec.cr"
end
it "allows to set files" do
config.files = ["file.cr"]
config.files.should eq ["file.cr"]
it "allows to set globs" do
config.globs = ["file.cr"]
config.globs.should eq ["file.cr"]
end
end
describe "#sources" do
config = Config.load config_sample
it "returns list of sources" do
config.sources.size.should be > 0
config.sources.first.should be_a Source
end
end

View File

@ -0,0 +1,38 @@
require "../spec_helper"
module Ameba
struct GlobUtilsClass
include GlobUtils
end
subject = GlobUtilsClass.new
current_file_basename = File.basename(__FILE__)
current_file_path = "spec/ameba/#{current_file_basename}"
describe GlobUtils do
describe "#find_files_by_globs" do
it "returns a file by globs" do
subject.find_files_by_globs(["**/#{current_file_basename}"])
.should eq [current_file_path]
end
it "returns files by globs" do
subject.find_files_by_globs(["**/*_spec.cr"])
.should contain current_file_path
end
it "doesn't return rejected globs" do
subject
.find_files_by_globs(["**/*_spec.cr", "!**/#{current_file_basename}"])
.should_not contain current_file_path
end
end
describe "#expand" do
it "expands globs" do
subject.expand(["**/#{current_file_basename}"])
.should eq [current_file_path]
end
end
end
end

View File

@ -4,7 +4,7 @@ module Ameba
private def runner(files = [__FILE__], formatter = DummyFormatter.new)
config = Config.load
config.formatter = formatter
config.files = files
config.globs = files
config.update_rule ErrorRule.rule_name, enabled: false

View File

@ -8,7 +8,7 @@ module Ameba::Cli
def run(args)
opts = parse_args args
config = Config.load opts.config, opts.colors?
config.files = opts.files
config.globs = opts.globs
configure_formatter(config, opts)
configure_rules(config, opts)
@ -28,7 +28,7 @@ module Ameba::Cli
private class Opts
property config = Config::PATH
property formatter : Symbol | String | Nil
property files : Array(String)?
property globs : Array(String)?
property only : Array(String)?
property except : Array(String)?
property location_to_explain : NamedTuple(file: String, line: Int32, column: Int32)?
@ -48,7 +48,7 @@ module Ameba::Cli
if f.size == 1 && f.first =~ /.+:\d+:\d+/
configure_explain_opts(f.first, opts)
else
opts.files = f if f.any?
opts.globs = f if f.any?
end
end
@ -121,7 +121,7 @@ module Ameba::Cli
private def configure_explain_opts(loc, opts)
location_to_explain = parse_explain_location(loc)
opts.location_to_explain = location_to_explain
opts.files = [location_to_explain[:file]]
opts.globs = [location_to_explain[:file]]
opts.formatter = :silent
end

View File

@ -1,4 +1,5 @@
require "yaml"
require "./glob_utils"
# A configuration entry for `Ameba::Runner`.
#
@ -12,6 +13,8 @@ require "yaml"
# By default config loads `.ameba.yml` file in a current directory.
#
class Ameba::Config
include GlobUtils
AVAILABLE_FORMATTERS = {
progress: Formatter::DotFormatter,
todo: Formatter::TODOFormatter,
@ -23,7 +26,7 @@ class Ameba::Config
PATH = ".ameba.yml"
setter formatter : Formatter::BaseFormatter?
setter files : Array(String)?
setter globs : Array(String)?
getter rules : Array(Rule::Base)
@rule_groups : Hash(String, Array(Rule::Base))
@ -60,16 +63,30 @@ class Ameba::Config
# Returns a list of paths (with wildcards) to files.
# Represents a list of sources to be inspected.
# If files are not set, it will return default list of files.
# If globs are not set, it will return default list of files.
#
# ```
# config = Ameba::Config.load
# config.files = ["**/*.cr"]
# config.files
# config.globs = ["**/*.cr"]
# config.globs
# ```
#
def files
@files ||= default_files
def globs
@globs ||= default_files
end
# Returns a list of sources.
#
# ```
# config = Ameba::Config.load
# config.sources # => list of default sources
# config.globs = ["**/*.cr"]
# config.sources # => list of sources pointing to files found by the wildcards
# ```
#
def sources
find_files_by_globs(globs)
.map { |path| Source.new File.read(path), path }
end
# Returns a formatter to be used while inspecting files.

37
src/ameba/glob_utils.cr Normal file
View File

@ -0,0 +1,37 @@
module Ameba
# Helper module that is utilizes helpers for working with globs.
module GlobUtils
# Returns all files that match specified globs.
# Globs can have wildcards or be rejected:
#
# ```
# find_files_by_globs(["**/*.cr", "!lib"])
# ```
#
def find_files_by_globs(globs)
rejected = rejected_globs(globs)
selected = globs - rejected
expand(selected) - expand(rejected.map! { |p| p[1..-1] })
end
# Expands globs. Globs can point to files or even directories.
#
# ```
# expand(["spec/*.cr", "src"]) # => all files in src folder + first level specs
# ```
#
def expand(globs)
globs.map do |glob|
glob += "/**/*.cr" if File.directory?(glob)
Dir[glob]
end.flatten
end
private def rejected_globs(globs)
globs.select do |glob|
glob.starts_with?('!') && !File.exists?(glob)
end
end
end
end

View File

@ -37,7 +37,7 @@ module Ameba
# ```
#
def initialize(config : Config)
@sources = load_sources(config)
@sources = config.sources
@formatter = config.formatter
@rules = config.rules.select(&.enabled).reject!(&.special?)
@ -115,13 +115,5 @@ module Ameba
rule.test(source)
end
end
private def load_sources(config)
config.files.map do |wildcard|
wildcard += "/**/*.cr" if File.directory?(wildcard)
Dir[wildcard]
end.flatten
.map { |path| Source.new File.read(path), path }
end
end
end