leftovers 0.3.0 → 0.4.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.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/README.md +28 -45
  4. data/docs/Configuration.md +598 -0
  5. data/exe/leftovers +1 -1
  6. data/leftovers.gemspec +9 -6
  7. data/lib/config/attr_encrypted.yml +3 -4
  8. data/lib/config/audited.yml +9 -4
  9. data/lib/config/datagrid.yml +1 -1
  10. data/lib/config/flipper.yml +1 -3
  11. data/lib/config/graphql.yml +15 -13
  12. data/lib/config/okcomputer.yml +1 -3
  13. data/lib/config/parser.yml +89 -91
  14. data/lib/config/rails.yml +125 -107
  15. data/lib/config/redcarpet.yml +35 -38
  16. data/lib/config/rollbar.yml +1 -3
  17. data/lib/config/rspec.yml +18 -10
  18. data/lib/config/ruby.yml +40 -50
  19. data/lib/config/selenium-webdriver.yml +19 -21
  20. data/lib/config/sidekiq.yml +4 -8
  21. data/lib/config/will_paginate.yml +12 -14
  22. data/lib/leftovers.rb +38 -26
  23. data/lib/leftovers/ast.rb +8 -0
  24. data/lib/leftovers/ast/builder.rb +4 -4
  25. data/lib/leftovers/ast/node.rb +50 -77
  26. data/lib/leftovers/backports.rb +27 -23
  27. data/lib/leftovers/cli.rb +0 -3
  28. data/lib/leftovers/collector.rb +4 -8
  29. data/lib/leftovers/config.rb +19 -25
  30. data/lib/leftovers/config_validator.rb +60 -0
  31. data/lib/leftovers/config_validator/error_processor.rb +196 -0
  32. data/lib/leftovers/config_validator/schema_hash.rb +495 -0
  33. data/lib/leftovers/definition.rb +11 -36
  34. data/lib/leftovers/definition_set.rb +7 -17
  35. data/lib/leftovers/dynamic_processors.rb +11 -0
  36. data/lib/leftovers/dynamic_processors/call.rb +25 -0
  37. data/lib/leftovers/dynamic_processors/call_definition.rb +31 -0
  38. data/lib/leftovers/dynamic_processors/definition.rb +26 -0
  39. data/lib/leftovers/dynamic_processors/each.rb +19 -0
  40. data/lib/leftovers/dynamic_processors/null.rb +9 -0
  41. data/lib/leftovers/erb.rb +2 -2
  42. data/lib/leftovers/file.rb +3 -5
  43. data/lib/leftovers/file_collector.rb +65 -49
  44. data/lib/leftovers/file_list.rb +0 -1
  45. data/lib/leftovers/haml.rb +1 -1
  46. data/lib/leftovers/matcher_builders.rb +24 -0
  47. data/lib/leftovers/matcher_builders/and.rb +19 -0
  48. data/lib/leftovers/matcher_builders/and_not.rb +14 -0
  49. data/lib/leftovers/matcher_builders/argument_node_value.rb +21 -0
  50. data/lib/leftovers/matcher_builders/name.rb +29 -0
  51. data/lib/leftovers/matcher_builders/node.rb +40 -0
  52. data/lib/leftovers/matcher_builders/node_has_argument.rb +71 -0
  53. data/lib/leftovers/matcher_builders/node_has_keyword_argument.rb +22 -0
  54. data/lib/leftovers/matcher_builders/node_has_positional_argument.rb +24 -0
  55. data/lib/leftovers/matcher_builders/node_name.rb +15 -0
  56. data/lib/leftovers/matcher_builders/node_pair_name.rb +18 -0
  57. data/lib/leftovers/matcher_builders/node_pair_value.rb +16 -0
  58. data/lib/leftovers/matcher_builders/node_path.rb +14 -0
  59. data/lib/leftovers/matcher_builders/node_type.rb +28 -0
  60. data/lib/leftovers/matcher_builders/or.rb +73 -0
  61. data/lib/leftovers/matcher_builders/path.rb +15 -0
  62. data/lib/leftovers/matcher_builders/string.rb +11 -0
  63. data/lib/leftovers/matcher_builders/string_pattern.rb +19 -0
  64. data/lib/leftovers/matcher_builders/unless.rb +13 -0
  65. data/lib/leftovers/matchers.rb +26 -0
  66. data/lib/leftovers/matchers/all.rb +25 -0
  67. data/lib/leftovers/matchers/and.rb +24 -0
  68. data/lib/leftovers/matchers/any.rb +27 -0
  69. data/lib/leftovers/matchers/node_has_any_keyword_argument.rb +28 -0
  70. data/lib/leftovers/matchers/node_has_any_positional_argument_with_value.rb +25 -0
  71. data/lib/leftovers/matchers/node_has_positional_argument.rb +23 -0
  72. data/lib/leftovers/matchers/node_has_positional_argument_with_value.rb +25 -0
  73. data/lib/leftovers/matchers/node_name.rb +23 -0
  74. data/lib/leftovers/matchers/node_pair_value.rb +23 -0
  75. data/lib/leftovers/matchers/node_path.rb +23 -0
  76. data/lib/leftovers/matchers/node_scalar_value.rb +25 -0
  77. data/lib/leftovers/matchers/node_type.rb +23 -0
  78. data/lib/leftovers/matchers/not.rb +23 -0
  79. data/lib/leftovers/matchers/or.rb +26 -0
  80. data/lib/leftovers/merged_config.rb +13 -8
  81. data/lib/leftovers/parser.rb +1 -4
  82. data/lib/leftovers/processor_builders.rb +22 -0
  83. data/lib/leftovers/processor_builders/action.rb +63 -0
  84. data/lib/leftovers/processor_builders/add_prefix.rb +20 -0
  85. data/lib/leftovers/processor_builders/add_suffix.rb +20 -0
  86. data/lib/leftovers/processor_builders/argument.rb +25 -0
  87. data/lib/leftovers/processor_builders/dynamic.rb +27 -0
  88. data/lib/leftovers/processor_builders/each.rb +36 -0
  89. data/lib/leftovers/processor_builders/each_action.rb +51 -0
  90. data/lib/leftovers/processor_builders/each_dynamic.rb +54 -0
  91. data/lib/leftovers/processor_builders/each_for_definition_set.rb +36 -0
  92. data/lib/leftovers/processor_builders/itself.rb +13 -0
  93. data/lib/leftovers/processor_builders/keyword.rb +24 -0
  94. data/lib/leftovers/processor_builders/keyword_argument.rb +14 -0
  95. data/lib/leftovers/processor_builders/transform.rb +55 -0
  96. data/lib/leftovers/processor_builders/transform_chain.rb +24 -0
  97. data/lib/leftovers/processor_builders/transform_set.rb +47 -0
  98. data/lib/leftovers/processor_builders/value.rb +13 -0
  99. data/lib/leftovers/rake_task.rb +1 -1
  100. data/lib/leftovers/reporter.rb +1 -1
  101. data/lib/leftovers/value_processors.rb +40 -0
  102. data/lib/leftovers/value_processors/add_dynamic_prefix.rb +31 -0
  103. data/lib/leftovers/value_processors/add_dynamic_suffix.rb +31 -0
  104. data/lib/leftovers/value_processors/add_prefix.rb +20 -0
  105. data/lib/leftovers/value_processors/add_suffix.rb +20 -0
  106. data/lib/leftovers/value_processors/camelize.rb +24 -0
  107. data/lib/leftovers/value_processors/capitalize.rb +19 -0
  108. data/lib/leftovers/value_processors/deconstantize.rb +24 -0
  109. data/lib/leftovers/value_processors/delete_after.rb +22 -0
  110. data/lib/leftovers/value_processors/delete_before.rb +22 -0
  111. data/lib/leftovers/value_processors/delete_prefix.rb +26 -0
  112. data/lib/leftovers/value_processors/delete_suffix.rb +26 -0
  113. data/lib/leftovers/value_processors/demodulize.rb +24 -0
  114. data/lib/leftovers/value_processors/downcase.rb +19 -0
  115. data/lib/leftovers/value_processors/each.rb +21 -0
  116. data/lib/leftovers/value_processors/each_for_definition_set.rb +33 -0
  117. data/lib/leftovers/value_processors/each_keyword.rb +27 -0
  118. data/lib/leftovers/value_processors/each_keyword_argument.rb +27 -0
  119. data/lib/leftovers/value_processors/each_positional_argument.rb +24 -0
  120. data/lib/leftovers/value_processors/itself.rb +17 -0
  121. data/lib/leftovers/value_processors/keyword.rb +36 -0
  122. data/lib/leftovers/value_processors/keyword_argument.rb +36 -0
  123. data/lib/leftovers/value_processors/parameterize.rb +24 -0
  124. data/lib/leftovers/value_processors/placeholder.rb +18 -0
  125. data/lib/leftovers/value_processors/pluralize.rb +24 -0
  126. data/lib/leftovers/value_processors/positional_argument.rb +26 -0
  127. data/lib/leftovers/value_processors/replace_value.rb +18 -0
  128. data/lib/leftovers/value_processors/return_definition.rb +24 -0
  129. data/lib/leftovers/value_processors/return_string.rb +14 -0
  130. data/lib/leftovers/value_processors/singularize.rb +24 -0
  131. data/lib/leftovers/value_processors/split.rb +22 -0
  132. data/lib/leftovers/value_processors/swapcase.rb +19 -0
  133. data/lib/leftovers/value_processors/titleize.rb +24 -0
  134. data/lib/leftovers/value_processors/underscore.rb +24 -0
  135. data/lib/leftovers/value_processors/upcase.rb +19 -0
  136. data/lib/leftovers/version.rb +1 -1
  137. metadata +143 -24
  138. data/lib/leftovers/argument_rule.rb +0 -229
  139. data/lib/leftovers/core_ext.rb +0 -15
  140. data/lib/leftovers/hash_rule.rb +0 -42
  141. data/lib/leftovers/name_rule.rb +0 -98
  142. data/lib/leftovers/rule.rb +0 -82
  143. data/lib/leftovers/transform_rule.rb +0 -169
  144. data/lib/leftovers/value_rule.rb +0 -57
