quiet_quality 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 637f00e52eae2e4b0cee2cf1e4c76b17595e7ac4a59aa2568ae0eee17b4a7d4c
4
- data.tar.gz: a45040a9379e05a86e87d01f274ea044084c0af13e65c6d00b7c664dde33afc6
3
+ metadata.gz: b6aea488d2026da63fdf9483d1df9bd4e2363270d7b441cbca384cd803cab803
4
+ data.tar.gz: 0536d6eb0b8cdd1c4678f49058be4d37017b7ff6156d363afa71df8a979d30aa
5
5
  SHA512:
6
- metadata.gz: f0666d43b98ea76f55b8dab0d3d38cc786f8c9a750b14dee1eff2c4a13ee7da94f94a83757fe643efa1d448197583864c02c34c0e49b7adda5d790d51eaad0ef
7
- data.tar.gz: 3cd316700e1abda994248dbd5959d242ccec0551d2f516212671fee07df1cfa5d36a9b53137ea299cce03b6bbbab9e328ba38132be6148d8626a7e4b1d71e346
6
+ metadata.gz: 766f24f8211b83610c05e57b0f81d77bbf2d4bf8c206cc5e9af1d4e302adc9fee6425c506b344850a1421b7a30f18b6dfa6a23132aaa64dc3e6fbeb5e59c4c0b
7
+ data.tar.gz: 7b72dcf22a6696b2ff88a5efb08fb0338d2d4f0b43f506f147a2d5cb0ed7186328157ff4b8ded7198fff3785f6636b32d8b1ecd1102cd462b341f28c57dfd429
@@ -29,3 +29,6 @@ jobs:
29
29
 
30
30
  - name: Run rubocop (complexity checks)
31
31
  run: bundle exec rubocop --parallel
32
+
33
+ - name: Run markdownlint
34
+ run: bundle exec mdl .
data/.mdl_rules.rb ADDED
@@ -0,0 +1,2 @@
1
+ all
2
+ rule "MD013", ignore_code_blocks: true
data/.mdlrc ADDED
@@ -0,0 +1,2 @@
1
+ style File.expand_path("../.mdl_rules.rb", __FILE__)
2
+ git_recurse true
data/README.md CHANGED
@@ -1,34 +1,172 @@
1
1
  # QuietQuality
2
2
 
3
- Work in Progress
3
+ There are a lot of different tools that you need to run as you work - possibly
4
+ before you commit, or before you make a pull request, or after you make changes
5
+ to a class.. style checkers, tests, complexity metrics, static analyzers, etc.
6
+ QuietQuality can make that simpler and faster!
4
7
 
5
- But essentially, QuietQuality is intended for two purposes:
8
+ Or you may have a huge existing project, that's not _fully_ in compliance with
9
+ your style guides, but you want to avoid introducing _new_ issues, without
10
+ having to first resolve all of the existing ones. QuietQuality can help with
11
+ that too.
6
12
 
7
- 1. Let you conveniently run tools like rubocop, rspec, and standard against the _relevant_
8
- files locally (the files that have changed locally relative to the default branch)
9
- 2. Let you run those tools in CI (probably github actions) and annotate any issues found
10
- with _new or modified_ code, without bothering you about existing issues that you didn't
11
- touch.
13
+ ## Tool Support
12
14
 
15
+ So far, we have support for the following tools:
13
16
 
