goodcheck 2.5.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +31 -2
 - data/README.md +4 -447
 - data/lib/goodcheck.rb +5 -5
 - data/lib/goodcheck/analyzer.rb +13 -9
 - data/lib/goodcheck/buffer.rb +11 -16
 - data/lib/goodcheck/cli.rb +80 -56
 - data/lib/goodcheck/commands/check.rb +42 -26
 - data/lib/goodcheck/commands/config_loading.rb +20 -2
 - data/lib/goodcheck/commands/init.rb +4 -2
 - data/lib/goodcheck/commands/pattern.rb +2 -1
 - data/lib/goodcheck/commands/test.rb +14 -11
 - data/lib/goodcheck/config_loader.rb +17 -20
 - data/lib/goodcheck/error.rb +3 -0
 - data/lib/goodcheck/exit_status.rb +6 -0
 - data/lib/goodcheck/glob.rb +14 -3
 - data/lib/goodcheck/import_loader.rb +42 -10
 - data/lib/goodcheck/issue.rb +3 -3
 - data/lib/goodcheck/location.rb +28 -0
 - data/lib/goodcheck/logger.rb +4 -4
 - data/lib/goodcheck/reporters/json.rb +4 -0
 - data/lib/goodcheck/reporters/text.rb +42 -11
 - data/lib/goodcheck/version.rb +1 -1
 - metadata +29 -92
 - data/.github/workflows/test.yml +0 -37
 - data/.gitignore +0 -13
 - data/.rubocop.yml +0 -5
 - data/Dockerfile +0 -13
 - data/Gemfile +0 -6
 - data/Rakefile +0 -70
 - data/benchmark/gc.c +0 -12221
 - data/bin/console +0 -14
 - data/bin/setup +0 -8
 - data/cheatsheet.pdf +0 -0
 - data/docusaurus/.dockerignore +0 -2
 - data/docusaurus/.gitignore +0 -12
 - data/docusaurus/Dockerfile +0 -10
 - data/docusaurus/docker-compose.yml +0 -18
 - data/docusaurus/docs/commands.md +0 -69
 - data/docusaurus/docs/configuration.md +0 -300
 - data/docusaurus/docs/development.md +0 -15
 - data/docusaurus/docs/getstarted.md +0 -46
 - data/docusaurus/docs/rules.md +0 -79
 - data/docusaurus/website/README.md +0 -193
 - data/docusaurus/website/core/Footer.js +0 -100
 - data/docusaurus/website/package.json +0 -14
 - data/docusaurus/website/pages/en/index.js +0 -207
 - data/docusaurus/website/pages/en/versions.js +0 -118
 - data/docusaurus/website/sidebars.json +0 -11
 - data/docusaurus/website/siteConfig.js +0 -171
 - data/docusaurus/website/static/css/code-block-buttons.css +0 -39
 - data/docusaurus/website/static/css/custom.css +0 -245
 - data/docusaurus/website/static/img/favicon.ico +0 -0
 - data/docusaurus/website/static/js/code-block-buttons.js +0 -47
 - data/docusaurus/website/versioned_docs/version-1.0.0/commands.md +0 -70
 - data/docusaurus/website/versioned_docs/version-1.0.0/configuration.md +0 -296
 - data/docusaurus/website/versioned_docs/version-1.0.0/development.md +0 -16
 - data/docusaurus/website/versioned_docs/version-1.0.0/getstarted.md +0 -47
 - data/docusaurus/website/versioned_docs/version-1.0.0/rules.md +0 -81
 - data/docusaurus/website/versioned_docs/version-1.0.2/rules.md +0 -79
 - data/docusaurus/website/versioned_docs/version-2.4.0/configuration.md +0 -301
 - data/docusaurus/website/versioned_docs/version-2.4.3/rules.md +0 -80
 - data/docusaurus/website/versioned_sidebars/version-1.0.0-sidebars.json +0 -11
 - data/docusaurus/website/versioned_sidebars/version-1.0.2-sidebars.json +0 -11
 - data/docusaurus/website/versioned_sidebars/version-2.4.0-sidebars.json +0 -11
 - data/docusaurus/website/versions.json +0 -10
 - data/docusaurus/website/yarn.lock +0 -6806
 - data/goodcheck.gemspec +0 -36
 - data/goodcheck.yml +0 -10
 - data/logo/GoodCheck Horizontal.pdf +0 -899
 - data/logo/GoodCheck Horizontal.png +0 -0
 - data/logo/GoodCheck Horizontal.svg +0 -55
 - data/logo/GoodCheck logo.png +0 -0
 - data/logo/GoodCheck vertical.png +0 -0
 - data/sample.yml +0 -57
 
    
        data/lib/goodcheck.rb
    CHANGED
    
    | 
         @@ -1,19 +1,19 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require "strscan"
         
     | 
| 
       2 
2 
     | 
    
         
             
            require "pathname"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "set"
         
     | 
| 
       3 
4 
     | 
    
         
             
            require "strong_json"
         
     | 
| 
       4 
5 
     | 
    
         
             
            require "yaml"
         
     | 
| 
       5 
6 
     | 
    
         
             
            require "json"
         
     | 
| 
       6 
     | 
    
         
            -
            require " 
     | 
| 
       7 
     | 
    
         
            -
            require "active_support/core_ext/integer/inflections"
         
     | 
| 
       8 
     | 
    
         
            -
            require "active_support/tagged_logging"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "logger"
         
     | 
| 
       9 
