quiet_quality 1.2.2 → 1.3.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/.quiet_quality.ci.yml +1 -0
- data/.quiet_quality.yml +1 -0
- data/CHANGELOG.md +9 -0
- data/README.md +7 -1
- data/lib/quiet_quality/cli/arg_parser.rb +19 -5
- data/lib/quiet_quality/cli/entrypoint.rb +13 -9
- data/lib/quiet_quality/cli/presenter.rb +26 -13
- data/lib/quiet_quality/colorize.rb +19 -0
- data/lib/quiet_quality/config/builder.rb +1 -0
- data/lib/quiet_quality/config/options.rb +39 -2
- data/lib/quiet_quality/config/parsed_options.rb +1 -0
- data/lib/quiet_quality/config/parser.rb +2 -1
- data/lib/quiet_quality/config/tool_options.rb +9 -0
- data/lib/quiet_quality/executors/pipeline.rb +26 -5
- data/lib/quiet_quality/logger.rb +54 -6
- data/lib/quiet_quality/logging.rb +21 -0
- data/lib/quiet_quality/tools/base_runner.rb +9 -0
- data/lib/quiet_quality/tools/relevant_runner.rb +1 -0
- data/lib/quiet_quality/version.rb +1 -1
- data/lib/quiet_quality.rb +6 -0
- data/quiet_quality.gemspec +1 -1
- metadata +8 -7
- data/lib/quiet_quality/config/logging.rb +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 921a945aaedb335246c6944ae8f460505357a73d20f4f1cf2ae3dba3e9fe9041
|
4
|
+
data.tar.gz: fab1f3330661738cc146e26590d489bb9fff0cc0c0318a5e9529fb9fd0802038
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84a082f31fb8a6ae290399a97fdb5918bd91c2eaa701ec7b3909fe27e2d66845ceae7db7bcf9a59dd6696c71bfe99b4cc189f1d529bea49f5f82ba849c8fb553
|
7
|
+
data.tar.gz: 222a7432405df57d2739c0799bc5844b1a916c76febf34c798891ee39e17ce79c17dedaec15928488a819261fdc35d3d746276109455cba7d490b2140c5d31c4
|
data/.quiet_quality.ci.yml
CHANGED
data/.quiet_quality.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## Release 1.3.0
|
4
|
+
|
5
|
+
* Support (and enable by default) colorizing the console stderr output from
|
6
|
+
`bin/qq` - disable with the `--no-colorize` flag or the `colorize: false`
|
7
|
+
configuration entry. (#94, resolved #36)
|
8
|
+
* Introduce a Logging facility, and add the `--verbose/-v` flag - supply it
|
9
|
+
either once or twice to enable (colorized) logging in either `info` or `debug`
|
10
|
+
level, providing much more detail about what's going on during execution.
|
11
|
+
|
3
12
|
## Release 1.2.2
|
4
13
|
|
5
14
|
* Add some code to the Rspec::Parser that _cleans_ the json of certain text that
|
data/README.md
CHANGED
@@ -148,6 +148,9 @@ The configuration file supports the following _global_ options (top-level keys):
|
|
148
148
|
prints a aggregated result (e.g. "3 tools executed: 1 passed, 2 failed
|
149
149
|
(rubocop, standardrb)"). The `quiet` option will only return a status code,
|
150
150
|
printing nothing.
|
151
|
+
* `colorize`: by default, `bin/qq` will include color codes in its output, to
|
152
|
+
make failing tools easier to spot, and messages easier to read. But you can
|
153
|
+
supply `colorize: false` to tell it not to do that if you don't want them.
|
151
154
|
|
152
155
|
And then each tool can have an entry, within which `changed_files` and
|
153
156
|
`filter_messages` can be specified - the tool-specific settings override the
|
@@ -196,7 +199,10 @@ Usage: qq [TOOLS] [GLOBAL_OPTIONS] [TOOL_OPTIONS]
|
|
196
199
|
-B, --comparison-branch BRANCH Specify the branch to compare against
|
197
200
|
-f, --filter-messages [tool] Filter messages from tool(s) based on changed lines
|
198
201
|
-u, --unfiltered [tool] Don't filter messages from tool(s)
|
202
|
+
--[no-]colorize Colorize the logging output
|
203
|
+
-n, --normal Print outcomes and messages
|
199
204
|
-l, --light Print aggregated results only
|
200
205
|
-q, --quiet Don't print results, only return a status code
|
201
|
-
-L, --logging LEVEL Specify logging mode
|
206
|
+
-L, --logging LEVEL Specify logging mode (from light/quiet/normal)
|
207
|
+
-v, --verbose Log more verbosely - multiple times is more verbose
|
202
208
|
```
|
@@ -65,7 +65,9 @@ module QuietQuality
|
|
65
65
|
setup_annotation_options(parser)
|
66
66
|
setup_file_target_options(parser)
|
67
67
|
setup_filter_messages_options(parser)
|
68
|
+
setup_colorization_options(parser)
|
68
69
|
setup_logging_options(parser)
|
70
|
+
setup_verbosity_options(parser)
|
69
71
|
end
|
70
72
|
end
|
71
73
|
|
@@ -136,24 +138,36 @@ module QuietQuality
|
|
136
138
|
end
|
137
139
|
end
|
138
140
|
|
141
|
+
def setup_colorization_options(parser)
|
142
|
+
parser.on("--[no-]colorize", "Colorize the logging output") do |value|
|
143
|
+
set_global_option(:colorize, value)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
139
147
|
def setup_logging_options(parser)
|
140
148
|
parser.on("-n", "--normal", "Print outcomes and messages") do
|
141
|
-
set_global_option(:logging,
|
149
|
+
set_global_option(:logging, :normal)
|
142
150
|
end
|
143
151
|
|
144
152
|
parser.on("-l", "--light", "Print aggregated results only") do
|
145
|
-
set_global_option(:logging,
|
153
|
+
set_global_option(:logging, :light)
|
146
154
|
end
|
147
155
|
|
148
156
|
parser.on("-q", "--quiet", "Don't print results, only return a status code") do
|
149
|
-
set_global_option(:logging,
|
157
|
+
set_global_option(:logging, :quiet)
|
150
158
|
end
|
151
159
|
|
152
|
-
parser.on("-L", "--logging LEVEL", "Specify logging mode
|
153
|
-
validate_value_from("logging level", level, Config::
|
160
|
+
parser.on("-L", "--logging LEVEL", "Specify logging mode (from normal/light/quiet)") do |level|
|
161
|
+
validate_value_from("logging level", level.to_sym, Config::Options::LOGGING_LEVELS)
|
154
162
|
set_global_option(:logging, level.to_sym)
|
155
163
|
end
|
156
164
|
end
|
165
|
+
|
166
|
+
def setup_verbosity_options(parser)
|
167
|
+
parser.on("-v", "--verbose", "Log more verbosely - multiple times is more verbose") do
|
168
|
+
QuietQuality.logger.increase_level!
|
169
|
+
end
|
170
|
+
end
|
157
171
|
end
|
158
172
|
end
|
159
173
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module QuietQuality
|
2
2
|
module Cli
|
3
3
|
class Entrypoint
|
4
|
+
include Logging
|
5
|
+
|
4
6
|
def initialize(argv:, output_stream: $stdout, error_stream: $stderr)
|
5
7
|
@argv = argv
|
6
8
|
@output_stream = output_stream
|
@@ -15,6 +17,7 @@ module QuietQuality
|
|
15
17
|
elsif no_tools?
|
16
18
|
log_no_tools_text
|
17
19
|
else
|
20
|
+
log_options
|
18
21
|
executed
|
19
22
|
log_results
|
20
23
|
annotate_messages
|
@@ -33,19 +36,19 @@ module QuietQuality
|
|
33
36
|
|
34
37
|
attr_reader :argv, :output_stream, :error_stream
|
35
38
|
|
36
|
-
def logger
|
37
|
-
@_logger ||= QuietQuality::Logger.new(stream: error_stream, logging: options.logging)
|
38
|
-
end
|
39
|
-
|
40
39
|
def presenter
|
41
40
|
@_presenter ||= Presenter.new(
|
42
|
-
|
43
|
-
|
41
|
+
stream: error_stream,
|
42
|
+
options: options,
|
44
43
|
outcomes: executor.outcomes,
|
45
44
|
messages: executor.messages
|
46
45
|
)
|
47
46
|
end
|
48
47
|
|
48
|
+
def log_options
|
49
|
+
debug("Complete Options object:", data: options.to_h)
|
50
|
+
end
|
51
|
+
|
49
52
|
def log_results
|
50
53
|
presenter.log_results
|
51
54
|
end
|
@@ -71,15 +74,15 @@ module QuietQuality
|
|
71
74
|
end
|
72
75
|
|
73
76
|
def log_help_text
|
74
|
-
|
77
|
+
error_stream.puts(arg_parser.help_text)
|
75
78
|
end
|
76
79
|
|
77
80
|
def log_version_text
|
78
|
-
|
81
|
+
error_stream.puts(QuietQuality::VERSION)
|
79
82
|
end
|
80
83
|
|
81
84
|
def log_no_tools_text
|
82
|
-
|
85
|
+
error_stream.puts(<<~TEXT)
|
83
86
|
You must specify one or more tools to run, either on the command-line or in the
|
84
87
|
default_tools key in a configuration file.
|
85
88
|
TEXT
|
@@ -113,6 +116,7 @@ module QuietQuality
|
|
113
116
|
|
114
117
|
def annotate_messages
|
115
118
|
return unless options.annotator
|
119
|
+
info("Annotating with #{options.annotator}")
|
116
120
|
annotator = options.annotator.new(output_stream: output_stream)
|
117
121
|
annotator.annotate!(executed.messages)
|
118
122
|
end
|
@@ -1,17 +1,17 @@
|
|
1
1
|
module QuietQuality
|
2
2
|
module Cli
|
3
3
|
class Presenter
|
4
|
-
def initialize(
|
5
|
-
@
|
6
|
-
@
|
4
|
+
def initialize(stream:, options:, outcomes:, messages:)
|
5
|
+
@stream = stream
|
6
|
+
@options = options
|
7
7
|
@outcomes = outcomes
|
8
8
|
@messages = messages
|
9
9
|
end
|
10
10
|
|
11
11
|
def log_results
|
12
|
-
return if
|
12
|
+
return if options.quiet?
|
13
13
|
|
14
|
-
if
|
14
|
+
if options.light?
|
15
15
|
log_light_outcomes
|
16
16
|
else
|
17
17
|
log_outcomes
|
@@ -21,7 +21,7 @@ module QuietQuality
|
|
21
21
|
|
22
22
|
private
|
23
23
|
|
24
|
-
attr_reader :
|
24
|
+
attr_reader :stream, :options, :outcomes, :messages
|
25
25
|
|
26
26
|
def failed_outcomes
|
27
27
|
@_failed_outcomes ||= outcomes.select(&:failure?)
|
@@ -31,26 +31,38 @@ module QuietQuality
|
|
31
31
|
@_successful_outcomes ||= outcomes.select(&:success?)
|
32
32
|
end
|
33
33
|
|
34
|
+
def colorize(color_name, s)
|
35
|
+
return s unless options.colorize?
|
36
|
+
Colorize.colorize(s, color: color_name)
|
37
|
+
end
|
38
|
+
|
39
|
+
def failed_tools_text
|
40
|
+
colorize(:red, " (#{failed_outcomes.map(&:tool).join(", ")})")
|
41
|
+
end
|
42
|
+
|
34
43
|
def log_light_outcomes
|
35
44
|
line = "%d tools executed: %d passed, %d failed" % [
|
36
45
|
outcomes.count,
|
37
46
|
successful_outcomes.count,
|
38
47
|
failed_outcomes.count
|
39
48
|
]
|
40
|
-
line +=
|
41
|
-
|
49
|
+
line += failed_tools_text if failed_outcomes.any?
|
50
|
+
stream.puts line
|
42
51
|
end
|
43
52
|
|
44
53
|
def log_outcomes
|
45
54
|
outcomes.each do |outcome|
|
46
|
-
|
47
|
-
|
55
|
+
if outcome.success?
|
56
|
+
stream.puts "--- " + colorize(:green, "Passed: #{outcome.tool}")
|
57
|
+
else
|
58
|
+
stream.puts "--- " + colorize(:red, "Failed: #{outcome.tool}")
|
59
|
+
end
|
48
60
|
end
|
49
61
|
end
|
50
62
|
|
51
63
|
def log_messages
|
52
64
|
return unless messages.any?
|
53
|
-
|
65
|
+
stream.puts "\n\n#{messages.count} messages:"
|
54
66
|
messages.each { |msg| log_message(msg) }
|
55
67
|
end
|
56
68
|
|
@@ -67,10 +79,11 @@ module QuietQuality
|
|
67
79
|
end
|
68
80
|
|
69
81
|
def log_message(msg)
|
82
|
+
tool = colorize(:yellow, msg.tool_name)
|
70
83
|
line_range = line_range_for(msg)
|
71
|
-
rule_string = msg.rule ? " [#{msg.rule}]" : ""
|
84
|
+
rule_string = msg.rule ? " [#{colorize(:yellow, msg.rule)}]" : ""
|
72
85
|
truncated_body = reduce_text(msg.body, 120)
|
73
|
-
|
86
|
+
stream.puts "#{tool} #{msg.path}:#{line_range}#{rule_string} #{truncated_body}"
|
74
87
|
end
|
75
88
|
end
|
76
89
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module QuietQuality
|
2
|
+
module Colorize
|
3
|
+
CODES = {
|
4
|
+
red: "\e[31m",
|
5
|
+
green: "\e[32m",
|
6
|
+
yellow: "\e[33m",
|
7
|
+
light_blue: "\e[94m",
|
8
|
+
light_cyan: "\e[96m"
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
RESET_CODE = "\e[0m"
|
12
|
+
|
13
|
+
def self.colorize(s, color:)
|
14
|
+
fail(ArgumentError, "Unrecognized color '#{color}'") unless CODES.include?(color.to_sym)
|
15
|
+
color_code = CODES.fetch(color.to_sym)
|
16
|
+
"#{color_code}#{s}#{RESET_CODE}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -106,6 +106,7 @@ module QuietQuality
|
|
106
106
|
|
107
107
|
def update_logging
|
108
108
|
set_unless_nil(options, :logging, apply.global_option(:logging))
|
109
|
+
set_unless_nil(options, :colorize, apply.global_option(:colorize))
|
109
110
|
end
|
110
111
|
|
111
112
|
# ---- update the tool options (apply global forms first) -------
|
@@ -1,19 +1,56 @@
|
|
1
1
|
module QuietQuality
|
2
2
|
module Config
|
3
3
|
class Options
|
4
|
+
LOGGING_LEVELS = [:quiet, :light, :normal].freeze
|
5
|
+
|
4
6
|
def initialize
|
5
7
|
@annotator = nil
|
6
8
|
@executor = Executors::ConcurrentExecutor
|
7
9
|
@tools = nil
|
8
10
|
@comparison_branch = nil
|
9
|
-
@
|
11
|
+
@colorize = true
|
12
|
+
@logging = :normal
|
10
13
|
end
|
11
14
|
|
12
15
|
attr_accessor :tools, :comparison_branch, :annotator, :executor
|
13
16
|
attr_reader :logging
|
17
|
+
attr_writer :colorize
|
14
18
|
|
15
19
|
def logging=(level)
|
16
|
-
|
20
|
+
fail(ArgumentError, "Unrecognized logging level '#{level}'") unless LOGGING_LEVELS.include?(level.to_sym)
|
21
|
+
@logging = level.to_sym
|
22
|
+
end
|
23
|
+
|
24
|
+
def colorize?
|
25
|
+
!!@colorize
|
26
|
+
end
|
27
|
+
|
28
|
+
def quiet?
|
29
|
+
logging == :quiet
|
30
|
+
end
|
31
|
+
|
32
|
+
def light?
|
33
|
+
logging == :light
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_h
|
37
|
+
{
|
38
|
+
annotator: annotator,
|
39
|
+
executor: executor.name,
|
40
|
+
comparison_branch: comparison_branch,
|
41
|
+
colorize: colorize?,
|
42
|
+
logging: logging,
|
43
|
+
tools: tool_hashes_by_name
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def tool_hashes_by_name
|
50
|
+
return {} unless tools
|
51
|
+
tools
|
52
|
+
.map { |tool_option| [tool_option.tool_name, tool_option.to_h] }
|
53
|
+
.to_h
|
17
54
|
end
|
18
55
|
end
|
19
56
|
end
|
@@ -46,7 +46,8 @@ module QuietQuality
|
|
46
46
|
read_global_option(opts, :all_files, :limit_targets, as: :reversed_boolean)
|
47
47
|
read_global_option(opts, :filter_messages, :filter_messages, as: :boolean)
|
48
48
|
read_global_option(opts, :unfiltered, :filter_messages, as: :reversed_boolean)
|
49
|
-
read_global_option(opts, :
|
49
|
+
read_global_option(opts, :colorize, :colorize, as: :boolean)
|
50
|
+
read_global_option(opts, :logging, :logging, as: :symbol, validate_from: Options::LOGGING_LEVELS)
|
50
51
|
end
|
51
52
|
|
52
53
|
def store_tool_options(opts)
|
@@ -35,6 +35,15 @@ module QuietQuality
|
|
35
35
|
return nil if @file_filter.nil?
|
36
36
|
Regexp.new(@file_filter)
|
37
37
|
end
|
38
|
+
|
39
|
+
def to_h
|
40
|
+
{
|
41
|
+
tool_name: tool_name,
|
42
|
+
limit_targets: limit_targets?,
|
43
|
+
filter_messages: filter_messages?,
|
44
|
+
file_filter: file_filter&.to_s
|
45
|
+
}
|
46
|
+
end
|
38
47
|
end
|
39
48
|
end
|
40
49
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module QuietQuality
|
2
2
|
module Executors
|
3
3
|
class Pipeline
|
4
|
+
include Logging
|
5
|
+
|
4
6
|
def initialize(tool_options:, changed_files: nil)
|
5
7
|
@tool_options = tool_options
|
6
8
|
@changed_files = changed_files
|
@@ -25,10 +27,7 @@ module QuietQuality
|
|
25
27
|
|
26
28
|
def messages
|
27
29
|
return @_messages if defined?(@_messages)
|
28
|
-
@_messages = parser.messages
|
29
|
-
@_messages = relevance_filter.filter(@_messages) if filter_messages? && changed_files
|
30
|
-
@_messages.each { |m| locator.update!(m) } if changed_files
|
31
|
-
@_messages
|
30
|
+
@_messages = relocated(filtered(parser.messages))
|
32
31
|
end
|
33
32
|
|
34
33
|
private
|
@@ -51,7 +50,12 @@ module QuietQuality
|
|
51
50
|
@_runner ||= tool_options.runner_class.new(
|
52
51
|
changed_files: limit_targets? ? changed_files : nil,
|
53
52
|
file_filter: tool_options.file_filter
|
54
|
-
)
|
53
|
+
).tap { |r| log_runner(r) }
|
54
|
+
end
|
55
|
+
|
56
|
+
def log_runner(r)
|
57
|
+
info("Runner #{r.tool_name} command: `#{r.command.join(" ")}`")
|
58
|
+
debug("Full command for #{r.tool_name}", data: r.command)
|
55
59
|
end
|
56
60
|
|
57
61
|
def parser
|
@@ -65,6 +69,23 @@ module QuietQuality
|
|
65
69
|
def locator
|
66
70
|
@_locator ||= AnnotationLocator.new(changed_files: changed_files)
|
67
71
|
end
|
72
|
+
|
73
|
+
def filtered(messages_object)
|
74
|
+
return messages_object unless filter_messages? && changed_files
|
75
|
+
|
76
|
+
original_count = messages_object.count
|
77
|
+
relevance_filter.filter(messages_object).tap do |filtered|
|
78
|
+
info("Messages for #{tool_name} filtered from #{original_count} to #{filtered.count}")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def relocated(messages_object)
|
83
|
+
if changed_files && !messages_object.empty?
|
84
|
+
messages_object.each { |m| locator.update!(m) }
|
85
|
+
info("Messages for #{tool_name} positioned into the diff for annotation purposes")
|
86
|
+
end
|
87
|
+
messages_object
|
88
|
+
end
|
68
89
|
end
|
69
90
|
end
|
70
91
|
end
|
data/lib/quiet_quality/logger.rb
CHANGED
@@ -1,17 +1,65 @@
|
|
1
1
|
module QuietQuality
|
2
2
|
class Logger
|
3
|
-
|
3
|
+
LEVEL_UPS = {none: :warn, warn: :info, info: :debug}.freeze
|
4
|
+
LEVELS = {none: 0, warn: 1, info: 2, debug: 3}.freeze
|
5
|
+
COLORS = {warn: :yellow, info: :light_blue, debug: :light_cyan}.freeze
|
6
|
+
|
7
|
+
def initialize(level: :warn, stream: $stderr)
|
8
|
+
@level = level
|
4
9
|
@stream = stream
|
5
|
-
@logging = logging
|
6
10
|
end
|
7
11
|
|
8
|
-
|
9
|
-
|
10
|
-
|
12
|
+
attr_reader :level
|
13
|
+
|
14
|
+
def increase_level!
|
15
|
+
next_level = LEVEL_UPS.fetch(level, nil)
|
16
|
+
self.level = next_level if next_level
|
17
|
+
end
|
18
|
+
|
19
|
+
def show?(message_level)
|
20
|
+
LEVELS[message_level] <= LEVELS[level]
|
21
|
+
end
|
22
|
+
|
23
|
+
def level=(name)
|
24
|
+
fail(ArgumentError, "Unrecognized Logger level '#{name}'") unless LEVELS.include?(name.to_sym)
|
25
|
+
@level = name.to_sym
|
26
|
+
end
|
27
|
+
|
28
|
+
def warn(message, data: nil)
|
29
|
+
log_message(message, data, :warn)
|
30
|
+
end
|
31
|
+
|
32
|
+
def info(message, data: nil)
|
33
|
+
log_message(message, data, :info)
|
34
|
+
end
|
35
|
+
|
36
|
+
def debug(message, data: nil)
|
37
|
+
log_message(message, data, :debug)
|
11
38
|
end
|
12
39
|
|
13
40
|
private
|
14
41
|
|
15
|
-
attr_reader :stream
|
42
|
+
attr_reader :stream
|
43
|
+
|
44
|
+
def log_message(message, data, message_level)
|
45
|
+
return unless show?(message_level)
|
46
|
+
stream.puts formatted_message(message, data, message_level)
|
47
|
+
stream.flush
|
48
|
+
end
|
49
|
+
|
50
|
+
def formatted_message(message, data, message_level)
|
51
|
+
prefix = message_level.to_s.upcase.rjust(5)
|
52
|
+
if data
|
53
|
+
data_text = JSON.pretty_generate(data)
|
54
|
+
message = message + "\n" + data_text
|
55
|
+
end
|
56
|
+
prefixed_message = message.split("\n").map { |line| "[#{prefix}] #{line}" }.join("\n")
|
57
|
+
colorize(prefixed_message, message_level)
|
58
|
+
end
|
59
|
+
|
60
|
+
def colorize(s, message_level)
|
61
|
+
color = COLORS.fetch(message_level)
|
62
|
+
Colorize.colorize(s, color: color)
|
63
|
+
end
|
16
64
|
end
|
17
65
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module QuietQuality
|
2
|
+
module Logging
|
3
|
+
def warn(message, data: nil)
|
4
|
+
logger.warn(message, data: data)
|
5
|
+
end
|
6
|
+
|
7
|
+
def info(message, data: nil)
|
8
|
+
logger.info(message, data: data)
|
9
|
+
end
|
10
|
+
|
11
|
+
def debug(message, data: nil)
|
12
|
+
logger.debug(message, data: data)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def logger
|
18
|
+
QuietQuality.logger
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module QuietQuality
|
2
2
|
module Tools
|
3
3
|
class BaseRunner
|
4
|
+
include Logging
|
5
|
+
|
4
6
|
# In general, we don't want to supply a huge number of arguments to a command-line tool.
|
5
7
|
MAX_FILES = 100
|
6
8
|
|
@@ -36,6 +38,8 @@ module QuietQuality
|
|
36
38
|
|
37
39
|
def performed_outcome
|
38
40
|
out, err, stat = Open3.capture3(*command)
|
41
|
+
log_performance(err, stat)
|
42
|
+
|
39
43
|
if success_status?(stat)
|
40
44
|
Outcome.new(tool: tool_name, output: out, logging: err)
|
41
45
|
elsif failure_status?(stat)
|
@@ -44,6 +48,11 @@ module QuietQuality
|
|
44
48
|
fail(ExecutionError, "Execution of #{tool_name} failed with #{stat.exitstatus}")
|
45
49
|
end
|
46
50
|
end
|
51
|
+
|
52
|
+
def log_performance(err, stat)
|
53
|
+
info("Runner #{tool_name} exited with #{stat.exitstatus}")
|
54
|
+
debug("Runner logs from #{tool_name}:", data: err&.split("\n"))
|
55
|
+
end
|
47
56
|
end
|
48
57
|
end
|
49
58
|
end
|
data/lib/quiet_quality.rb
CHANGED
@@ -10,7 +10,13 @@ require "set" # rubocop:disable Lint/RedundantRequireStatement
|
|
10
10
|
|
11
11
|
module QuietQuality
|
12
12
|
Error = Class.new(StandardError)
|
13
|
+
|
14
|
+
def self.logger
|
15
|
+
@_logger ||= QuietQuality::Logger.new
|
16
|
+
end
|
13
17
|
end
|
14
18
|
|
19
|
+
require_relative "./quiet_quality/logger"
|
20
|
+
require_relative "./quiet_quality/logging"
|
15
21
|
glob = File.expand_path("../quiet_quality/*.rb", __FILE__)
|
16
22
|
Dir.glob(glob).sort.each { |f| require f }
|
data/quiet_quality.gemspec
CHANGED
@@ -40,6 +40,6 @@ Gem::Specification.new do |spec|
|
|
40
40
|
spec.add_development_dependency "pry", "~> 0.14"
|
41
41
|
spec.add_development_dependency "standard", "~> 1.28"
|
42
42
|
spec.add_development_dependency "rubocop", "~> 1.50"
|
43
|
-
spec.add_development_dependency "debug"
|
43
|
+
spec.add_development_dependency "debug", "~> 1.7"
|
44
44
|
spec.add_development_dependency "mdl", "~> 0.12"
|
45
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.
|
4
|
+
version: 1.3.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-06-
|
11
|
+
date: 2023-06-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: git
|
@@ -126,16 +126,16 @@ dependencies:
|
|
126
126
|
name: debug
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- - "
|
129
|
+
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
131
|
+
version: '1.7'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- - "
|
136
|
+
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
138
|
+
version: '1.7'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: mdl
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -186,10 +186,10 @@ files:
|
|
186
186
|
- lib/quiet_quality/cli/arg_parser.rb
|
187
187
|
- lib/quiet_quality/cli/entrypoint.rb
|
188
188
|
- lib/quiet_quality/cli/presenter.rb
|
189
|
+
- lib/quiet_quality/colorize.rb
|
189
190
|
- lib/quiet_quality/config.rb
|
190
191
|
- lib/quiet_quality/config/builder.rb
|
191
192
|
- lib/quiet_quality/config/finder.rb
|
192
|
-
- lib/quiet_quality/config/logging.rb
|
193
193
|
- lib/quiet_quality/config/options.rb
|
194
194
|
- lib/quiet_quality/config/parsed_options.rb
|
195
195
|
- lib/quiet_quality/config/parser.rb
|
@@ -200,6 +200,7 @@ files:
|
|
200
200
|
- lib/quiet_quality/executors/pipeline.rb
|
201
201
|
- lib/quiet_quality/executors/serial_executor.rb
|
202
202
|
- lib/quiet_quality/logger.rb
|
203
|
+
- lib/quiet_quality/logging.rb
|
203
204
|
- lib/quiet_quality/message.rb
|
204
205
|
- lib/quiet_quality/message_filter.rb
|
205
206
|
- lib/quiet_quality/messages.rb
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module QuietQuality
|
2
|
-
module Config
|
3
|
-
class Logging
|
4
|
-
LIGHT = :light
|
5
|
-
QUIET = :quiet
|
6
|
-
NORMAL = :normal
|
7
|
-
LEVELS = [LIGHT, QUIET, NORMAL].freeze
|
8
|
-
|
9
|
-
attr_accessor :level
|
10
|
-
|
11
|
-
def initialize(level: NORMAL)
|
12
|
-
@level = level
|
13
|
-
end
|
14
|
-
|
15
|
-
def light?
|
16
|
-
@level == LIGHT
|
17
|
-
end
|
18
|
-
|
19
|
-
def quiet?
|
20
|
-
@level == QUIET
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|