quiet_quality 1.0.3 → 1.1.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/README.md +18 -1
- data/lib/quiet_quality/cli/arg_parser.rb +4 -0
- data/lib/quiet_quality/cli/entrypoint.rb +26 -1
- data/lib/quiet_quality/config/builder.rb +2 -1
- data/lib/quiet_quality/config/parsed_options.rb +6 -2
- data/lib/quiet_quality/config/parser.rb +20 -11
- data/lib/quiet_quality/config/tool_options.rb +8 -2
- data/lib/quiet_quality/executors/pipeline.rb +4 -2
- data/lib/quiet_quality/tools/brakeman/runner.rb +5 -1
- data/lib/quiet_quality/tools/haml_lint/runner.rb +6 -3
- data/lib/quiet_quality/tools/rspec/runner.rb +6 -3
- data/lib/quiet_quality/tools/rubocop/runner.rb +6 -3
- data/lib/quiet_quality/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6aea488d2026da63fdf9483d1df9bd4e2363270d7b441cbca384cd803cab803
|
4
|
+
data.tar.gz: 0536d6eb0b8cdd1c4678f49058be4d37017b7ff6156d363afa71df8a979d30aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 766f24f8211b83610c05e57b0f81d77bbf2d4bf8c206cc5e9af1d4e302adc9fee6425c506b344850a1421b7a30f18b6dfa6a23132aaa64dc3e6fbeb5e59c4c0b
|
7
|
+
data.tar.gz: 7b72dcf22a6696b2ff88a5efb08fb0338d2d4f0b43f506f147a2d5cb0ed7186328157ff4b8ded7198fff3785f6636b32d8b1ecd1102cd462b341f28c57dfd429
|
data/README.md
CHANGED
@@ -144,6 +144,22 @@ And then each tool can have an entry, within which `changed_files` and
|
|
144
144
|
`filter_messages` can be specified - the tool-specific settings override the
|
145
145
|
global ones.
|
146
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
|
+
|
147
163
|
### CLI Options
|
148
164
|
|
149
165
|
The same options are all available on the CLI, plus some additional ones - run
|
@@ -151,5 +167,6 @@ The same options are all available on the CLI, plus some additional ones - run
|
|
151
167
|
|
152
168
|
* `--help/-H`: See a list of the options
|
153
169
|
* `--no-config/-N`: Do _not_ load a config file, even if present.
|
154
|
-
* `--config/-C
|
170
|
+
* `--config/-C`: load the supplied config file (instead of the detected one, if
|
155
171
|
found)
|
172
|
+
* `--version/-V`: what version of the gem are you using?
|
@@ -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? ||
|
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
|
-
|
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, :
|
44
|
-
read_global_option(opts, :
|
45
|
-
read_global_option(opts, :
|
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
|
-
|
58
|
-
read_tool_option(opts, tool_name, :
|
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(
|
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,
|
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
|
@@ -48,8 +48,10 @@ module QuietQuality
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def runner
|
51
|
-
@_runner ||= tool_options.runner_class
|
52
|
-
|
51
|
+
@_runner ||= tool_options.runner_class.new(
|
52
|
+
changed_files: limit_targets? ? changed_files : nil,
|
53
|
+
file_filter: tool_options.file_filter
|
54
|
+
)
|
53
55
|
end
|
54
56
|
|
55
57
|
def parser
|
@@ -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
|
-
|
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
|
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
|
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
|
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
|
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
|
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-
|
11
|
+
date: 2023-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: git
|
@@ -241,7 +241,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
241
241
|
- !ruby/object:Gem::Version
|
242
242
|
version: '0'
|
243
243
|
requirements: []
|
244
|
-
rubygems_version: 3.
|
244
|
+
rubygems_version: 3.3.7
|
245
245
|
signing_key:
|
246
246
|
specification_version: 4
|
247
247
|
summary: A system for comparing quality tool outputs against the forward diffs
|