8 
     | 
    
         
             
            require "rainbow"
         
     | 
| 
       10 
9 
     | 
    
         
             
            require "digest/sha2"
         
     | 
| 
       11 
     | 
    
         
            -
            require " 
     | 
| 
      
 10 
     | 
    
         
            +
            require "net/http"
         
     | 
| 
       12 
11 
     | 
    
         | 
| 
       13 
12 
     | 
    
         
             
            require "goodcheck/version"
         
     | 
| 
      
 13 
     | 
    
         
            +
            require "goodcheck/error"
         
     | 
| 
       14 
14 
     | 
    
         
             
            require "goodcheck/logger"
         
     | 
| 
       15 
15 
     | 
    
         
             
            require "goodcheck/home_path"
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
      
 16 
     | 
    
         
            +
            require "goodcheck/exit_status"
         
     | 
| 
       17 
17 
     | 
    
         
             
            require "goodcheck/glob"
         
     | 
| 
       18 
18 
     | 
    
         
             
            require "goodcheck/buffer"
         
     | 
| 
       19 
19 
     | 
    
         
             
            require "goodcheck/location"
         
     | 
    
        data/lib/goodcheck/analyzer.rb
    CHANGED
    
    | 
         @@ -13,7 +13,7 @@ module Goodcheck 
     | 
|
| 
       13 
13 
     | 
    
         
             
                def scan(&block)
         
     | 
| 
       14 
14 
     | 
    
         
             
                  if block_given?
         
     | 
| 
       15 
15 
     | 
    
         
             
                    if trigger.patterns.empty?
         
     | 
