leftovers 0.2.3 → 0.4.3

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 (147) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/README.md +65 -49
  4. data/docs/Configuration.md +627 -0
  5. data/exe/leftovers +2 -2
  6. data/leftovers.gemspec +13 -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 +126 -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 +42 -49
  19. data/lib/config/selenium-webdriver.yml +19 -0
  20. data/lib/config/sidekiq.yml +4 -8
  21. data/lib/config/will_paginate.yml +12 -14
  22. data/lib/leftovers.rb +66 -54
  23. data/lib/leftovers/ast.rb +8 -0
  24. data/lib/leftovers/ast/builder.rb +6 -3
  25. data/lib/leftovers/ast/node.rb +66 -107
  26. data/lib/leftovers/backports.rb +24 -40
  27. data/lib/leftovers/cli.rb +27 -15
  28. data/lib/leftovers/collector.rb +8 -11
  29. data/lib/leftovers/config.rb +38 -13
  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 +496 -0
  33. data/lib/leftovers/definition.rb +16 -41
  34. data/lib/leftovers/definition_node.rb +36 -0
  35. data/lib/leftovers/definition_set.rb +17 -24
  36. data/lib/leftovers/dynamic_processors.rb +11 -0
  37. data/lib/leftovers/dynamic_processors/call.rb +25 -0
  38. data/lib/leftovers/dynamic_processors/call_definition.rb +31 -0
  39. data/lib/leftovers/dynamic_processors/definition.rb +26 -0
  40. data/lib/leftovers/dynamic_processors/each.rb +19 -0
  41. data/lib/leftovers/dynamic_processors/null.rb +9 -0
  42. data/lib/leftovers/erb.rb +2 -2
  43. data/lib/leftovers/file.rb +3 -5
  44. data/lib/leftovers/file_collector.rb +79 -61
  45. data/lib/leftovers/file_list.rb +9 -15
  46. data/lib/leftovers/haml.rb +9 -12
  47. data/lib/leftovers/matcher_builders.rb +24 -0
  48. data/lib/leftovers/matcher_builders/and.rb +19 -0
  49. data/lib/leftovers/matcher_builders/and_not.rb +14 -0
  50. data/lib/leftovers/matcher_builders/argument_node_value.rb +21 -0
  51. data/lib/leftovers/matcher_builders/name.rb +29 -0
  52. data/lib/leftovers/matcher_builders/node.rb +40 -0
  53. data/lib/leftovers/matcher_builders/node_has_argument.rb +71 -0
  54. data/lib/leftovers/matcher_builders/node_has_keyword_argument.rb +22 -0
  55. data/lib/leftovers/matcher_builders/node_has_positional_argument.rb +24 -0
  56. data/lib/leftovers/matcher_builders/node_name.rb +15 -0
  57. data/lib/leftovers/matcher_builders/node_pair_name.rb +18 -0
  58. data/lib/leftovers/matcher_builders/node_pair_value.rb +16 -0
  59. data/lib/leftovers/matcher_builders/node_path.rb +14 -0
  60. data/lib/leftovers/matcher_builders/node_type.rb +28 -0
  61. data/lib/leftovers/matcher_builders/or.rb +73 -0
  62. data/lib/leftovers/matcher_builders/path.rb +15 -0
  63. data/lib/leftovers/matcher_builders/string.rb +11 -0
  64. data/lib/leftovers/matcher_builders/string_pattern.rb +19 -0
  65. data/lib/leftovers/matcher_builders/unless.rb +13 -0
  66. data/lib/leftovers/matchers.rb +26 -0
  67. data/lib/leftovers/matchers/all.rb +25 -0
  68. data/lib/leftovers/matchers/and.rb +24 -0
  69. data/lib/leftovers/matchers/any.rb +27 -0
  70. data/lib/leftovers/matchers/node_has_any_keyword_argument.rb +28 -0
  71. data/lib/leftovers/matchers/node_has_any_positional_argument_with_value.rb +25 -0
  72. data/lib/leftovers/matchers/node_has_positional_argument.rb +23 -0
  73. data/lib/leftovers/matchers/node_has_positional_argument_with_value.rb +25 -0
  74. data/lib/leftovers/matchers/node_name.rb +23 -0
  75. data/lib/leftovers/matchers/node_pair_value.rb +23 -0
  76. data/lib/leftovers/matchers/node_path.rb +23 -0
  77. data/lib/leftovers/matchers/node_scalar_value.rb +25 -0
  78. data/lib/leftovers/matchers/node_type.rb +23 -0
  79. data/lib/leftovers/matchers/not.rb +23 -0
  80. data/lib/leftovers/matchers/or.rb +26 -0
  81. data/lib/leftovers/merged_config.rb +29 -14
  82. data/lib/leftovers/parser.rb +1 -4
  83. data/lib/leftovers/processor_builders.rb +22 -0
  84. data/lib/leftovers/processor_builders/action.rb +63 -0
  85. data/lib/leftovers/processor_builders/add_prefix.rb +20 -0
  86. data/lib/leftovers/processor_builders/add_suffix.rb +20 -0
  87. data/lib/leftovers/processor_builders/argument.rb +25 -0
  88. data/lib/leftovers/processor_builders/dynamic.rb +27 -0
  89. data/lib/leftovers/processor_builders/each.rb +36 -0
  90. data/lib/leftovers/processor_builders/each_action.rb +51 -0
  91. data/lib/leftovers/processor_builders/each_dynamic.rb +54 -0
  92. data/lib/leftovers/processor_builders/each_for_definition_set.rb +36 -0
  93. data/lib/leftovers/processor_builders/itself.rb +13 -0
  94. data/lib/leftovers/processor_builders/keyword.rb +24 -0
  95. data/lib/leftovers/processor_builders/keyword_argument.rb +14 -0
  96. data/lib/leftovers/processor_builders/transform.rb +55 -0
  97. data/lib/leftovers/processor_builders/transform_chain.rb +24 -0
  98. data/lib/leftovers/processor_builders/transform_set.rb +47 -0
  99. data/lib/leftovers/processor_builders/value.rb +13 -0
  100. data/lib/leftovers/rake_task.rb +4 -4
  101. data/lib/leftovers/reporter.rb +56 -4
  102. data/lib/leftovers/todo_reporter.rb +124 -0
  103. data/lib/leftovers/value_processors.rb +40 -0
  104. data/lib/leftovers/value_processors/add_dynamic_prefix.rb +31 -0
  105. data/lib/leftovers/value_processors/add_dynamic_suffix.rb +31 -0
  106. data/lib/leftovers/value_processors/add_prefix.rb +20 -0
  107. data/lib/leftovers/value_processors/add_suffix.rb +20 -0
  108. data/lib/leftovers/value_processors/camelize.rb +24 -0
  109. data/lib/leftovers/value_processors/capitalize.rb +19 -0
  110. data/lib/leftovers/value_processors/deconstantize.rb +24 -0
  111. data/lib/leftovers/value_processors/delete_after.rb +22 -0
  112. data/lib/leftovers/value_processors/delete_before.rb +22 -0
  113. data/lib/leftovers/value_processors/delete_prefix.rb +26 -0
  114. data/lib/leftovers/value_processors/delete_suffix.rb +26 -0
  115. data/lib/leftovers/value_processors/demodulize.rb +24 -0
  116. data/lib/leftovers/value_processors/downcase.rb +19 -0
  117. data/lib/leftovers/value_processors/each.rb +21 -0
  118. data/lib/leftovers/value_processors/each_for_definition_set.rb +29 -0
  119. data/lib/leftovers/value_processors/each_keyword.rb +27 -0
  120. data/lib/leftovers/value_processors/each_keyword_argument.rb +27 -0
  121. data/lib/leftovers/value_processors/each_positional_argument.rb +24 -0
  122. data/lib/leftovers/value_processors/itself.rb +17 -0
  123. data/lib/leftovers/value_processors/keyword.rb +36 -0
  124. data/lib/leftovers/value_processors/keyword_argument.rb +36 -0
  125. data/lib/leftovers/value_processors/parameterize.rb +24 -0
  126. data/lib/leftovers/value_processors/placeholder.rb +18 -0
  127. data/lib/leftovers/value_processors/pluralize.rb +24 -0
  128. data/lib/leftovers/value_processors/positional_argument.rb +26 -0
  129. data/lib/leftovers/value_processors/replace_value.rb +18 -0
  130. data/lib/leftovers/value_processors/return_definition.rb +26 -0
  131. data/lib/leftovers/value_processors/return_string.rb +14 -0
  132. data/lib/leftovers/value_processors/singularize.rb +24 -0
  133. data/lib/leftovers/value_processors/split.rb +22 -0
  134. data/lib/leftovers/value_processors/swapcase.rb +19 -0
  135. data/lib/leftovers/value_processors/titleize.rb +24 -0
  136. data/lib/leftovers/value_processors/underscore.rb +24 -0
  137. data/lib/leftovers/value_processors/upcase.rb +19 -0
  138. data/lib/leftovers/version.rb +1 -1
  139. metadata +201 -25
  140. data/lib/config/selenium.yml +0 -21
  141. data/lib/leftovers/argument_rule.rb +0 -219
  142. data/lib/leftovers/core_ext.rb +0 -13
  143. data/lib/leftovers/hash_rule.rb +0 -40
  144. data/lib/leftovers/name_rule.rb +0 -53
  145. data/lib/leftovers/rule.rb +0 -74
  146. data/lib/leftovers/transform_rule.rb +0 -171
  147. data/lib/leftovers/value_rule.rb +0 -56
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'set'
4
+
5
+ module Leftovers
6
+ module MatcherBuilders
7
+ module Or
8
+ def self.each_or_self(value, &block)
9
+ case value
10
+ when nil then nil
11
+ when Array then build(value.map(&block))
12
+ else build([yield(value)])
13
+ end
14
+ end
15
+
16
+ def self.build(matchers)
17
+ matchers = compact(matchers)
18
+ case matchers.length
19
+ # :nocov:
20
+ when 0 then nil
21
+ # :nocov:
22
+ when 1 then matchers.first
23
+ when 2 then ::Leftovers::Matchers::Or.new(matchers.first, matchers[1])
24
+ else ::Leftovers::Matchers::Any.new(matchers.dup)
25
+ end
26
+ end
27
+
28
+ def self.flatten(value) # rubocop:disable Metrics/MethodLength
29
+ case value
30
+ when ::Leftovers::Matchers::Or
31
+ [*flatten(value.lhs), *flatten(value.rhs)]
32
+ when ::Leftovers::Matchers::Any
33
+ flatten(value.matchers)
34
+ when Array
35
+ ret = value.map { |v| flatten(v) }
36
+ ret.flatten!(1)
37
+ ret
38
+ else
39
+ value
40
+ end
41
+ end
42
+
43
+ def self.compact(matchers) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/AbcSize,
44
+ return matchers if matchers.length <= 1
45
+
46
+ set = Set.new
47
+ regexps = []
48
+ uncompactable = []
49
+
50
+ matchers = flatten(matchers)
51
+
52
+ matchers.each do |matcher|
53
+ case matcher
54
+ when nil then nil
55
+ when ::Integer, ::Symbol then set << matcher
56
+ # when ::Set then set.merge(matcher) # may not be necessary
57
+ when ::Regexp then regexps << matcher
58
+ else uncompactable << matcher
59
+ end
60
+ end
61
+
62
+ set = set.first if set.length <= 1
63
+ regexps = if regexps.length <= 1
64
+ regexps.first
65
+ else
66
+ Regexp.union(regexps)
67
+ end
68
+
69
+ [set, regexps].compact.concat(uncompactable)
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,15 @@
1
+ # frozen-string-literal: true
2
+
3
+ require 'fast_ignore'
4
+
5
+ module Leftovers
6
+ module MatcherBuilders
7
+ module Path
8
+ def self.build(path_pattern)
9
+ return if path_pattern.nil? || path_pattern.empty?
10
+
11
+ ::FastIgnore.new(include_rules: path_pattern, gitignore: false, root: Leftovers.pwd)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module MatcherBuilders
5
+ module String
6
+ def self.build(pattern)
7
+ pattern.to_sym
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module MatcherBuilders
5
+ module StringPattern
6
+ def self.build(match: nil, has_prefix: nil, has_suffix: nil)
7
+ if match
8
+ /\A#{match}\z/
9
+ elsif has_prefix && has_suffix
10
+ /\A#{::Regexp.escape(has_prefix)}.*#{::Regexp.escape(has_suffix)}\z/
11
+ elsif has_prefix
12
+ /\A#{::Regexp.escape(has_prefix)}/
13
+ elsif has_suffix
14
+ /#{::Regexp.escape(has_suffix)}\z/
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module MatcherBuilders
5
+ module Unless
6
+ def self.build(matcher)
7
+ return unless matcher
8
+
9
+ ::Leftovers::Matchers::Not.new(matcher)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Leftovers
4
+ module Matchers
5
+ autoload(:All, "#{__dir__}/matchers/all")
6
+ autoload(:And, "#{__dir__}/matchers/and")
7
+ autoload(:Any, "#{__dir__}/matchers/any")
8
+ autoload(:NodeHasAnyKeywordArgument, "#{__dir__}/matchers/node_has_any_keyword_argument")
9
+ autoload(
10
+ :NodeHasAnyPositionalArgumentWithValue,
11
+ "#{__dir__}/matchers/node_has_any_positional_argument_with_value"
12
+ )
13
+ autoload(
14
+ :NodeHasPositionalArgumentWithValue,
15
+ "#{__dir__}/matchers/node_has_positional_argument_with_value"
16
+ )
17
+ autoload(:NodeHasPositionalArgument, "#{__dir__}/matchers/node_has_positional_argument")
18
+ autoload(:NodeName, "#{__dir__}/matchers/node_name")
19
+ autoload(:NodePairValue, "#{__dir__}/matchers/node_pair_value")
20
+ autoload(:NodePath, "#{__dir__}/matchers/node_path")
21
+ autoload(:NodeScalarValue, "#{__dir__}/matchers/node_scalar_value")
22
+ autoload(:NodeType, "#{__dir__}/matchers/node_type")
23
+ autoload(:Not, "#{__dir__}/matchers/not")
24
+ autoload(:Or, "#{__dir__}/matchers/or")
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module Matchers
5
+ class All
6
+ # :nocov:
7
+ using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
8
+ # :nocov:
9
+
10
+ def initialize(matchers)
11
+ @matchers = matchers
12
+
13
+ freeze
14
+ end
15
+
16
+ def ===(value)
17
+ @matchers.all? do |matcher|
18
+ matcher === value
19
+ end
20
+ end
21
+
22
+ freeze
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module Matchers
5
+ class And
6
+ # :nocov:
7
+ using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
8
+ # :nocov:
9
+
10
+ def initialize(lhs, rhs)
11
+ @lhs = lhs
12
+ @rhs = rhs
13
+
14
+ freeze
15
+ end
16
+
17
+ def ===(value)
18
+ @lhs === value && @rhs === value
19
+ end
20
+
21
+ freeze
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module Matchers
5
+ class Any
6
+ # :nocov:
7
+ using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
8
+ # :nocov:
9
+
10
+ attr_reader :matchers
11
+
12
+ def initialize(matchers)
13
+ @matchers = matchers
14
+
15
+ freeze
16
+ end
17
+
18
+ def ===(value)
19
+ @matchers.any? do |matcher|
20
+ matcher === value
21
+ end
22
+ end
23
+
24
+ freeze
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module Matchers
5
+ class NodeHasAnyKeywordArgument
6
+ # :nocov:
7
+ using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
8
+ # :nocov:
9
+
10
+ def initialize(pair_matcher)
11
+ @pair_matcher = pair_matcher
12
+
13
+ freeze
14
+ end
15
+
16
+ def ===(node)
17
+ kwargs = node.kwargs
18
+ return false unless kwargs
19
+
20
+ kwargs.children.any? do |pair|
21
+ @pair_matcher === pair
22
+ end
23
+ end
24
+
25
+ freeze
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module Matchers
5
+ class NodeHasAnyPositionalArgumentWithValue
6
+ # :nocov:
7
+ using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
8
+ # :nocov:
9
+
10
+ def initialize(matcher)
11
+ @matcher = matcher
12
+
13
+ freeze
14
+ end
15
+
16
+ def ===(node)
17
+ node.positional_arguments.any? do |value|
18
+ @matcher === value
19
+ end
20
+ end
21
+
22
+ freeze
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module Matchers
5
+ class NodeHasPositionalArgument
6
+ # :nocov:
7
+ using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
8
+ # :nocov:
9
+
10
+ def initialize(position)
11
+ @position = position
12
+
13
+ freeze
14
+ end
15
+
16
+ def ===(node)
17
+ node.positional_arguments[@position]
18
+ end
19
+
20
+ freeze
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module Matchers
5
+ class NodeHasPositionalArgumentWithValue
6
+ # :nocov:
7
+ using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
8
+ # :nocov:
9
+
10
+ def initialize(position, matcher)
11
+ @position = position
12
+ @matcher = matcher
13
+
14
+ freeze
15
+ end
16
+
17
+ def ===(node)
18
+ value_node = node.positional_arguments[@position]
19
+ @matcher === value_node if value_node
20
+ end
21
+
22
+ freeze
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module Matchers
5
+ class NodeName
6
+ # :nocov:
7
+ using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
8
+ # :nocov:
9
+
10
+ def initialize(name_matcher)
11
+ @name_matcher = name_matcher
12
+
13
+ freeze
14
+ end
15
+
16
+ def ===(node)
17
+ @name_matcher === node.name
18
+ end
19
+
20
+ freeze
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module Matchers
5
+ class NodePairValue
6
+ # :nocov:
7
+ using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
8
+ # :nocov:
9
+
10
+ def initialize(value_matcher)
11
+ @value_matcher = value_matcher
12
+
13
+ freeze
14
+ end
15
+
16
+ def ===(node)
17
+ @value_matcher === node.second
18
+ end
19
+
20
+ freeze
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module Matchers
5
+ class NodePath
6
+ # :nocov:
7
+ using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
8
+ # :nocov:
9
+
10
+ def initialize(path_matcher)
11
+ @path_matcher = path_matcher
12
+
13
+ freeze
14
+ end
15
+
16
+ def ===(node)
17
+ @path_matcher === node.path
18
+ end
19
+
20
+ freeze
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Leftovers
4
+ module Matchers
5
+ class NodeScalarValue
6
+ # :nocov:
7
+ using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
8
+ # :nocov:
9
+
10
+ def initialize(matcher)
11
+ @matcher = matcher
12
+
13
+ freeze
14
+ end
15
+
16
+ def ===(node)
17
+ return false unless node.scalar?
18
+
19
+ @matcher === node.to_scalar_value
20
+ end
21
+
22
+ freeze
23
+ end
24
+ end
25
+ end