@@ -1,20 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'set'
4
- require_relative 'config'
5
4
  require 'fast_ignore'
6
5
 
7
6
  module Leftovers
8
7
  class MergedConfig
9
- def initialize
8
+ def initialize(load_defaults: false)
10
9
  @configs = []
11
10
  @loaded_configs = Set.new
11
+ return unless load_defaults
12
+
12
13
  self << :ruby
13
14
  self << project_config
14
15
  load_bundled_gem_config
15
16
  end
16
17
 
17
- def <<(config) # rubocop:disable Metrics/MethodLength
18
+ def <<(config)
18
19
  config = Leftovers::Config.new(config) unless config.is_a?(Leftovers::Config)
19
20
  return if @loaded_configs.include?(config.name)
20
21
 
@@ -22,6 +23,9 @@ module Leftovers
22
23
  @configs << config
23
24
  @loaded_configs << config.name
24
25
  config.gems.each { |gem| self << gem }
26
+ config.requires.each do |req|
27
+ Leftovers.try_require(req, message: "cannot require '#{req}' from #{config.name}.yml")
28
+ end
25
29
  end
26
30
 
27
31
  def project_config
@@ -32,7 +36,8 @@ module Leftovers
32
36
  remove_instance_variable(:@exclude_paths) if defined?(@exclude_paths)