| 
       16 
     | 
    
         
            -
                      yield Issue.new(buffer: buffer,  
     | 
| 
      
 16 
     | 
    
         
            +
                      yield Issue.new(buffer: buffer, rule: rule)
         
     | 
| 
       17 
17 
     | 
    
         
             
                    else
         
     | 
| 
       18 
18 
     | 
    
         
             
                      var_pats, novar_pats = trigger.patterns.partition {|pat|
         
     | 
| 
       19 
19 
     | 
    
         
             
                        pat.is_a?(Pattern::Token) && !pat.variables.empty?
         
     | 
| 
         @@ -44,9 +44,7 @@ module Goodcheck 
     | 
|
| 
       44 
44 
     | 
    
         
             
                    while true
         
     | 
| 
       45 
45 
     | 
    
         
             
                      case
         
     | 
| 
       46 
46 
     | 
    
         
             
                      when scanner.scan_until(regexp)
         
     | 
| 
       47 
     | 
    
         
            -
                         
     | 
| 
       48 
     | 
    
         
            -
                        range = (scanner.pos - text.bytesize) .. scanner.pos
         
     | 
| 
       49 
     | 
    
         
            -
                        issues << Issue.new(buffer: buffer, range: range, rule: rule, text: text)
         
     | 
| 
      
 47 
     | 
    
         
            +
                        issues << new_issue_with_matched(scanner)
         
     | 
| 
       50 
48 
     | 
    
         
             
                      else
         
     | 
| 
       51 
49 
     | 
    
         
             
                        break
         
     | 
| 
       52 
50 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -55,7 +53,7 @@ module Goodcheck 
     | 
|
| 
       55 
53 
     | 
    
         
             
                    issues.each(&block)
         
     | 
| 
       56 
54 
     | 
    
         
             
                  else
         
     | 
| 
       57 
55 
     | 
    
         
             
                    unless regexp =~ buffer.content
         
     | 
| 
       58 
     | 
    
         
            -
                      yield Issue.new(buffer: buffer,  
     | 
| 
      
 56 
     | 
    
         
            +
                      yield Issue.new(buffer: buffer, rule: rule)
         
     | 
| 
       59 
57 
     | 
    
         
             
                    end
         
     | 
| 
       60 
58 
     | 
    
         
             
                  end
         
     | 
| 
       61 
59 
     | 
    
         
             
                end
         
     | 
| 
         @@ -68,9 +66,7 @@ module Goodcheck 
     | 
|
| 
       68 
66 
     | 
    
         
             
                      case
         
     | 
| 
       69 
67 
     | 
    
         
             
                      when scanner.scan_until(pat.regexp)
         
     | 
| 
       70 
68 
     | 
    
         
             
                        if pat.test_variables(scanner)
         
     | 
| 
       71 
     | 
    
         
            -
                           
     | 
| 
       72 
     | 
    
         
            -
                          range = (scanner.pos - text.bytesize) .. scanner.pos
         
     | 
| 
       73 
     | 
    
         
            -
                          yield Issue.new(buffer: buffer, range: range, rule: rule, text: text)
         
     | 
| 
      
 69 
     | 
    
         
            +
                          yield new_issue_with_matched(scanner)
         
     | 
| 
       74 
70 
     | 
    
         
             
                        end
         
     | 
| 
       75 
71 
     | 
    
         
             
                      else
         
     | 
| 
       76 
72 
     | 
    
         
             
                        break
         
     | 
| 
         @@ -84,11 +80,19 @@ module Goodcheck 
     | 
|
| 
       84 
80 
     | 
    
         
             
                          break
         
     | 
| 
       85 
81 
     | 
    
         
             
                        end
         
     | 
| 
       86 
82 
     | 
    
         
             
                      else
         
     | 
| 
       87 
     | 
    
         
            -
                        yield Issue.new(buffer: buffer,  
     | 
| 
      
 83 
     | 
    
         
            +
                        yield Issue.new(buffer: buffer, rule: rule)
         
     | 
| 
       88 
84 
     | 
    
         
             
                        break
         
     | 
| 
       89 
85 
     | 
    
         
             
                      end
         
     | 
| 
       90 
86 
     | 
    
         
             
                    end
         
     | 
| 
       91 
87 
     | 
    
         
             
                  end
         
     | 
| 
       92 
88 
     | 
    
         
             
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                private
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                def new_issue_with_matched(scanner)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  Issue.new(buffer: buffer, rule: rule,
         
     | 
| 
      
 94 
     | 
    
         
            +
                            text: scanner.matched,
         
     | 
| 
      
 95 
     | 
    
         
            +
                            text_begin_pos: scanner.pos - scanner.matched_size)
         
     | 
| 
      
 96 
     | 
    
         
            +
                end
         
     | 
| 
       93 
97 
     | 
    
         
             
              end
         
     | 
| 
       94 
98 
     | 
    
         
             
            end
         
     | 
    
        data/lib/goodcheck/buffer.rb
    CHANGED
    
    | 
         @@ -8,7 +8,8 @@ module Goodcheck 
     | 
|
| 
       8 
8 
     | 
    
         
             
                  /# goodcheck-disable-line$/, # Ruby, Python, PHP, ...
         
     | 
| 
       9 
9 
     | 
    
         
             
                  /-- goodcheck-disable-line$/, # Haskel, SQL, ...
         
     | 
| 
       10 
10 
     | 
    
         
             
                  /<!-- goodcheck-disable-line -->$/, # HTML, Markdown, ...
         
     | 
| 
       11 
     | 
    
         
            -
                   
     | 
| 
      
 11 
     | 
    
         
            +
                  /\/\* goodcheck-disable-line \*\/$/, # CSS, SCSS,
         
     | 
| 
      
 12 
     | 
    
         
            +
                  /\{\s*\/\* goodcheck-disable-line \*\/\s*\}$/, # JSX, ...
         
     | 
| 
       12 
13 
     | 
    
         
             
                  /<%# goodcheck-disable-line %>$/, # ERB, ...
         
     | 
| 
       13 
14 
     | 
    
         
             
                  /' goodcheck-disable-line$/, # VB
         
     | 
| 
       14 
15 
     | 
    
         
             
                ].freeze
         
     | 
| 
         @@ -18,7 +19,8 @@ module Goodcheck 
     | 
|
| 
       18 
19 
     | 
    
         
             
                  /# goodcheck-disable-next-line$/, # Ruby, Python, PHP, ...
         
     | 
| 
       19 
20 
     | 
    
         
             
                  /-- goodcheck-disable-next-line$/, # Haskel, SQL, ...
         
     | 
| 
       20 
21 
     | 
    
         
             
                  /<!-- goodcheck-disable-next-line -->$/, # HTML, Markdown, ...
         
     | 
| 
       21 
     | 
    
         
            -
                   
     | 
| 
      
 22 
     | 
    
         
            +
                  /\/\* goodcheck-disable-next-line \*\/$/, # CSS, SCSS,
         
     | 
| 
      
 23 
     | 
    
         
            +
                  /\{\s*\/\* goodcheck-disable-next-line \*\/\s*\}$/, # JSX, ...
         
     | 
| 
       22 
24 
     | 
    
         
             
                  /<%# goodcheck-disable-next-line %>$/, # ERB, ...
         
     | 
| 
       23 
25 
     | 
    
         
             
                  /' goodcheck-disable-next-line$/, # VB
         
     | 
| 
       24 
26 
     | 
    
         
             
                ].freeze
         
     | 
| 
         @@ -41,7 +43,7 @@ module Goodcheck 
     | 
|
| 
       41 
43 
     | 
    
         
             
                    start_position = 0
         
     | 
| 
       42 
44 
     | 
    
         | 
| 
       43 
45 
     | 
    
         
             
                    content.split(/\n/, -1).each do |line|
         
     | 
| 
       44 
     | 
    
         
            -
                      range = start_position 
     | 
| 
      
 46 
     | 
    
         
            +
                      range = start_position..(start_position + line.bytesize)
         
     | 
| 
       45 
47 
     | 
    
         
             
                      @line_ranges << range
         
     | 
| 
       46 
48 
     | 
    
         
             
                      start_position = range.end + 1
         
     | 
| 
       47 
49 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -49,10 +51,10 @@ module Goodcheck 
     | 
|
| 
       49 
51 
     | 
    
         | 
| 
       50 
52 
     | 
    
         
             
                  @line_ranges
         
     | 
| 
       51 
53 
     | 
    
         
             
                end
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
       53 
55 
     | 
    
         
             
                def line_disabled?(line_number)
         
     | 
| 
       54 
56 
     | 
    
         
             
                  if line_number > 1
         
     | 
| 
       55 
     | 
    
         
            -
                    return true if DISABLE_NEXT_LINE_PATTERNS.any? { |pattern| line(line_number - 1).match?(pattern) } 
     | 
| 
      
 57 
     | 
    
         
            +
                    return true if DISABLE_NEXT_LINE_PATTERNS.any? { |pattern| line(line_number - 1).match?(pattern) }
         
     | 
| 
       56 
58 
     | 
    
         
             
                  end
         
     | 
| 
       57 
59 
     | 
    
         | 
| 
       58 
60 
     | 
    
         
             
                  if line_number <= lines.length
         
     | 
| 
         @@ -68,7 +70,9 @@ module Goodcheck 
     | 
|
| 
       68 
70 
     | 
    
         
             
                  end
         
     | 
| 
       69 
71 
     | 
    
         | 
| 
       70 
72 
     | 
    
         
             
                  if line_index
         
     | 
| 
       71 
     | 
    
         
            -
                     
     | 
| 
      
 73 
     | 
    
         
            +
                    line_number = line_index + 1
         
     | 
| 
      
 74 
     | 
    
         
            +
                    column_number = position - line_ranges[line_index].begin + 1
         
     | 
| 
      
 75 
     | 
    
         
            +
                    [line_number, column_number]
         
     | 
| 
       72 
76 
     | 
    
         
             
                  end
         
     | 
| 
       73 
77 
     | 
    
         
             
                end
         
     | 
| 
       74 
78 
     | 
    
         | 
| 
         @@ -77,16 +81,7 @@ module Goodcheck 
     | 
|
| 
       77 
81 
     | 
    
         
             
                end
         
     | 
| 
       78 
82 
     | 
    
         | 
| 
       79 
83 
     | 
    
         
             
                def line(line_number)
         
     | 
| 
       80 
     | 
    
         
            -
                  lines[line_number-1]
         
     | 
| 
       81 
     | 
    
         
            -
                end
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
                def position_for_location(line, column)
         
     | 
| 
       84 
     | 
    
         
            -
                  if (range = line_ranges[line-1])
         
     | 
| 
       85 
     | 
    
         
            -
                    pos = range.begin + column
         
     | 
| 
       86 
     | 
    
         
            -
                    if pos <= range.end
         
     | 
| 
       87 
     | 
    
         
            -
                      pos
         
     | 
| 
       88 
     | 
    
         
            -
                    end
         
     | 
| 
       89 
     | 
    
         
            -
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
                  lines[line_number - 1]
         
     | 
| 
       90 
85 
     | 
    
         
             
                end
         
     | 
| 
       91 
86 
     | 
    
         
             
              end
         
     | 
| 
       92 
87 
     | 
    
         
             
            end
         
     | 
    
        data/lib/goodcheck/cli.rb
    CHANGED
    
    | 
         @@ -1,9 +1,9 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require "optparse"
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            Version = Goodcheck::VERSION
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
3 
     | 
    
         
             
            module Goodcheck
         
     | 
| 
       6 
4 
     | 
    
         
             
              class CLI
         
     | 
| 
      
 5 
     | 
    
         
            +
                include ExitStatus
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
       7 
7 
     | 
    
         
             
                attr_reader :stdout
         
     | 
| 
       8 
8 
     | 
    
         
             
                attr_reader :stderr
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
         @@ -19,8 +19,9 @@ module Goodcheck 
     | 
|
| 
       19 
19 
     | 
    
         
             
                  pattern: "Print regexp for rules",
         
     | 
| 
       20 
20 
     | 
    
         
             
                  version: "Print version",
         
     | 
| 
       21 
21 
     | 
    
         
             
                  help: "Show help and quit"
         
     | 
| 
       22 
     | 
    
         
            -
                }
         
     | 
| 
      
 22 
     | 
    
         
            +
                }.freeze
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
                DEFAULT_CONFIG_FILE = Pathname("goodcheck.yml").freeze
         
     | 