14
- Basic usage examples:
17
+ * rubocop
18
+ * standardrb
19
+ * rspec
20
+ * haml-lint
21
+ * brakeman (though there's no way to run this against only changed files)
15
22
 
23
+ Supporting more tools is relatively straightforward - they're implemented by
24
+ wrapping cli invocations and parsing output files (which overall seem to be much
25
+ more stable interfaces than the code interfaces to the various tools), and each
26
+ tool's support is built orthogonally to the others, in a
27
+ `QuietQuality::Tools::[Something]` namespace, with a `Runner` and a `Parser`.
28
+
29
+ ## Local Usage Examples
30
+
31
+ Working locally, you'll generally want to commit a `.quiet_quality.yml`
32
+ configuration file into the root of your repository - it'll specify which tools
33
+ to run by default, and how to run them (whether you want to only run each tool
34
+ against the _changed files_, whether to _filter_ the resulting _messages_ down
35
+ to only those targeting lines that have been changed), and allows you to specify
36
+ the _comparison branch_, so you don't have to make a request to your origin
37
+ server every time you run the tool to see whether you're comparing against
38
+ `master` or `main` in this project.
39
+
40
+ If you have a configuration set up like that, you might have details specified
41
+ for `rubocop`, `rspec`, `standardrb`, and `brakeman`, but have only `rubocop`,
42
+ `standardrb`, and `rspec` set to run by default. That configuration file would
43
+ look like this (you can copy it from [here](docs/example-config.yml)):
44
+
45
+ ```yaml
46
+ ---
47
+ default_tools: ["standardrb", "rubocop", "rspec"]
48
+ executor: concurrent
49
+ comparison_branch: main
50
+ changed_files: true
51
+ filter_messages: true
52
+ brakeman:
53
+ changed_files: false
54
+ filter_messages: true
55
+ ```
56
+
57
+ Then if you invoke `qq`, you'll see output like this:
58
+
59
+ ```bash
60
+ ❯ qq
61
+ --- Passed: standardrb
62
+ --- Passed: rubocop
63
+ --- Passed: rspec
64
+ ```
65
+
66
+ But if you want to run brakeman, you could call `qq brakeman`:
67
+
68
+ ```bash
69
+ ❯ qq brakeman
70
+ --- Failed: brakeman
71
+
72
+
73
+ 2 messages:
74
+ app/controllers/articles_controller.rb:3 [SQL Injection] Possible SQL injection
75
+ app/controllers/articles_controller.rb:11 [Remote Code Execution] `YAML.load` called with parameter value
76
+
77
+ ```
78
+
79
+ ## CI Usage Examples
80
+
81
+ Currently, QuietQuality is most useful from GitHub Actions - in that context, it's
82
+ possible to generate nice annotations for the analyzed commit (using Workflow
83
+ Actions). But it can be used from other CI systems as well, you just won't get
84
+ nice annotations out of it (yet).
85
+
86
+ For CI systems, you can either configure your execution entirely through
87
+ command-line arguments, or you can create additional configuration files and
88
+ specify them on the command-line.
89
+
90
+ Here is an invocation that executes rubocop and standardrb, expecting the full
91
+ repository to pass the latter, but not the former:
92
+
93
+ ```bash
94
+ qq rubocop standardrb \
95
+ --all-files --changed-files rubocop \
96
+ --unfiltered --filter-messages rubocop \
97
+ --comparison-branch main \
98
+ --no-config \
99
+ --executor serial \
100
+ --annotate-github-stdout
16
101
  ```
17
- # you have five commits in your feature branch and 3 more files changes but not committed.
18
- # this will run rubocop against all of those files.
19
- qq rubocop
20
-
21
- # run rspec against the changed specs, and annotate any failing specs (well, the first 10
22
- # of them) against the commit using github's inline output-based annotation approach. Which
23
- # will of course only produce actual annotations if this happens to have been run in a
24
- # github action.
25
- qq rspec --annotate=github_stdout
26
-
27
- # run standardrb against all of the files (not just the changed ones). Still only print out
28
- # problems to lines that have changed, so not particularly useful :-)
29
- qq standard --all --incremental
30
-
31
- # run all of the tools against the entire repository, and print the first three messages
32
- # out for each tool.
33
- qq all --all --full --limit-per-tool=3
102
+
103
+ Note the use of `--no-config`, to cause it to _not_ automatically load the
104
+ `.quiet_quality.yml` config included in the repository.
105
+
106
+ Alternatively, we could have put all of that configuration into a config file
107
+ like this:
108
+
109
+ ```yaml
110
+ # config/quiet_quality/linters_workflow.yml
111
+ ---
112
+ default_tools: ["standardrb", "rubocop"]
113
+ executor: serial
114
+ comparison_branch: main
115
+ changed_files: false
116
+ filter_messages: false
117
+
118
+ rubocop:
119
+ changed_files: true
120
+ filter_messages: true
34
121
  ```
122
+
123
+ And then run `qq -C config/quiet_quality/linters_workflow.yml`
124
+
125
+ ## Available Options
126
+
127
+ The configuration file supports the following _global_ options (top-level keys):
128
+
129
+ * `executor`: 'serial' or 'concurrent' (the latter is the default)
130
+ * `annotator`: none set by default, and `github_stdout` is the only supported
131
+ value so far.
132
+ * `comparison_branch`: by default, this will be _fetched_ from git, but that
133
+ does require a remote request. You should set this, it saves about half a
134
+ second. This is normally 'main' or 'master', but it could be 'trunk', or
135
+ 'develop' - it is the branch that PR diffs are _against_.
136
+ * `changed_files`: defaults to false - should tools be run against only the
137
+ files that have changed, or against the entire repository? This is the global
138
+ setting, but it is also settable per tool.
139
+ * `filter_messages`: defaults to false - should the resulting messages that do
140
+ not refer to lines that were changed or added relative to the comparison
141
+ branch be skipped? Also possible to set for each tool.
142
+
143
+ And then each tool can have an entry, within which `changed_files` and
144
+ `filter_messages` can be specified - the tool-specific settings override the
145
+ global ones.
146
+
147
+ The tools have one additional setting that is not available at a global level:
148
+ `file_filter`. This is a string that will be turned into a _ruby regex_, and
149
+ used to limit what file paths are passed to the tool. For example, if you are
150
+ working in a rails engine `engines/foo/`, and you touch one of the rspec tests
151
+ there, you would not want `qq` in the root of the repository to run
152
+ `rspec engines/foo/spec/foo/thing_spec.rb` - that probably won't work, as your
153
+ engine will have its own test setup code and Gemfile. This setting is mostly
154
+ intended to be used like this:
155
+
156
+ ```yaml
157
+ rspec:
158
+ changed_files: true
159
+ filter_messages: false
160
+ file_filter: "^spec/"
161
+ ```
162
+
163
+ ### CLI Options
164
+
165
+ The same options are all available on the CLI, plus some additional ones - run
166
+ `qq --help` for a detailed list of the options, but the notable additions are:
167
+
168
+ * `--help/-H`: See a list of the options
169
+ * `--no-config/-N`: Do _not_ load a config file, even if present.
170
+ * `--config/-C`: load the supplied config file (instead of the detected one, if
171
+ found)
172
+ * `--version/-V`: what version of the gem are you using?
@@ -0,0 +1,9 @@
1
+ ---
2
+ default_tools: ["standardrb", "rubocop", "rspec"]
3
+ executor: concurrent
4
+ comparison_branch: main
5
+ changed_files: true
6
+ filter_messages: true
7
+ brakeman:
8
+ changed_files: false
9
+ filter_messages: true
@@ -76,6 +76,10 @@ module QuietQuality
76
76
  parser.on("-h", "--help", "Prints this help") do
77
77
  @parsed_options.helping = true
78
78
  end
79
+
80
+ parser.on("-V", "--version", "Print the current version of the gem") do
81
+ @parsed_options.printing_version = true
82
+ end
79
83
  end
80
84
 
81
85
  def setup_config_options(parser)
@@ -10,6 +10,10 @@ module QuietQuality
10
10
  def execute
11
11
  if helping?
12
12
  log_help_text
13
+ elsif printing_version?
14
+ log_version_text
15
+ elsif no_tools?
16
+ log_no_tools_text
13
17
  else
14
18
  executed
15
19
  log_outcomes
@@ -21,7 +25,9 @@ module QuietQuality
21
25
  end
22
26
 
23
27
  def successful?
24
- helping? || !executed.any_failure?
28
+ return true if helping? || printing_version?
29
+ return false if no_tools?
30
+ !executed.any_failure?
25
31
  end
26
32
 
27
33
  private
@@ -40,10 +46,29 @@ module QuietQuality
40
46
  parsed_options.helping?
41
47
  end
42
48
 
49
+ def printing_version?
50
+ parsed_options.printing_version?
51
+ end
52
+
53
+ def no_tools?
54
+ options.tools.empty?
55
+ end
56
+
43
57
  def log_help_text
44
58
  error_stream.puts(arg_parser.help_text)
45
59
  end
46
60
 
61
+ def log_version_text
62
+ error_stream.puts(QuietQuality::VERSION)
63
+ end
64
+
65
+ def log_no_tools_text
66
+ error_stream.puts(<<~TEXT)
67
+ You must specify one or more tools to run, either on the command-line or in the
68
+ default_tools key in a configuration file.
69
+ TEXT
70
+ end
71
+
47
72
  def options
48
73
  return @_options if defined?(@_options)
49
74
  builder = Config::Builder.new(parsed_cli_options: parsed_options)
@@ -28,7 +28,7 @@ module QuietQuality
28
28
  elsif config_file&.tools&.any?
29
29
  config_file.tools
30
30
  else
31
- Tools::AVAILABLE.keys
31
+ []
32
32
  end
33
33
  end
34
34
 
@@ -109,6 +109,7 @@ module QuietQuality
109
109
  options.tools.each do |tool_options|
110
110
  update_tool_option(tool_options, :limit_targets)
111
111
  update_tool_option(tool_options, :filter_messages)
112
+ update_tool_option(tool_options, :file_filter)
112
113
  end
113
114
  end
114
115
 
@@ -5,16 +5,20 @@ module QuietQuality
5
5
  @tools = []
6
6
  @tool_options = {}
7
7
  @global_options = {}
8
- @helping = false
8
+ @helping = @printing_version = false
9
9
  end
10
10
 
11
11
  attr_accessor :tools
12
- attr_writer :helping
12
+ attr_writer :helping, :printing_version
13
13
 
14
14
  def helping?
15
15
  @helping
16
16
  end
17
17
 
18
+ def printing_version?
19
+ @printing_version
20
+ end
21
+
18
22
  def set_global_option(name, value)
19
23
  @global_options[name.to_sym] = value
20
24
  end
@@ -38,11 +38,14 @@ module QuietQuality
38
38
  end
39
39
 
40
40
  def store_global_options(opts)
41
- read_global_option(opts, :executor, as: :symbol, validate_from: Executors::AVAILABLE)
42
- read_global_option(opts, :annotator, as: :symbol, validate_from: Annotators::ANNOTATOR_TYPES)
43
- read_global_option(opts, :comparison_branch, as: :string)
44
- read_global_option(opts, :changed_files, as: :boolean)
45
- read_global_option(opts, :filter_messages, as: :boolean)
41
+ read_global_option(opts, :executor, :executor, as: :symbol, validate_from: Executors::AVAILABLE)
42
+ read_global_option(opts, :annotator, :annotator, as: :symbol, validate_from: Annotators::ANNOTATOR_TYPES)
43
+ read_global_option(opts, :annotate, :annotator, as: :symbol, validate_from: Annotators::ANNOTATOR_TYPES)
44
+ read_global_option(opts, :comparison_branch, :comparison_branch, as: :string)
45
+ read_global_option(opts, :changed_files, :changed_files, as: :boolean)
46
+ read_global_option(opts, :all_files, :changed_files, as: :reversed_boolean)
47
+ read_global_option(opts, :filter_messages, :filter_messages, as: :boolean)
48
+ read_global_option(opts, :unfiltered, :filter_messages, as: :reversed_boolean)
46
49
  end
47
50
 
48
51
  def store_tool_options(opts)
@@ -54,8 +57,12 @@ module QuietQuality
54
57
  def store_tool_options_for(opts, tool_name)
55
58
  entries = data.fetch(tool_name, nil)
56
59
  return if entries.nil?
57
- read_tool_option(opts, tool_name, :filter_messages, as: :boolean)
58
- read_tool_option(opts, tool_name, :changed_files, as: :boolean)
60
+
61
+ read_tool_option(opts, tool_name, :filter_messages, :filter_messages, as: :boolean)
62
+ read_tool_option(opts, tool_name, :unfiltered, :filter_messages, as: :reversed_boolean)
63
+ read_tool_option(opts, tool_name, :changed_files, :changed_files, as: :boolean)
64
+ read_tool_option(opts, tool_name, :all_files, :changed_files, as: :reversed_boolean)
65
+ read_tool_option(opts, tool_name, :file_filter, :file_filter, as: :string)
59
66
  end
60
67
 
61
68
  def invalid!(message)
@@ -70,27 +77,28 @@ module QuietQuality
70
77
  [true, false].include?(value)
71
78
  end
72
79
 
73
- def read_global_option(opts, name, as:, validate_from: nil)
80
+ def read_global_option(opts, name, into, as:, validate_from: nil)
74
81
  parsed_value = data.fetch(name.to_sym, nil)
75
82
  return if parsed_value.nil?
76
83
 
77
84
  validate_value(name, parsed_value, as: as, from: validate_from)
78
85
  coerced_value = coerce_value(parsed_value, as: as)
79
- opts.set_global_option(name, coerced_value)
86
+ opts.set_global_option(into, coerced_value)
80
87
  end
81
88
 
82
- def read_tool_option(opts, tool, name, as:)
89
+ def read_tool_option(opts, tool, name, into, as:)
83
90
  parsed_value = data.dig(tool.to_sym, name.to_sym)
84
91
  return if parsed_value.nil?
85
92
 
86
93
  validate_value("#{tool}.#{name}", parsed_value, as: as)
87
94
  coerced_value = coerce_value(parsed_value, as: as)
88
- opts.set_tool_option(tool, name, coerced_value)
95
+ opts.set_tool_option(tool, into, coerced_value)
89
96
  end
90
97
 
91
98
  def validate_value(name, value, as:, from: nil)
92
99
  case as
93
100
  when :boolean then validate_boolean(name, value)
101
+ when :reversed_boolean then validate_boolean(name, value)
94
102
  when :symbol then validate_symbol(name, value, from: from)
95
103
  when :string then validate_string(name, value)
96
104
  else
@@ -123,6 +131,7 @@ module QuietQuality
123
131
  def coerce_value(value, as:)
124
132
  case as
125
133
  when :boolean then !!value
134
+ when :reversed_boolean then !value
126
135
  when :string then value.to_s
127
136
  when :symbol then value.to_sym
128
137
  else
@@ -1,14 +1,15 @@
1
1
  module QuietQuality
2
2
  module Config
3
3
  class ToolOptions
4
- def initialize(tool, limit_targets: true, filter_messages: true)
4
+ def initialize(tool, limit_targets: true, filter_messages: true, file_filter: nil)
5
5
  @tool_name = tool.to_sym
6
6
  @limit_targets = limit_targets
7
7
  @filter_messages = filter_messages
8
+ @file_filter = file_filter
8
9
  end
9
10
 
10
11
  attr_reader :tool_name
11
- attr_writer :limit_targets, :filter_messages
12
+ attr_writer :limit_targets, :filter_messages, :file_filter
12
13
 
13
14
  def limit_targets?
14
15
  @limit_targets
@@ -29,6 +30,11 @@ module QuietQuality
29
30
  def parser_class
30
31
  tool_namespace::Parser
31
32
  end
33
+
34
+ def file_filter
35
+ return nil if @file_filter.nil?
36
+ Regexp.new(@file_filter)
37
+ end
32
38
  end
33
39
  end
34
40
  end
@@ -11,11 +11,16 @@ module QuietQuality
11
11
  end
12
12
 
13
13
  def outcome
14
- @_outcome ||= runner.invoke!
14
+ @_outcome ||= Tools::Outcome.new(
15
+ tool: runner_outcome.tool,
16
+ output: runner_outcome.output,
17
+ logging: runner_outcome.logging,
18
+ failure: messages.any?
19
+ )
15
20
  end
16
21
 
17
22
  def failure?
18
- messages.any?
23
+ outcome.failure?
19
24
  end
20
25
 
21
26
  def messages
@@ -30,6 +35,10 @@ module QuietQuality
30
35
 
31
36
  attr_reader :changed_files, :tool_options
32
37
 
38
+ def runner_outcome
39
+ @_runner_outcome ||= runner.invoke!
40
+ end
41
+
33
42
  def limit_targets?
34
43
  tool_options.limit_targets?
35
44
  end
@@ -39,12 +48,14 @@ module QuietQuality
39
48
  end
40
49
 
41
50
  def runner
42
- @_runner ||= tool_options.runner_class
43
- .new(changed_files: limit_targets? ? changed_files : nil)
51
+ @_runner ||= tool_options.runner_class.new(
52
+ changed_files: limit_targets? ? changed_files : nil,
53
+ file_filter: tool_options.file_filter
54
+ )
44
55
  end
45
56
 
46
57
  def parser
47
- @_parser ||= tool_options.parser_class.new(outcome.output)
58
+ @_parser ||= tool_options.parser_class.new(runner_outcome.output)
48
59
  end
49
60
 
50
61
  def relevance_filter
@@ -6,8 +6,12 @@ module QuietQuality
6
6
  # https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman.rb#L6-L25
7
7
  KNOWN_EXIT_STATUSES = [3, 4, 5, 6, 7, 8].to_set
8
8
 
9
- def initialize(changed_files: nil)
9
+ # brakeman does not support being run against a portion of the project, so neither
10
+ # changed_files nor file_filter is actually used. But they are accepted here because
11
+ # that is what Runner initializers are required to accept.
12
+ def initialize(changed_files: nil, file_filter: nil)
10
13
  @changed_files = changed_files
14
+ @file_filter = file_filter
11
15
  end
12
16
 
13
17
  def invoke!
@@ -11,8 +11,9 @@ module QuietQuality
11
11
  # encountered"
12
12
  FAILURE_STATUS = 65
13
13
 
14
- def initialize(changed_files: nil)
14
+ def initialize(changed_files: nil, file_filter: nil)
15
15
  @changed_files = changed_files
16
+ @file_filter = file_filter
16
17
  end
17
18
 
18
19
  def invoke!
@@ -21,7 +22,7 @@ module QuietQuality
21
22
 
22
23
  private
23
24
 
24
- attr_reader :changed_files
25
+ attr_reader :changed_files, :file_filter
25
26
 
26
27
  def skip_execution?
27
28
  changed_files && relevant_files.empty?
@@ -29,7 +30,9 @@ module QuietQuality
29
30
 
30
31
  def relevant_files
31
32
  return nil if changed_files.nil?
32
- changed_files.paths.select { |path| path.end_with?(".haml") }
33
+ changed_files.paths
34
+ .select { |path| path.end_with?(".haml") }
35
+ .select { |path| file_filter.nil? || file_filter.match?(path) }
33
36
  end
34
37
 
35
38
  def target_files
@@ -5,8 +5,9 @@ module QuietQuality
5
5
  MAX_FILES = 100
6
6
  NO_FILES_OUTPUT = '{"examples": [], "summary": {"failure_count": 0}}'
7
7
 
8
- def initialize(changed_files: nil)
8
+ def initialize(changed_files: nil, file_filter: nil)
9
9
  @changed_files = changed_files
10
+ @file_filter = file_filter
10
11
  end
11
12
 
12
13
  def invoke!
@@ -15,7 +16,7 @@ module QuietQuality
15
16
 
16
17
  private
17
18
 
18
- attr_reader :changed_files
19
+ attr_reader :changed_files, :file_filter
19
20
 
20
21
  def skip_execution?
21
22
  changed_files && relevant_files.empty?
@@ -23,7 +24,9 @@ module QuietQuality
23
24
 
24
25
  def relevant_files
25
26
  return nil if changed_files.nil?
26
- changed_files.paths.select { |path| path.end_with?("_spec.rb") }
27
+ changed_files.paths
28
+ .select { |path| path.end_with?("_spec.rb") }
29
+ .select { |path| file_filter.nil? || file_filter.match?(path) }
27
30
  end
28
31
 
29
32
  def target_files
@@ -10,8 +10,9 @@ module QuietQuality
10
10
  end
11
11
 
12
12
  # Supplying changed_files: nil means "run against all files".
13
- def initialize(changed_files: nil)
13
+ def initialize(changed_files: nil, file_filter: nil)
14
14
  @changed_files = changed_files
15
+ @file_filter = file_filter
15
16
  end
16
17
 
17
18
  def invoke!
@@ -20,7 +21,7 @@ module QuietQuality
20
21
 
21
22
  private
22
23
 
23
- attr_reader :changed_files
24
+ attr_reader :changed_files, :file_filter
24
25
 
25
26
  # If we were told that _no files changed_ (which is distinct from not being told that
26
27
  # any files changed - a [] instead of a nil), then we shouldn't run rubocop at all.
@@ -38,7 +39,9 @@ module QuietQuality
38
39
 
39
40
  def relevant_files
40
41
  return nil if changed_files.nil?
41
- changed_files.paths.select { |path| path.end_with?(".rb") }
42
+ changed_files.paths
43
+ .select { |path| path.end_with?(".rb") }
44
+ .select { |path| file_filter.nil? || file_filter.match?(path) }
42
45
  end
43
46
 
44
47
  def target_files
@@ -1,3 +1,3 @@
1
1
  module QuietQuality
2
- VERSION = "1.0.2"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -41,4 +41,5 @@ Gem::Specification.new do |spec|
41
41
  spec.add_development_dependency "standard", "~> 1.28"
42
42
  spec.add_development_dependency "rubocop", "~> 1.50"
43
43
  spec.add_development_dependency "debug"
44
+ spec.add_development_dependency "mdl", "~> 0.12"
44
45
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quiet_quality
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Mueller
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-24 00:00:00.000000000 Z
11
+ date: 2023-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: git
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: mdl
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.12'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.12'
139
153
  description: |
140
154
  Allow your CI to notice and/or annotate new quality issues, despite the presences of
141
155
  many pre-existing issues in your codebase.
@@ -150,6 +164,8 @@ files:
150
164
  - ".github/workflows/linters.yml"
151
165
  - ".github/workflows/rspec.yml"
152
166
  - ".gitignore"
167
+ - ".mdl_rules.rb"
168
+ - ".mdlrc"
153
169
  - ".quiet_quality.yml"
154
170
  - ".rspec"
155
171
  - ".rubocop.yml"
@@ -157,6 +173,7 @@ files:
157
173
  - LICENSE
158
174
  - README.md
159
175
  - bin/qq
176
+ - docs/example-config.yml
160
177
  - lib/quiet_quality.rb
161
178
  - lib/quiet_quality/annotation_locator.rb
162
179
  - lib/quiet_quality/annotators.rb
@@ -224,7 +241,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
224
241
  - !ruby/object:Gem::Version
225
242
  version: '0'
226
243
  requirements: []
227
- rubygems_version: 3.1.6
244
+ rubygems_version: 3.3.7
228
245
  signing_key:
229
246
  specification_version: 4
230
247
  summary: A system for comparing quality tool outputs against the forward diffs