33
37
  remove_instance_variable(:@include_paths) if defined?(@include_paths)
34
38
  remove_instance_variable(:@test_paths) if defined?(@test_paths)
35
- remove_instance_variable(:@rules) if defined?(@rules)
39
+ remove_instance_variable(:@dynamic) if defined?(@dynamic)
40
+ remove_instance_variable(:@keep) if defined?(@keep)
36
41
  end
37
42
 
38
43
  def exclude_paths
@@ -51,12 +56,12 @@ module Leftovers
51
56
  )
52
57
  end
53
58
 
54
- def skip_rules
55
- @skip_rules ||= rules.select(&:skip?)
59
+ def dynamic
60
+ @dynamic ||= ::Leftovers::ProcessorBuilders::EachDynamic.build(@configs.map(&:dynamic))
56
61
  end
57
62
 
58
- def rules
59
- @rules ||= @configs.flat_map(&:rules)
63
+ def keep
64
+ @keep ||= ::Leftovers::MatcherBuilders::Or.build(@configs.map(&:keep))
60
65
  end
61
66
 
62
67
  private
@@ -3,9 +3,6 @@
3
3
  require 'parser'
4
4
  require 'parser/current'
5
5
 
6
- require_relative 'ast/builder'
7
- require_relative 'ast/node'
8
-
9
6
  module Leftovers