| 
       24 
25 
     | 
    
         | 
| 
       25 
26 
     | 
    
         
             
                def run(args)
         
     | 
| 
       26 
27 
     | 
    
         
             
                  command = args.shift&.to_sym
         
     | 
| 
         @@ -30,16 +31,22 @@ module Goodcheck 
     | 
|
| 
       30 
31 
     | 
    
         
             
                  elsif command == :"--version"
         
     | 
| 
       31 
32 
     | 
    
         
             
                    version(args)
         
     | 
| 
       32 
33 
     | 
    
         
             
                  else
         
     | 
| 
       33 
     | 
    
         
            -
                     
     | 
| 
      
 34 
     | 
    
         
            +
                    if command
         
     | 
| 
      
 35 
     | 
    
         
            +
                      stderr.puts "invalid command: #{command}"
         
     | 
| 
      
 36 
     | 
    
         
            +
                      stderr.puts ""
         
     | 
| 
      
 37 
     | 
    
         
            +
                    end
         
     | 
| 
       34 
38 
     | 
    
         
             
                    help(args)
         
     | 
| 
       35 
     | 
    
         
            -
                     
     | 
| 
      
 39 
     | 
    
         
            +
                    EXIT_ERROR
         
     | 
| 
       36 
40 
     | 
    
         
             
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
                rescue OptionParser::ParseError => exn
         
     | 
| 
      
 42 
     | 
    
         
            +
                  stderr.puts exn
         
     | 
| 
      
 43 
     | 
    
         
            +
                  EXIT_ERROR
         
     | 
| 
       37 
44 
     | 
    
         
             
                rescue => exn
         
     | 
| 
       38 
45 
     | 
    
         
             
                  stderr.puts exn.inspect
         
     | 
| 
       39 
46 
     | 
    
         
             
                  exn.backtrace.each do |bt|
         
     | 
| 
       40 
47 
     | 
    
         
             
                    stderr.puts "  #{bt}"
         
     | 
| 
       41 
48 
     | 
    
         
             
                  end
         
     | 
| 
       42 
     | 
    
         
            -
                   
     | 
