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
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class DeleteBefore
6
+ def initialize(delete_before, then_processor)
7
+ @delete_before = delete_before
8
+ @then_processor = then_processor
9
+
10
+ freeze
11
+ end
12
+
13
+ def process(str, node, method_node)
14
+ return unless str
15
+
16
+ # TODO: investigate index
17
+ str = str.split(@delete_before, 2)[1] || str
18
+ @then_processor.process(str, node, method_node)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class DeletePrefix
6
+ # :nocov:
7
+ if defined?(::Leftovers::Backports::StringDeletePrefixSuffix)
8
+ using ::Leftovers::Backports::StringDeletePrefixSuffix
9
+ end
10
+ # :nocov:
11
+
12
+ def initialize(prefix, then_processor)
13
+ @prefix = prefix
14
+ @then_processor = then_processor
15
+
16
+ freeze
17
+ end
18
+
19
+ def process(str, node, method_node)
20
+ return unless str
21
+
22
+ @then_processor.process(str.delete_prefix(@prefix), node, method_node)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class DeleteSuffix
6
+ # :nocov:
7
+ if defined?(::Leftovers::Backports::StringDeletePrefixSuffix)
8
+ using ::Leftovers::Backports::StringDeletePrefixSuffix
9
+ end
10
+ # :nocov:
11
+
12
+ def initialize(suffix, then_processor)
13
+ @suffix = suffix
14
+ @then_processor = then_processor
15
+
16
+ freeze
17
+ end
18
+
19
+ def process(str, node, method_node)
20
+ return unless str
21
+
22
+ @then_processor.process(str.delete_suffix(@suffix), node, method_node)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class Demodulize
6
+ def initialize(then_processor)
7
+ @then_processor = then_processor
8
+
9
+ freeze
10
+ end
11
+
12
+ def process(str, node, method_node)
13
+ return unless str
14
+
15
+ @then_processor.process(str.demodulize, node, method_node)
16
+ rescue NoMethodError
17
+ Leftovers.error <<~MESSAGE
18
+ Tried using the String#demodulize method, but the activesupport gem was not available and/or not required
19
+ `gem install activesupport`, and/or add `requires: 'active_support/core_ext/string'` to your .leftovers.yml
20
+ MESSAGE
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class Downcase
6
+ def initialize(then_processor)
7
+ @then_processor = then_processor
8
+
9
+ freeze
10
+ end
11
+
12
+ def process(str, node, method_node)
13
+ return unless str
14
+
15
+ @then_processor.process(str.downcase, node, method_node)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class Each
6
+ attr_reader :processors
7
+
8
+ def initialize(processors)
9
+ @processors = processors
10
+
11
+ freeze
12
+ end
13
+
14
+ def process(str, node, method_node)
15
+ @processors.flat_map do |processor|
16
+ processor.process(str, node, method_node)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,33 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class EachForDefinitionSet
6
+ def initialize(then_processors)
7
+ @then_processors = then_processors
8
+
9
+ freeze
10
+ end
11
+
12
+ def process(str, node, method_node) # rubocop:disable Metrics/MethodLength
13
+ definitions = @then_processors.map do |then_processor|
14
+ processed = then_processor.process(str, node, method_node)
15
+ return if processed == :keep # rubocop:disable Lint/NonLocalExitFromIterator
16
+
17
+ processed
18
+ end
19
+
20
+ definitions.flatten!
21
+ definitions.compact!
22
+
23
+ return definitions.first if definitions.length <= 1
24
+
25
+ ::Leftovers::DefinitionSet.new(
26
+ definitions,
27
+ location: node.loc.expression,
28
+ method_node: method_node
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class EachKeyword
6
+ def initialize(then_processor)
7
+ @then_processor = then_processor
8
+
9
+ freeze
10
+ end
11
+
12
+ def process(_str, node, method_node)
13
+ kwargs = node.kwargs
14
+ return unless kwargs
15
+
16
+ kwargs.children.map do |pair|
17
+ next unless pair.type == :pair
18
+
19
+ argument_node = pair.first
20
+ str = argument_node.to_s if argument_node.string_or_symbol?
21
+
22
+ @then_processor.process(str, argument_node, method_node)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class EachKeywordArgument
6
+ def initialize(then_processor)
7
+ @then_processor = then_processor
8
+
9
+ freeze
10
+ end
11
+
12
+ def process(_str, node, method_node)
13
+ kwargs = node.kwargs
14
+ return unless kwargs
15
+
16
+ kwargs.children.map do |pair|
17
+ next unless pair.type == :pair
18
+
19
+ argument_node = pair.second
20
+ str = argument_node.to_s if argument_node.string_or_symbol?
21
+
22
+ @then_processor.process(str, argument_node, method_node)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class EachPositionalArgument
6
+ def initialize(then_processor)
7
+ @then_processor = then_processor
8
+
9
+ freeze
10
+ end
11
+
12
+ def process(_str, node, method_node)
13
+ positional_arguments = node.positional_arguments
14
+ return unless positional_arguments
15
+
16
+ positional_arguments.map do |argument_node|
17
+ str = argument_node.to_s if argument_node.string_or_symbol?
18
+
19
+ @then_processor.process(str, argument_node, method_node)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class Itself
6
+ def initialize(then_processor)
7
+ @then_processor = then_processor
8
+
9
+ freeze
10
+ end
11
+
12
+ def process(_str, node, method_node)
13
+ @then_processor.process(method_node.to_s, node, method_node)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class Keyword
6
+ # :nocov:
7
+ using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
8
+ # :nocov:
9
+
10
+ def initialize(matcher, then_processor)
11
+ @matcher = matcher
12
+ @then_processor = then_processor
13
+
14
+ freeze
15
+ end
16
+
17
+ def process(_str, node, method_node)
18
+ kwargs = node.kwargs
19
+ return unless kwargs
20
+
21
+ result = []
22
+
23
+ kwargs.children.each do |pair|
24
+ next unless @matcher === pair
25
+
26
+ argument_node = pair.first
27
+ str = argument_node.to_s
28
+
29
+ result << @then_processor.process(str, argument_node, method_node)
30
+ end
31
+
32
+ result
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class KeywordArgument
6
+ # :nocov:
7
+ using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
8
+ # :nocov:
9
+
10
+ def initialize(matcher, then_processor)
11
+ @matcher = matcher
12
+ @then_processor = then_processor
13
+
14
+ freeze
15
+ end
16
+
17
+ def process(_str, node, method_node)
18
+ kwargs = node.kwargs
19
+ return unless kwargs
20
+
21
+ result = []
22
+
23
+ kwargs.children.each do |pair|
24
+ next unless @matcher === pair
25
+
26
+ argument_node = pair.second
27
+ str = argument_node.to_s if argument_node.string_or_symbol?
28
+
29
+ result << @then_processor.process(str, argument_node, method_node)
30
+ end
31
+
32
+ result
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class Parameterize
6
+ def initialize(then_processor)
7
+ @then_processor = then_processor
8
+
9
+ freeze
10
+ end
11
+
12
+ def process(str, node, method_node)
13
+ return unless str
14
+
15
+ @then_processor.process(str.parameterize, node, method_node)
16
+ rescue NoMethodError
17
+ Leftovers.error <<~MESSAGE
18
+ Tried using the String#parameterize method, but the activesupport gem was not available and/or not required
19
+ `gem install activesupport`, and/or add `requires: 'active_support/core_ext/string'` to your .leftovers.yml
20
+ MESSAGE
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ # frozen-string-literal: true
2
+
3
+ # TODO: find a way for this to remove itself from the chain
4
+ module Leftovers
5
+ module ValueProcessors
6
+ class Placeholder
7
+ def processor=(value)
8
+ @processor = value
9
+
10
+ freeze
11
+ end
12
+
13
+ def process(str, node, method_node)
14
+ @processor.process(str, node, method_node)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class Pluralize
6
+ def initialize(then_processor)
7
+ @then_processor = then_processor
8
+
9
+ freeze
10
+ end
11
+
12
+ def process(str, node, method_node)
13
+ return unless str
14
+
15
+ @then_processor.process(str.pluralize, node, method_node)
16
+ rescue NoMethodError
17
+ Leftovers.error <<~MESSAGE
18
+ Tried using the String#pluralize method, but the activesupport gem was not available and/or not required
19
+ `gem install activesupport`, and/or add `requires: 'active_support/core_ext/string'` to your .leftovers.yml
20
+ MESSAGE
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ValueProcessors
5
+ class PositionalArgument
6
+ def initialize(index, then_processor)
7
+ @index = index
8
+ @then_processor = then_processor
9
+
10
+ freeze
11
+ end
12
+
13
+ def process(_str, node, method_node)
14
+ positional_arguments = node.positional_arguments
15
+ return unless positional_arguments
16
+
17
+ argument_node = positional_arguments[@index]
18
+ return unless argument_node
19
+
20
+ str = argument_node.to_s if argument_node.string_or_symbol?
21
+
22
+ @then_processor.process(str, argument_node, method_node)
23
+ end
24
+ end
25
+ end
26
+ end