quiet_quality 1.4.0 → 1.5.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/.github/workflows/dogfood.yml +1 -1
- data/.github/workflows/linters.yml +1 -1
- data/.github/workflows/rspec.yml +1 -1
- data/.quiet_quality.yml +1 -0
- data/.standard.yml +3 -0
- data/CHANGELOG.md +12 -0
- data/README.md +37 -0
- data/lib/quiet_quality/cli/arg_parser.rb +12 -0
- data/lib/quiet_quality/cli/entrypoint.rb +21 -1
- data/lib/quiet_quality/cli/message_formatter.rb +190 -0
- data/lib/quiet_quality/cli/presenter.rb +18 -2
- data/lib/quiet_quality/cli.rb +2 -2
- data/lib/quiet_quality/config/builder.rb +15 -1
- data/lib/quiet_quality/config/options.rb +5 -1
- data/lib/quiet_quality/config/parsed_options.rb +2 -0
- data/lib/quiet_quality/config/parser.rb +1 -0
- data/lib/quiet_quality/executors/execcer.rb +46 -0
- data/lib/quiet_quality/executors/serial_executor.rb +1 -1
- data/lib/quiet_quality/tools/base_runner.rb +4 -0
- data/lib/quiet_quality/tools/brakeman/runner.rb +4 -0
- data/lib/quiet_quality/tools/brakeman.rb +1 -1
- data/lib/quiet_quality/tools/haml_lint/runner.rb +4 -0
- data/lib/quiet_quality/tools/markdown_lint/runner.rb +9 -3
- data/lib/quiet_quality/tools/relevant_runner.rb +10 -1
- data/lib/quiet_quality/tools/rspec/runner.rb +4 -0
- data/lib/quiet_quality/tools/rubocop/runner.rb +4 -0
- data/lib/quiet_quality/tools/standardrb/runner.rb +4 -0
- data/lib/quiet_quality/tools/standardrb.rb +1 -1
- data/lib/quiet_quality/tools.rb +2 -2
- data/lib/quiet_quality/version.rb +1 -1
- data/lib/quiet_quality.rb +2 -2
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ff5a82876936d746842d76e055475ba19e78d0bfff7967b2f179a2262cb5d7e
|
4
|
+
data.tar.gz: 529ed1d29fdf3c3c6ba381e7ab71cbf006bc44c8d608858e8ec84d67c2efb267
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b840cfe8d90929c0fcc32fdc1370310924a46464006b39afa5dceff69b8c24254d701002e77f33a845baaa7fe5373243486b5d1422a3beea4fd45a50e65ec8b
|
7
|
+
data.tar.gz: e3176f406a5de5a027cae5a2edcbd897395a0191dad1a6cb402bf48fb005f9dce3783d8e6778f91e7d05c03b3f12f473ee23438b9235ed5eedd5e4d588a58526
|
data/.github/workflows/rspec.yml
CHANGED
data/.quiet_quality.yml
CHANGED
data/.standard.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## Release 1.5.0
|
4
|
+
|
5
|
+
* Update to comply with current standardrb rules, and use checkout@v4
|
6
|
+
* Add a `-X/--exec` argument that allows you to let qq craft the command, but
|
7
|
+
then actually exec the command instead of running it and handling its output.
|
8
|
+
Especially useful for things like `rspec`, where the output it gives you about
|
9
|
+
failing tests is very useful, and qq is mostly only helpful for determining
|
10
|
+
what specs to run.
|
11
|
+
* Add a `--message-format` argument and `message_format` config file option,
|
12
|
+
which allow for a fairly complex configuration of the output format for
|
13
|
+
messages, so they can be displayed in various colorized/tabular formats.
|
14
|
+
|
3
15
|
## Release 1.4.0
|
4
16
|
|
5
17
|
* Support specifying `excludes` per-tool, so that certain files won't be passed
|
data/README.md
CHANGED
@@ -151,6 +151,9 @@ The configuration file supports the following _global_ options (top-level keys):
|
|
151
151
|
* `colorize`: by default, `bin/qq` will include color codes in its output, to
|
152
152
|
make failing tools easier to spot, and messages easier to read. But you can
|
153
153
|
supply `colorize: false` to tell it not to do that if you don't want them.
|
154
|
+
* `message_format`: you can specify a format string with which to render the
|
155
|
+
messages, which interpolates values with various formatting flags. Details
|
156
|
+
given in the "Message Formatting" section below.
|
154
157
|
|
155
158
|
And then each tool can have an entry, within which `changed_files` and
|
156
159
|
`filter_messages` can be specified - the tool-specific settings override the
|
@@ -181,6 +184,40 @@ generated file like `db/schema.rb`, and that file doesn't meet your rubocop (or
|
|
181
184
|
standardrb) rules, you'll get _told_ unless you exclude it at the quiet-quality
|
182
185
|
level as well.
|
183
186
|
|
187
|
+
### Message Formatting
|
188
|
+
|
189
|
+
You can supply a message-format string on the cli or in your config file, which
|
190
|
+
will override the default formatting for message output on the CLI. These format
|
191
|
+
strings are intended to be a single line containing "substitution tokens", which
|
192
|
+
each look like `%[lr]?[bem]?color?(Size)(Source)`.
|
193
|
+
|
194
|
+
* The first (optional) flag can be an "l", and "r", or be left off (which is the
|
195
|
+
same as "l"). This flag indicates the 'justification' - left or right.
|
196
|
+
* The second (optional) flag can be a "b", an "e", or an "m", defaulting to "e";
|
197
|
+
these stand for "beginning", "ending", and "middle", and represent what part
|
198
|
+
of the string should be truncated if it needs to be shortened.
|
199
|
+
* The third (optional) part is a color name, and can be any of "yellow", "red",
|
200
|
+
"green", "blue", "cyan", or "none" (leaving it off is the same as specifing
|
201
|
+
"none"). This is the color to use for the token in the output - note that any
|
202
|
+
color supplied here is used regardless of the '--colorize' flag.
|
203
|
+
* The fourth part of the token is required, and is the _size_ of the token. If a
|
204
|
+
positive integer is supplied, then the token will take up that much space, and
|
205
|
+
will be padded on the appropriate side if necessary; if a negative integer is
|
206
|
+
supplied, then the token will not be padded out, but will still get truncated
|
207
|
+
if it is too long. The value '0' is special, and indicates that the token
|
208
|
+
should be neither padded nor truncated.
|
209
|
+
* The last part of the token is a string indicating the _source_ data to
|
210
|
+
represent, and must be one of these values: "tool", "loc", "level", "path",
|
211
|
+
"lines", "rule", "body". Each of these represents one piece of data out of the
|
212
|
+
message object that can be rendered into the message line.
|
213
|
+
|
214
|
+
Some example message formats:
|
215
|
+
|
216
|
+
```text
|
217
|
+
%lcyan8tool | %lmyellow30rule | %0loc
|
218
|
+
%le6tool [%mblue20rule] %b45loc %cyan-100body
|
219
|
+
```
|
220
|
+
|
184
221
|
### CLI Options
|
185
222
|
|
186
223
|
To specify which _tools_ to run (and if any are specified, the `default_tools`
|
@@ -67,6 +67,7 @@ module QuietQuality
|
|
67
67
|
setup_filter_messages_options(parser)
|
68
68
|
setup_colorization_options(parser)
|
69
69
|
setup_logging_options(parser)
|
70
|
+
setup_message_formatting_options(parser)
|
70
71
|
setup_verbosity_options(parser)
|
71
72
|
end
|
72
73
|
end
|
@@ -100,6 +101,11 @@ module QuietQuality
|
|
100
101
|
validate_value_from("executor", name, Executors::AVAILABLE)
|
101
102
|
set_global_option(:executor, name.to_sym)
|
102
103
|
end
|
104
|
+
|
105
|
+
parser.on("-X", "--exec TOOL", "Exec one tool instead of managing several") do |tool_name|
|
106
|
+
validate_value_from("tool", tool_name, Tools::AVAILABLE)
|
107
|
+
set_global_option(:exec_tool, tool_name.to_sym)
|
108
|
+
end
|
103
109
|
end
|
104
110
|
|
105
111
|
def setup_annotation_options(parser)
|
@@ -163,6 +169,12 @@ module QuietQuality
|
|
163
169
|
end
|
164
170
|
end
|
165
171
|
|
172
|
+
def setup_message_formatting_options(parser)
|
173
|
+
parser.on("-F", "--message-format FMT", "A format string with which to print messages") do |fmt|
|
174
|
+
set_global_option(:message_format, fmt)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
166
178
|
def setup_verbosity_options(parser)
|
167
179
|
parser.on("-v", "--verbose", "Log more verbosely - multiple times is more verbose") do
|
168
180
|
QuietQuality.logger.increase_level!
|
@@ -18,7 +18,7 @@ module QuietQuality
|
|
18
18
|
log_no_tools_text
|
19
19
|
else
|
20
20
|
log_options
|
21
|
-
|
21
|
+
execute!
|
22
22
|
log_results
|
23
23
|
annotate_messages
|
24
24
|
end
|
@@ -114,6 +114,26 @@ module QuietQuality
|
|
114
114
|
@_executed = executor
|
115
115
|
end
|
116
116
|
|
117
|
+
def exec_tool_options
|
118
|
+
@_exec_tool_options ||= options.tools
|
119
|
+
.detect { |topts| topts.tool_name == options.exec_tool.to_sym }
|
120
|
+
end
|
121
|
+
|
122
|
+
def execcer
|
123
|
+
@_execcer ||= QuietQuality::Executors::Execcer.new(
|
124
|
+
tool_options: exec_tool_options,
|
125
|
+
changed_files: changed_files
|
126
|
+
)
|
127
|
+
end
|
128
|
+
|
129
|
+
def execute!
|
130
|
+
if options.exec_tool
|
131
|
+
execcer.exec!
|
132
|
+
else
|
133
|
+
executed
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
117
137
|
def annotate_messages
|
118
138
|
return unless options.annotator
|
119
139
|
info("Annotating with #{options.annotator}")
|
@@ -0,0 +1,190 @@
|
|
1
|
+
module QuietQuality
|
2
|
+
module Cli
|
3
|
+
class MessageFormatter
|
4
|
+
TOKEN_MATCHING_REGEX = %r{%[a-z]*-?\d+(?:tool|loc|level|path|lines|rule|body)}
|
5
|
+
|
6
|
+
def initialize(message_format:)
|
7
|
+
@message_format = message_format
|
8
|
+
end
|
9
|
+
|
10
|
+
def format(message)
|
11
|
+
formatted_tokens = parsed_tokens.map { |pt| FormattedToken.new(parsed_token: pt, message: message) }
|
12
|
+
formatted_tokens.reduce(message_format) do |interpolating, ftok|
|
13
|
+
interpolating.gsub(ftok.token, ftok.formatted_token)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :message_format
|
20
|
+
|
21
|
+
def tokens
|
22
|
+
@_tokens ||= message_format.scan(TOKEN_MATCHING_REGEX)
|
23
|
+
end
|
24
|
+
|
25
|
+
def parsed_tokens
|
26
|
+
@_parsed_tokens ||= tokens.map { |tok| ParsedToken.new(tok) }
|
27
|
+
end
|
28
|
+
|
29
|
+
class ParsedToken
|
30
|
+
TOKEN_PARSING_REGEX = %r{
|
31
|
+
% # start the interplation token
|
32
|
+
(?<just>[lr])? # specify the justification
|
33
|
+
(?<trunc>[bem])? # where to truncate from
|
34
|
+
(?<color>yellow|red|green|blue|cyan|none)? # what color
|
35
|
+
(?<size>-?\d+) # string size (may be negative)
|
36
|
+
(?<source>tool|loc|level|path|lines|rule|body) # data source name
|
37
|
+
}x
|
38
|
+
|
39
|
+
COLORS = {
|
40
|
+
"yellow" => :yellow,
|
41
|
+
"red" => :red,
|
42
|
+
"green" => :green,
|
43
|
+
"blue" => :light_blue,
|
44
|
+
"cyan" => :light_cyan,
|
45
|
+
"none" => nil
|
46
|
+
}.freeze
|
47
|
+
|
48
|
+
JUSTIFICATIONS = {"l" => :left, "r" => :right}.freeze
|
49
|
+
TRUNCATIONS = {"b" => :beginning, "m" => :middle, "e" => :ending}.freeze
|
50
|
+
|
51
|
+
def initialize(token)
|
52
|
+
@token = token
|
53
|
+
end
|
54
|
+
|
55
|
+
attr_reader :token
|
56
|
+
|
57
|
+
def justification
|
58
|
+
JUSTIFICATIONS.fetch(token_pieces[:just]&.downcase, :left)
|
59
|
+
end
|
60
|
+
|
61
|
+
def truncation
|
62
|
+
TRUNCATIONS.fetch(token_pieces[:trunc]&.downcase, :ending)
|
63
|
+
end
|
64
|
+
|
65
|
+
def color
|
66
|
+
COLORS.fetch(token_pieces[:color]&.downcase, nil)
|
67
|
+
end
|
68
|
+
|
69
|
+
def size
|
70
|
+
raw_size.abs
|
71
|
+
end
|
72
|
+
|
73
|
+
def source
|
74
|
+
token_pieces[:source]
|
75
|
+
end
|
76
|
+
|
77
|
+
def allow_pad?
|
78
|
+
raw_size.positive?
|
79
|
+
end
|
80
|
+
|
81
|
+
def allow_truncate?
|
82
|
+
!raw_size.zero?
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def token_pieces
|
88
|
+
@_token_pieces ||= token.match(TOKEN_PARSING_REGEX)
|
89
|
+
end
|
90
|
+
|
91
|
+
def raw_size
|
92
|
+
@_raw_size ||= token_pieces[:size].to_i
|
93
|
+
end
|
94
|
+
end
|
95
|
+
private_constant :ParsedToken
|
96
|
+
|
97
|
+
class FormattedToken
|
98
|
+
def initialize(parsed_token:, message:)
|
99
|
+
@parsed_token = parsed_token
|
100
|
+
@message = message
|
101
|
+
end
|
102
|
+
|
103
|
+
def formatted_token
|
104
|
+
colorized(padded(truncated(base_string)))
|
105
|
+
end
|
106
|
+
|
107
|
+
def token
|
108
|
+
parsed_token.token
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
attr_reader :parsed_token, :message
|
114
|
+
|
115
|
+
def line_range
|
116
|
+
if message.start_line == message.stop_line
|
117
|
+
message.start_line.to_s
|
118
|
+
else
|
119
|
+
"#{message.start_line}-#{message.stop_line}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def base_string
|
124
|
+
case parsed_token.source
|
125
|
+
when "tool" then message.tool_name
|
126
|
+
when "loc" then location_string
|
127
|
+
when "level" then message.level
|
128
|
+
when "path" then message.path
|
129
|
+
when "lines" then line_range
|
130
|
+
when "rule" then message.rule
|
131
|
+
when "body" then flattened_body
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def location_string
|
136
|
+
"#{message.path}:#{line_range}"
|
137
|
+
end
|
138
|
+
|
139
|
+
def flattened_body
|
140
|
+
message.body.gsub(/ *\n */, "\\n")
|
141
|
+
end
|
142
|
+
|
143
|
+
def truncated(s)
|
144
|
+
return s unless parsed_token.allow_truncate?
|
145
|
+
return s if s.length <= parsed_token.size
|
146
|
+
size = parsed_token.size
|
147
|
+
|
148
|
+
case parsed_token.truncation
|
149
|
+
when :beginning then truncate_beginning(s, size)
|
150
|
+
when :middle then truncate_middle(s, size)
|
151
|
+
when :ending then truncate_ending(s, size)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def truncate_beginning(s, size)
|
156
|
+
"…" + s.slice(1 - size, size - 1)
|
157
|
+
end
|
158
|
+
|
159
|
+
def truncate_middle(s, size)
|
160
|
+
front_len = (size / 2.0).floor
|
161
|
+
back_len = (size / 2.0).ceil - 1
|
162
|
+
s.slice(0, front_len) + "…" + s.slice(-back_len, back_len)
|
163
|
+
end
|
164
|
+
|
165
|
+
def truncate_ending(s, size)
|
166
|
+
s.slice(0, size - 1) + "…"
|
167
|
+
end
|
168
|
+
|
169
|
+
def padded(s)
|
170
|
+
return s unless parsed_token.allow_pad?
|
171
|
+
return s if s.length >= parsed_token.size
|
172
|
+
|
173
|
+
case parsed_token.justification
|
174
|
+
when :left then s.ljust(parsed_token.size)
|
175
|
+
when :right then s.rjust(parsed_token.size)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def colorized(s)
|
180
|
+
if parsed_token.color.nil?
|
181
|
+
s
|
182
|
+
else
|
183
|
+
Colorize.colorize(s, color: parsed_token.color)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
private_constant :FormattedToken
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
@@ -78,12 +78,28 @@ module QuietQuality
|
|
78
78
|
s.gsub(/ *\n */, "\\n").slice(0, length)
|
79
79
|
end
|
80
80
|
|
81
|
-
def
|
81
|
+
def locally_formatted_message(msg)
|
82
82
|
tool = colorize(:yellow, msg.tool_name)
|
83
83
|
line_range = line_range_for(msg)
|
84
84
|
rule_string = msg.rule ? " [#{colorize(:yellow, msg.rule)}]" : ""
|
85
85
|
truncated_body = reduce_text(msg.body, 120)
|
86
|
-
|
86
|
+
"#{tool} #{msg.path}:#{line_range}#{rule_string} #{truncated_body}"
|
87
|
+
end
|
88
|
+
|
89
|
+
def loggable_message(msg)
|
90
|
+
if options.message_format
|
91
|
+
message_formatter.format(msg)
|
92
|
+
else
|
93
|
+
stream.puts locally_formatted_message(msg)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def log_message(msg)
|
98
|
+
stream.puts loggable_message(msg)
|
99
|
+
end
|
100
|
+
|
101
|
+
def message_formatter
|
102
|
+
@_message_formatter ||= MessageFormatter.new(message_format: options.message_format)
|
87
103
|
end
|
88
104
|
end
|
89
105
|
end
|
data/lib/quiet_quality/cli.rb
CHANGED
@@ -22,7 +22,7 @@ module QuietQuality
|
|
22
22
|
Options.new.tap { |opts| opts.tools = tools }
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def specified_tool_names
|
26
26
|
if cli.tools.any?
|
27
27
|
cli.tools
|
28
28
|
elsif config_file&.tools&.any?
|
@@ -32,6 +32,14 @@ module QuietQuality
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
def exec_tool_name
|
36
|
+
cli.global_option(:exec_tool)
|
37
|
+
end
|
38
|
+
|
39
|
+
def tool_names
|
40
|
+
(specified_tool_names + [exec_tool_name]).compact.uniq
|
41
|
+
end
|
42
|
+
|
35
43
|
def config_finder
|
36
44
|
@_config_finder ||= Finder.new(from: ".")
|
37
45
|
end
|
@@ -84,6 +92,7 @@ module QuietQuality
|
|
84
92
|
def update_globals
|
85
93
|
update_annotator
|
86
94
|
update_executor
|
95
|
+
update_exec_tool
|
87
96
|
update_comparison_branch
|
88
97
|
update_logging
|
89
98
|
end
|
@@ -100,6 +109,10 @@ module QuietQuality
|
|
100
109
|
options.executor = Executors::AVAILABLE.fetch(executor_name)
|
101
110
|
end
|
102
111
|
|
112
|
+
def update_exec_tool
|
113
|
+
set_unless_nil(options, :exec_tool, apply.global_option(:exec_tool))
|
114
|
+
end
|
115
|
+
|
103
116
|
def update_comparison_branch
|
104
117
|
set_unless_nil(options, :comparison_branch, apply.global_option(:comparison_branch))
|
105
118
|
end
|
@@ -107,6 +120,7 @@ module QuietQuality
|
|
107
120
|
def update_logging
|
108
121
|
set_unless_nil(options, :logging, apply.global_option(:logging))
|
109
122
|
set_unless_nil(options, :colorize, apply.global_option(:colorize))
|
123
|
+
set_unless_nil(options, :message_format, apply.global_option(:message_format))
|
110
124
|
end
|
111
125
|
|
112
126
|
# ---- update the tool options (apply global forms first) -------
|
@@ -7,12 +7,14 @@ module QuietQuality
|
|
7
7
|
@annotator = nil
|
8
8
|
@executor = Executors::ConcurrentExecutor
|
9
9
|
@tools = nil
|
10
|
+
@exec_tool = nil
|
10
11
|
@comparison_branch = nil
|
11
12
|
@colorize = true
|
12
13
|
@logging = :normal
|
14
|
+
@message_format = nil
|
13
15
|
end
|
14
16
|
|
15
|
-
attr_accessor :tools, :comparison_branch, :annotator, :executor
|
17
|
+
attr_accessor :tools, :comparison_branch, :annotator, :executor, :exec_tool, :message_format
|
16
18
|
attr_reader :logging
|
17
19
|
attr_writer :colorize
|
18
20
|
|
@@ -37,9 +39,11 @@ module QuietQuality
|
|
37
39
|
{
|
38
40
|
annotator: annotator,
|
39
41
|
executor: executor.name,
|
42
|
+
exec_tool: exec_tool,
|
40
43
|
comparison_branch: comparison_branch,
|
41
44
|
colorize: colorize?,
|
42
45
|
logging: logging,
|
46
|
+
message_format: message_format,
|
43
47
|
tools: tool_hashes_by_name
|
44
48
|
}
|
45
49
|
end
|
@@ -48,6 +48,7 @@ module QuietQuality
|
|
48
48
|
read_global_option(opts, :unfiltered, :filter_messages, as: :reversed_boolean)
|
49
49
|
read_global_option(opts, :colorize, :colorize, as: :boolean)
|
50
50
|
read_global_option(opts, :logging, :logging, as: :symbol, validate_from: Options::LOGGING_LEVELS)
|
51
|
+
read_global_option(opts, :message_format, :message_format, as: :string)
|
51
52
|
end
|
52
53
|
|
53
54
|
def store_tool_options(opts)
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module QuietQuality
|
2
|
+
module Executors
|
3
|
+
class Execcer
|
4
|
+
include Logging
|
5
|
+
|
6
|
+
def initialize(tool_options:, changed_files: nil)
|
7
|
+
@tool_options = tool_options
|
8
|
+
@changed_files = changed_files
|
9
|
+
end
|
10
|
+
|
11
|
+
def exec!
|
12
|
+
if runner.exec_command
|
13
|
+
Kernel.exec(*runner.exec_command)
|
14
|
+
else
|
15
|
+
info <<~LOG_MESSAGE
|
16
|
+
This runner does not believe it needs to execute at all.
|
17
|
+
This typically means that it was told to target changed-files, but no relevant
|
18
|
+
files were changed.
|
19
|
+
LOG_MESSAGE
|
20
|
+
Kernel.exit(0)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :tool_options, :changed_files
|
27
|
+
|
28
|
+
def limit_targets?
|
29
|
+
tool_options.limit_targets?
|
30
|
+
end
|
31
|
+
|
32
|
+
def runner
|
33
|
+
@_runner ||= tool_options.runner_class.new(
|
34
|
+
changed_files: limit_targets? ? changed_files : nil,
|
35
|
+
file_filter: tool_options.file_filter
|
36
|
+
).tap { |r| log_runner(r) }
|
37
|
+
end
|
38
|
+
|
39
|
+
def log_runner(r)
|
40
|
+
command_string = r.exec_command ? "`#{r.exec_command.join(" ")}`" : "(skipped)"
|
41
|
+
info("Runner #{r.tool_name} exec_command: #{command_string}")
|
42
|
+
debug("Full exec_command for #{r.tool_name}", data: r.exec_command)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -23,6 +23,10 @@ module QuietQuality
|
|
23
23
|
fail(NoMethodError, "BaseRunner subclass must implement `command`")
|
24
24
|
end
|
25
25
|
|
26
|
+
def exec_command
|
27
|
+
fail(NoMethodError, "BaseRunner subclass must implement `exec_command`")
|
28
|
+
end
|
29
|
+
|
26
30
|
def success_status?(stat)
|
27
31
|
stat.success?
|
28
32
|
end
|
@@ -10,6 +10,10 @@ module QuietQuality
|
|
10
10
|
["brakeman", "-f", "json"]
|
11
11
|
end
|
12
12
|
|
13
|
+
def exec_command
|
14
|
+
["brakeman"]
|
15
|
+
end
|
16
|
+
|
13
17
|
# These are specified in constants at the top of brakeman.rb:
|
14
18
|
# https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman.rb#L6-L25
|
15
19
|
def failure_status?(stat)
|
@@ -10,15 +10,21 @@ module QuietQuality
|
|
10
10
|
"[]"
|
11
11
|
end
|
12
12
|
|
13
|
-
def command
|
13
|
+
def command(json: true)
|
14
14
|
return nil if skip_execution?
|
15
|
+
base_command = ["mdl"]
|
16
|
+
base_command << "--json" if json
|
15
17
|
if target_files.any?
|
16
|
-
|
18
|
+
base_command + target_files.sort
|
17
19
|
else
|
18
|
-
|
20
|
+
base_command + ["."]
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
24
|
+
def exec_command
|
25
|
+
command(json: false)
|
26
|
+
end
|
27
|
+
|
22
28
|
def relevant_path?(path)
|
23
29
|
path.end_with?(".md")
|
24
30
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative "
|
1
|
+
require_relative "base_runner"
|
2
2
|
|
3
3
|
module QuietQuality
|
4
4
|
module Tools
|
@@ -16,6 +16,11 @@ module QuietQuality
|
|
16
16
|
base_command + target_files.sort
|
17
17
|
end
|
18
18
|
|
19
|
+
def exec_command
|
20
|
+
return nil if skip_execution?
|
21
|
+
base_exec_command + target_files.sort
|
22
|
+
end
|
23
|
+
|
19
24
|
def relevant_path?(path)
|
20
25
|
fail(NoMethodError, "RelevantRunner subclass must implement `relevant_path?`")
|
21
26
|
end
|
@@ -24,6 +29,10 @@ module QuietQuality
|
|
24
29
|
fail(NoMethodError, "RelevantRunner subclass must implement either `command` or `base_command`")
|
25
30
|
end
|
26
31
|
|
32
|
+
def base_exec_command
|
33
|
+
fail(NoMethodError, "RelevantRunner subclass must implement either `exec_command` or `base_exec_command`")
|
34
|
+
end
|
35
|
+
|
27
36
|
def no_files_output
|
28
37
|
fail(NoMethodError, "RelevantRunner subclass must implement `no_files_output`")
|
29
38
|
end
|
data/lib/quiet_quality/tools.rb
CHANGED
@@ -8,8 +8,8 @@ module QuietQuality
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
require_relative "
|
12
|
-
require_relative "
|
11
|
+
require_relative "tools/base_runner"
|
12
|
+
require_relative "tools/relevant_runner"
|
13
13
|
|
14
14
|
glob = File.expand_path("../tools/*.rb", __FILE__)
|
15
15
|
Dir.glob(glob).sort.each { |f| require f }
|
data/lib/quiet_quality.rb
CHANGED
@@ -16,7 +16,7 @@ module QuietQuality
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
require_relative "
|
20
|
-
require_relative "
|
19
|
+
require_relative "quiet_quality/logger"
|
20
|
+
require_relative "quiet_quality/logging"
|
21
21
|
glob = File.expand_path("../quiet_quality/*.rb", __FILE__)
|
22
22
|
Dir.glob(glob).sort.each { |f| require f }
|
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.
|
4
|
+
version: 1.5.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-
|
11
|
+
date: 2023-11-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: git
|
@@ -184,6 +184,7 @@ files:
|
|
184
184
|
- ".quiet_quality.yml"
|
185
185
|
- ".rspec"
|
186
186
|
- ".rubocop.yml"
|
187
|
+
- ".standard.yml"
|
187
188
|
- CHANGELOG.md
|
188
189
|
- Gemfile
|
189
190
|
- LICENSE
|
@@ -199,6 +200,7 @@ files:
|
|
199
200
|
- lib/quiet_quality/cli.rb
|
200
201
|
- lib/quiet_quality/cli/arg_parser.rb
|
201
202
|
- lib/quiet_quality/cli/entrypoint.rb
|
203
|
+
- lib/quiet_quality/cli/message_formatter.rb
|
202
204
|
- lib/quiet_quality/cli/presenter.rb
|
203
205
|
- lib/quiet_quality/colorize.rb
|
204
206
|
- lib/quiet_quality/config.rb
|
@@ -212,6 +214,7 @@ files:
|
|
212
214
|
- lib/quiet_quality/executors.rb
|
213
215
|
- lib/quiet_quality/executors/base_executor.rb
|
214
216
|
- lib/quiet_quality/executors/concurrent_executor.rb
|
217
|
+
- lib/quiet_quality/executors/execcer.rb
|
215
218
|
- lib/quiet_quality/executors/pipeline.rb
|
216
219
|
- lib/quiet_quality/executors/serial_executor.rb
|
217
220
|
- lib/quiet_quality/logger.rb
|