| 
      
 49 
     | 
    
         
            +
                  EXIT_ERROR
         
     | 
| 
       43 
50 
     | 
    
         
             
                end
         
     | 
| 
       44 
51 
     | 
    
         | 
| 
       45 
52 
     | 
    
         
             
                def home_path
         
     | 
| 
         @@ -51,35 +58,31 @@ module Goodcheck 
     | 
|
| 
       51 
58 
     | 
    
         
             
                end
         
     | 
| 
       52 
59 
     | 
    
         | 
| 
       53 
60 
     | 
    
         
             
                def check(args)
         
     | 
| 
       54 
     | 
    
         
            -
                  config_path =  
     | 
| 
      
 61 
     | 
    
         
            +
                  config_path = DEFAULT_CONFIG_FILE
         
     | 
| 
       55 
62 
     | 
    
         
             
                  targets = []
         
     | 
| 
       56 
63 
     | 
    
         
             
                  rules = []
         
     | 
| 
       57 
     | 
    
         
            -
                   
     | 
| 
       58 
     | 
    
         
            -
                   
     | 
| 
      
 64 
     | 
    
         
            +
                  formats = [:text, :json]
         
     | 
| 
      
 65 
     | 
    
         
            +
                  format = :text
         
     | 
| 
      
 66 
     | 
    
         
            +
                  loglevel = nil
         
     | 
| 
       59 
67 
     | 
    
         
             
                  force_download = false
         
     | 
| 
       60 
68 
     | 
    
         | 
