quiet_quality 1.0.3 → 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: d7372d3c4b395adb2890c54270426bf92b9a2a9e2669ef27d5145eda776d1072
4
- data.tar.gz: 5877277009b82e9685e62f8f8a1f17aec823faaad93c3c8e40dcb7f2640d0e7c
3
+ metadata.gz: b6aea488d2026da63fdf9483d1df9bd4e2363270d7b441cbca384cd803cab803
4
+ data.tar.gz: 0536d6eb0b8cdd1c4678f49058be4d37017b7ff6156d363afa71df8a979d30aa
5
5
  SHA512:
6
- metadata.gz: 4c860d24410fd6a03390e726fdc699113f3d0c21b722e12ccf564c666b5708690d8ed90a092448f3942496a47331e10b3d3bb7580ba2e0feeafbf74ea60bdb03
7
- data.tar.gz: 67b89da10e8fc43370d586d9282776c2f1f23a0fa4fcfbea5bfd596ab6520cca7c9319731fd960c63dc04e36ab7021b83e27497d52f2e10b8cdd9ef8a39ad394
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` load the supplied config file (instead of the detected one, if
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? || !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
@@ -48,8 +48,10 @@ module QuietQuality
48
48
  end
49
49
 
50
50
  def runner
51
- @_runner ||= tool_options.runner_class
52
- .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
+ )
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
- 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.3"
2
+ VERSION = "1.1.0"
3
3
  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.3
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
@@ -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.1.6
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