Class: Keela::Scanner
- Inherits:
-
Object
- Object
- Keela::Scanner
- Defined in:
- lib/keela/scanner.rb
Constant Summary collapse
- DEFAULT_EXCLUDED_PATHS =
[".keela/excluded.yml", "keela_excluded.yml"].freeze
- DEFAULT_BASELINE_PATHS =
[".keela/baseline.yml", "keela_baseline.yml"].freeze
Instance Attribute Summary collapse
-
#baseline ⇒ Object
readonly
Returns the value of attribute baseline.
-
#configuration ⇒ Object
readonly
Returns the value of attribute configuration.
-
#new_unused ⇒ Object
readonly
Returns the value of attribute new_unused.
-
#removed ⇒ Object
readonly
Returns the value of attribute removed.
-
#source_files ⇒ Object
readonly
Returns the value of attribute source_files.
-
#strategy ⇒ Object
readonly
Returns the value of attribute strategy.
-
#unused_collection ⇒ Object
readonly
Returns the value of attribute unused_collection.
Class Method Summary collapse
- .build_file_globs(configuration) ⇒ Object
- .excluded_file?(filename, configuration) ⇒ Boolean
-
.load_source_files(configuration: Keela.configuration) ⇒ Object
Load source files once for sharing across multiple Scanner instances.
Instance Method Summary collapse
- #file_globs ⇒ Object
-
#initialize(strategy:, configuration: Keela.configuration, baseline: nil, source_files: nil) ⇒ Scanner
constructor
A new instance of Scanner.
- #run(force_report: false, update_baseline: false, silent: false) ⇒ Object
Constructor Details
#initialize(strategy:, configuration: Keela.configuration, baseline: nil, source_files: nil) ⇒ Scanner
Returns a new instance of Scanner.
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/keela/scanner.rb', line 44 def initialize(strategy:, configuration: Keela.configuration, baseline: nil, source_files: nil) @strategy = strategy @configuration = configuration @baseline = baseline || Baseline.new(resolve_baseline_path) @source_files = source_files || {} @source_files_preloaded = !source_files.nil? @unused_collection = Hash.new { |hash, key| hash[key] = [] } @new_unused = [] @removed = [] end |
Instance Attribute Details
#baseline ⇒ Object (readonly)
Returns the value of attribute baseline.
8 9 10 |
# File 'lib/keela/scanner.rb', line 8 def baseline @baseline end |
#configuration ⇒ Object (readonly)
Returns the value of attribute configuration.
8 9 10 |
# File 'lib/keela/scanner.rb', line 8 def configuration @configuration end |
#new_unused ⇒ Object (readonly)
Returns the value of attribute new_unused.
8 9 10 |
# File 'lib/keela/scanner.rb', line 8 def new_unused @new_unused end |
#removed ⇒ Object (readonly)
Returns the value of attribute removed.
8 9 10 |
# File 'lib/keela/scanner.rb', line 8 def removed @removed end |
#source_files ⇒ Object (readonly)
Returns the value of attribute source_files.
8 9 10 |
# File 'lib/keela/scanner.rb', line 8 def source_files @source_files end |
#strategy ⇒ Object (readonly)
Returns the value of attribute strategy.
8 9 10 |
# File 'lib/keela/scanner.rb', line 8 def strategy @strategy end |
#unused_collection ⇒ Object (readonly)
Returns the value of attribute unused_collection.
8 9 10 |
# File 'lib/keela/scanner.rb', line 8 def unused_collection @unused_collection end |
Class Method Details
.build_file_globs(configuration) ⇒ Object
28 29 30 31 32 33 34 |
# File 'lib/keela/scanner.rb', line 28 def self.build_file_globs(configuration) all_patterns = configuration.directory_patterns + configuration.include_patterns configuration.extensions.flat_map do |ext| all_patterns.map { |pattern| format(pattern, ext: ext) } end end |
.excluded_file?(filename, configuration) ⇒ Boolean
36 37 38 39 40 41 42 |
# File 'lib/keela/scanner.rb', line 36 def self.excluded_file?(filename, configuration) return false if configuration.exclude_patterns.empty? configuration.exclude_patterns.any? do |pattern| File.fnmatch?(pattern, filename, File::FNM_PATHNAME | File::FNM_EXTGLOB) end end |
.load_source_files(configuration: Keela.configuration) ⇒ Object
Load source files once for sharing across multiple Scanner instances. Returns a hash of { filename => [lines] }.
15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/keela/scanner.rb', line 15 def self.load_source_files(configuration: Keela.configuration) source_files = {} file_globs = build_file_globs(configuration) Dir.glob(file_globs).each do |filename| next if excluded_file?(filename, configuration) source_files[filename] = File.readlines(filename) end source_files end |
Instance Method Details
#file_globs ⇒ Object
95 96 97 98 99 100 101 |
# File 'lib/keela/scanner.rb', line 95 def file_globs all_patterns = configuration.directory_patterns + configuration.include_patterns configuration.extensions.flat_map do |ext| all_patterns.map { |pattern| format(pattern, ext: ext) } end end |
#run(force_report: false, update_baseline: false, silent: false) ⇒ Object
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 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/keela/scanner.rb', line 55 def run(force_report: false, update_baseline: false, silent: false) return true unless should_run? validate_configuration! start = Process.clock_gettime(Process::CLOCK_MONOTONIC) load_source_files definitions = find_definitions definitions = filter_excluded(definitions) # Determine mode: report if forced, updating baseline, or no baseline exists report_mode = force_report || update_baseline || !baseline.exists? find_unused(definitions, show_progress: report_mode && !silent && configuration.show_progress) if report_mode elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start reporter.print_full_report(unused_collection, elapsed) unless silent if update_baseline baseline.set(strategy.name, unused_collection) # Note: caller is responsible for calling baseline.save after all strategies run end return true end # Baseline mode: compare against known unused code compare_with_baseline unless silent reporter.print_diff_report( new_unused, removed, excluded_path: resolve_excluded_path || ".keela/excluded.yml", baseline_path: baseline.path ) end new_unused.empty? && removed.empty? end |