| 
       61 
     | 
    
         
            -
                  OptionParser.new("Usage: goodcheck check [options]  
     | 
| 
       62 
     | 
    
         
            -
                    opts 
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
                     
     | 
| 
       65 
     | 
    
         
            -
                    opts 
     | 
| 
      
 69 
     | 
    
         
            +
                  OptionParser.new("Usage: goodcheck check [options] paths...") do |opts|
         
     | 
| 
      
 70 
     | 
    
         
            +
                    config_option(opts) { |config| config_path = config }
         
     | 
| 
      
 71 
     | 
    
         
            +
                    verbose_option(opts) { |level| loglevel = level }
         
     | 
| 
      
 72 
     | 
    
         
            +
                    debug_option(opts) { |level| loglevel = level }
         
     | 
| 
      
 73 
     | 
    
         
            +
                    force_download_option(opts) { force_download = true }
         
     | 
| 
      
 74 
     | 
    
         
            +
                    common_options(opts)
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                    opts.on("-R RULE", "--rule=RULE", "Only rule(s) to check") do |rule|
         
     | 
| 
       66 
77 
     | 
    
         
             
                      rules << rule
         
     | 
| 
       67 
78 
     | 
    
         
             
                    end
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                    opts.on("--format=<#{formats.join('|')}>", formats, "Output format [default: '#{format}']") do |f|
         
     | 
| 
       69 
81 
     | 
    
         
             
                      format = f
         
     | 
| 
       70 
82 
     | 
    
         
             
                    end
         
     | 
| 
       71 
     | 
    
         
            -
                    opts.on("-v", "--verbose") do
         
     | 
| 
       72 
     | 
    
         
            -
                      loglevel = Logger::INFO
         
     | 
| 
       73 
     | 
    
         
            -
                    end
         
     | 
| 
       74 
     | 
    
         
            -
                    opts.on("-d", "--debug") do
         
     | 
| 
       75 
     | 
    
         
            -
                      loglevel = Logger::DEBUG
         
     | 
| 
       76 
     | 
    
         
            -
                    end
         
     | 
| 
       77 
     | 
    
         
            -
                    opts.on("--force") do
         
     | 
| 
       78 
     | 
    
         
            -
                      force_download = true
         
     | 
| 
       79 
     | 
    
         
            -
                    end
         
     | 
| 
       80 
83 
     | 
    
         
             
                  end.parse!(args)
         
     | 
| 
       81 
84 
     | 
    
         | 
| 
       82 
     | 
    
         
            -
                  Goodcheck.logger.level = loglevel
         
     | 
| 
      
 85 
     | 
    
         
            +
                  Goodcheck.logger.level = loglevel if loglevel
         
     | 
| 
       83 
86 
     | 
    
         | 
| 
       84 
87 
     | 
    
         
             
                  if args.empty?
         
     | 
| 
       85 
88 
     | 
    
         
             
                    targets << Pathname(".")
         
     | 
| 
         @@ -88,13 +91,12 @@ module Goodcheck 
     | 
|
| 
       88 
91 
     | 
    
         
             
                  end
         
     | 
| 
       89 
92 
     | 
    
         | 
| 
       90 
93 
     | 
    
         
             
                  reporter = case format
         
     | 
| 
       91 
     | 
    
         
            -
                             when  
     | 
| 
      
 94 
     | 
    
         
            +
                             when :text
         
     | 
| 
       92 
95 
     | 
    
         
             
                               Reporters::Text.new(stdout: stdout)
         
     | 
| 
       93 
     | 
    
         
            -
                             when  
     | 
| 
      
 96 
     | 
    
         
            +
                             when :json
         
     | 
| 
       94 
97 
     | 
    
         
             
                               Reporters::JSON.new(stdout: stdout, stderr: stderr)
         
     | 
| 
       95 
98 
     | 
    
         
             
                             else
         
     | 
| 
       96 
     | 
    
         
            -
                                
     | 
| 
       97 
     | 
    
         
            -
                               return 1
         
     | 
| 
      
 99 
     | 
    
         
            +
                               raise ArgumentError, format.inspect
         
     | 
| 
       98 
100 
     | 
    
         
             
                             end
         
     | 
| 
       99 
101 
     | 
    
         | 
| 
       100 
102 
     | 
    
         
             
                  Goodcheck.logger.info "Configuration = #{config_path}"
         
     | 
| 
         @@ -108,23 +110,16 @@ module Goodcheck 
     | 
|
| 
       108 
110 
     | 
    
         
             
                end
         
     | 
| 
       109 
111 
     | 
    
         | 
| 
       110 
112 
     | 
    
         
             
                def test(args)
         
     | 
| 
       111 
     | 
    
         
            -
                  config_path =  
     | 
| 
       112 
     | 
    
         
            -
                  loglevel = Logger::ERROR
         
     | 
| 
      
 113 
     | 
    
         
            +
                  config_path = DEFAULT_CONFIG_FILE
         
     | 
| 
      
 114 
     | 
    
         
            +
                  loglevel = ::Logger::ERROR
         
     | 
| 
       113 
115 
     | 
    
         
             
                  force_download = false
         
     | 
| 
       114 
116 
     | 
    
         | 
| 
       115 
117 
     | 
    
         
             
                  OptionParser.new("Usage: goodcheck test [options]") do |opts|
         
     | 
| 
       116 
     | 
    
         
            -
                    opts 
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
                     
     | 
| 
       119 
     | 
    
         
            -
                    opts 
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
                    end
         
     | 
| 
       122 
     | 
    
         
            -
                    opts.on("-d", "--debug") do
         
     | 
| 
       123 
     | 
    
         
            -
                      loglevel = Logger::DEBUG
         
     | 
| 
       124 
     | 
    
         
            -
                    end
         
     | 
| 
       125 
     | 
    
         
            -
                    opts.on("--force") do
         
     | 
| 
       126 
     | 
    
         
            -
                      force_download = true
         
     | 
| 
       127 
     | 
    
         
            -
                    end
         
     | 
| 
      
 118 
     | 
    
         
            +
                    config_option(opts) { |config| config_path = config }
         
     | 
| 
      
 119 
     | 
    
         
            +
                    verbose_option(opts) { |level| loglevel = level }
         
     | 
| 
      
 120 
     | 
    
         
            +
                    debug_option(opts) { |level| loglevel = level }
         
     | 
| 
      
 121 
     | 
    
         
            +
                    force_download_option(opts) { force_download = true }
         
     | 
| 
      
 122 
     | 
    
         
            +
                    common_options(opts)
         
     | 
| 
       128 
123 
     | 
    
         
             
                  end.parse!(args)
         
     | 
| 
       129 
124 
     | 
    
         | 
| 
       130 
125 
     | 
    
         
             
                  Goodcheck.logger.level = loglevel
         
     | 
| 
         @@ -137,14 +132,14 @@ module Goodcheck 
     | 
|
| 
       137 
132 
     | 
    
         
             
                end
         
     | 
| 
       138 
133 
     | 
    
         | 
| 
       139 
134 
     | 
    
         
             
                def init(args)
         
     | 
| 
       140 
     | 
    
         
            -
                  config_path =  
     | 
| 
      
 135 
     | 
    
         
            +
                  config_path = DEFAULT_CONFIG_FILE
         
     | 
| 
       141 
136 
     | 
    
         
             
                  force = false
         
     | 
| 
       142 
137 
     | 
    
         | 
| 
       143 
138 
     | 
    
         
             
                  OptionParser.new("Usage: goodcheck init [options]") do |opts|
         
     | 
| 
       144 
     | 
    
         
            -
                    opts 
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
                    opts.on("--force") do
         
     | 
| 
      
 139 
     | 
    
         
            +
                    config_option(opts) { |config| config_path = config }
         
     | 
| 
      
 140 
     | 
    
         
            +
                    common_options(opts)
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                    opts.on("--force", "Overwrite an existing file") do
         
     | 
| 
       148 
143 
     | 
    
         
             
                      force = true
         
     | 
| 
       149 
144 
     | 
    
         
             
                    end
         
     | 
| 
       150 
145 
     | 
    
         
             
                  end.parse!(args)
         
     | 
| 
         @@ -152,9 +147,9 @@ module Goodcheck 
     | 
|
| 
       152 
147 
     | 
    
         
             
                  Commands::Init.new(stdout: stdout, stderr: stderr, path: config_path, force: force).run
         
     | 
| 
       153 
148 
     | 
    
         
             
                end
         
     | 
| 
       154 
149 
     | 
    
         | 
| 
       155 
     | 
    
         
            -
                def version( 
     | 
| 
      
 150 
     | 
    
         
            +
                def version(_args = nil)
         
     | 
| 
       156 
151 
     | 
    
         
             
                  stdout.puts "goodcheck #{VERSION}"
         
     | 
| 
       157 
     | 
    
         
            -
                   
     | 
| 
      
 152 
     | 
    
         
            +
                  EXIT_SUCCESS
         
     | 
| 
       158 
153 
     | 
    
         
             
                end
         
     | 
| 
       159 
154 
     | 
    
         | 
| 
       160 
155 
     | 
    
         
             
                def help(args)
         
     | 
| 
         @@ -164,19 +159,48 @@ module Goodcheck 
     | 
|
| 
       164 
159 
     | 
    
         
             
                  COMMANDS.each do |c, msg|
         
     | 
| 
       165 
160 
     | 
    
         
             
                    stdout.puts "  goodcheck #{c}\t#{msg}"
         
     | 
| 
       166 
161 
     | 
    
         
             
                  end
         
     | 
| 
       167 
     | 
    
         
            -
                   
     | 
| 
      
 162 
     | 
    
         
            +
                  EXIT_SUCCESS
         
     | 
| 
       168 
163 
     | 
    
         
             
                end
         
     | 
| 
       169 
164 
     | 
    
         | 
| 
       170 
165 
     | 
    
         
             
                def pattern(args)
         
     | 
| 
       171 
     | 
    
         
            -
                  config_path =  
     | 
| 
      
 166 
     | 
    
         
            +
                  config_path = DEFAULT_CONFIG_FILE
         
     | 
| 
       172 
167 
     | 
    
         | 
| 
       173 
     | 
    
         
            -
                  OptionParser.new 
     | 
| 
       174 
     | 
    
         
            -
                    opts. 
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
                     
     | 
| 
      
 168 
     | 
    
         
            +
                  OptionParser.new do |opts|
         
     | 
| 
      
 169 
     | 
    
         
            +
                    opts.banner = "Usage: goodcheck pattern [options] ids..."
         
     | 
| 
      
 170 
     | 
    
         
            +
                    config_option(opts) { |config| config_path = config }
         
     | 
| 
      
 171 
     | 
    
         
            +
                    common_options(opts)
         
     | 
| 
       177 
172 
     | 
    
         
             
                  end.parse!(args)
         
     | 
| 
       178 
173 
     | 
    
         | 
| 
       179 
174 
     | 
    
         
             
                  Commands::Pattern.new(stdout: stdout, stderr: stderr, path: config_path, ids: Set.new(args), home_path: home_path).run
         
     | 
| 
       180 
175 
     | 
    
         
             
                end
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                def config_option(opts)
         
     | 
| 
      
 178 
     | 
    
         
            +
                  opts.on("-c CONFIG", "--config=CONFIG", "Configuration file path [default: '#{DEFAULT_CONFIG_FILE}']") do |config|
         
     | 
| 
      
 179 
     | 
    
         
            +
                    yield Pathname(config)
         
     | 
| 
      
 180 
     | 
    
         
            +
                  end
         
     | 
| 
      
 181 
     | 
    
         
            +
                end
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
                def verbose_option(opts)
         
     | 
| 
      
 184 
     | 
    
         
            +
                  opts.on("-v", "--verbose", "Set log level to verbose") { yield ::Logger::INFO }
         
     | 
| 
      
 185 
     | 
    
         
            +
                end
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                def debug_option(opts)
         
     | 
| 
      
 188 
     | 
    
         
            +
                  opts.on("-d", "--debug", "Set log level to debug") { yield ::Logger::DEBUG }
         
     | 
| 
      
 189 
     | 
    
         
            +
                end
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                def force_download_option(opts, &block)
         
     | 
| 
      
 192 
     | 
    
         
            +
                  opts.on("--force", "Download importing files always", &block)
         
     | 
| 
      
 193 
     | 
    
         
            +
                end
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
      
 195 
     | 
    
         
            +
                def common_options(opts)
         
     | 
| 
      
 196 
     | 
    
         
            +
                  opts.on_tail("--version", COMMANDS.fetch(:version)) do
         
     | 
| 
      
 197 
     | 
    
         
            +
                    version
         
     | 
| 
      
 198 
     | 
    
         
            +
                    exit EXIT_SUCCESS
         
     | 
| 
      
 199 
     | 
    
         
            +
                  end
         
     | 
| 
      
 200 
     | 
    
         
            +
                  opts.on_tail("-h", "--help", COMMANDS.fetch(:help)) do
         
     | 
| 
      
 201 
     | 
    
         
            +
                    stdout.puts opts.help
         
     | 
| 
      
 202 
     | 
    
         
            +
                    exit EXIT_SUCCESS
         
     | 
| 
      
 203 
     | 
    
         
            +
                  end
         
     | 
| 
      
 204 
     | 
    
         
            +
                end
         
     | 
| 
       181 
205 
     | 
    
         
             
              end
         
     | 
| 
       182 
206 
     | 
    
         
             
            end
         
     | 
| 
         @@ -13,6 +13,9 @@ module Goodcheck 
     | 
|
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                  include ConfigLoading
         
     | 
| 
       15 
15 
     | 
    
         
             
                  include HomePath
         
     | 
| 
      
 16 
     | 
    
         
            +
                  include ExitStatus
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  EXIT_MATCH = 2
         
     | 
| 
       16 
19 
     | 
    
         | 
| 
       17 
20 
     | 
    
         
             
                  def initialize(config_path:, rules:, targets:, reporter:, stderr:, home_path:, force_download:)
         
     | 
| 
       18 
21 
     | 
    
         
             
                    @config_path = config_path
         
     | 
| 
         @@ -30,6 +33,14 @@ module Goodcheck 
     | 
|
| 
       30 
33 
     | 
    
         | 
| 
       31 
34 
     | 
    
         
             
                      reporter.analysis do
         
     | 
| 
       32 
35 
     | 
    
         
             
                        load_config!(force_download: force_download, cache_path: cache_dir_path)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                        unless missing_rules.empty?
         
     | 
| 
      
 38 
     | 
    
         
            +
                          missing_rules.each do |rule|
         
     | 
| 
      
 39 
     | 
    
         
            +
                            stderr.puts "missing rule: #{rule}"
         
     | 
| 
      
 40 
     | 
    
         
            +
                          end
         
     | 
| 
      
 41 
     | 
    
         
            +
                          return EXIT_ERROR
         
     | 
| 
      
 42 
     | 
    
         
            +
                        end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
       33 
44 
     | 
    
         
             
                        each_check do |buffer, rule, trigger|
         
     | 
| 
       34 
45 
     | 
    
         
             
                          reported_issues = Set[]
         
     | 
| 
       35 
46 
     | 
    
         | 
| 
         @@ -46,38 +57,43 @@ module Goodcheck 
     | 
|
| 
       46 
57 
     | 
    
         
             
                        end
         
     | 
| 
       47 
58 
     | 
    
         
             
                      end
         
     | 
| 
       48 
59 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
                       
     | 
| 
      
 60 
     | 
    
         
            +
                      reporter.summary
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                      issue_reported ? EXIT_MATCH : EXIT_SUCCESS
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                  def missing_rules
         
     | 
| 
      
 67 
     | 
    
         
            +
                    @missing_rules ||= begin
         
     | 
| 
      
 68 
     | 
    
         
            +
                      config_rule_ids = config.rules.map(&:id)
         
     | 
| 
      
 69 
     | 
    
         
            +
                      rules.reject { |rule| config_rule_ids.include?(rule) }
         
     | 
| 
       50 
70 
     | 
    
         
             
                    end
         
     | 
| 
       51 
71 
     | 
    
         
             
                  end
         
     | 
| 
       52 
72 
     | 
    
         | 
| 
       53 
73 
     | 
    
         
             
                  def each_check
         
     | 
| 
       54 
74 
     | 
    
         
             
                    targets.each do |target|
         
     | 
| 
       55 
75 
     | 
    
         
             
                      Goodcheck.logger.info "Checking target: #{target}"
         
     | 
| 
       56 
     | 
    
         
            -
                       
     | 
| 
       57 
     | 
    
         
            -
                         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
                           
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
                                    buffer = Buffer.new(path: path, content: content)
         
     | 
| 
       73 
     | 
    
         
            -
                                    buffers[encoding] = buffer
         
     | 
| 
       74 
     | 
    
         
            -
                                  end
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
                                  yield buffer, rule, trigger
         
     | 
| 
       77 
     | 
    
         
            -
                                rescue ArgumentError => exn
         
     | 
| 
       78 
     | 
    
         
            -
                                  stderr.puts "#{path}: #{exn.inspect}"
         
     | 
| 
       79 
     | 
    
         
            -
                                end
         
     | 
| 
      
 76 
     | 
    
         
            +
                      each_file target, immediate: true do |path|
         
     | 
| 
      
 77 
     | 
    
         
            +
                        Goodcheck.logger.debug "Checking file: #{path}"
         
     | 
| 
      
 78 
     | 
    
         
            +
                        reporter.file(path) do
         
     | 
| 
      
 79 
     | 
    
         
            +
                          buffers = {}
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                          config.rules_for_path(path, rules_filter: rules) do |rule, glob, trigger|
         
     | 
| 
      
 82 
     | 
    
         
            +
                            Goodcheck.logger.debug "Checking rule: #{rule.id}"
         
     | 
| 
      
 83 
     | 
    
         
            +
                            begin
         
     | 
| 
      
 84 
     | 
    
         
            +
                              encoding = glob&.encoding || Encoding.default_external.name
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                              if buffers[encoding]
         
     | 
| 
      
 87 
     | 
    
         
            +
                                buffer = buffers[encoding]
         
     | 
| 
      
 88 
     | 
    
         
            +
                              else
         
     | 
| 
      
 89 
     | 
    
         
            +
                                content = path.read(encoding: encoding).encode(Encoding.default_internal || Encoding::UTF_8)
         
     | 
| 
      
 90 
     | 
    
         
            +
                                buffer = Buffer.new(path: path, content: content)
         
     | 
| 
      
 91 
     | 
    
         
            +
                                buffers[encoding] = buffer
         
     | 
| 
       80 
92 
     | 
    
         
             
                              end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                              yield buffer, rule, trigger
         
     | 
| 
      
 95 
     | 
    
         
            +
                            rescue ArgumentError => exn
         
     | 
| 
      
 96 
     | 
    
         
            +
                              stderr.puts "#{path}: #{exn.inspect}"
         
     | 
| 
       81 
97 
     | 
    
         
             
                            end
         
     | 
| 
       82 
98 
     | 
    
         
             
                          end
         
     | 
| 
       83 
99 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -94,7 +110,7 @@ module Goodcheck 
     | 
|
| 
       94 
110 
     | 
    
         
             
                      when DEFAULT_EXCLUSIONS.include?(path.basename.to_s)
         
     | 
| 
       95 
111 
     | 
    
         
             
                        # noop
         
     | 
| 
       96 
112 
     | 
    
         
             
                      when immediate || !excluded?(path)
         
     | 
| 
       97 
     | 
    
         
            -
                        path.children.each do |child|
         
     | 
| 
      
 113 
     | 
    
         
            +
                        path.children.sort.each do |child|
         
     | 
| 
       98 
114 
     | 
    
         
             
                          each_file(child, &block)
         
     | 
| 
       99 
115 
     | 
    
         
             
                        end
         
     | 
| 
       100 
116 
     | 
    
         
             
                      end
         
     |