10
7
  module Parser
11
8
  class << self
@@ -23,7 +20,7 @@ module Leftovers
23
20
 
24
21
  # mostly copied from https://github.com/whitequark/parser/blob/master/lib/parser/base.rb
25
22
  # but with our builder
26
- def parser # rubocop:disable Metrics/MethodLength
23
+ def parser
27
24
  p = ::Parser::CurrentRuby.new(Leftovers::AST::Builder.new)
28
25
  p.diagnostics.all_errors_are_fatal = true
29
26
  p.diagnostics.ignore_warnings = true
@@ -0,0 +1,22 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Leftovers
4
+ module ProcessorBuilders
5
+ autoload(:Action, "#{__dir__}/processor_builders/action")
6
+ autoload(:AddPrefix, "#{__dir__}/processor_builders/add_prefix")
7
+ autoload(:AddSuffix, "#{__dir__}/processor_builders/add_suffix")
8
+ autoload(:Argument, "#{__dir__}/processor_builders/argument")
9
+ autoload(:Dynamic, "#{__dir__}/processor_builders/dynamic")
10
+ autoload(:EachAction, "#{__dir__}/processor_builders/each_action")
11
+ autoload(:EachDynamic, "#{__dir__}/processor_builders/each_dynamic")
12
+ autoload(:EachForDefinitionSet, "#{__dir__}/processor_builders/each_for_definition_set")
13
+ autoload(:Each, "#{__dir__}/processor_builders/each")
14
+ autoload(:Itself, "#{__dir__}/processor_builders/itself")
15
+ autoload(:Keyword, "#{__dir__}/processor_builders/keyword")
16
+ autoload(:KeywordArgument, "#{__dir__}/processor_builders/keyword_argument")
17
+ autoload(:TransformChain, "#{__dir__}/processor_builders/transform_chain")
18
+ autoload(:TransformSet, "#{__dir__}/processor_builders/transform_set")
19
+ autoload(:Transform, "#{__dir__}/processor_builders/transform")
20
+ autoload(:Value, "#{__dir__}/processor_builders/value")
21
+ end
22
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ProcessorBuilders
5
+ module Action
6
+ def self.build(patterns, action)
7
+ ::Leftovers::ProcessorBuilders::EachAction.each_or_self(patterns) do |pattern|
8
+ case pattern
9
+ when ::String, ::Integer
10
+ ::Leftovers::ProcessorBuilders::Argument.build(pattern, final_transformer(action))
11
+ when ::Hash
12
+ build_from_hash_value(action, **pattern)
13
+ # :nocov:
14
+ else raise
15
+ # :nocov:
16
+ end
17
+ end
18
+ end
19
+
20
+ def self.final_transformer(action)
21
+ ::Leftovers::ProcessorBuilders::TransformSet.build_final(action)
22
+ end
23
+
24
+ def self.build_from_hash_value( # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
25
+ action,
26
+ arguments: nil,
27
+ keywords: nil,
28
+ itself: nil,
29
+ value: nil,
30
+ nested: nil,
31
+ recursive: nil,
32
+ **transform_args
33
+ )
34
+ transformer = ::Leftovers::ProcessorBuilders::TransformSet.build(transform_args, action)
35
+ if nested
36
+ transformer = ::Leftovers::ProcessorBuilders::Each.build([
37
+ ::Leftovers::ProcessorBuilders::Action.build(nested, action),
38
+ transformer
39
+ ])
40
+ end
41
+
42
+ if recursive
43
+ placeholder = ::Leftovers::ValueProcessors::Placeholder.new
44
+ transformer = ::Leftovers::ProcessorBuilders::Each.build(
45
+ [placeholder, transformer]
46
+ )
47
+ end
48
+
49
+ processor = ::Leftovers::ProcessorBuilders::EachAction.build([
50
+ ::Leftovers::ProcessorBuilders::Argument.build(arguments, transformer),
51
+ ::Leftovers::ProcessorBuilders::Keyword.build(keywords, transformer),
52
+ ::Leftovers::ProcessorBuilders::Itself.build(itself, transformer),
53
+ ::Leftovers::ProcessorBuilders::Value.build(value, transformer)
54
+ ])
55
+
56
+ return processor unless recursive
57
+
58
+ placeholder.processor = processor
59
+ placeholder
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ProcessorBuilders
5
+ module AddPrefix
6
+ def self.build(argument, then_processor)
7
+ case argument
8
+ when ::Hash
9
+ dynamic_prefix = ::Leftovers::ProcessorBuilders::Action.build(argument, :call)
10
+ ::Leftovers::ValueProcessors::AddDynamicPrefix.new(dynamic_prefix, then_processor)
11
+ when ::String
12
+ ::Leftovers::ValueProcessors::AddPrefix.new(argument, then_processor)
13
+ # :nocov:
14
+ else raise
15
+ # :nocov:
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ProcessorBuilders
5
+ module AddSuffix
6
+ def self.build(argument, then_processor)
7
+ case argument
8
+ when ::Hash
9
+ dynamic_suffix = ::Leftovers::ProcessorBuilders::Action.build(argument, :call)
10
+ ::Leftovers::ValueProcessors::AddDynamicSuffix.new(dynamic_suffix, then_processor)
11
+ when ::String
12
+ ::Leftovers::ValueProcessors::AddSuffix.new(argument, then_processor)
13
+ # :nocov:
14
+ else raise
15
+ # :nocov:
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ProcessorBuilders
5
+ module Argument
6
+ def self.build(patterns, then_processor) # rubocop:disable Metrics/MethodLength
7
+ ::Leftovers::ProcessorBuilders::EachAction.each_or_self(patterns) do |pattern|
8
+ case pattern
9
+ when ::Integer
10
+ ::Leftovers::ValueProcessors::PositionalArgument.new(pattern, then_processor)
11
+ when '*'
12
+ ::Leftovers::ValueProcessors::EachPositionalArgument.new(then_processor)
13
+ when '**'
14
+ ::Leftovers::ValueProcessors::EachKeywordArgument.new(then_processor)
15
+ when ::String, ::Hash
16
+ ::Leftovers::ProcessorBuilders::KeywordArgument.build(pattern, then_processor)
17
+ # :nocov:
18
+ else raise
19
+ # :nocov:
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Leftovers
4
+ module ProcessorBuilders
5
+ module Dynamic
6
+ def self.build(dynamic_rules) # rubocop:disable Metrics/MethodLength
7
+ ::Leftovers::ProcessorBuilders::EachDynamic.each_or_self(dynamic_rules) do |dynamic|
8
+ call = ::Leftovers::ProcessorBuilders::Action.build(dynamic.delete(:call), :call)
9
+ define = ::Leftovers::ProcessorBuilders::Action.build(dynamic.delete(:define), :define)
10
+ matcher = ::Leftovers::MatcherBuilders::Node.build(**dynamic)
11
+
12
+ # this nonsense saves a method call and array instantiation per method
13
+ if call && define
14
+ ::Leftovers::DynamicProcessors::CallDefinition.new(matcher, call, define)
15
+ elsif define
16
+ ::Leftovers::DynamicProcessors::Definition.new(matcher, define)
17
+ elsif call
18
+ ::Leftovers::DynamicProcessors::Call.new(matcher, call)
19
+ # :nocov:
20
+ else raise
21
+ # :nocov:
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ProcessorBuilders
5
+ module Each
6
+ def self.each_or_self(value, &block)
7
+ case value
8
+ # :nocov:
9
+ when nil then raise
10
+ # :nocov:
11
+ when Array then build(value.map(&block))
12
+ else build([yield(value)])
13
+ end
14
+ end
15
+
16
+ def self.build(processors)
17
+ processors = compact(processors)
18
+
19
+ case processors.length
20
+ # :nocov:
21
+ when 0 then raise
22
+ # :nocov:
23
+ when 1 then processors.first
24
+ else ::Leftovers::ValueProcessors::Each.new(processors)
25
+ end
26
+ end
27
+
28
+ def self.compact(processors)
29
+ processors.flatten!
30
+ processors.compact!
31
+
32
+ processors
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ProcessorBuilders
5
+ module EachAction
6
+ def self.each_or_self(value, &block)
7
+ case value
8
+ when nil then nil
9
+ when Array then build(value.map(&block))
10
+ else build([yield(value)])
11
+ end
12
+ end
13
+
14
+ def self.build(processors)
15
+ processors = compact(processors)
16
+
17
+ case processors.length
18
+ # :nocov:
19
+ when 0 then raise
20
+ # :nocov:
21
+ when 1 then processors.first
22
+ else ::Leftovers::ValueProcessors::Each.new(processors)
23
+ end
24
+ end
25
+
26
+ def self.flatten(value) # rubocop:disable Metrics/MethodLength
27
+ case value
28
+ when ::Leftovers::ValueProcessors::Each
29
+ ret = value.processors.map { |v| flatten(v) }
30
+ ret.flatten!(1)
31
+ ret
32
+ when Array
33
+ ret = value.map { |v| flatten(v) }
34
+ ret.flatten!(1)
35
+ ret
36
+ else
37
+ value
38
+ end
39
+ end
40
+
41
+ def self.compact(processors)
42
+ return processors if processors.length <= 1
43
+
44
+ processors = flatten(processors)
45
+ processors.compact!
46
+
47
+ processors
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ProcessorBuilders
5
+ module EachDynamic
6
+ def self.each_or_self(value, &block)
7
+ case value
8
+ when nil then ::Leftovers::DynamicProcessors::Null
9
+ when Array then build(value.map(&block))
10
+ else build([yield(value)])
11
+ end
12
+ end
13
+
14
+ def self.build(processors)
15
+ processors = compact(processors)
16
+
17
+ case processors.length
18
+ # :nocov:
19
+ when 0 then raise
20
+ # :nocov:
21
+ when 1 then processors.first
22
+ else ::Leftovers::DynamicProcessors::Each.new(processors)
23
+ end
24
+ end
25
+
26
+ def self.flatten(value) # rubocop:disable Metrics/MethodLength
27
+ case value
28
+ when ::Leftovers::DynamicProcessors::Each
29
+ ret = value.processors.map { |v| flatten(v) }
30
+ ret.flatten!(1)
31
+ ret
32
+ when Array
33
+ ret = value.map { |v| flatten(v) }
34
+ ret.flatten!(1)
35
+ ret
36
+ else
37
+ value
38
+ end
39
+ end
40
+
41
+ def self.compact(processors)
42
+ return processors if processors.length <= 1
43
+
44
+ processors = flatten(processors)
45
+
46
+ processors.reject! do |p|
47
+ p == ::Leftovers::DynamicProcessors::Null
48
+ end
49
+
50
+ processors
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ProcessorBuilders
5
+ module EachForDefinitionSet
6
+ def self.each_or_self(value, &block)
7
+ case value
8
+ # :nocov:
9
+ when nil then raise
10
+ # :nocov:
11
+ when Array then build(value.map(&block))
12
+ else build([yield(value)])
13
+ end
14
+ end
15
+
16
+ def self.build(processors)
17
+ processors = compact(processors)
18
+
19
+ case processors.length
20
+ # :nocov:
21
+ when 0 then raise
22
+ # :nocov:
23
+ when 1 then processors.first
24
+ else ::Leftovers::ValueProcessors::EachForDefinitionSet.new(processors)
25
+ end
26
+ end
27
+
28
+ def self.compact(processors)
29
+ processors.flatten!
30
+ processors.compact!
31
+
32
+ processors
33
+ end
34
+ end
35
+ end
36
+ end