Class: Goodcheck::Commands::Check

Inherits:
Object
  • Object
show all
Includes:
ConfigLoading, HomePath
Defined in:
lib/goodcheck/commands/check.rb

Instance Attribute Summary collapse

Attributes included from ConfigLoading

#config

Instance Method Summary collapse

Methods included from HomePath

#cache_dir_path

Methods included from ConfigLoading

#handle_config_errors, #load_config!

Constructor Details

#initialize(config_path:, rules:, targets:, reporter:, stderr:, home_path:, force_download:) ⇒ Check

Returns a new instance of Check.



15
16
17
18
19
20
21
22
23
# File 'lib/goodcheck/commands/check.rb', line 15

def initialize(config_path:, rules:, targets:, reporter:, stderr:, home_path:, force_download:)
  @config_path = config_path
  @rules = rules
  @targets = targets
  @reporter = reporter
  @stderr = stderr
  @force_download = force_download
  @home_path = home_path
end

Instance Attribute Details

#config_path ⇒ Object (readonly)

Returns the value of attribute config_path.



4
5
6
# File 'lib/goodcheck/commands/check.rb', line 4

def config_path
  @config_path
end

#force_download ⇒ Object (readonly)

Returns the value of attribute force_download.



9
10
11
# File 'lib/goodcheck/commands/check.rb', line 9

def force_download
  @force_download
end

#home_path ⇒ Object (readonly)

Returns the value of attribute home_path.



10
11
12
# File 'lib/goodcheck/commands/check.rb', line 10

def home_path
  @home_path
end

#reporter ⇒ Object (readonly)

Returns the value of attribute reporter.



7
8
9
# File 'lib/goodcheck/commands/check.rb', line 7

def reporter
  @reporter
end

#rules ⇒ Object (readonly)

Returns the value of attribute rules.



5
6
7
# File 'lib/goodcheck/commands/check.rb', line 5

def rules
  @rules
end

#stderr ⇒ Object (readonly)

Returns the value of attribute stderr.



8
9
10
# File 'lib/goodcheck/commands/check.rb', line 8

def stderr
  @stderr
end

#targets ⇒ Object (readonly)

Returns the value of attribute targets.



6
7
8
# File 'lib/goodcheck/commands/check.rb', line 6

def targets
  @targets
end

Instance Method Details

#each_check ⇒ Object



50
51
52
53
54
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
# File 'lib/goodcheck/commands/check.rb', line 50

def each_check
  targets.each do |target|
    Goodcheck.logger.info "Checking target: #{target}"
    Goodcheck.logger.tagged target.to_s do
      each_file target, immediate: true do |path|
        Goodcheck.logger.debug "Checking file: #{path}"
        Goodcheck.logger.tagged path.to_s do
          reporter.file(path) do
            buffers = {}

            config.rules_for_path(path, rules_filter: rules) do |rule, glob, trigger|
              Goodcheck.logger.debug "Checking rule: #{rule.id}"
              begin
                encoding = glob&.encoding || Encoding.default_external.name

                if buffers[encoding]
                  buffer = buffers[encoding]
                else
                  content = path.read(encoding: encoding).encode(Encoding.default_internal || Encoding::UTF_8)
                  buffer = Buffer.new(path: path, content: content)
                  buffers[encoding] = buffer
                end

                yield buffer, rule, trigger
              rescue ArgumentError => exn
                stderr.puts "#{path}: #{exn.inspect}"
              end
            end
          end
        end
      end
    end
  end
end

#each_file(path, immediate: false, &block) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/goodcheck/commands/check.rb', line 89

def each_file(path, immediate: false, &block)
  case
  when path.symlink?
    # noop
  when path.directory?
    if immediate || (!is_dotfile?(path) && !excluded?(path))
      path.children.each do |child|
        each_file(child, &block)
      end
    end
  when path.file?
    case
    when path == config_path || is_dotfile?(path)
      # Skip dotfiles/config file unless explicitly given by command line
      yield path if immediate
    when excluded?(path)
      # Skip excluded files unless explicitly given by command line
      yield path if immediate
    else
      yield path
    end
  end
end

#excluded?(path) ⇒ Boolean

Returns:

  • (Boolean)


113
114
115
# File 'lib/goodcheck/commands/check.rb', line 113

def excluded?(path)
  config.exclude_paths.any? {|pattern| path.fnmatch?(pattern, File::FNM_PATHNAME | File::FNM_EXTGLOB) }
end

#is_dotfile?(path) ⇒ Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/goodcheck/commands/check.rb', line 85

def is_dotfile?(path)
  /\A\.[^.]+/.match?(path.basename.to_s)
end

#run ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/goodcheck/commands/check.rb', line 25

def run
  handle_config_errors(stderr) do
    issue_reported = false

    reporter.analysis do
      load_config!(force_download: force_download, cache_path: cache_dir_path)
      each_check do |buffer, rule, trigger|
        reported_issues = Set[]

        reporter.rule(rule) do
          analyzer = Analyzer.new(rule: rule, buffer: buffer, trigger: trigger)
          analyzer.scan do |issue|
            if reported_issues.add?(issue)
              issue_reported = true
              reporter.issue(issue)
            end
          end
        end
      end
    end

    issue_reported ? 2 : 0
  end
end